Building an HTML5 Video Player
Steve Heffernan, Video.js & Zencoder & Brightcove
http://videojs.com
@heff @videojs
Agenda

History
User Support
Formats
Code
Bugs
Future
Resources




2 | Confidential   © 2013 Brightcove Inc.
3 | Confidential   © 2013 Brightcove Inc.
4 | Confidential   © 2013 Brightcove Inc.
5 | Confidential   © 2013 Brightcove Inc.
~2000    ~2008   ~2015




6 | Confidential                   © 2013 Brightcove Inc.
7 | Confidential   © 2013 Brightcove Inc.
Reasons to use HTML5 Video

It’s the future!
 Runs natively in the browser
 Cleaner code




8 | Confidential                © 2013 Brightcove Inc.
<video src=“video.mp4” controls></video>




9 | Confidential                      © 2013 Brightcove Inc.
<video controls>
      <source src=“video.mp4” type=“video/mp4”>
      <source src=“video.webm” type=“video/webm”>
      <source src=“video.ogv” type=“video/ogg”>
      <object type=“application/x-shockwave-flash” data=“flash.swf”>
            <param name=“movie” value=“flash.swf” />
            <param name=“flashvars” value=“file=video.mp4” />
      </object>
</video>




 10 | Confidential                                                     © 2013 Brightcove Inc.
11 | Confidential   © 2013 Brightcove Inc.
12 | Confidential   © 2013 Brightcove Inc.
http://blog.mefeedia.com/html5-dec-2011




13 | Confidential                                             © 2013 Brightcove Inc.
The ‘Format War’




14 | Confidential   © 2013 Brightcove Inc.
15 | Confidential   © 2013 Brightcove Inc.
OPEN   CLOSED




16 | Confidential                   © 2013 Brightcove Inc.
17 | Confidential   © 2013 Brightcove Inc.
18 | Confidential   © 2013 Brightcove Inc.
CONTAINER FORMAT




                       VIDEO CODEC




                       AUDIO CODEC




19 | Confidential                      © 2013 Brightcove Inc.
MP4




                              H.264




                              AAC
  3+                9+   9+



20 | Confidential                     © 2013 Brightcove Inc.
OGV




                               THEORA




                               VORBIS
3.5+                3+ 10.5+



21 | Confidential                       © 2013 Brightcove Inc.
WEBM




                            VP8




                           VORBIS
 4+             6+ 10.6+



22 | Confidential                   © 2013 Brightcove Inc.
23 | Confidential   © 2013 Brightcove Inc.
Three Formats




   9+               3+   3+   9+



                    4+   6+ 10.6+



               3.5+      3+ 10.5+



24 | Confidential                   © 2013 Brightcove Inc.
Two Formats




   9+               3+   3+   9+



                    4+   6+ 10.6+




25 | Confidential                   © 2013 Brightcove Inc.
One Format




   9+               3+   3+   9+




26 | Confidential                  © 2013 Brightcove Inc.
Handbrake.fr




27 | Confidential   © 2013 Brightcove Inc.
Firefogg.org




28 | Confidential   © 2013 Brightcove Inc.
Zencoder.com




29 | Confidential   © 2013 Brightcove Inc.
Content Protection




    RTMP Streaming   Source Obscurity      Native App Obscurity
    DRM (Flash       Time/GEO/IP limited   HTTP Streaming
    Access/Smooth    URLs                  AES Encryption
    Streaming)




30 | Confidential                                                 © 2013 Brightcove Inc.
Content Protection




  bit.ly/wAkriF
31 | Confidential    © 2013 Brightcove Inc.
<video src=“video.mp4” controls></video>




32 | Confidential                      © 2013 Brightcove Inc.
<video controls>
      <source src=“video.mp4” type=“video/mp4”>
      <source src=“video.webm” type=“video/webm”>
      <source src=“video.ogv” type=“video/ogg”>
</video>




 33 | Confidential                                  © 2013 Brightcove Inc.
<video controls>
      <source src=“video.mp4” type=“video/mp4”>
      <source src=“video.webm” type=“video/webm”>
      <source src=“video.ogv” type=“video/ogg”>
</video>




 34 | Confidential                                  © 2013 Brightcove Inc.
<video controls>
      <source src=“video.mp4” type=“video/mp4”>
      <source src=“video.webm” type=“video/webm”>
      <source src=“video.ogv” type=“video/ogg”>
      <object type=“application/x-shockwave-flash” data=“flash.swf”>
            <param name=“movie” value=“flash.swf” />
            <param name=“flashvars” value=“file=video.mp4” />
      </object>
</video>




 35 | Confidential                                                     © 2013 Brightcove Inc.
<video controls>
      <source src=“video.mp4” type=“video/mp4”>
      <source src=“video.webm” type=“video/webm”>
      <source src=“video.ogv” type=“video/ogg”>
      <object type=“application/x-shockwave-flash” data=“flash.swf”>
            <param name=“movie” value=“flash.swf” />
            <param name=“flashvars” value=“file=video.mp4” />
            <img src=“image.jpg” alt=“title” title=“Can’t play video” />
      </object>
</video>
<p>
      <strong>Download Video:</strong>
      <a href=“video.mp4”>MP4</a>
      <a href=“video.ogv”>Ogg</a>
</p>


 36 | Confidential                                                         © 2013 Brightcove Inc.
Controls           Autoplay             Tracks
  Poster             Loop
  Preload            Width/Height


<video controls autoplay loop width=“480” height=“270”
 poster=“poster.png”
 preload=“auto”>
      <source src=“video.mp4” type=“video/mp4”>
      <track kind=“captions” src=“captions.vtt” srclang=“en”>
</video>




 37 | Confidential                                              © 2013 Brightcove Inc.
Tag Builder




http://videojs.com/tag-builder/
 38 | Confidential                © 2013 Brightcove Inc.
JavaScript API

     Attributes
     Functions
•    Events




    39 | Confidential   © 2013 Brightcove Inc.
Browser/General Issues

•    Autobuffer => Preload
•    Cross-browser Load Progress Tracking
•    Missing Poster in Some Safari Devices
•    HTML5 Browsers Do Not Fallback on Incompatible Sources




    40 | Confidential                                         © 2013 Brightcove Inc.
<video controls>
      <source src=“video.mp4” type=“video/mp4”>
      <source src=“video.webm” type=“video/webm”>
      <source src=“video.ogv” type=“video/ogg”>
      <object type=“application/x-shockwave-flash” data=“flash.swf”>
            <param name=“movie” value=“flash.swf” />
            <param name=“flashvars” value=“file=video.mp4” />
      </object>
</video>




 41 | Confidential                                                     © 2013 Brightcove Inc.
Determine Video Support

<script>

  var vidTag = document.createElement(“video”),
        flashVersion = swfobject.getFlashPlayerVersion();
  if (vidTag.canPlayType && vidTag.canPlayType(“video/mp4”)) {
   // Video Tag
  } else if (flashVersion.major > 9){
   // Flash Object
  } else {
   // No Video Support

</script>



SWF Object: http://code.google.com/p/swfobject/


  42 | Confidential                                              © 2013 Brightcove Inc.
Device Quirks: iOS 3

•    Needs MP4 as first source. iPad Poster Attribute Bug
•    iPad JS in Head / iPhone JS not in Head




    43 | Confidential                                       © 2013 Brightcove Inc.
Device Quirks: Android 2.1 / 2.2

•    Can’t touch to start Type attribute breaks video
•    canPlayType function broken
•    ~25% of Android Users




    44 | Confidential                                   © 2013 Brightcove Inc.
Android Touch Start Fix

<script>

 if (navigator.userAgent.match(/Android/i) !== null) {
    $(“video”).click(function(){
      this.play();
    });
 }

</script>




 45 | Confidential                                       © 2013 Brightcove Inc.
Android Type Attribute Fix Options

•    Don’t include type attribute Don’t use source tags
     <video src=“video.mp4” controls></video>
•    Set source through JS API
     video.src(“video.mp4”)




    46 | Confidential                                     © 2013 Brightcove Inc.
Android canPlayType Fix

<script>
Var androidMatch = navigator.userAgent.match(/Android (d+./i);

if (androidMatch && androidMatch[1] < 3) {

            //Overwrite canPlayType
            document.createElement(“video”)
                  .constructor.prototype.canPlayType = function(type){
                         if (type && type.toLowerCase()>indexOf(“video/mp4”) !== -1) {
                            return “maybe”;
                         } else {
                            return “”;
                         }
};

}
</script>

     47 | Confidential                                                                   © 2013 Brightcove Inc.
The Future of HTML5 Video

•     Content Protection - Encrypted Media Extensions
•     Adaptive Streaming - Media Source Extensions
•     Timed Text/Events - WebVTT
•     Video Chat - WebRTC
•     New Formats/Codecs - VPnext, h.265, Opus, TransOgg




    48 | Confidential                                      © 2013 Brightcove Inc.
VideoJS.com




49 | Confidential   © 2013 Brightcove Inc.
Video for Everybody by Krox Camen




50 | Confidential                   © 2013 Brightcove Inc.
Dive into HTML 5 by Mark Pilgrim




51 | Confidential                  © 2013 Brightcove Inc.
HTML5 Video and Audio in Depth




                http://videojs.com/lynda




52 | Confidential                          © 2013 Brightcove Inc.
Building an HTML5 Video Player

                          Brightcove Webcast, March 2013
                    Steve Heffernan, Video.js & Zencoder & Brightcove


                                   http://videojs.com
                                    @heff @videojs

53 | Confidential                                                       © 2013 Brightcove Inc.
Thank you

Building an HTML5 Video Player

  • 1.
    Building an HTML5Video Player Steve Heffernan, Video.js & Zencoder & Brightcove http://videojs.com @heff @videojs
  • 2.
  • 3.
    3 | Confidential © 2013 Brightcove Inc.
  • 4.
    4 | Confidential © 2013 Brightcove Inc.
  • 5.
    5 | Confidential © 2013 Brightcove Inc.
  • 6.
    ~2000 ~2008 ~2015 6 | Confidential © 2013 Brightcove Inc.
  • 7.
    7 | Confidential © 2013 Brightcove Inc.
  • 8.
    Reasons to useHTML5 Video It’s the future! Runs natively in the browser Cleaner code 8 | Confidential © 2013 Brightcove Inc.
  • 9.
    <video src=“video.mp4” controls></video> 9| Confidential © 2013 Brightcove Inc.
  • 10.
    <video controls> <source src=“video.mp4” type=“video/mp4”> <source src=“video.webm” type=“video/webm”> <source src=“video.ogv” type=“video/ogg”> <object type=“application/x-shockwave-flash” data=“flash.swf”> <param name=“movie” value=“flash.swf” /> <param name=“flashvars” value=“file=video.mp4” /> </object> </video> 10 | Confidential © 2013 Brightcove Inc.
  • 11.
    11 | Confidential © 2013 Brightcove Inc.
  • 12.
    12 | Confidential © 2013 Brightcove Inc.
  • 13.
  • 14.
    The ‘Format War’ 14| Confidential © 2013 Brightcove Inc.
  • 15.
    15 | Confidential © 2013 Brightcove Inc.
  • 16.
    OPEN CLOSED 16 | Confidential © 2013 Brightcove Inc.
  • 17.
    17 | Confidential © 2013 Brightcove Inc.
  • 18.
    18 | Confidential © 2013 Brightcove Inc.
  • 19.
    CONTAINER FORMAT VIDEO CODEC AUDIO CODEC 19 | Confidential © 2013 Brightcove Inc.
  • 20.
    MP4 H.264 AAC 3+ 9+ 9+ 20 | Confidential © 2013 Brightcove Inc.
  • 21.
    OGV THEORA VORBIS 3.5+ 3+ 10.5+ 21 | Confidential © 2013 Brightcove Inc.
  • 22.
    WEBM VP8 VORBIS 4+ 6+ 10.6+ 22 | Confidential © 2013 Brightcove Inc.
  • 23.
    23 | Confidential © 2013 Brightcove Inc.
  • 24.
    Three Formats 9+ 3+ 3+ 9+ 4+ 6+ 10.6+ 3.5+ 3+ 10.5+ 24 | Confidential © 2013 Brightcove Inc.
  • 25.
    Two Formats 9+ 3+ 3+ 9+ 4+ 6+ 10.6+ 25 | Confidential © 2013 Brightcove Inc.
  • 26.
    One Format 9+ 3+ 3+ 9+ 26 | Confidential © 2013 Brightcove Inc.
  • 27.
    Handbrake.fr 27 | Confidential © 2013 Brightcove Inc.
  • 28.
    Firefogg.org 28 | Confidential © 2013 Brightcove Inc.
  • 29.
    Zencoder.com 29 | Confidential © 2013 Brightcove Inc.
  • 30.
    Content Protection RTMP Streaming Source Obscurity Native App Obscurity DRM (Flash Time/GEO/IP limited HTTP Streaming Access/Smooth URLs AES Encryption Streaming) 30 | Confidential © 2013 Brightcove Inc.
  • 31.
    Content Protection bit.ly/wAkriF 31 | Confidential © 2013 Brightcove Inc.
  • 32.
    <video src=“video.mp4” controls></video> 32| Confidential © 2013 Brightcove Inc.
  • 33.
    <video controls> <source src=“video.mp4” type=“video/mp4”> <source src=“video.webm” type=“video/webm”> <source src=“video.ogv” type=“video/ogg”> </video> 33 | Confidential © 2013 Brightcove Inc.
  • 34.
    <video controls> <source src=“video.mp4” type=“video/mp4”> <source src=“video.webm” type=“video/webm”> <source src=“video.ogv” type=“video/ogg”> </video> 34 | Confidential © 2013 Brightcove Inc.
  • 35.
    <video controls> <source src=“video.mp4” type=“video/mp4”> <source src=“video.webm” type=“video/webm”> <source src=“video.ogv” type=“video/ogg”> <object type=“application/x-shockwave-flash” data=“flash.swf”> <param name=“movie” value=“flash.swf” /> <param name=“flashvars” value=“file=video.mp4” /> </object> </video> 35 | Confidential © 2013 Brightcove Inc.
  • 36.
    <video controls> <source src=“video.mp4” type=“video/mp4”> <source src=“video.webm” type=“video/webm”> <source src=“video.ogv” type=“video/ogg”> <object type=“application/x-shockwave-flash” data=“flash.swf”> <param name=“movie” value=“flash.swf” /> <param name=“flashvars” value=“file=video.mp4” /> <img src=“image.jpg” alt=“title” title=“Can’t play video” /> </object> </video> <p> <strong>Download Video:</strong> <a href=“video.mp4”>MP4</a> <a href=“video.ogv”>Ogg</a> </p> 36 | Confidential © 2013 Brightcove Inc.
  • 37.
    Controls Autoplay Tracks Poster Loop Preload Width/Height <video controls autoplay loop width=“480” height=“270” poster=“poster.png” preload=“auto”> <source src=“video.mp4” type=“video/mp4”> <track kind=“captions” src=“captions.vtt” srclang=“en”> </video> 37 | Confidential © 2013 Brightcove Inc.
  • 38.
    Tag Builder http://videojs.com/tag-builder/ 38| Confidential © 2013 Brightcove Inc.
  • 39.
    JavaScript API Attributes Functions • Events 39 | Confidential © 2013 Brightcove Inc.
  • 40.
    Browser/General Issues • Autobuffer => Preload • Cross-browser Load Progress Tracking • Missing Poster in Some Safari Devices • HTML5 Browsers Do Not Fallback on Incompatible Sources 40 | Confidential © 2013 Brightcove Inc.
  • 41.
    <video controls> <source src=“video.mp4” type=“video/mp4”> <source src=“video.webm” type=“video/webm”> <source src=“video.ogv” type=“video/ogg”> <object type=“application/x-shockwave-flash” data=“flash.swf”> <param name=“movie” value=“flash.swf” /> <param name=“flashvars” value=“file=video.mp4” /> </object> </video> 41 | Confidential © 2013 Brightcove Inc.
  • 42.
    Determine Video Support <script> var vidTag = document.createElement(“video”), flashVersion = swfobject.getFlashPlayerVersion(); if (vidTag.canPlayType && vidTag.canPlayType(“video/mp4”)) { // Video Tag } else if (flashVersion.major > 9){ // Flash Object } else { // No Video Support </script> SWF Object: http://code.google.com/p/swfobject/ 42 | Confidential © 2013 Brightcove Inc.
  • 43.
    Device Quirks: iOS3 • Needs MP4 as first source. iPad Poster Attribute Bug • iPad JS in Head / iPhone JS not in Head 43 | Confidential © 2013 Brightcove Inc.
  • 44.
    Device Quirks: Android2.1 / 2.2 • Can’t touch to start Type attribute breaks video • canPlayType function broken • ~25% of Android Users 44 | Confidential © 2013 Brightcove Inc.
  • 45.
    Android Touch StartFix <script> if (navigator.userAgent.match(/Android/i) !== null) { $(“video”).click(function(){ this.play(); }); } </script> 45 | Confidential © 2013 Brightcove Inc.
  • 46.
    Android Type AttributeFix Options • Don’t include type attribute Don’t use source tags <video src=“video.mp4” controls></video> • Set source through JS API video.src(“video.mp4”) 46 | Confidential © 2013 Brightcove Inc.
  • 47.
    Android canPlayType Fix <script> VarandroidMatch = navigator.userAgent.match(/Android (d+./i); if (androidMatch && androidMatch[1] < 3) { //Overwrite canPlayType document.createElement(“video”) .constructor.prototype.canPlayType = function(type){ if (type && type.toLowerCase()>indexOf(“video/mp4”) !== -1) { return “maybe”; } else { return “”; } }; } </script> 47 | Confidential © 2013 Brightcove Inc.
  • 48.
    The Future ofHTML5 Video • Content Protection - Encrypted Media Extensions • Adaptive Streaming - Media Source Extensions • Timed Text/Events - WebVTT • Video Chat - WebRTC • New Formats/Codecs - VPnext, h.265, Opus, TransOgg 48 | Confidential © 2013 Brightcove Inc.
  • 49.
    VideoJS.com 49 | Confidential © 2013 Brightcove Inc.
  • 50.
    Video for Everybodyby Krox Camen 50 | Confidential © 2013 Brightcove Inc.
  • 51.
    Dive into HTML5 by Mark Pilgrim 51 | Confidential © 2013 Brightcove Inc.
  • 52.
    HTML5 Video andAudio in Depth http://videojs.com/lynda 52 | Confidential © 2013 Brightcove Inc.
  • 53.
    Building an HTML5Video Player Brightcove Webcast, March 2013 Steve Heffernan, Video.js & Zencoder & Brightcove http://videojs.com @heff @videojs 53 | Confidential © 2013 Brightcove Inc.
  • 54.