Tying to play videos but The use of my variables are not working.
First video play only once, when stops second video starts.
Second video plays and loops.
Video should play smoothly with no gaps and no jumps.
My Demo: http://jsfiddle.net/654geqvp/1/
var start = [
"http://praegnanz.de/html5video/player/video_SD.webm",
"http://praegnanz.de/html5video/player/video_SD.webm",
"http://praegnanz.de/html5video/player/video_SD.mp4"];
var loop = [
"http://broken-links.com/tests/media/BigBuck.webm",
"http://broken-links.com/tests/media/BigBuck.theora.ogv",
"http://broken-links.com/tests/media/BigBuck.m4v"];
var curSrc = 0;
$(function() {
$('#start').attr(start, start[curSrc % start.length]);
curSrc++;
var video = $('#start').get(0);
$('#start').on('loadedmetadata', function() {
video.currentTime = 0.01;
video.play();
}).on('ended', function() {
//console.log('ended');
video.loop = loop[curSrc % loop.length];
video.load();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<video id="start" style="width:100%;"></video>
I figured it out, I changed some variable names around. You need to set the loop attribute on the video to true. You can remove the controls attribute it you wish. I converted the original to a jQuery plugin.
To get rid of the black flash when transitioning videos, you can set the poster attribute of the video element to be the first frame of the second video.
$.fn.videoLoop = function(options) {
var video = $(this),
videoEl = video.get(0),
selVideoIdx = 0;
options = options || {};
var playlist = options.playlist || [],
// Use a white background by default if a poster is not provided. This
// should prevent the transition from showing a black screen. If possible,
// use the first frame of the looping video or a solid color to match
// the backdrop of the video.
poster = options.poster || "http://placehold.it/1024x768/FFFFFF/FFFFFF";
if (playlist.length > 1) {
video.attr('src', playlist[selVideoIdx % playlist.length]);
video.attr('poster', poster);
video.attr('autoload', true);
selVideoIdx++;
video.on('loadedmetadata', function() {
videoEl.currentTime = 0.5;
videoEl.play();
}).bind('ended', function() {
videoEl.src = playlist[selVideoIdx % playlist.length];
videoEl.loop = true;
videoEl.load();
});
}
};
$(function() {
$('#start').videoLoop({
'playlist': [
'../video-start/Homepage_video_ref_v01.mp4',
'../video-loop/7_Sec_Loop_v01.mp4'
],
'poster': "http://placehold.it/1024x768/6DBBD2/6DBBD2"
});
});
video {
width: 100%;
background: #53abc5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<video id="start" controls="controls"></video>
Related
I'm making a random order video player, adapting code from here but the same video just keeps playing, even though I can see (from text above the video) that the random ordering is working. Live version is here.
Is the problem with the appendChild meaning the new video is end of a list but the first in list keeps playing? I tried replaceChild but that didn't work.
<script type="text/javascript">
$(document).ready(function(){
var videos = [
[{type:'mp4', 'src':'carlos/one-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/two-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/three-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/four-carlostest.mp4'}],
[{type:'mp4', 'src':'carlos/five-carlostest.mp4'}]
];
// selecting random item from array as first to be played
var randomitem = videos[Math.floor(Math.random()*videos.length)];
// This function adds a new video source (dynamic) in the video html tag
function videoadd(element, src, type) {
var source = document.createElement('source');
source.src = src;
source.type = type;
element.appendChild(source);
}
// this function fires the video for particular video tag
function newvideo(src){
var vid = document.getElementById("myVideo");
videoadd(vid,src ,'video/ogg');
vid.autoplay = true;
vid.load();
vid.play();
}
// function call
newvideo(randomitem[0].src)
// Added an event listener so that everytime the video finishes ,a new video is loaded from array
document.getElementById('myVideo').addEventListener('ended',handler,false);
function handler(){
var newRandom = videos[Math.floor(Math.random()*videos.length)];
newvideo(newRandom[0].src)
document.getElementById("monitor").innerHTML = "randomitem is " + newRandom[0].src;
}
})
</script>
Also, if anyone can tell me why the autoplay never works that'd be appreciated, though it's the least of my problems.
I have kinda found this solution for your video playing one after other. now in your JS file, now you just will need to add your video src path.
var vidElement = document.getElementById('video');
var vidSources = [
"https://lutins.co.uk/carlos/one-carlostest.mp4",
"http://www.w3schools.com/html/movie.mp4"
];
var activeVideo = Math.floor((Math.random() * vidSources.length));
vidElement.src = vidSources[activeVideo];
vidElement.addEventListener('ended', function(e) {
// update the active video index
activeVideo = (++activeVideo) % vidSources.length;
if(activeVideo === vidSources.length){
activeVideo = 0;
}
// update the video source and play
vidElement.src = vidSources[activeVideo];
vidElement.play();
});
video {
width:350px;
}
<p>wowww you got it!</p>
<video src="https://lutins.co.uk/carlos/one-carlostest.mp4" id="video" autoplay muted playsinline></video>
Change the randomIt variable into a callback, only this way, it will generate new random number each time it get call.
// I have change randomitem into a function with ofcourse a proper name
var getRandomItem = function() {
return videos[Math.floor(Math.random()*videos.length)];
}
You should also call it properly like this:
//newvideo(randomitem[0].src) -> change it to
newvideo(getrandomItem().src)
There might also other adjustments requires for your code to work.
So I'm using video.js on a multipage project that has pages with differing numbers of videos on each page. I want playing one video to pause any other video playing on the page. I've got it to work, but my code only works if it's made specifically to the page, as opposed to working on each page on its own.
HTML (example)
<video id="video5" poster="poster.png" class="video-js vjs-16-9 vjs-big-play-centered"
data-setup='{
"controls": true,
"autoplay": false,
"preload": "none"
}'>
<source src="video.mp4" type='video/mp4'>
</video>
JS
var player1 = videojs('video1');
var player2 = videojs('video2');
var player3 = videojs('video3');
var player4 = videojs('video4');
var player5 = videojs('video5');
var player6 = videojs('video6');
var players = [player1, player2, player3, player4, player5, player6];
players.forEach(function(player) {
player.on('play', function() {
console.log('test');
players.forEach(function(pl) {
if (pl !== player) {
pl.pause();
}
})
})
});
So this works fine if I have 6 videos with those coinciding id's. But if I have more or less, it breaks. Is there a way to format the JS to just pause anything by class as opposed to by id? I've tried ('.video-js').pause() but this throws an error.
NM, found the answer. Leaving this up so it's easier to find for people possibly.
var medias = Array.prototype.slice.apply(document.querySelectorAll('audio,video'));
medias.forEach(function(media) {
media.addEventListener('play', function(event) {
medias.forEach(function(media) {
if(event.target != media) media.pause();
});
});
});
You can select these elements by class name instead of id. Something like this:
var videos = document.getElementsByClassName('video-js');
for (var i = 0; i < videos.length; i++) {
videos[i].pause();
}
If you are using jquery then.
$('video').each((videoIndex, video) => {
console.log('video paused', video);
video.pause();
})
I am running the following code which changes the source of an html5 video at the end of each video, so that it constantly plays one video after another. After the first video finishes, it runs the second, then the third and eventually starts again from the beginning, resulting in an endless cycle. It also chooses a random starting point, but that is not important for my question.
In the code below you will only find two video sources but the final code would use around ten or so.
My problem is that there is a small pause between the end of a video and the beginning of the next one. I have made the background-color of the video tag red so that you will be able to see a red flash between the playback of each video.
I'm guessing that this could be solved by preloading all videos specified inside the javascript code. So what I would like to achieve is to preload only the next video in the list specified inside the javascript code when the current video is playing. So when video nr. 5 is playing, it should preload video nr. 6 etc..
Or is this not something that could be solved by effective buffering / preloading? I'm happy about any other suggestions as well..
var vidElement = document.getElementById('video');
var vidSources = [
"http://www.w3schools.com/html/mov_bbb.mp4",
"http://www.w3schools.com/html/movie.mp4"
];
var activeVideo = Math.floor((Math.random() * vidSources.length));
vidElement.src = vidSources[activeVideo];
vidElement.addEventListener('ended', function(e) {
// update the active video index
activeVideo = (++activeVideo) % vidSources.length;
if(activeVideo === vidSources.length){
activeVideo = 0;
}
// update the video source and play
vidElement.src = vidSources[activeVideo];
vidElement.play();
});
video { background-color: red }
<video src="http://www.w3schools.com/html/mov_bbb.mp4" id="video" autoplay muted playsinline></video>
<p>(each video is just ~ 10 seconds)</p>
You can create video elements with preload attribute and add it to div containar like follows:
function initVideoElement(videoEl)
{
videoEl.playsinline = true;
videoEl.muted = false;
videoEl.preload = 'auto'; //but do not set autoplay, because it deletes preload
//loadedmetadata is wrong because if we use it then we get endless loop
videoEl.onplaying = function(e)
{
if(++nextActiveVideo == 2)
nextActiveVideo = 0;
//replace the video elements against each other:
if(this.inx == 0)
nextVideoElement = videoElements[1];
else
nextVideoElement = videoElements[0];
nextVideoElement.src = vidSources[nextActiveVideo];
nextVideoElement.pause();
};
videoEl.onended = function(e)
{
this.style.display = 'none';
nextVideoElement.style.display = 'block';
nextVideoElement.play();
};
}
var videoContainer = document.getElementById('videoContainer'),
nextActiveVideo = 0,
nextVideoElement,
videoElements =
[
document.createElement('video'),
document.createElement('video')
],
vidSources =
[
"http://www.w3schools.com/html/mov_bbb.mp4",
"http://www.w3schools.com/html/movie.mp4"
];
videoElements[0].inx = 0; //set index
videoElements[1].inx = 1;
initVideoElement(videoElements[0]);
initVideoElement(videoElements[1]);
videoElements[0].autoplay = true;
videoElements[0].src = vidSources[0];
videoContainer.appendChild(videoElements[0]);
videoElements[1].style.display = 'none';
videoContainer.appendChild(videoElements[1]);
video{background-color: red}
<div id="videoContainer"></div>
how to track the status of video watched or not
if I write like this after 60%, I can send an ajax call and update the status to watched 60%
var i=0;
$("#video").bind("timeupdate", function(){
var currentTime = this.currentTime;
if(currentTime > 0.66*(this.duration)) {
if(i<1) {
/* Watched 66% ajax call will be here*/
}
i=i+1; //Reset for duplicates
}
});
Similarly.
if I write like this after 100% I can send an ajax call and update the status to completely watched 100%
$("#video").bind("ended", function() {
if(j<1) {
/* Watched 100% Finished */
}
j=j+1; //Reset for duplicates
});
But when someone forwarded the video to 90% and started playing from there then also 100% ajax call will trigger so what is the logic should I use to update the status to not watched in this case.
How about manipulating the functions like this
var watchPoints = [];
$("#video").bind("timeupdate", function(){
var currentTime = this.currentTime;
var watchPoint = Math.floor((currentTime/this.duration) * 100);
if(watchPoints.indexOf(watchPoint) == -1){
watchPoints.push(Math.floor(watchPoint))
}
});
/* Assuming that this will be called regardless of whether the user watches till the end point */
$("#video").bind("ended", function() {
/* use the watchPoints array to do the analysis(ordered array)
Eg.1 [1,2,3,4,5....100] - length is 100
2.[90,91..100] - length is only 10 and the starting point is 90
3.[1,2,3,4,5,50,51,52,61,62,63,64,65,66,67,68,69,70,98,99,100] - length is 21 and the index of 66 is 13 which clearly tells the user has skipped most of the parts
*/
});
With the research and little hard work i got the solution like this:
my HTML is this:
<div id="videoData">
<video width="75%" style="max-width: 60em;" autoplay="" controls="" class="center-block" id="video">
<source type="video/mp4" src="http://amerytech.net/lc_production/uploads/course_videos/Time Speed & Distance/Time Speed & Distance.mp4" le="max-width: 60em;" sty="">
</source>
</video>
</div>
<p id="display">asdddddd</p>
my javascript is this:
$(document).ajaxStop(function() {
var video = document.querySelector('video');
if (video) {
video.addEventListener("loadedmetadata", function() {
totalTime = this.duration;
});
$("#video").bind("timeupdate", function() {
var currentTime = this.currentTime;
var totalPlayed = 0;
var played = video.played;
for (var i = 0; i < played.length; i++) {
totalPlayed += played.end(i) - played.start(i);
console.log(totalPlayed);
$("#display").html(totalPlayed);
}
});
} else {
alert("not coming");
}
});
I want to create an audio background player where user can only click on image to play or stop the playback. I have trouble creating or rewirting existing codes to make a playlist for it, that automatically plays next song when previous is finished. I want to do it in vanilla js.
Here is what I have so far:
https://jsfiddle.net/rockarou/ad8Lkkrj/
var imageTracker = 'playImage';
swapImage = function() {
var image = document.getElementById('swapImage');
if (imageTracker == 'playImage') {
image.src = 'http://findicons.com/files/icons/129/soft_scraps/256/button_pause_01.png';
imageTracker = 'stopImage';
} else {
image.src = 'http://findicons.com/files/icons/129/soft_scraps/256/button_play_01.png';
imageTracker = 'playImage';
}
};
var musicTracker = 'noMusic';
audioStatus = function() {
var music = document.getElementById('natureSounds');
if (musicTracker == 'noMusic') {
music.play();
musicTracker = 'playMusic';
} else {
music.pause();
musicTracker = 'noMusic';
}
};
here is the trick to trigger next song:
music.addEventListener('ended',function(){
//play next song
});
How to play another song on same audio tag:
music.pause();
music.src = "new url";
music.load();
music.play();
Now here is a cool example of a playlist in html5, you can load each song at the time, case some clients (mobile) will not be happy when you consume the traffic, in next example all audios are loaded at same time to have a smooth transition from song to song,
loading the songs:
//playing flag
var musicTracker = 'noMusic';
//playlist audios
var audios = [];
$(".song").each(function(){
var load = new Audio($(this).attr("url"));
load.load();
load.addEventListener('ended',function(){
forward();
});
audios.push(load);
});
//active track
var activeTrack = 0;
Highlighting witch song is playing, with a bit of jquery, yeah, case yeah I'm lazy, lazy:
var showPlaying = function()
{
var src = audios[activeTrack].src;
$(".song").removeClass("playing");
$("div[url='" + src + "']").addClass("playing");
};
Fiddle here
Note: If the sound's doesn't play, manually check if audio url's are accessible
[Here a non vanilla solution.] My playlist consists of four songs, they are named 0.mp3, 1.mp3, 2.mp3 and 3.mp3.
<html>
<head><script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script></head>
<body>
<audio id="player" autoplay controls><source src="0.mp3" type="audio/mp3"></audio>
</body>
<script>
var x = 0;
var music = document.getElementById("player");
$("#player").bind("ended", function(){
x=x+1;
music.src = x%4 + ".mp3";
music.load();
music.play();
});
</script>
</html>
The playlist is repeated indefinetely.
Vanilla Javascript variant:
const audioArray = document.getElementsByClassName('songs'); //Get a list of all songs
let i = 0; //Initiate current Index
const player = document.getElementById('player'); //get the player
player.src = audioArray[i].getAttribute('data-url'); //set first Song to play
player.addEventListener('ended',function(){ //when a song finished playing
i++; //increase index
if (i < audioArray.length) { //If current index is smaller than count of songs
player.src = audioArray[i].getAttribute('data-url'); //set next song
return; // stop further processing of this function for now
}
// current index is greater than count of songs
i = 0; // therefore we reset the current index to the first available song
player.src = audioArray[i].getAttribute('data-url'); // and set it to be played
});
In this example you don't set an initial src for the audioplayers source-tag but instead have a list of class 'song'-items with an data-url attribute containing the url/path to the tracks.
I added comments to learn what and why this code is doing what it does.
Of course it could be better but it's a quick throwup of code ;)