Loading chunks into html5 video - javascript

Where I can read information and see examples of loading chunks into html5 video?
Scenario:
1. User starts play a large video.
2. 10-20 seconds of the video should be downloaded.
3. If user watches first 10 seconds then next 10 seconds should be downloaded. Thus, there will be no load if the user looks only the first 9 seconds of video.
If we use this scenario it will reduce server load (in some cases).
For example:
Try to watch video on YouTube. They work like this. Try to load half video (~3 mins) and start watch it from beginning. Other part of video will not be downloaded until you reach special point (~ 50 seconds before the downloads point, in my case).
I can't find any controls of buffering in html5 video. Also I can't find any controls of buffering in popular html5 based video players like VideoJs, JPlayer.
Does somebody know how to do it?

I can't find any controls of buffering in html5 video.
The .buffered property of the HTMLMediaElement interface, and the TimeRanges object which you can get back from that, don’t give you direct control over buffering, but can give you some control over the user experience at least. For a simple case that uses them, here’s some sample code:
<!doctype html>
<html>
<head>
<title>JavaScript Progress Monitor</title>
<script type="text/javascript">
function getPercentProg() {
var myVideo = document.getElementsByTagName('video')[0];
var endBuf = myVideo.buffered.end(0);
var soFar = parseInt(((endBuf / myVideo.duration) * 100));
document.getElementById("loadStatus").innerHTML = soFar + '%';
}
function myAutoPlay() {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.play();
}
function addMyListeners(){
var myVideo = document.getElementsByTagName('video')[0];
myVideo.addEventListener('progress', getPercentProg, false);
myVideo.addEventListener('canplaythrough', myAutoPlay, false);
}
</script>
</head>
<body onload="addMyListeners()">
<div>
<video controls
src="http://homepage.mac.com/qt4web/sunrisemeditations/myMovie.m4v">
</video>
<p id="loadStatus">MOVIE LOADING...</p>
</div>
</body>
</html>
That code is from a detailed Controlling Media with JavaScript guide over at the Safari Developer site. There’s also another good Media buffering, seeking, and time ranges how-to over at MDN.
If you really want more direct control over buffering, you need to do some work on the server side and use the MediaSource and SourceBuffer interfaces.
Appending .webm video chunks using the Media Source API is a good demo; code snippet:
var ms = new MediaSource();
var video = document.querySelector('video');
video.src = window.URL.createObjectURL(ms);
ms.addEventListener('sourceopen', function(e) {
...
var sourceBuffer = ms.addSourceBuffer('video/webm; codecs="vorbis,vp8"');
sourceBuffer.appendBuffer(oneVideoWebMChunk);
....
}, false);

Related

How to make MPEG-DASH video loop

If playing an MPEG Dash video using dash.js, is it possible to make it loop, i.e. when the video has downloaded fully, replay the downloaded content, without having to download any more data or possibly just raising the resolution if possible, but this is not essential.
The standard code for displaying this is:
<div>
<video id="videoPlayer"></video>
</div>
<script src="https://cdn.dashjs.org/v2.0.0/dash.all.min.js"></script>
<script>
(function(){
var url = "./Videos/146252.mpd";
var player = dashjs.MediaPlayer().create();
player.initialize(document.querySelector("#videoPlayer"), url, true);
})();
</script>
The video element has a loop attribute. Have you tried setting it?

cannot set video.currentTime in html5 video using jquery/javascript

Either from the console or from in my tags, I cannot set the current time of an html5 video element with javascript. I also am using jQuery but I do not know if that is relevant to the issue. I am using Google Chrome 24.0.1312.57 on Ubuntu; below is an example of what I am trying to do
<html>
<script type="text/javascript">
var video = document.getElementById("video");
var videoSourceString = "<source src=http://URL:PORT" + path + " type='video/mp4'></source>";
$(video).html(videoSourceString);
video.load();
var frameRate = 24;
video.currentTime += 1/frameRate;// doesn't do anything, leaves currentTime same as before
</script>
<body>
<video id="video">
</video>
</body>
</html>
The video plays and pauses fine, but whenever I try to manually change the time it does not work.
I already looked at HTML5 Video - Chrome - Error settings currentTime and no such errors are present in the console, in fact it does not display any errors. I also cannot change the currentTime from the console using video.currentTime += 1 or document.getElementById("video").currentTime = 0 with any number.
Thank you very much!
Even though I was waiting until the loadedmetadata event was reached, it turned out to be the lack of support for HTTP byte range requests by web.py that was preventing seeking. HTTP Byte Range requests are required to seek in HTML5 video and it turns out web.py does not support them, so I served the video using Apache and it worked flawlessy. Thank you for your responses!

Playing random audio in HTML/Javascript

I am trying to figure out how to continuously play random audio sound bites, one after another without having them overlap on an HTML page using jquery. I have code that plays random sound bites on a timer, but sometimes they overlap and sometimes there is a pause in between the sounds. I had looked into ended and other EventListeners but I really have no idea what I am doing. Here is a portion my code:
<html>
<audio id="audio1">
<source src="cnn.mp3"></source>
</audio>
<audio id="audio2">
<source src="sonycrackle.mp3"></source>
</audio>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('audio').each(function(){
this.volume = 0.6;
});
var tid = setInterval(playIt, 2000);
});
function playIt() {
var n = Math.ceil(Math.random() * 2);
$("#audio"+n).trigger('play');
};
Is there a way to just continuously play these sounds bites one after another right after the previous sound plays? FWIW I have many sound bites but I am just showing two above for reference.
So I dabbled a bit, here's a full pure JavaScript solution.
Should be cross-browser, haven't tested (/lazy). Do tell me if you find bugs though
var collection=[];// final collection of sounds to play
var loadedIndex=0;// horrible way of forcing a load of audio sounds
// remap audios to a buffered collection
function init(audios) {
for(var i=0;i<audios.length;i++) {
var audio = new Audio(audios[i]);
collection.push(audio);
buffer(audio);
}
}
// did I mention it's a horrible way to buffer?
function buffer(audio) {
if(audio.readyState==4)return loaded();
setTimeout(function(){buffer(audio)},100);
}
// check if we're leady to dj this
function loaded() {
loadedIndex++;
if(collection.length==loadedIndex)playLooped();
}
// play and loop after finished
function playLooped() {
var audio=Math.floor(Math.random() * (collection.length));
audio=collection[audio];
audio.play();
setTimeout(playLooped,audio.duration*1000);
}
// the songs to be played!
init([
'http://static1.grsites.com/archive/sounds/background/background005.mp3',
'http://static1.grsites.com/archive/sounds/background/background006.mp3',
'http://static1.grsites.com/archive/sounds/background/background007.mp3'
]);
Some quick suggestions is add the attribute preload="auto" to the audio element and change the script to be $(window).onload instead of document ready. Document ready fires when html is in place but not necessarily when audio and other assets (like images) have loaded.
You could also look into using the AudioBuffer Interface in the new Web Audio API, it's described as "this interface represents a memory-resident audio asset (for one-shot sounds and other short audio clips)." which sounds like what you need. I believe part of the issues you're having (random pauses/delays/sound glitches with the audio element) are one of the reasons why it's being developed.
Read more here:
https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#AudioBuffer
Unfortunately it's only Chrome and lastest Safari supported with Firefox support supposedly in the next 6(ish) months and no word yet on IE support.

trying to add a multi source video player with more then one video?

Im trying to make a video player work in all browsers. There is
more then one video and every time you click on demo reel it plays the
video and if you click the video 1 the other video plays. How can i
make them both work in all browsers? Here is my html and javascript
html
<video id="myVideo" controls autoplay></video>
<div>
Demo Reel</div>
video 1</div>
</div>
javascript
function changeVid1() {
var changeStuff = document.getElementById("myVideo");
changeStuff.src = "video/demoreel.mp4"
}
function changeVid2() {
var changeStuff = document.getElementById("myVideo");
changeStuff.src = "video/video1.mp4";
}
After you switch the source of the video, you need to run .load() on it to force it to load the new file. Also, you need to provide multiple formats, because there is no video codec supported by all browsers.
First, set up your sources like this:
var sources = [
{
'mp4': 'http://video-js.zencoder.com/oceans-clip.mp4',
'webm':'http://video-js.zencoder.com/oceans-clip.webm',
'ogg':'http://video-js.zencoder.com/oceans-clip.ogv'
}
// as many as you need...
];
Then, your switch function should look like this:
function switchVideo(index) {
var s = sources[index], source, i;
video.innerHTML = '';
for (i in s) {
source = document.createElement('source');
source.src = s[i];
source.setAttribute('type', 'video/' + i);
video.appendChild(source);
}
video.load();
video.play(); //optional
}
See a working demo here.
This gives the browser a list of different formats to try. It will go through each URL until it finds one it likes. Setting the "type" attribute on each source element tells the browser in advance what type of video it is so it can skip the ones it doesn't support. Otherwise, it has to hit the server to retrieve the header and figure out what kind of file it is.
This should work in Firefox going back to 3.5 as long as you provide an ogg/theora file. And it will work in iPads, because you only have one video element on the page at a time. However, auto-play won't work until after the user clicks play manually at least once.
For extra credit, you can append a flash fallback to the video element, after the source tags, for older browsers that don't support html5 video. (i.e., IE < 9 - though you'll need to use jQuery or another shim to replace addEventListener.)

