I try to work with HTML5 tag and create my own palyer.
My html:
<video id="video">
<source src="video/v.mp4" />
<source src="video/v.ogg" />
<source src="video/v.webm" />
</video>
<br />
<button id="part1Button">
1
</button>
<button id="part2Button">
2
</button>
<button id="part3Button">
3
</button>
<button id="playButton">play</button>
<button id="pauseButton">pause</button>
My JavaScript:
<script type="text/javascript">
window.onload = function () {
var video = document.getElementById("video");
var p = v.duration / 3;
document.getElementById("part1Button").onclick = function () {
video.currentTime = 0;
};
document.getElementById("part2Button").onclick = function () {
video.currentTime = p;
};
document.getElementById("part3Button").onclick = function () {
video.currentTime = p * 2;
};
document.getElementById("playButton").onclick = function () {
video.play();
};
document.getElementById("pauseButton").onclick = function () {
video.pause();
};
}
</script>
All three buttons: 1,2,3 do not work in Google Chrome. I will have the next error when I click on them : "Uncaught TypeError: Failed to set the 'currentTime' property on 'HTMLMediaElement': The provided double value is non-finite".
When I replace video.currentTime = p * 2 on video.currentTime = (video.duration / 3) * 2 everything works fine.
Can somebody explan me why is this happening?
Many thanks.
The problem are these lines:
var video = document.getElementById("video");
var p = v.duration / 3;
I guess you wanted to write:
var p = video.duration / 3;
Hope it helps!
UPDATE 1:
And, as Derek 朕會功夫 has pointed out, if the video is not ready is not possible to calculate the duration. You can get more info here.
UPDATE 2:
I have added a snippet with all the buttons working.
var v = document.getElementById("video");
v.onloadedmetadata = function() {
var part = Math.floor(v.duration / 3);
document.getElementById("part1Button").onclick = function() {
v.currentTime = 0;
};
document.getElementById("part2Button").onclick = function() {
v.currentTime = part;
};
document.getElementById("part3Button").onclick = function() {
v.currentTime = part * 2;
};
document.getElementById("playButton").onclick = function() {
v.play();
};
document.getElementById("pauseButton").onclick = function() {
v.pause();
};
}
<video id="video" style="border: 2px solid gray;" height="200" width="200">
<source src="https://upload.wikimedia.org/wikipedia/commons/transcoded/4/4d/Wikipedia_Edit_2014.webm/Wikipedia_Edit_2014.webm.480p.webm" />
</video>
<br>
<button id="part1Button">
1
</button>
<button id="part2Button">
2
</button>
<button id="part3Button">
3
</button>
<button id="playButton">play</button>
<button id="pauseButton">pause</button>
Related
I have 2 function which play the same video but with different timing.
I can't play make the function to work properly.
Looks like the function doesn't reset the other function
I tried to change variables names but still change the timing on click.
var video = document.getElementById('videoElm');
function playShortVideo() {
var starttime = 0; // start at 0 seconds
var endtime = 2; // stop at 2 seconds
video.addEventListener("timeupdate", function() {
if (this.currentTime >= endtime) {
this.currentTime = 0; // change time index here
}
}, false);
video.load();
video.play();
}
function playFullVideo() {
var starttime = 0; // start at 0 seconds
var endtime = 24; // stop at 2 seconds
video.addEventListener("timeupdate", function() {
if (this.currentTime >= endtime) {
this.currentTime = 0; // change time index here
}
}, false);
video.load();
video.play();
}
//play short video by default
playShortVideo();
//CLICK events
var btnshort = $('.shortvideo');
var btnfull = $('.fullvideo');
btnshort.click(function() {
playShortVideo();
});
btnfull.click(function() {
playFullVideo();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<video id="videoElm" autoplay muted controls loop>
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type="video/webm">
</video>
</div>
<button class="shortvideo">play 2 secs only</a><br>
<button class="fullvideo">loop full video</button>
That's because the listener is still there, you need to remove it.
Remember, in order to remove it, you can't use anonymous function as callback so I turned it into defined function.
var video = document.getElementById('videoElm');
const playShort = function() {
if (this.currentTime >= 2) {
this.currentTime = 0; // change time index here
}
};
const playFull = function() {
if (this.currentTime >= 24) {
this.currentTime = 0; // change time index here
}
};
function playShortVideo() {
video.removeEventListener("timeupdate", playFull, false)
video.addEventListener("timeupdate", playShort, false);
video.load();
video.play();
}
function playFullVideo() {
video.removeEventListener("timeupdate", playShort, false)
video.addEventListener("timeupdate", playFull, false);
video.load();
video.play();
}
//play short video by default
playShortVideo();
//CLICK events
var btnshort = $('.shortvideo');
var btnfull = $('.fullvideo');
btnshort.click(function() {
playShortVideo();
});
btnfull.click(function() {
playFullVideo();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<video id="videoElm" autoplay muted controls loop>
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type="video/webm">
</video>
</div>
<button class="shortvideo">play 2 secs only</a><br>
<button class="fullvideo">loop full video</button>
And here is the approach for starting the video at 49 sec (60 > 49 + 10)
const shortStartTime = 49;
const shortDuration = 10;
var video = document.getElementById('videoElm');
const playShort = function() {
if (this.currentTime > (shortStartTime + shortDuration)) {
this.currentTime = shortStartTime; // change time index here
}
};
const playFull = function() {
if (this.currentTime >= 24) {
this.currentTime = 0; // change time index here
}
};
function playShortVideo() {
video.removeEventListener("timeupdate", playFull, false)
video.addEventListener("timeupdate", playShort, false);
video.load();
video.currentTime = shortStartTime;
video.play();
}
function playFullVideo() {
video.removeEventListener("timeupdate", playShort, false)
video.addEventListener("timeupdate", playFull, false);
video.load();
video.play();
}
//play short video by default
playShortVideo();
//CLICK events
var btnshort = $('.shortvideo');
var btnfull = $('.fullvideo');
btnshort.click(function() {
playShortVideo();
});
btnfull.click(function() {
playFullVideo();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<video id="videoElm" autoplay muted controls loop>
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type="video/webm">
</video>
</div>
<button class="shortvideo">play 2 secs only</a><br>
<button class="fullvideo">loop full video</button>
That happens because you're attaching a timeUpdate event listener multiple times.
You either need to use one-only or delete it before attaching a new one.
var video = document.getElementById('videoElm');
var listener;
var starttime = 0;
var endtime = 2;
function updateVideo(e) {
if (e.target.currentTime >= endtime) {
e.target.currentTime = 0; // change time index here
}
}
function playShortVideo() {
starttime = 0; // start at 0 seconds
endtime = 2; // stop at 2 seconds
if (!listener) {
listener = video.addEventListener("timeupdate", updateVideo, false);
}
video.load();
video.play();
}
function playFullVideo() {
starttime = 0; // start at 0 seconds
endtime = 24; // stop at 2 seconds
if (!listener) {
listener = video.addEventListener("timeupdate", updateVideo, false);
}
video.load();
video.play();
}
//play short video by default
playShortVideo();
//CLICK events
var btnshort = $('.shortvideo');
var btnfull = $('.fullvideo');
btnshort.click(function() {
playShortVideo();
});
btnfull.click(function() {
playFullVideo();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<video id="videoElm" autoplay muted controls loop>
<source src="http://clips.vorwaerts-gmbh.de/VfE_html5.mp4" type="video/webm">
</video>
</div>
<button class="shortvideo">play 2 secs only</a><br>
<button class="fullvideo">loop full video</button>
I'm designing a landing page with video background. I'd like to auto-play a series of background video clips (looping back to #1 when the sequence runs out, although I haven't tried to integrate this wrinkle yet). I pulled some sample code off a reputable webdev blog and adapted it, but currently to no effect (my initial video plays once with the desired effect, but gives way to its poster image, rather than the next clip). Relevant html and js below. Help much appreciated!
<div id="video-box">
<video class="landing-video" autoplay muted poster="./resources/media/images/Two-Swimmers.jpg">
<source src="./resources/media/video/Two-Swimmers.mp4" type="video/mp4" />
</video>
<div class="video-playlist">
</div>
</div>
<script type="text/javascript" src="video.js"></script>
video.js code:
( function() {
var videoPlayer = document.getElementById( 'video-box' ),
video = videoPlayer.getElementsByClassName( 'landing-video' )[0],
playlist = videoPlayer.getElementsByClassName( 'video-playlist' )[0],
source = video.getElementsByTagName( 'source' ),
linkList = [],
videoDirectory = './resources/media/video/',
currentVideo = 0,
allLinks = playlist.children,
linkNumber = allLinks.length,
i, filename;
function playVideo( index ) {
allLinks[index].classList.add( 'current-video' );
currentVideo = index;
source[0].src = videoDirectory + linkList[index] + '.mp4';
video.load();
video.play();
}
for ( i = 0; i < linkNumber; i++ ) {
filename = allLinks[i].href;
linkList[i] = filename.match( /([^\/]+)(?=\.\w+$)/ )[0];
}
video.addEventListener( 'ended', function () {
allLinks[currentVideo].classList.remove( 'current-video' );
nextVideo = currentVideo + 1;
if ( nextVideo >= linkNumber ) {
nextVideo = 0;
}
playVideo( nextVideo );
} );
} () );
I changed video to have a src attribute, and I used setAttribute in the ended event handler.
var video = document.querySelector('video');
var links = document.querySelectorAll('.video-playlist > a');
var i = 0;
video.addEventListener('ended', function() {
i++;
if (i >= links.length) {
current = 0;
}
var a = links.item(i);
a.className = 'current-video';
video.setAttribute('src', a.href);
video.play();
});
<div id="video-box">
<video class="landing-video" autoplay muted src="https://www.w3schools.com/html/mov_bbb.mp4">
</video>
<div class="video-playlist">
</div>
</div>
I don't have your CSS so you can't see the <a> tags or the current-video class. I also don't have your video files so I grabbed some public videos for demonstration purposes.
I'm looking for a simple way to temporarily disable a mouseover event, for literally 1000 miliseconds. All my attempts to do so, have so-far failed. I am trying to stop my images from flickering when the mouse enters several times as it hovers over the edge of the div. Here is my code:
var ranNum, result_10, resultFloor, piccy, audio;
function myFunction() {
ranNum = Math.random();
result_10 = (ranNum * 5) + 1;
resultFloor = Math.floor(result_10);
piccy = "<img src=\"random_images/" + resultFloor + ".gif\" />";
document.getElementById("demo").innerHTML = piccy;
audio = document.getElementById("audio");
audio.play();
}
<div id="container">
<div id="demo" onmouseenter="myFunction()">This</div>
<audio id="audio" src="pop.wav" ></audio>
</div>
This will stop the flicker:
var ranNum, result_10, resultFloor, piccy, audio;
var isPlaying = false;
var audio = document.getElementById("audio");
function myFunction() {
if (!isPlaying) {
isPlaying = true;
ranNum = Math.random();
result_10 = (ranNum * 5) + 1;
resultFloor = Math.floor(result_10);
piccy = "<img src=\"http://d2.alternativeto.net/dist/icons/cloudapp_2094.png?width=64&height=64&mode=crop&upscale=false\" />";
document.getElementById("demo").innerHTML = piccy;
// check every 1/2 second to see if the audio has ended
var t = setInterval(function() {
console.log(audio.ended);
if (audio.ended) {
isPlaying = false;
clearInterval(t);
}
}, 500);
audio.play();
}
}
<div id="container">
<div id="demo" onmouseenter="myFunction()">This</div>
<audio id="audio" src="http://freewavesamples.com/files/Casio-MT-45-Pops.wav" ></audio>
</div>
var myFunctionDisabled = null;
function disableMyFunction() {
clearTimeout(myFunctionDisabled);
myFunctionDisabled = setTimeout(function() { myFunctionDisabled = false; }, 1000);
}
function myFunction() {
if (myFunctionDisabled) return;
...
}
Here's a quick and dirty approach. Simply uses a variable referencing a function, and changes the reference to point to a function that does nothing, then back to the original function.
I agree with Kosch's suggestion of using the underscore/lodash debounce function if you're already using those libraries or if you see them helping you in more than just this one case.
var ranNum, result_10, resultFloor, piccy, audio;
function myFunction() {
disableMouseOverHandler();
ranNum = Math.random();
result_10 = (ranNum * 5) + 1;
resultFloor = Math.floor(result_10);
piccy = "<img src=\"random_images/" + resultFloor + ".gif\" />";
document.getElementById("demo").innerHTML = piccy;
audio = document.getElementById("audio");
audio.play();
}
function doNothing() {
}
var mouseOverHandler = myFunction;
function disableMouseOverHandler() {
mouseOverHandler = doNothing;
setTimeout(function(){ mouseOverHandler = myFunction; }, 3000);
//I used 3000ms (3 seconds) to make it more pronounced.
}
<div id="container">
<div id="demo" onmouseenter="mouseOverHandler()">This</div>
<audio id="audio" src="pop.wav" ></audio>
</div>
I've been using this custom audio player I put together with a few tutorials and solves around the Internet and have been using it for the past 2 months.
It worked 100% in Chrome, but after an update the seek bar happened to stop working.
Is this an issue on my end? or does it work for anyone else?
HTML:
<div id="musicplayer">
<table>
<tr>
<audio id="audio" src="../audio/oby/weightless/Got To Be Free.mp3"></audio>
<td>
<button id="play" type="button" onclick="playPause()" ></button>
</td>
<td>
<div id="boxed" >
Select a song from the playlist
<p class="right" id="timeInfo">00:00</p>
<input type="range" step="any" id="seekbar"></input>
</div>
</td>
</tr>
</table>
</div>
JavaScript:
<script>
var audio = document.getElementsByTagName('audio')[0],
div = document.getElementById('timeInfo');
function formatTime(s, m) {
s = Math.floor( s );
m = Math.floor( s / 60 );
m = m >= 10 ? m : '0' + m;
s = Math.floor( s % 60 );
s = s >= 10 ? s : '0' + s;
return m + ':' + s;
}
setInterval(function()
{
div.textContent = formatTime(audio.currentTime);
}, 100);
seekbar.value = 0;
var audio = document.getElementById("audio");
var seekbar = document.getElementById('seekbar');
function setupSeekbar() {
seekbar.min = audio.startTime;
seekbar.max = audio.startTime + audio.duration;
}
audio.ondurationchange = setupSeekbar;
function seekAudio() {
audio.currentTime = seekbar.value;
}
function updateUI() {
var lastBuffered = audio.buffered.end(audio.buffered.length-1);
seekbar.min = audio.startTime;
seekbar.max = lastBuffered;
seekbar.value = audio.currentTime;
}
seekbar.onchange = seekAudio;
audio.ontimeupdate = updateUI;
audio.addEventListener('durationchange', setupSeekbar);
audio.addEventListener('timeupdate', updateUI);
</script>
Duplicate code:
audio.ondurationchange = setupSeekbar;
and
audio.addEventListener('durationchange', setupSeekbar);
try removing any of these lines.
and if setting seekbar value in javascript will triger onchange... you will have to remove seekbar.onchange = seekAudio;
Is your seekbar doesn't seek when user click any time? Or is there a problem on updating time. (time is updating but seekbar doesn't)?
You do not need these codes, might also cause problem one... (the seekbar update problem)
var lastBuffered = audio.buffered.end(audio.buffered.length-1);
seekbar.min = audio.startTime;
seekbar.max = lastBuffered;
EDIT (offtopic): For better performance remove the code
setInterval(function()
{
div.textContent = formatTime(audio.currentTime);
}, 100);
and append this to updateUI
div.textContent = formatTime(audio.currentTime);
right now I have an array of videos. How do I make it so when i click next and prev the next or previous video in the array loads.
<video id="video" controls autoplay width="1000">
<source src="videos/test.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
<source src="videos/test.ogv" />
</video>
next
<script>
var vidURL=["videos/test.ogv","videos/test2.ogv","videos/test3.ogv","videos/test4.ogv","videos/test5.ogv" ]; // literal array
function vidSwap(vidURL) {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = vidURL;
myVideo.load();
myVideo.play();
}
Using yout code, it'll be something like this.
What you need to do is have the video that you loaded on a javascript variable.
Then, when you click prev or next you can call a function that will put the correct video number and call it.
<script>
var vidURL=["videos/test.ogv","videos/test2.ogv","videos/test3.ogv","videos"]
var video = 0;
function vidSwap() {
var myVideo = document.getElementsByTagName('video')[video];
myVideo.src = vidURL[video];
myVideo.load();
myVideo.play();
}
function prevVideo() {
if(video == 0) {
video = vidUrl.length;
}
else {
video -= 1;
}
vidSwap();
}
function nextVideo() {
if(video == length) {
video = 0;
}
else {
video += 1;
}
vidSwap();
}
</script>
<video id="video" controls autoplay width="1000">
<source src="videos/test.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
<source src="videos/test.ogv" />
</video>
prev
next
Introduce variable which will save current video index, then increment it or decrement it each time you press next/prev
</script>
var i = 0;
<script>
javascript:vidSwap(vidURL[i++])
It looks like you're missing another plus sign in your increment operator.
Try changing
next
To this
next
Wrapped up alternative with wrap-around;
next
prev
...
var Vids = (function() {
var _currentId = -1;
var _urls = ["videos/test.ogv","videos/test2.ogv","videos/test3.ogv","videos/test4.ogv","videos/test5.ogv" ]; // literal array
return {
next: function() {
if (++_currentId >= _urls.length)
_currentId = 0;
return this.play(_currentId);
},
prev: function() {
if (--_currentId < 0)
_currentId = _urls.length - 1;
return this.play(_currentId);
},
play: function(id) {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = _urls[id];
myVideo.load();
myVideo.play();
return false;
}
}
})();