Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>In order to make a player that can play videos continously you need to implement some sort of double-buffering at load level (I'll demonstrate later).</p> <p>But there are some issues in the code as it is -</p> <pre><code>myVideo.src = "videos/80s_Mix_II-700.mp4"; myVideo.src = "videos/80s_Mix_II-700.webm"; myVideo.load(); </code></pre> <p>This will simply override the source property. And setting the source will automatically start loading the video.</p> <p>The proper way to check for video support is using the method <code>canPlayType</code> like this:</p> <pre><code>/// which format can we play? if (video.canPlayType("video/mp4").length &gt; 0) { video.src = urlToMP4; } else if (video.canPlayType("video/webm").length &gt; 0) { video.src = urlToWEBM; } else { video.src = urlToOggOrSomeOtherSupportedFormat; } </code></pre> <p>The problem though with <code>canPlayType</code> is that it returns <code>maybe</code> in Chrome and <code>probably</code> in Firefox. It returns an empty string if it cannot play the video type so we check if string contains anything to determine the possibility for this format to play.</p> <p>You also need to implement an event listener for <code>canplay</code> which tells your app that the video was loaded and buffered successfully and can now be started using play (or starts if <code>autoplay</code> was set to <code>true</code>).</p> <p>I would recommend a simple procedure like this:</p> <ul> <li>Create an array of objects with the video URLs you want to play for the various formats</li> <li>When first video is loaded (<code>canplay</code>) start loading the next video in the list when start playing the first</li> </ul> <p>I would also recommend a re-factoring of the code to handle loading and playing.</p> <p>For example, if we initialize an array to hold our custom video objects:</p> <pre><code>var list = []; </code></pre> <p>we can now add URLs like this:</p> <pre><code>function addVideo(urlMP4, url) { list.push({ urlMP4: urlMP4, url: url, isReady: false }) } </code></pre> <p>Then this function will let us add a MP4 and a link for WEBM or OGG:</p> <pre><code>addVideo('http://video1.mp4', 'http://video1.webm'); addVideo('http://video2.mp4', 'http://video2.webm'); addVideo('http://video3.mp4', 'http://video3.ogg'); ... </code></pre> <p>Then we need to start a "chain-reaction" so to speak by using a double-buffered loading mechanism. The first time we need to trigger it manually:</p> <pre><code>getVideo(list[0], play); function getVideo(vid, callback) { /// which video is playing? (see demo for details) var video = (isVideo1 === false ? video1 : video2), me = this; /// we need to know when video is ready video.addEventListener('canplay', canPlay, false);; /// call this when ready function canPlay(e) { /// remove event listener (in case setting new src does not trigger) video.removeEventListener('canplay', canPlay, false); /// update our object with useful data, for example: vid.isReady = true; /// if we provided a callback then call that with custom video object if (typeof callback === 'function') callback(vid); } /// check video format support (see demo for details) if (video.canPlayType("video/mp4").length &gt; 0) { video.src = vid.urlMP4; } else { video.src = vid.url; } } </code></pre> <p>Our <code>play</code> function will manage which video is playing and what to play next:</p> <pre><code>function play(){ /// what video is currently not playing? var video = (isVideo1 === false ? video1 : video2), next = current; /// current is index for list, starts at 0 /// switch isVideo1 = !isVideo1; /// increment for next video to platy and start over if list ended next++; if (next &gt; list.length - 1) next = 0; /// only attempt next if there are more videos than 1 in list if (list.length &gt; 0) getVideo(list[next]); /// start already loaded video (getVideo) video.play(); isPlaying = true; /// set current to next in list current = next; } </code></pre> <p><strong><a href="http://jsfiddle.net/AbdiasSoftware/a8g4n/" rel="nofollow">Here is an online demo</a></strong></p> <p>I made this demo just to demonstrate the double-buffered loading. Feel free to incorporate in your own project with pause, stop etc.</p> <p>There is room to move things around in the code I provided here but it's as said just example of the principle. You also need to consider a scenario where next video takes longer to load then what current video playing takes to play (ie. current video ends before next has finished loading). This is not checked in this code.</p> <p>In order to properly synchronize video frames with canvas you <strong>need</strong> to use <code>requestAnimationFrame</code> or you will get freezes from time to time.</p> <p>In the demo the loop runs all the time. You can consider to implement a conditional to stop the loop. I just implemented a conditional for drawing when video list has started playing (rAF does not use much resources in it self and you may get problems synchronizing stop and start when you switch videos so I would personally leave it running as-is for this type of scenarios (continuous video play) and only stop it if there is an error occurring).</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload