I am trying to build HTML5 video player but the volume seems to be currently an issue for me.
I want the volume bar to change depending on the user clicking on the volume icon. Currently if you click on the volume button it will set the volume value to 0 but then if I click again it should set it to 1. Unfortunately, it stays the whole time in the 0 and doesn't change as I click. My js looks like:
window.onload = function() {
//video
var video = document.getElementsByClassName("js-video-container__video")[0];
//Buttons
var playButton = document.getElementsByClassName("js-video-controls__play-pause")[0];
var timer = document.getElementsByClassName("js-video-controls__timer")[0];
var seconds = document.getElementsByClassName("js-video-controls__timer__seconds")[0];
var minutes = document.getElementsByClassName("js-video-controls__timer__minutes")[0];
var fullScreenButton = document.getElementsByClassName("js-video-controls__full-screen")[0];
var volumeButton = document.getElementsByClassName("js-video-controls__volume-icon")[0];
//sliders
var seekBar = document.getElementsByClassName("js-video-controls__seek-bar")[0];
var volumeBar = document.getElementsByClassName("js-video-controls__volume-bar")[0];
//event listener for the play and pause button
playButton.addEventListener("click", function() {
if (video.paused == true) {
video.play();
//button text will change to Pause
playButton.style.backgroundImage='url("https://image.flaticon.com/icons/svg/64/64485.svg")';
playButton.style.backgroundSize="13px";
} else {
//pause the video
video.pause();
//button will update its text to play
playButton.style.backgroundImage='url("https://image.flaticon.com/icons/svg/149/149657.svg")';
playButton.style.backgroundSize="13px";
// playButton.style.backgroundPositionY="4px";
}
});
// Event listener for the full-screen button
fullScreenButton.addEventListener("click", function() {
if (video.requestFullscreen) {
video.requestFullscreen();
} else if (video.mozRequestFullScreen) {
video.mozRequestFullScreen(); // Firefox
} else if (video.webkitRequestFullscreen) {
video.webkitRequestFullscreen(); // Chrome and Safari
}
});
// Event listener for the volume button
volumeButton.addEventListener("click", function() {
if (volumeBar.value !== 0) {
console.log("clicked the right button");
volumeBar.value = 0;
volumeButton.style.backgroundImage='url("https://image.flaticon.com/icons/svg/2089/2089815.svg")';
volumeButton.style.backgroundSize="13px";
} else {
volumeBar.value = 1;
}
});
//event listener for the change bar
seekBar.addEventListener("change", function() {
//calculate the new time
var time = video.duration * (seekBar.value / 100);
//update the video time
video.currentTime = time;
});
//the change bar will move as the video plays
video.addEventListener("timeupdate", function() {
//Calculate the slider value
var value = (100 / video.duration) * video.currentTime;
//Update the slider value
seekBar.value = value;
console.log(video.currentTime);
console.log(video.duration)
seconds.innerHTML = 0 + ":" + Math.floor(video.currentTime) + " / ";
minutes.innerHTML = Math.floor(video.duration / 60) + ":00";
});
//pause the video when the slider handle is being dragged
seekBar.addEventListener("mousedown", function() {
video.pause();
});
//play the video when the
seekBar.addEventListener("mouseup", function() {
video.play();
});
volumeBar.addEventListener("change", function() {
//update the video volume
video.volume = volumeBar.value;
});
}
And my html is currently:
<div class="video-controls">
<button type="button" class="video-controls__play-pause js-video-controls__play-pause"></button>
<input type="range" class="video-controls__seek-bar js-video-controls__seek-bar" value="0">
<div class="video-controls__space"></div>
<div class="video-controls__timer js-video-controls__timer">
<div class="video-controls__timer__seconds js-video-controls__timer__seconds">0:00 /</div>
<div class="video-controls__timer__minutes js-video-controls__timer__minutes"> 0:00</div>
</div>
<button class="video-controls__volume-icon js-video-controls__volume-icon"> </button>
<input type="range" class="video-controls__volume-bar js-video-controls__volume-bar" min="0" max="1" step="0.1" value="1">
<button type="button" class="video-controls__full-screen js-video-controls__full-screen"></button>
</div>
</div>
hey here's my solution I think this is what you want :)
https://jsfiddle.net/nb5Lcmvh/
var volumeButton = $(".js-video-controls__volume-icon");
//sliders
var seekBar = $(".js-video-controls__seek-bar");
var volumeBar = $(".js-video-controls__volume-bar");
$(volumeButton).click(function(){
if ($(volumeBar).val() != 0) {
$(volumeBar).val(0);
}
else{
$(volumeBar).val(1);
}
});
Related
When first loading the code, the pause button works fine, it pauses the audio and changes the HTML class of the button inside, the button continues to work after using the previous/next buttons to go to another song, however after the eventListener is triggered the pause button stops working, it doesn't pause the songs but the HTML inside still changes.
Edit: After a little bit of further debugging I found that the pause button is only able to pause the first time a track is loaded, once the audio.addEventListener('ended', nextTrack); is triggered it is unable to pause/play any audio.
let audio = new Audio;
let playing = false;
let playpause = document.getElementById('play-pause');
let root = document.documentElement;
let songname = document.getElementById('name');
let next = document.getElementById('next');
let prev = document.getElementById('previous');
let index = 0;
songlist = [
{"name":"Love Again"
,"artist":"The Kid LAROI",
"path":"resources/music/love-again.mp3",
},
{
"name":"Always Do",
"artist":"The Kid LAROI",
"path":"resources/music/always-do.mp3",
},
{
"name":"Bye Bye",
"artist":"Juice WRLD",
"path":"resources/music/bye-bye.mp3",
},
{
"name":"Understand",
"artist":"BoyWithUke",
"path":"resources/music/understand.mp3",
}
]
function progress_animation(){
var currentTime = audio.currentTime;
var duration = audio.duration;
$('#progbar').stop(true, true).animate({ 'width': (currentTime + .25) / duration * 100 + '%' }, 250, 'linear');
window.requestAnimationFrame(progress_animation);
};
function load(index){
songname.textContent = `${songlist[index].artist} - ${songlist[index].name}`;
audio.src = songlist[index].path;
audio.load()
};
audio.addEventListener('ended', nextTrack);
$('#play-pause').click(function (){
if (!playing) {
Play()
playing = true
} else {
Pause()
playing = false
}
});
function nextTrack(){
if (index < songlist.length - 1) {
index++;
} else {
index = 0;
}
load(index);
};
function prevTrack(){
if (index > 0) {
index--;
} else {
index = songlist.length - 1;
}
load(index);
};
function Play() {
audio.play();
playing = true;
playpause.innerHTML = '<i class="fa-solid fa-pause"></i>';
};
function Pause() {
audio.pause()
playing = false;
playpause.innerHTML = '<i class="fa-solid fa-play"></i>';
};
The pause button still changes its HTML class and sets the "playing" variable to false/true depending on the state of "playing" but doesn't actually pause the song
My play/pause button works the first time I press pause and the first time I press play. But after that if I want to pause the slideshow again, it just plays the slideshow at a faster speed and I am no longer able to pause it.
I am thinking maybe it is to do with the fact I have two separate functions: one for the play/pause button icon toggle, and another for the actual play pause behaviour? (update: this has now been fixed, but still doesn't work)
Sorry, I am struggling with javascript, I have a lot to learn.
My script:
const playPause = document.querySelector('.pause');
let slideId;
// FUNCTION TO MOVE TO NEXT SLIDE
const moveToNextSlide = () => {
slides = getSlides();
if (index >= slides.length - 1) return;
index++;
slideGroup.style.transform = `translateX(${-slideWidth * index}px)`;
slideGroup.style.transition = '.8s';
}
// FUNCTION TO START SLIDESHOW
const startSlide = () => {
slideId = setInterval(() => {
moveToNextSlide();
}, interval);
playing = true;
};
// START AUTOMATIC SLIDESHOW UPON ENTERING THE PAGE
startSlide();
//PLAY PAUSE BUTTON - slideshow start/stop
playPause.addEventListener('click', () => {
if(!slideId) {
slideId = startSlide();
console.log('started');
} else {
clearInterval(slideId);
slideId = null;
console.log('stopped');
}
});
//PLAY PAUSE BUTTON - image change
function toggle(button) {
if (button.className != 'pause') {
button.src = 'img/pause.png';
button.className = 'pause';
}
else if (button.className == 'pause') {
button.src = 'img/play.png';
button.className = 'play';
}
return false;
}
HTML:
<input type='image' src='img/pause.png' class='pause' onclick='toggle(this);' />
This is what the console looks like when I try to pause the slideshow for a second time:
There are some details in your code that are missing and would be helpful to have, but I guess that you can get rid of the onclick handler and attach two event listeners:
let slideId;
// FUNCTION TO START SLIDESHOW
const startSlide = () => {
let interval = 2000; // using just as sample
playing = true;
return setInterval(() => {
console.log('moveToNextSlide();') // replaced just to test without missing code
}, interval);
};
//PLAY PAUSE BUTTON - slideshow start/stop
playPause.addEventListener('click', () => {
if(!slideId) {
slideId = startSlide();
console.log('started');
} else {
clearInterval(slideId);
slideId = null;
console.log('stopped');
}
});
//PLAY PAUSE BUTTON - image change
playPause.addEventListener('click', function toggle() { // the arrow function would not work in this case
var button = this;
if (button.className != 'pause') {
button.src = 'img/pause.png';
button.className = 'pause';
}
else if (button.className == 'pause') {
button.src = 'img/play.png';
button.className = 'play';
}
return false;
});
I'm attempting to create two audio players on the same page. I've seen a similar question, which suggested, "filtering tasks for each audio element and audio value," but my player is so different than the one in that question that I'm not sure how to apply it to mine.
Whenever I try to play the first player, the second starts instead and breaks if I start clicking around. The scripts for the two players are in different files, I've already changed the IDs so there aren't duplicates, and I also tried changing the variable and function names thinking that maybe they were having some impact. Nothing has worked.
I'm using the same code for each player, but with a different prefix on each ID:
/* global $ */
var audio;
//Hide Pause
$('#pause').hide();
initAudio($('#playlist').find('li:first-child'));
$('#playlist').on('click', function(event) {
initAudio($(event.target));
});
// Initiate play sequence
function initAudio(element){
var recording = element.attr('data-id');
var title = element.text();
var artist = element.attr('data-artist');
//Create audio object
audio = new Audio('public/audio_files/'+ recording);
//Insert audio info
$('.artist').text(artist);
$('.title').text(title);
$('#playlist li').removeClass('active');
element.addClass('active');
// Set timer to 0
$('#duration').html('0:00');
// Maintain volume on song change
audio.volume = $('#volume').val() / 100;
}
//Play button
$('#play').click(function() {
audio.play();
showPause();
showDuration();
});
//Pause button
$('#pause').click(function() {
audio.pause();
showPlay();
});
//Next button
$('#next').click(function() {
audio.pause();
var next = $('#playlist li.active').next();
if(next.length == 0){
next = $('#playlist li:first-child');
}
showPause();
initAudio(next);
audio.play();
showDuration();
});
//Prev button
$('#prev').click(function() {
audio.pause();
var prev = $('#playlist li.active').prev();
if(prev.length == 0){
prev = $('#playlist li:last-child');
}
showPause();
initAudio(prev);
audio.play();
showDuration();
});
//Playlist song click
$('#playlist li').click(function() {
audio.pause();
initAudio($(this));
showPause();
audio.play();
showDuration();
});
//Volume control
$('#volume').change(function() {
audio.volume = parseFloat(this.value / 100);
});
// Show play button, hide pause
function showPlay() {
$('#play').show();
$('#pause').hide();
}
// Show pause button, hide play
function showPause() {
$('#play').hide();
$('#pause').show();
}
// Automatically play next song
function autoPlayNext() {
if(audio.currentTime == audio.duration) {
var next = $('#playlist li.active').next();
if(next.length == 0){
next = $('#playlist li:first-child');
}
showPause();
initAudio(next);
audio.play();
showDuration();
}
}
// Time/Duration
function showDuration() {
$(audio).bind('timeupdate', function() {
//Get hours and minutes
var s = parseInt(audio.currentTime % 60, 10);
var m = parseInt(audio.currentTime / 60, 10) % 60;
if(s < 10) {
s = '0' + s;
}
$('#duration').html(m + ':'+ s);
var value = 0;
if(audio.currentTime > 0){
value = Math.floor((100 / audio.duration) * audio.currentTime);
}
$('#progress').css('width', value + '%');
autoPlayNext();
});
}
// Skip time via progress bar click
$('#progress-bar').bind('click', function (e) {
var $div = $(e.target);
var offset = $div.offset();
var x = e.clientX - offset.left;
audio.currentTime = ((x / 2.3)/(100 / audio.duration)); /* length of progress-bar is 230px hence (x/2.3) */
});
Any insight?
I wrote the code like this, and the play button works but the timer does not.
<input type="button" id="play" onclick="videoplay();" value=">"/>
....
<span id="timer">0%</span>
....
function videoplay() {
var video = document.getElementById("video");
var button = document.getElementById("play");
if (video.paused) {
video.play();
button.value = "||";
var timer = getElementbyId("timer");
var update = setInterval(function () {
timer.textContent = Math.round(video.currentTime / video.duration * 100) + "%";
}, 500);
} else {
video.pause();
button.value = ">";
if (update)
clearInterval(update);
}
}
timer.innerText = Math.round(video.currentTime / video.duration * 100) + "%";
i want to play 2 sounds in ios and since it could not be done, i defined 2 audio objects.
i start playing the first sound and when want to play the second, i pause the first and wait till the second end, then i resume playing the first from the point it reached.
you can check the following code, if i remove the alert("test"); the first audio start playing from zero and so current time don't work!
kindly help.
Thanks,
var PlayedTime = 0; ; //in seconds
var AudioObj;
var audioType = '.mp3';
var isResume = false;
$(document).ready(function () {
if (!!AudioSound.canPlayType('audio/ogg') === true) {
audioType = '.ogg' //For firefox and others who do not support .mp3
}
AudioObj = document.getElementById('AudioSound');
document.getElementById('AudioSound').addEventListener('ended', function () {
resume();
});
});
function play1() {
AudioObj.src = "Images/Sound1" + audioType;
AudioObj.load();
}
function play2() {
PlayedTime = AudioObj.currentTime;
AudioObj.pause();
AudioObj.src = "Images/Sound2" + audioType;
AudioObj.load();
AudioObj.play();
}
function resume() {
isResume = true;
AudioObj.pause();
AudioObj.src = "Images/Sound1" + audioType;
AudioObj.load();
}
function JumpAudio() {
AudioObj.currentTime = 36;
}
function DataLoadedtoPlay() {
AudioObj.play();
if (isResume) {
isResume = false;
try {
alert("test");
AudioObj.currentTime = PlayedTime;
}
catch (e) {
alert("catch");
}
}
}
<div id="containerAud">
<audio id="AudioSound" onloadeddata="DataLoadedtoPlay()"></audio>
</div>
<input type = "button" onclick="play1()" value="click1"/>
<input type = "button" onclick="play2()" value="click2" />
<input type = "button" onclick="JumpAudio()" value="JumpAudio" />
</div>