I'm coding one audio player which play/pause on button but its also autoplaying. So first button that appears is Pause button and when its clicked it pauses the audio and changes to Play button. Now I tried to add text under it that says Playing or Paused. I managed to do that but its only happening when the button is clicked. So when I refresh the website there is no text under playing audio, then I have to click it and it will appear first Paused and then after one more hit Playing.
So I want Playing to be under Pause Button without needing to click it.
function changeImage() {
var image = document.getElementById('player');
if (image.src.match("pause")) {
image.src = "assets/img/icons/play.png";
document.getElementById("fetch").innerHTML = "Paused";
} else {
image.src = "assets/img/icons/pause.png";
document.getElementById("fetch").innerHTML = "Playing";
}
}
var playing = true;
function action() {
var audio = document.getElementById("audio");
if (playing === false) {
audio.play();
playing = true;
document.getElementById("append").innerHTML = "Playing";
} else {
audio.pause();
playing = false;
}
}
#audioplayer {
position: relative;
left: 65px;
bottom: 11px;
float: right;
z-index: 100;
cursor: pointer;
height: 81px;
width: 81px;
border-radius: 50%;
background-color: #0FB6D1;
}
#audioplayer:hover {
-moz-box-shadow: 0 0 20px #6854e7;
-webkit-box-shadow: 0 0 20px #6854e7;
box-shadow: 0px 0px 20px #6854e7;
}
#fetch {
font-family: 'gothic';
text-align: center;
font-weight: 500;
margin-left: 1.9px;
}
<div id="audioplayer">
<img id="player" onclick="action();changeImage();" src="assets/img/icons/pause.png" />
<audio id="audio" src="assets/music/music.wav" loop autoloop autoplay></audio>
<p id="fetch"></p>
<p id="append"></p>
</div>
I am not sure why you have "fetch" & "append" divs so I have removed one for this example.
document.getElementById('player').addEventListener('click', function() {
action();
});
var playing = true;
var image = document.getElementById('player');
function action() {
var audio = document.getElementById("audio");
if (playing === false) {
audio.play();
playing = true;
document.getElementById("fetch").innerHTML = "Playing";
image.src = "assets/img/icons/pause.png";
} else {
audio.pause();
playing = false;
document.getElementById("fetch").innerHTML = "Paused";
image.src = "assets/img/icons/play.png";
}
}
HTML:
<div id="audioplayer">
<img id="player" src="assets/img/icons/pause.png" />
<audio id="audio" src="assets/music/music.wav" loop autoloop autoplay></audio>
<p id="fetch">Playing</p>
</div>
Related
Hi i need to record audio and video content on frontend that is streamed to the browser from server
I've found some info about MediaStreams so i did it and it seems that i don't record my html video and audio output but a camera output
<audio id="audio" autoplay="true"></audio>
<video id="video" autoplay="true" playsinline="true" controls></video>
var constraints = {
audio: true,
video: true,
};
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStreamObj) {
let start = document.getElementById('btnStart');
let stop = document.getElementById('btnStop');
let vidSave = document.getElementById('vid2');
let mediaRecorder = new MediaRecorder(mediaStreamObj);
let chunks = [];
start.addEventListener('click', (ev)=>{
mediaRecorder.start();
console.log(mediaRecorder.state);
})
stop.addEventListener('click', (ev)=>{
mediaRecorder.stop();
console.log(mediaRecorder.state);
});
mediaRecorder.ondataavailable = function(ev) {
chunks.push(ev.data);
}
mediaRecorder.onstop = (ev)=>{
let blob = new Blob(chunks, { 'type' : 'video/mp4;' });
chunks = [];
let videoURL = window.URL.createObjectURL(blob);
vidSave.src = videoURL;
}
})
.catch(function(err) {
console.log(err.name, err.message);
});
}
any help is appreciated because i want to do this in clean way but for now only option i see is to record whole browser window
Well, I'm guessing you're aiming for a webcam-like setup, so this works, on a server, keep in mind, you can't download video/audio unless you're hosting HTML through a server. It won't work while testing on a file though:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style type="text/css">
body {
padding: 0;
margin: 0;
}
svg:not(:root) {
display: block;
}
.playable-code {
background-color: #f4f7f8;
border: none;
border-left: 6px solid #558abb;
border-width: medium medium medium 6px;
color: #4d4e53;
height: 100px;
width: 90%;
padding: 10px 10px 0;
}
.playable-canvas {
border: 1px solid #4d4e53;
border-radius: 2px;
}
.playable-buttons {
text-align: right;
width: 90%;
padding: 5px 10px 5px 26px;
}
</style>
<style type="text/css">
body {
font: 14px "Open Sans", "Arial", sans-serif;
}
video {
margin-top: 2px;
border: 1px solid black;
}
.button {
cursor: pointer;
display: block;
width: 160px;
border: 1px solid black;
font-size: 16px;
text-align: center;
padding-top: 2px;
padding-bottom: 4px;
color: white;
background-color: darkgreen;
text-decoration: none;
}
h2 {
margin-bottom: 4px;
}
.left {
margin-right: 10px;
float: left;
width: 160px;
padding: 0px;
}
.right {
margin-left: 10px;
float: left;
width: 160px;
padding: 0px;
}
.bottom {
clear: both;
padding-top: 10px;
}
</style>
<title>Recording a media element - Example - code sample</title>
</head>
<body>
<p>Click the "Start" button to begin video recording for a few seconds. You can stop
the video by clicking the creatively-named "Stop" button. The "Download"
button will download the received data (although it's in a raw, unwrapped form
that isn't very useful).
</p>
<br>
<div class="left">
<div id="startButton" class="button">
Start
</div>
<h2>Preview</h2>
<video id="preview" width="160" height="120" autoplay muted></video>
</div>
<div class="right">
<div id="stopButton" class="button">
Stop
</div>
<h2>Recording</h2>
<video id="recording" width="160" height="120" controls></video>
<a id="downloadButton" class="button">
Download
</a>
</div>
<div class="bottom">
<pre id="log"></pre>
</div>
<script>
let preview = document.getElementById("preview");
let recording = document.getElementById("recording");
let startButton = document.getElementById("startButton");
let stopButton = document.getElementById("stopButton");
let downloadButton = document.getElementById("downloadButton");
let logElement = document.getElementById("log");
let recordingTimeMS = 5000;
function log(msg) {
logElement.innerHTML += msg + "\n";
}
function wait(delayInMS) {
return new Promise(resolve => setTimeout(resolve, delayInMS));
}
function startRecording(stream, lengthInMS) {
let recorder = new MediaRecorder(stream);
let data = [];
recorder.ondataavailable = event => data.push(event.data);
recorder.start();
log(recorder.state + " for " + (lengthInMS/1000) + " seconds...");
let stopped = new Promise((resolve, reject) => {
recorder.onstop = resolve;
recorder.onerror = event => reject(event.name);
});
let recorded = wait(lengthInMS).then(
() => recorder.state == "recording" && recorder.stop()
);
return Promise.all([
stopped,
recorded
])
.then(() => data);
}
function stop(stream) {
stream.getTracks().forEach(track => track.stop());
}
startButton.addEventListener("click", function() {
navigator.mediaDevices.getUserMedia({
video: true,
audio: true
}).then(stream => {
preview.srcObject = stream;
downloadButton.href = stream;
preview.captureStream = preview.captureStream || preview.mozCaptureStream;
return new Promise(resolve => preview.onplaying = resolve);
}).then(() => startRecording(preview.captureStream(), recordingTimeMS))
.then (recordedChunks => {
let recordedBlob = new Blob(recordedChunks, { type: "video/webm" });
recording.src = URL.createObjectURL(recordedBlob);
downloadButton.href = recording.src;
downloadButton.download = "RecordedVideo.webm";
log("Successfully recorded " + recordedBlob.size + " bytes of " +
recordedBlob.type + " media.");
})
.catch(log);
}, false);
stopButton.addEventListener("click", function() {
stop(preview.srcObject);
}, false);
</script>
</body>
</html>
This will work if you're hosting on a server, like I said, so assuming you are, this is your code. If you haven't setup a server yet, consider using Python and Flask, my personal favourites.
The above code is from MDN Web Docs by the way. This is where you can find the full tutorial and code: https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API/Recording_a_media_element.
Thanks and I hope this helps you, if not, please let me know!
I have officially exhausted my thought capabilities of this one (probably because I'm a noob to javascript) but I have a webpage where all of the elements are dynamically created from a database on that site. I have the ability for people to post videos and I want to create my own player so that I can add the functionality I want to the page. Thing is that because the elements are dynamically created I can't really use a specific ID and so I append numbers onto the end I have it so I can grab the dynamic id's and I can even get it so they all play the first vid on the page however, I can't seem to assign the play pause functionality to my buttons dynamically. here is the html I'm trying to adjust
{% if post.clip %}
<div class="container">
<div class="overlay c-vid">
<video class="vid" playsinline="playsinline" width=100%>
<source src="{{ post.clip.url }}" poster="/media/sample.jpg" type='video/mp4'>
Your browser does not support the video tag.
</video>
<div class="vid-controls">
<div class="vid-bar">
<div class="vid-bar-fill">
</div>
</div>
<div class="vid-buttons">
<button id="play-pause{{ forloop.counter }}"></button>
</div>
</div>
</div>
</div>
{% endif %}
this is the css
.vid{
width: 100%;
}
.c-vid{
width: 100%;
max-width: 800px;
position: relative;
overflow: hidden;
}
.c-vid:hover .vid-controls {
transform: translateY(0);
}
.vid-controls {
display: flex;
position: absolute;
bottom: 0%;
width:100%;
flex-wrap: wrap;
background: rgba(0,0,0,0.5);
transform: translateY(100%) translateY(-2px);
transition: all 0.1s;
}
.vid-buttons button {
background: none;
border: 0;
outline: 0;
cursor: pointer;
}
.vid-buttons button:before {
content: '\f144';
font-family: 'Font Awesome 5 free';
width: 30px;
height: 30px;
display: inline-block;
font-size: 28px;
color: #fff;
-webkit-font-smoothing: antialiased;
}
.vid-buttons button.play:before {
content: '\f144';
}
.vid-buttons button.pause:before {
content: '\f28b';
}
.vid-bar {
height: 10px;
top: 0;
left: 0;
width: 100%;
}
.vid-bar-fill {
height: 10px;
background-color: orangered;
}
and this is the javascript player I am trying to get to work
let video = document.getElementsByTagName('video');
let filling = document.querySelector('.vii-bar-fill');
let PABtn = document.getElementsByTagName('button');
let btn = [];
for (var i = 0; i < PABtn.length; i++) {
if (PABtn[i].getAttribute("id") !== null)
{
let xBtn = PABtn[i].getAttribute("id");
//console.log(i + xBtn);
let ibtn = document.getElementById(xBtn);
//console.log(btn);
btn.push(ibtn);
//console.log(btn)
}
}
//console.log(video)
//console.log(btn)
function togglePlayPause(a) {
//console.log("a="+a)
if(video.paused){
a.className = "pause";
video.play();
}
else {
a.className = "play";
video.pause();
}
}
for (i = 0; i < btn.length; i++){
let xBtn = btn[i].id
let iBtn = document.getElementById(xBtn)
iBtn.addEventListener("click", function (iBtn) {
togglePlayPause (iBtn);
});
}
for (i = 0; i < video.length; i++){
video[i].addEventListener("timeupdate", function() {
var fillPos = video[i].currentTime / video[i].duration;
filling.style.width = fillPos * 100 + "%";
});
}
any help or insight would be appreciated, just know these objects instantiate from django from a database in a for loop. I can get the videos and if I use the native player I can even play each individually but I want to program the player for better look and control than the default player.
So I found a way to do it but I'm not sure it's the simplest or most functional way. here is my end javascript
let video = document.querySelectorAll('.vid');
let filling = document.querySelector('.vid-bar-fill');
let btn = document.querySelectorAll("button[id]")
console.log(btn)
console.log(video)
function togglePlayPause(a) {
let xVid = a.srcElement.offsetParent.offsetParent.children[0]
if(xVid.paused){
a.srcElement.className = "pause";
xVid.play();
}
else {
a.srcElement.className = "play";
xVid.pause();
}
}
for (i = 0; i < btn.length; i++) {
let xBtn = btn[i]
//let xVid = video[i]
btn[i].addEventListener("click", function (xBtn) { //xVid wouldn't add here
togglePlayPause (xBtn);
});
}
so basically I just fed the button identifier through to the function, from there I was able to drill up then drill down the attributes I needed until I finally found the video attribute for the button attribute and that allowed the individual movie to play for the individual button. For some reason using btn.indexOf never worked, trying to feed 2 arguments into the anonymous function never worked and I'm not sure exactly why. But this works and so I'm satisfied. If anyone has any other suggestions I'd be more than happy to try and clean up this code a bit more.
I have an embedded YouTube video, but I want to use my own custom image for the face (thumbnail) of the video before and after the video plays. I have it working successfully up to where it shows the custom image in place of the video, and when the image is clicked, the image is removed and the video is loaded and played. Once the video is complete, the image is restored back to what appears to be the video's ready-to-play state.
However, once the image is clicked again to replay the video, the video won't play again. I was hoping that every time my playYouTubeVideo() function is called from the click event listener, that the YT.Player object would reset and load again, but this isn't working.
Any help you can give would be appreciated.
The stackoverflow snippet I created as a demo doesn't actually play the YouTube embed, and you kind of need to be able to see the video end to know what I mean, so I've included and link to a fiddle as well:
https://jsfiddle.net/MichaelVanEs/otq74r3w/3/
$(document).ready(function() {
handleYouTubePlayer();
});
//
function handleYouTubePlayer() {
// YouTube iPlayer API
var tag = document.createElement("script");
tag.src = "https://www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
//
var player;
var playerContainer = document.getElementById("player");
var iFrameVideo = document.getElementById("iFrameVideo");
var thumbnailWrap = document.getElementById("thumbnailWrap");
//
thumbnailWrap.addEventListener("click", playYouTubeVideo, false);
//
function playYouTubeVideo() {
console.log("Comes into playYouTubeVideo");
iFrameVideo.style.display = "block";
thumbnailWrap.style.display = "none";
//
player = null;
//
player = new YT.Player("iFrameVideo", {
playerVars: {
mute: 1,
autoplay: 1,
},
events: {
"onReady": onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
//
function onPlayerReady(event) {
console.log("Comes into onPlayerReady");
event.target.mute();
event.target.playVideo();
}
//
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.ENDED) { // Video has finished playing
console.log("Comes into PlayerState.ENDED");
thumbnailWrap.style.display = "block";
iFrameVideo.style.display = "none";
//
event.target.pauseVideo();
event.target.seekTo(0, true);
}
}
}
}
.imgBrd {
box-shadow: 0 0 0 1px #ccc;
}
.vid {
display: block;
width: 550px;
height: 309px;
margin: 0 auto;
}
#player {
position: relative;
}
#iFrameVideo {
display: none;
}
#thumbnailWrap {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
#thumbnail {
position: absolute;
top: 0;
left: 0;
}
#youtubeBtn {
position: absolute;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
font-size: 70px;
color: rgba(40, 40, 40, 0.95);
height: 100%;
width: 100%;
z-index: 2;
}
#youtubeBtn:hover {
cursor: pointer;
color: rgba(255, 0, 0, 0.95);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<div id="player" class="vid">
<div id="thumbnailWrap">
<img id="thumbnail" class="vid imgBrd" src="https://libapps-au.s3-ap-southeast-2.amazonaws.com/customers/4753/images/dragArticleToGroup-thumb.png" alt="Video thumbnail" />
<div id="youtubeBtn">
<i class="fa fa-youtube-play" aria-hidden="true"></i>
</div>
</div>
<iframe id="iFrameVideo" class="vid" src="https://www.youtube-nocookie.com/embed/tgbNymZ7vqY?rel=0&vq=hd720&enablejsapi=1" frameborder="0" allow="accelerometer; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
Do not create a second YT.Player. Reuse the first player you created when the thumbnail is clicked.
function playYouTubeVideo() {
...
// remove `player = null`
if (player) {
player.playVideo();
return;
}
player = new YT.Player("iFrameVideo", {
...
}
Firstly I'm trying not to use the default html5 standard controls and I'd be happy to use jQuery if possible but I've taken it out for now as I was unsure of what the problem is.
At the moment I'm simply trying to have a play button which plays some music once clicked, which will change to a pause button. This pause button will then obviously pause the music once clicked.
I will leave some annotation in so you can see some of the things I have tried. Currently the play button appears but nothing happens when it is clicked.
Any help would be greatly appreciated.
HTML:
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="javascript/audio-controls.js"></script>
<link rel="stylesheet" href="css/menu.css">
</head>
<div id="content-container">
<audio id="music">
<source src="media/mexico-music.mp3" type="audio/mpeg"/>
</audio>
<button id="play-music-button" class="play"></button>
</div>
CSS:
#play-music-button {
height:60px;
width: 60px;
border: none;
background-size: 50% 50%;
background-position: center;
}
.play {
background: url("../assets/play.png") no-repeat;
}
.pause {
background: url("../assets/pause.png") no-repeat;
}
JS:
$(document).ready(function() {
var music = document.getElementById("music");
var play_music_button = document.getElementById("play-music-button");
function playAudio() {
if (music.paused) {
music.play();
play_music_button.innerHTML = "Pause";
/*play-music-button.className = "";
play-music-button.className = "pause";*/
} else {
music.pause();
play_music_button.innerHTML = "Resume";
/*play-music-button.className = "";
play-music-button.className = "play";*/
}
music.addEventListener('ended',function() {
play_music_button.innerHTML = "Play";
});
}
play-music-button.addEventListener("click", playAudio);
});
You're calling play_music_button as play-music-button, and you've defined that twice when you only need it inside of your defined function. And you need to add an ended event listener to set the button back to "Play"
$(document).ready(function() {
var music = document.getElementById("music");
var play_music_button = document.getElementById("play-music-button");
function playAudio() {
if (music.paused) {
music.play();
play_music_button.className = 'pause';
} else {
music.pause();
play_music_button.className = 'play';
}
music.addEventListener('ended',function() {
play_music_button.className = 'play';
});
}
play_music_button.addEventListener("click", playAudio);
});
#play-music-button {
height: 60px;
width: 60px;
border: none;
background-size: 50% 50%;
background-position: center;
}
.play {
background: url("https://image.flaticon.com/icons/png/512/0/375.png") no-repeat;
}
.pause {
background: url("http://downloadicons.net/sites/default/files/pause-icon-14021.png") no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content-container">
<audio id="music">
<source src="http://skwaat.com/clips/iloveyou.mp3" type="audio/mpeg">
</audio>
<button id="play-music-button" class="play"></button>
</div>
I'm attempting to customise the control buttons on my video player. Currently I have a button that plays and pauses my video. This is working great. Though I want a visual representation of the play and pause buttons, instead of them staying the same when in the paused state or when the video is playing. I plan on having two seperate images for play and pause.
My problem is that I can't quite get my javascript to toggle my buttons, I'm thinking the best way to toggle the buttons is when one is paused, hide one element and when the video is playing hide the other element.
So here is what I have currently:
function playPause() {
mediaPlayer = document.getElementById('media-video');
if (mediaPlayer.paused)
mediaPlayer.play();
$('.play-btn').hide();
else
mediaPlayer.pause();
$('.pause-btn').hide();
}
Any help is greatly appreciated.
You need to use more Braces '{}' in if and else
function playPause() {
var mediaPlayer = document.getElementById('media-video');
if (mediaPlayer.paused) {
mediaPlayer.play();
$('.pause-btn').show();
$('.play-btn').hide();
} else {
mediaPlayer.pause();
$('.play-btn').show();
$('.pause-btn').hide();
}
}
I think it's works well.
For e.g.:
function togglePlayPause() {
// If the mediaPlayer is currently paused or has ended
if (mediaPlayer.paused || mediaPlayer.ended) {
// Change the button to be a pause button
changeButtonType(playPauseBtn, 'pause');
// Play the media
mediaPlayer.play();
}
// Otherwise it must currently be playing
else {
// Change the button to be a play button
changeButtonType(playPauseBtn, 'play');
// Pause the media
mediaPlayer.pause();
}}
Source: http://www.creativebloq.com/html5/build-custom-html5-video-player-9134473
/* in Jquery*/
$('#play-pause-button').click(function () {
if ($("#media-video").get(0).paused) {
$("#media-video").get(0).play();
}
else {
$("#media-video").get(0).pause();
}
});
Video is a DOM element not the javascript function;
Here are two examples, each comes with html, css and js.
const $ = (s, c = document) => c.querySelector(s);
const $$ = (s, c = document) => Array.prototype.slice.call(c.querySelectorAll(s));
function main(){
/* Example 1 */
// optional code to trigger click for label when 'Space' key pressed
$$('label.btn-toggle').forEach((label) => {
label.addEventListener('keypress', (e) => {
if(e.key === ' ' || e.code === 'Space'){
let input = e.target.control;
if(input){
input.click();
}
}
});
});
$('#btnPlayPause>input[type="checkbox"]').addEventListener('click', (e) => {
let input = e.target;
if(input.parentNode.getAttribute('aria-disabled') === 'true'){
e.preventDefault();
return;
}
if(input.checked){
// TODO play
console.log('playing');
}else{
// TODO pause
console.log('paused');
}
});
/* Example 2 */
$('#btnMuteUnmute').addEventListener('click', (e) => {
let button = e.target;
let isOn = button.value==='on';
if(!isOn){
// TODO mute
console.log('muted');
}else{
// TODO unmute
console.log('unmuted');
}
button.value = isOn?'off':'on';
});
}
document.addEventListener('DOMContentLoaded', main);
/* Example 1 */
label.btn-toggle{
font-size: 13.3333px;
font-family: sans-serif;
display: inline-flex;
flex-flow: row wrap;
align-content: center;
justify-content: center;
cursor: default;
box-sizing: border-box;
margin: 0px;
padding: 1px 6px;
background-color: #efefef;
color: buttontext;
border: 1px solid buttonborder;
border-radius: 2px;
user-select: none;
}
label.btn-toggle:hover{
background-color: #dfdfdf;
}
label.btn-toggle:active{
background-color: #f5f5f5;
}
.btn-toggle>input[type="checkbox"]:not(:checked)~.on-text{
display: none;
}
.btn-toggle>input[type="checkbox"]:checked~.off-text{
display: none;
}
#btnPlayPause{
width: 60px;
height: 60px;
}
/* Example 2 */
button.btn-toggle[value="on"]::after{
content: attr(data-on-text);
}
button.btn-toggle[value="off"]::after{
content: attr(data-off-text);
}
#btnMuteUnmute{
width: 60px;
height: 60px;
}
<!-- Example 1 -->
<label id="btnPlayPause" role="button" class="btn-toggle" tabindex="0" title="Play / Pause">
<input type="checkbox" tabindex="-1" autocomplete="off" hidden aria-hidden="true" />
<span class="on-text">Pause</span>
<span class="off-text">Play</span>
</label>
<!-- Example 2 -->
<button id="btnMuteUnmute" type="button" class="btn-toggle"
value="off" data-on-text="Unmute" data-off-text="Mute" title="Mute / Unmute"></button>