Getting Current YouTube Video Time

I am writing a Browser Plugin and need to find a way to get the current time a YouTube Video playing on YouTube using JavaScript. I have been playing around in the Chrome JavaScript Console and haven't had any luck.
It appears that the chrome API only works with embedded video players not a video that is playing on on youtube.com. One option I looked into is in the share section of a video their is an input box for the "start at:" time that contains the current time of the video. I have tried using .value and .text on this input box and they both return undefined? Does anyone have any ideas?
ytplayer = document.getElementById("movie_player");
ytplayer.getCurrentTime();
See the api
Update: if it didn't work, also try player.playerInfo.currentTime (codepen live example)
Depends on what you want
player.getCurrentTime():Number
Returns the elapsed time in seconds since the video started playing.
player.getDuration():Number
Returns the duration in seconds of the currently playing video. Note
that getDuration() will return 0 until the video's metadata is loaded,
which normally happens just after the video starts playing.
http://code.google.com/apis/youtube/js_api_reference.html
Finally I found how to make it work on iOS (and Android too).
Actually, the whole youtube js api was broken for me if run on mobile browser.
Problem solved by creating player using new YT.Player as described in YouTube IFrame API.
Please note: only creating <iframe> from <div> placeholder works for mobile browsers at the time. If you try to use existing <iframe> in new YT.Player call, as mentioned in IFrame API, this will not work.
After player created, it's possible to use player.getCurrentTime() or player.getDuration() with player instance created.
Note: I had no luck calling this methods on player obtained with
player = document.getElementById(...) (from #JosephMarikle answer).
Only created player instance worked in mobile browsers.
Useful links:
YouTube IFrame API
YouTube JavaScript API
YouTube Player Demo
You can use Html5 Video API on youtube.com
var htmlVideoPlayer = document.getElementsByTagName('video')[0];
htmlVideoPlayer.currentTime
Note: It's not gonna work on Youtube Iframe API because Iframes are isolated. You cannot access the context of a Youtube IFrame .
In 2020, this works:
player.playerInfo.currentTime
full code:
see it live on codepen
Just FYI, There is a new iframe API for the YouTube player:
https://developers.google.com/youtube/iframe_api_reference
document.querySelector('video').currentTime
Stop at specific time youtube video and show notification box in GWD
<script>
var yid = document.getElementById("gwd-youtube_1");
var idBox = document.getElementById("box1");
pausing_function = function(event) {
var aa = setInterval(function() {
if (yid.getCurrentTime() > 8.0 && yid.getCurrentTime() < 8.1) {
yid.pause(yid);
idBox.style.opacity = 1;
console.log(yid.getCurrentTime() + "playing")
clearInterval(aa);
yid.removeEventListener("playing", pausing_function);
}
}, 100)
}
yid.addEventListener("playing", pausing_function);
var pausing_function_1 = function() {
if (yid.getCurrentTime() > 8.1) {
console.log(yid.getCurrentTime() + "pause")
// remove the event listener after you paused the playback
yid.removeEventListener("playing", pausing_function);
}
};
</script>
play video and hide notification
<script type="text/javascript" gwd-events="handlers">
window.gwd = window.gwd || {};
gwd.pauseVideo = function(event) {
var idBox = document.getElementById("box1");
idBox.style.opacity = 0;
};
</script>
<script type="text/javascript" gwd-events="registration">
// Support code for event handling in Google Web Designer
// This script block is auto-generated. Please do not edit!
gwd.actions.events.registerEventHandlers = function(event) {
gwd.actions.events.addHandler('gwd-youtube_1', 'playing', gwd.pauseVideo, false);
};
gwd.actions.events.deregisterEventHandlers = function(event) {
gwd.actions.events.removeHandler('gwd-youtube_1', 'playing', gwd.pauseVideo, false);
};
document.addEventListener("DOMContentLoaded", gwd.actions.events.registerEventHandlers);
document.addEventListener("unload", gwd.actions.events.deregisterEventHandlers);
</script>

Categories

Resources