Skip to content

Instantly share code, notes, and snippets.

@neo22s
Last active February 24, 2024 03:43
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neo22s/fcf9d3e75e8d00c96912dae9a5de897e to your computer and use it in GitHub Desktop.
Save neo22s/fcf9d3e75e8d00c96912dae9a5de897e to your computer and use it in GitHub Desktop.
Playlist video player for HTML5
jQuery(document).ready(function( $ ) {
/**
* improving the current html5 video player
*/
//when we pause we store the current time
$("video").on("pause", function(event) {
// Save into local storage,if you change the browser will not work
localStorage.setItem('bvideo-'+btoa(this.src), this.currentTime);
});
//play video restores the video from the last point
$("video").on("play", function(event) {
$storedtime = localStorage.getItem('bvideo-'+btoa(this.src));
// Get the time from localStorage and play if not at the end.
if ($storedtime < this.duration)
this.currentTime = $storedtime;
this.play();
});
//if you close the window and video playing store the current time
$(window).on("unload", function(e) {
$("video").each(function(index, value) {
if ( ! this.paused ) {
localStorage.setItem('bvideo-'+btoa(this.src), this.currentTime);
}
});
});
/**
* Playlist player for 1 video HTML tag
*/
if ($('#bvideo_playlist').length )
{
var video_list = [];
var current_url = btoa(window.location.href.split('?')[0].split('#')[0]);
// 1st way to load the playlist comes from a plylist JS array
if (typeof directLinkData !== 'undefined' || typeof video_playlist !== 'undefined')
{
//in case there's a default playlist array
if (typeof video_playlist !== 'undefined'){
video_list = video_playlist;
}
// loading playlist from a pcloud array, in a public folder view page use the directLinkData array embeded in the HTML
if (typeof directLinkData !== 'undefined')
{
//created the list of links
var pcloud = directLinkData.content;
var path = 'https://filedn.eu/'+directLinkData.code+directLinkData.dirpath;
for (i=0; i<pcloud.length; i++)
{
var temp = [];
temp["name"] = pcloud[i].name.slice(0, -4);
temp["link"] = path+pcloud[i].urlencodedname;
temp["size"] = pcloud[i].size;
video_list.push(temp);
}
}
// from array video_list to a table
var html_list = "";
for (i=0; i<video_list.length; i++) {
html_list+='<li>';
if (is_played_video(video_list[i].link))
html_list+='&#10004;&nbsp;';
html_list+='<a data-bvideo_id="'+i+'" href="'+video_list[i].link+'">'+video_list[i].name+'</a>';
if (video_list[i].size!=undefined)
{
video_size = (video_list[i].size!=undefined?fileSize(video_list[i].size):'-')
html_list+='<span style="float:right;"><a target="_blank" download href="'+video_list[i].link+'">'+video_size+'</a></span>';
}
html_list+='</li>';
}
//print html
$("#bvideo_playlist").html(html_list);
}
// 2nd way to get a playlist load video_list array from a list instead than JS array
else if($('#bvideo_playlist').is('ol, ul'))
{
var video_list = [];
$("#bvideo_playlist li a").each(function(e) {
a = $(this);
a.attr('data-bvideo_id',e);
var temp = [];
temp["name"] = this.text;
temp["link"] = this.href;
temp["size"] = a.data('size')!==undefined?a.data('size'):0;
video_list.push(temp);
});
}
// playlist video player
if (typeof video_list !== 'undefined')
{
//start video from parameeter ID....
var start_video = new URLSearchParams(window.location.search).get('start_video');
if (start_video!==null && $.isNumeric(start_video))
id_current = start_video-1;//we start counting from 1 so we do not use the 0.
else//init video at last play
id_current = localStorage.getItem('bvideo-'+current_url);
id_current = ($.isNumeric(id_current))?id_current:0;
id_current = (id_current > video_list.length-1)?0:id_current;
//current video playing
localStorage.setItem('bvideo-'+current_url, id_current);
//setuo player to play current video
$("video").attr({
"id":"bvideo",
"src": $('a[data-bvideo_id~="'+id_current+'"]').attr("href"),
"data-bvideo_id":id_current//which video are we playing
});
//on finished video play next
$("video").on('ended', function(e){
//current id,using attribute since data gets cached and we are updating it
id = parseInt($(this).attr("data-bvideo_id"));
//we mark this video as played
mark_played_video(id);
//what to play next
id_next = (id == video_list.length-1)?0:id+1;
//getting the source of the a
src = $('a[data-bvideo_id~="'+id_next+'"]').attr("href");
$(this).attr({
"src": src,
"autoplay": "autoplay",
"data-bvideo_id":id_next //which video are we playing
});
//remember next video
localStorage.setItem('bvideo-'+current_url, id_next);
});
//sets the source of the video from an ahref
$("#bvideo_playlist a[target!='_blank']").on("click", function(e) {
//we prevent any default action, so we do not go to the url
e.preventDefault();
$("video").attr({
"src": $(this).attr("href"),
"autoplay": "autoplay",
"data-bvideo_id":$(this).data("bvideo_id") //which video are we playing
});
location.href = "#bvideo";
//remember last video
localStorage.setItem('bvideo-'+current_url, $(this).data("bvideo_id"));
});
}
/**
* we mark a video as played, we use the btoa of the current url and we store the btoa of the video src
* @param id_video we get the src from the a
*/
function mark_played_video(id_video)
{
//getting the source of the a
a = $('a[data-bvideo_id~="'+id_video+'"]');
src = a.attr("href");
// if it was not in the array before, then store
if(is_played_video(src) == false)
{
var watched_videos;
watched_videos = localStorage.getItem('bvideo-played-'+ current_url);
if (watched_videos == null)
watched_videos = [];
else
watched_videos = JSON.parse(watched_videos);
watched_videos.push(btoa(src));
localStorage.setItem('bvideo-played-'+ current_url, JSON.stringify(watched_videos));
a.parent().prepend('&#10004;&nbsp;');
}
}
/**
* tells us if we have seen that video in this url
* @param string btoa src of the video
* @return boolean
*/
function is_played_video(src)
{
watched_videos = localStorage.getItem('bvideo-played-'+ current_url);
if (watched_videos == null)
return false;
watched_videos = JSON.parse(watched_videos);
if( watched_videos.indexOf(btoa(src)) != -1 )
return true;
else
return false;
}
}
})
//from https://stackoverflow.com/a/20463021
function fileSize(a,b,c,d,e)
{
return (b=Math,c=b.log,d=1e3,e=c(a)/c(d)|0,a/b.pow(d,e)).toFixed(e?2:0)+' '+(e?'kMGTPEZY'[--e]+'B':'Bytes')
}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Playlist video player for HTML5</title>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script>
<script src="better-video.js"></script>
</head>
<body>
<div id="site-content"></div>
<video height="500px" controls="" src="http://s3.amazonaws.com/akamai.netstorage/HD_downloads/earth_night_rotate_1080.mov" ></video>
<ol id="bvideo_playlist">
<li><a href="http://s3.amazonaws.com/akamai.netstorage/HD_downloads/earth_night_rotate_1080.mov">Animation: Rotating Earth at Night</a><span style="float:right;"><a target="_blank" download="" href="http://s3.amazonaws.com/akamai.netstorage/HD_downloads/earth_night_rotate_1080.mov">55.00 MB</a></span></li>
<li><a href="http://s3.amazonaws.com/akamai.netstorage/HD_downloads/rbsp_launch_1080p.mp4">Radiation Belt Storm Probes Launch</a></li>
<li><a href="http://s3.amazonaws.com/akamai.netstorage/HD_downloads/curiosity_lands.mov">Dropping in on Mars in High-Res</a><span style="float:right;"><a target="_blank" download="" href="http://s3.amazonaws.com/akamai.netstorage/HD_downloads/curiosity_lands.mov">105.00 MB</a></span></li>
<li><a href="http://s3.amazonaws.com/akamai.netstorage/HD_downloads/GRAIL_launch_1080.mov">GRAIL Launches on Mission to Moon</a></li>
<li><a href="http://s3.amazonaws.com/akamai.netstorage/HD_downloads/HLV_Launch_anim.mov">Space Launch System Animation</a></li>
</ol>
<script>
var video_playlist = [
{
"name": "Animation: Rotating Earth at Night",
"link": "http://s3.amazonaws.com/akamai.netstorage/HD_downloads/earth_night_rotate_1080.mov",
"size": 55000000,
},
{
"name": "Radiation Belt Storm Probes Launch",
"link": "http://s3.amazonaws.com/akamai.netstorage/HD_downloads/rbsp_launch_1080p.mp4",
"size": 475000000,
},
{
"name": "Dropping in on Mars in High-Res",
"link": "http://s3.amazonaws.com/akamai.netstorage/HD_downloads/curiosity_lands.mov",
"size": 105000000,
},
{
"name": "GRAIL Launches on Mission to Moon",
"link": "http://s3.amazonaws.com/akamai.netstorage/HD_downloads/GRAIL_launch_1080.mov",
"size": 1113000000,
},
{
"name": "Space Launch System Animation",
"link": "http://s3.amazonaws.com/akamai.netstorage/HD_downloads/HLV_Launch_anim.mov",
"size": 642570000,
},
];
</script>
</body>
</html>
@eltippytoez
Copy link

Thank you for such a useful script. Is it possible to give the currently playing link in the list an active css class or something similar?

@neo22s
Copy link
Author

neo22s commented May 12, 2023

Hello! here you can find a newer better version and in this line you can change the color or css or whatever you want

https://github.com/neo22s/better-video/blob/main/js/better-video.js#L187

@neo22s
Copy link
Author

neo22s commented May 12, 2023

@eltippytoez
Copy link

Excellent! Thank you for taking the time to answer.

@neo22s
Copy link
Author

neo22s commented May 12, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment