<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Video.js Blog</title>
  
  <link href="/rss" rel="self"/>
  
  <link href="http://blog.videojs.com/"/>
  <updated>2019-01-18T19:57:55.575Z</updated>
  <id>http://blog.videojs.com/</id>
  
  <author>
    <name>John Doe</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>In-band Captions Support with videojs-http-streaming</title>
    <link href="http://blog.videojs.com/Inband-Captions-Support-with-VHS/"/>
    <id>http://blog.videojs.com/Inband-Captions-Support-with-VHS/</id>
    <published>2019-01-16T18:36:32.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<p>With the release of <a href="https://blog.videojs.com/introducing-video-js-http-streaming-vhs/">videojs-http-streaming</a> (VHS) v1.2.0 on July 16th 2018, Video.js has built-in support for CEA/CTA-608 captions carried in FMP4 segments. This means that closed captions are automatically parsed out and made available to Video.js players for MPEG-DASH content and HLS streams using FMP4 segments. Here’s a <a href="https://jsfiddle.net/ugnkw65y/" target="_blank" rel="external">sample player</a> that shows the captions (English with the “CC” button is the track with CEA-608 captions).</p>
<iframe src="https://jsfiddle.net/ugnkw65y/1/embedded/result,html/light" width="100%" height="550" frameborder="0" allowfullscreen></iframe>
<p>If you are curious about CEA-608 captions and the approach we used to parse them out of fmp4s, or a general overivew, you can watch my <a href="https://www.twitch.tv/videos/326082416?collection=u1vmyYMIYBXvlQ" target="_blank" rel="external">talk from Demuxed 2018</a>.</p>
<div class="video-container"><iframe src="//www.youtube.com/embed/0yTYNIajBQM" frameborder="0" allowfullscreen></iframe></div>
<p>Caption Parsing is handled by the <a href="https://github.com/videojs/mux.js" target="_blank" rel="external">mux.js</a> library and interacts with VHS to feed parsed captions back to Video.js.</p>
<h2 id="Usage"><a href="/Inband-Captions-Support-with-VHS/#Usage" class="headerlink" title="Usage"></a>Usage</h2><p>Create a CaptionParser:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; CaptionParser &#125; <span class="keyword">from</span> <span class="string">'mux.js/lib/mp4'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> captionParser = <span class="keyword">new</span> CaptionParser();</span><br><span class="line"></span><br><span class="line"><span class="comment">// initalize the CaptionParser to ensure that it is ready for data</span></span><br><span class="line"><span class="keyword">if</span> (!captionParser.isInitialized()) &#123;</span><br><span class="line">  captionParser.init();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>When working with HLS and MPEG-DASH with fmp4 segments, it’s likely that not all the information needed to parse out captions are included in the media segments themselves, and metadata from the <code>init</code> segment needs to be passed to the CaptionParser. For this reason, the video trackIds and timescales defined in the <code>init</code> segment should be passed into the CaptionParser.</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> mp4probe <span class="keyword">from</span> <span class="string">'mux.js/lib/mp4/probe'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// Typed array containing video and caption data</span></span><br><span class="line"><span class="keyword">const</span> data = <span class="keyword">new</span> <span class="built_in">Uint8Array</span>();</span><br><span class="line"><span class="comment">// Timescale = 90000</span></span><br><span class="line"><span class="keyword">const</span> timescales = mp4probe.timescale(data);</span><br><span class="line"><span class="comment">// trackId = 1</span></span><br><span class="line"><span class="keyword">const</span> videoTrackIds = mp4probe.videoTrackIds(data);</span><br><span class="line"></span><br><span class="line"><span class="comment">// Parsed captions are returned</span></span><br><span class="line"><span class="keyword">const</span> parsed = captionParser.parse(</span><br><span class="line">  data,</span><br><span class="line">  videoTrackIds,</span><br><span class="line">  timescales</span><br><span class="line">);</span><br></pre></td></tr></table></figure>
<p>Calling <code>captionParser.parse</code> with data containing CEA-608 captions will result in an object with this structure:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">&#123;</span><br><span class="line">  captions: [</span><br><span class="line">    &#123;</span><br><span class="line">      <span class="comment">// You can ignore the startPts and endPts values here</span></span><br><span class="line">      startPts: <span class="number">90000</span>,</span><br><span class="line">      endPts: <span class="number">99000</span>,</span><br><span class="line">      <span class="comment">// startTime and endTime can be used for caption times in the TextTrack API</span></span><br><span class="line">      startTime: <span class="number">1</span>,</span><br><span class="line">      endTime: <span class="number">1.1</span>,</span><br><span class="line">      text: <span class="string">'This is a test caption'</span>,</span><br><span class="line">      <span class="comment">// This is the CEA-608 "channel" the caption belongs to</span></span><br><span class="line">      stream: <span class="string">'CC1'</span></span><br><span class="line">    &#125;</span><br><span class="line">  ],</span><br><span class="line">  <span class="comment">// Includes any (or none) of: CC1, CC2, CC3, CC4</span></span><br><span class="line">  <span class="comment">// This should match the captions returned in the above caption array</span></span><br><span class="line">  captionStreams: &#123;</span><br><span class="line">    CC1: <span class="literal">true</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>
<p>You can then take one caption and create a <code>VTTCue</code> to add to a <code>TextTrack</code> with Video.js APIs</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> player = videojs(<span class="string">'video'</span>);</span><br><span class="line"><span class="keyword">const</span> track = player.addRemoteTextTrack(&#123;</span><br><span class="line">  kind: <span class="string">'captions'</span>,</span><br><span class="line">  label: parsed.captions[<span class="number">0</span>].stream,</span><br><span class="line">  <span class="keyword">default</span>: <span class="literal">true</span>,</span><br><span class="line">  language: <span class="string">'en'</span></span><br><span class="line">&#125;, <span class="literal">false</span>);</span><br><span class="line"></span><br><span class="line">track.addCue(parsed.captions[<span class="number">0</span>]);</span><br></pre></td></tr></table></figure>
<p>VHS is included by default with videojs v7.x.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;With the release of &lt;a href=&quot;https://blog.videojs.com/introducing-video-js-http-streaming-vhs/&quot;&gt;videojs-http-streaming&lt;/a&gt; (VHS) v1.2.0 o
    
    </summary>
    
    
      <category term="vhs" scheme="http://blog.videojs.com/tags/vhs/"/>
    
      <category term="videojs-http-streaming" scheme="http://blog.videojs.com/tags/videojs-http-streaming/"/>
    
      <category term="playback" scheme="http://blog.videojs.com/tags/playback/"/>
    
      <category term="captions" scheme="http://blog.videojs.com/tags/captions/"/>
    
      <category term="cea-608" scheme="http://blog.videojs.com/tags/cea-608/"/>
    
      <category term="608" scheme="http://blog.videojs.com/tags/608/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 7.4</title>
    <link href="http://blog.videojs.com/Video-js-7-4/"/>
    <id>http://blog.videojs.com/Video-js-7-4/</id>
    <published>2019-01-11T16:24:34.000Z</published>
    <updated>2019-01-18T19:57:55.603Z</updated>
    
    <content type="html"><![CDATA[<p>It’s time to have an overview of Video.js 7.4, first released early December. The big new feature for this release is a UI that allows you to seek during live streams. We updated focus-visible to work with our Menus, added more translations, added a replay option to the Play/Pause button, and many, many fixes, multiple of which are accessibility related.</p>
<p>We also dropped our usage of Grunt from our build process. We owe a lot to Grunt as it has served us well but it was time to move on.</p>
<p>Video.js 7.4.1 is currently the latest release with 7.4.2 out as a pre-release until next week.</p>
<h2 id="Thanks"><a href="/Video-js-7-4/#Thanks" class="headerlink" title="Thanks"></a>Thanks</h2><p>Before continuing, I’d like to thank everyone that was involved, we really appreciate your contributions! There were a total of 14 first time contributors, I think this is a historic high for us and I hope this continues!</p>
<ul>
<li><a href="https://github.com/BrandonOCasey" target="_blank" rel="external">@BrandonOCasey</a></li>
<li><a href="https://github.com/gesinger" target="_blank" rel="external">@gesinger</a></li>
<li><a href="https://github.com/gjanblaszczyk" target="_blank" rel="external">@gjanblaszczyk</a> (first time contributor!)</li>
<li><a href="https://github.com/valse" target="_blank" rel="external">@valse</a> (first time contributor!)</li>
<li><a href="https://github.com/gstrat88" target="_blank" rel="external">@gstrat88</a></li>
<li><a href="https://github.com/eranshmil" target="_blank" rel="external">@eranshmil</a> (first time contributor!)</li>
<li><a href="https://github.com/carlmorris" target="_blank" rel="external">@carlmorris</a> (first time contributor!)</li>
<li><a href="https://github.com/bartlomein" target="_blank" rel="external">@bartlomein</a> (first time contributor!)</li>
<li><a href="https://github.com/DanielRuf" target="_blank" rel="external">@DanielRuf</a> (first time contributor!)</li>
<li><a href="https://github.com/Quenty31" target="_blank" rel="external">@Quenty31</a> (first time contributor!)</li>
<li><a href="https://github.com/fketchakeu" target="_blank" rel="external">@fketchakeu</a> (first time contributor!)</li>
<li><a href="https://github.com/OwenEdwards" target="_blank" rel="external">@OwenEdwards</a></li>
<li><a href="https://github.com/alex-barstow" target="_blank" rel="external">@alex-barstow</a></li>
<li><a href="https://github.com/vitaliytv" target="_blank" rel="external">@vitaliytv</a> (first time contributor!)</li>
<li><a href="https://github.com/oaprograms" target="_blank" rel="external">@oaprograms</a> (first time contributor!)</li>
<li><a href="https://github.com/xjoaoalvesx" target="_blank" rel="external">@xjoaoalvesx</a> (first time contributor!)</li>
<li><a href="https://github.com/webdeveloperpr" target="_blank" rel="external">@webdeveloperpr</a> (first time contributor!)</li>
<li><a href="https://github.com/smbea" target="_blank" rel="external">@smbea</a> (first time contributor!)</li>
<li><a href="https://github.com/dustin71728" target="_blank" rel="external">@dustin71728</a> (first time contributor!)</li>
</ul>
<h2 id="Live-UI"><a href="/Video-js-7-4/#Live-UI" class="headerlink" title="Live UI"></a>Live UI</h2><p>Video.js has supported live streams for a while, either natively, or via <a href="https://github.com/videojs/http-streaming" target="_blank" rel="external">videojs-http-streaming (VHS)</a>. However, this UI was very minimal, it disabled the progress bar and basically only allowed pausing, though, there was an indicator that this was a live stream.</p>
<p><img src="/Video-js-7-4/live ui.png" alt="Video.js, with the new Live UI, playing a live stream"></p>
<p>The new UI looks pretty similar to the previous live UI and the regular control bar. The “live” indicator moves to the right side of the progress bar and also indicates whether we are playing back live or we are behind live. Clicking this button will seek to the “live point”. The time displays and tooltips will show time with respect to the live point; so, current time at the live point will be <code>0</code> and if you seek back 30 seconds it’ll show <code>-00:30</code>.</p>
<p>This feature is still somewhat experimental, so, it is behind an option that is off by default. We hope that you try it out and give us feedback and that we can enable it by default in a future release.</p>
<p>To enable the feature, pass in <code>liveui: true</code> to the player:<br>In JavaScript:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> player = videojs(<span class="string">'my-id'</span>, &#123;</span><br><span class="line">  liveui: <span class="literal">true</span></span><br><span class="line">  &#125;</span><br><span class="line">);</span><br></pre></td></tr></table></figure></p>
<p>Or HTML:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">video-js</span> <span class="attr">id</span>=<span class="string">"my-id"</span> <span class="attr">data-setup</span>=<span class="string">'&#123;"liveui": true&#125;'</span>&#125;&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">source</span> <span class="attr">src</span>=<span class="string">"https://example.com/live.m3u8"</span> <span class="attr">type</span>=<span class="string">"application/x-mpegurl"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">video-js</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<h2 id="Languages"><a href="/Video-js-7-4/#Languages" class="headerlink" title="Languages"></a>Languages</h2><p>We’ve had a bunch of language additions and updates in the 7.4 release line. In addition, we now copy the JSON files into the dist/lang folder for easier inclusion your projects.</p>
<h3 id="Languages-added-and-updated"><a href="/Video-js-7-4/#Languages-added-and-updated" class="headerlink" title="Languages added and updated"></a>Languages added and updated</h3><ul>
<li>Occitan (oc)</li>
<li>Russian (ru)</li>
<li>Welsh/Cymraeg (cy)</li>
<li>Ukrainian (uk)</li>
<li>Serbian (sr)</li>
<li>Swedish (sv)</li>
</ul>
<h2 id="Accessibility"><a href="/Video-js-7-4/#Accessibility" class="headerlink" title="Accessibility"></a>Accessibility</h2><p>As always, we aim to make Video.js as accessible and usable as we can. To that end, we’ve had a bunch of accessibility related fixes in these releases.</p>
<ul>
<li>Time displays accessibility with VoiceOver</li>
<li>remove hidden control text in progress bar</li>
<li>make the seek-to-live button announce itself to screen readers properly</li>
<li>Make the <code>-</code> in the remaining time display be visual only and not readable by screen readers</li>
</ul>
<h2 id="Other-Features-Updates"><a href="/Video-js-7-4/#Other-Features-Updates" class="headerlink" title="Other Features Updates"></a>Other Features Updates</h2><h3 id="Responsive-Captions-Settings-Dialog"><a href="/Video-js-7-4/#Responsive-Captions-Settings-Dialog" class="headerlink" title="Responsive Captions Settings Dialog"></a>Responsive Captions Settings Dialog</h3><p>This uses the new <code>responsive</code> setting and breakpoints to make the dialog respond to the size of the player and improves the user experience.</p>
<h3 id="replay-option-for-PlayToggle"><a href="/Video-js-7-4/#replay-option-for-PlayToggle" class="headerlink" title="replay option for PlayToggle"></a>replay option for PlayToggle</h3><p>The PlayToggle button changes the icon to a replay icon when the video ends, most users don’t mind it and it was a highly requested feature previously. This adds an option to turn it off.</p>
<h3 id="focus-visisble-menu-backgrounds"><a href="/Video-js-7-4/#focus-visisble-menu-backgrounds" class="headerlink" title="focus-visisble menu backgrounds"></a>focus-visisble menu backgrounds</h3><p>Like outlines for other buttons, we use a different background color to represent the focus in menus. We should respect focus-visible there like we do for outlines in buttons.</p>
<h3 id="playerreset-event"><a href="/Video-js-7-4/#playerreset-event" class="headerlink" title="playerreset event"></a>playerreset event</h3><p>When the player is reset with the <code>reset()</code> method, it’ll now trigger a <code>playerreset</code> event to let components and users know.</p>
<h2 id="Other-Fixes"><a href="/Video-js-7-4/#Other-Fixes" class="headerlink" title="Other Fixes"></a>Other Fixes</h2><ul>
<li>Fix fullscreen event triggering twice (7.4.2)</li>
<li>PlayToggle cursor pointer</li>
<li>select default subtitles on loadedmetadata not loadstart</li>
<li>don’t apply user preference to subtitles if no language is set</li>
<li>make sure that vjs-waiting is only removed if we started playback again</li>
<li>allow duration to be set to NaN, making Video.js more spec compliant</li>
<li>fix locking menus when the menu button is pressed</li>
<li>remove child component from old parent when moving the component to a new parent</li>
<li>remove vjs-ended when seeking after video has ended</li>
<li>don’t autohide the control bar when hovering with the mouse</li>
</ul>
<h2 id="Full-CHANGELOG-for-7-4-0-7-4-1-and-7-4-2"><a href="/Video-js-7-4/#Full-CHANGELOG-for-7-4-0-7-4-1-and-7-4-2" class="headerlink" title="Full CHANGELOG for 7.4.0, 7.4.1, and 7.4.2"></a>Full CHANGELOG for 7.4.0, 7.4.1, and 7.4.2</h2><p><a name="7.4.2"></a></p>
<h2 id="7-4-2-2019-01-08"><a href="/Video-js-7-4/#7-4-2-2019-01-08" class="headerlink" title="7.4.2 (2019-01-08)"></a><a href="https://github.com/videojs/video.js/compare/v7.4.1...v7.4.2" target="_blank" rel="external">7.4.2</a> (2019-01-08)</h2><h3 id="Bug-Fixes"><a href="/Video-js-7-4/#Bug-Fixes" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>Control-bar autohide when cursor placed over it <a href="https://github.com/videojs/video.js/issues/5258" target="_blank" rel="external">#5258</a> (<a href="https://github.com/videojs/video.js/issues/5692" target="_blank" rel="external">#5692</a>) (<a href="https://github.com/videojs/video.js/commit/6ebc772" target="_blank" rel="external">6ebc772</a>)</li>
<li>css animation shorthand property order (<a href="https://github.com/videojs/video.js/issues/5687" target="_blank" rel="external">#5687</a>) (<a href="https://github.com/videojs/video.js/commit/0e69ce9" target="_blank" rel="external">0e69ce9</a>)</li>
<li><strong>fs:</strong> make sure there’s only one fullscreenchange event (<a href="https://github.com/videojs/video.js/issues/5686" target="_blank" rel="external">#5686</a>) (<a href="https://github.com/videojs/video.js/commit/2bc90a1" target="_blank" rel="external">2bc90a1</a>), closes <a href="https://github.com/videojs/video.js/issues/5685" target="_blank" rel="external">#5685</a></li>
<li><strong>lang:</strong> adds sv translation used by liveui component (<a href="https://github.com/videojs/video.js/issues/5704" target="_blank" rel="external">#5704</a>) (<a href="https://github.com/videojs/video.js/commit/f38726e" target="_blank" rel="external">f38726e</a>)</li>
<li><strong>package:</strong> update <a href="https://github.com/videojs" target="_blank" rel="external">@videojs</a>/http-streaming to version 1.6.0 🚀 (<a href="https://github.com/videojs/video.js/issues/5705" target="_blank" rel="external">#5705</a>) (<a href="https://github.com/videojs/video.js/commit/3d093ed" target="_blank" rel="external">3d093ed</a>)</li>
<li><strong>player:</strong> remove vjs-ended class on seeked (<a href="https://github.com/videojs/video.js/issues/5728" target="_blank" rel="external">#5728</a>) (<a href="https://github.com/videojs/video.js/commit/f1637cd" target="_blank" rel="external">f1637cd</a>), closes <a href="https://github.com/videojs/video.js/issues/5654" target="_blank" rel="external">#5654</a></li>
<li><strong>remaining-time-display:</strong> make the ‘-‘ be visual and not readable by screen readers (<a href="https://github.com/videojs/video.js/issues/5671" target="_blank" rel="external">#5671</a>) (<a href="https://github.com/videojs/video.js/commit/05513f8" target="_blank" rel="external">05513f8</a>), closes <a href="https://github.com/videojs/video.js/issues/5168" target="_blank" rel="external">#5168</a></li>
<li><strong>seekbar:</strong> don’t disable if live tracker’s seekable is infinity (<a href="https://github.com/videojs/video.js/issues/5721" target="_blank" rel="external">#5721</a>) (<a href="https://github.com/videojs/video.js/commit/7f507df" target="_blank" rel="external">7f507df</a>)</li>
<li>remove child from old parent when moving to new parent via addChild (<a href="https://github.com/videojs/video.js/issues/5702" target="_blank" rel="external">#5702</a>) (<a href="https://github.com/videojs/video.js/commit/8a3e2a7" target="_blank" rel="external">8a3e2a7</a>)</li>
</ul>
<h3 id="Chores"><a href="/Video-js-7-4/#Chores" class="headerlink" title="Chores"></a>Chores</h3><ul>
<li><strong>package:</strong> update babel to version 7.2.2 (<a href="https://github.com/videojs/video.js/issues/5697" target="_blank" rel="external">#5697</a>) (<a href="https://github.com/videojs/video.js/commit/30d0b98" target="_blank" rel="external">30d0b98</a>), closes <a href="https://github.com/videojs/video.js/issues/5689" target="_blank" rel="external">#5689</a></li>
<li><strong>package:</strong> update rollup to version 0.68.0 🚀 (<a href="https://github.com/videojs/video.js/issues/5690" target="_blank" rel="external">#5690</a>) (<a href="https://github.com/videojs/video.js/commit/f0ba1f5" target="_blank" rel="external">f0ba1f5</a>)</li>
</ul>
<h3 id="Documentation"><a href="/Video-js-7-4/#Documentation" class="headerlink" title="Documentation"></a>Documentation</h3><ul>
<li><strong>liveui:</strong> Add a guide for the live ui and live api (<a href="https://github.com/videojs/video.js/issues/5677" target="_blank" rel="external">#5677</a>) (<a href="https://github.com/videojs/video.js/commit/c147581" target="_blank" rel="external">c147581</a>)</li>
</ul>
<p><a name="7.4.1"></a></p>
<h2 id="7-4-1-2018-12-11"><a href="/Video-js-7-4/#7-4-1-2018-12-11" class="headerlink" title="7.4.1 (2018-12-11)"></a><a href="https://github.com/videojs/video.js/compare/v7.4.0...v7.4.1" target="_blank" rel="external">7.4.1</a> (2018-12-11)</h2><h3 id="Bug-Fixes-1"><a href="/Video-js-7-4/#Bug-Fixes-1" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li><strong>a11y:</strong> current time and duration display accessibility with VoiceOver (<a href="https://github.com/videojs/video.js/issues/5653" target="_blank" rel="external">#5653</a>) (<a href="https://github.com/videojs/video.js/commit/8932611" target="_blank" rel="external">8932611</a>), closes <a href="https://github.com//www.w3.org/TR/html-aam-1.0//issues/details-id-124" target="_blank" rel="external">/www.w3.org/TR/html-aam-1.0/#details-id-124</a></li>
<li><strong>a11y:</strong> fix hidden Control Text in Progress bar (Fixes <a href="https://github.com/videojs/video.js/issues/5251" target="_blank" rel="external">#5251</a>) (<a href="https://github.com/videojs/video.js/issues/5655" target="_blank" rel="external">#5655</a>) (<a href="https://github.com/videojs/video.js/commit/70a71ae" target="_blank" rel="external">70a71ae</a>)</li>
<li><strong>a11y:</strong> make seek-to-live better announce itself to screen reader users (<a href="https://github.com/videojs/video.js/issues/5651" target="_blank" rel="external">#5651</a>) (<a href="https://github.com/videojs/video.js/commit/165c120" target="_blank" rel="external">165c120</a>)</li>
<li><strong>lang:</strong> append UKR translations and fix check translations command (<a href="https://github.com/videojs/video.js/issues/5642" target="_blank" rel="external">#5642</a>) (<a href="https://github.com/videojs/video.js/commit/b7aafdc" target="_blank" rel="external">b7aafdc</a>)</li>
<li><strong>lang:</strong> improves sv lang file (<a href="https://github.com/videojs/video.js/issues/5673" target="_blank" rel="external">#5673</a>) (<a href="https://github.com/videojs/video.js/commit/b9d8744" target="_blank" rel="external">b9d8744</a>)</li>
<li><strong>lang:</strong> Update sr.json (<a href="https://github.com/videojs/video.js/issues/5657" target="_blank" rel="external">#5657</a>) (<a href="https://github.com/videojs/video.js/commit/98b4a1c" target="_blank" rel="external">98b4a1c</a>)</li>
<li><strong>liveui:</strong> make edge detection less strict, add docs for option (<a href="https://github.com/videojs/video.js/issues/5661" target="_blank" rel="external">#5661</a>) (<a href="https://github.com/videojs/video.js/commit/dce4a2c" target="_blank" rel="external">dce4a2c</a>)</li>
<li><strong>liveui:</strong> seek to live should be immediate and other tweaks (<a href="https://github.com/videojs/video.js/issues/5650" target="_blank" rel="external">#5650</a>) (<a href="https://github.com/videojs/video.js/commit/831961b" target="_blank" rel="external">831961b</a>)</li>
<li><strong>package:</strong> update <a href="https://github.com/videojs" target="_blank" rel="external">@videojs</a>/http-streaming to version 1.5.1 🚀 (<a href="https://github.com/videojs/video.js/issues/5658" target="_blank" rel="external">#5658</a>) (<a href="https://github.com/videojs/video.js/commit/8c9702a" target="_blank" rel="external">8c9702a</a>)</li>
</ul>
<h3 id="Chores-1"><a href="/Video-js-7-4/#Chores-1" class="headerlink" title="Chores"></a>Chores</h3><ul>
<li><strong>package:</strong> update autoprefixer to version 9.4.2 (<a href="https://github.com/videojs/video.js/issues/5647" target="_blank" rel="external">#5647</a>) (<a href="https://github.com/videojs/video.js/commit/19f3465" target="_blank" rel="external">19f3465</a>)</li>
<li><strong>package:</strong> update rollup-plugin-node-resolve to version 4.0.0 🚀 (<a href="https://github.com/videojs/video.js/issues/5666" target="_blank" rel="external">#5666</a>) (<a href="https://github.com/videojs/video.js/commit/d07b6c2" target="_blank" rel="external">d07b6c2</a>)</li>
</ul>
<h3 id="Documentation-1"><a href="/Video-js-7-4/#Documentation-1" class="headerlink" title="Documentation"></a>Documentation</h3><ul>
<li>remove grunt and update usage of build scripts (<a href="https://github.com/videojs/video.js/issues/5656" target="_blank" rel="external">#5656</a>) (<a href="https://github.com/videojs/video.js/commit/62f9e78" target="_blank" rel="external">62f9e78</a>)</li>
</ul>
<h3 id="Tests"><a href="/Video-js-7-4/#Tests" class="headerlink" title="Tests"></a>Tests</h3><ul>
<li>verify null-checks with player and control bar children set to false (<a href="https://github.com/videojs/video.js/issues/5670" target="_blank" rel="external">#5670</a>) (<a href="https://github.com/videojs/video.js/commit/13b42ad" target="_blank" rel="external">13b42ad</a>)</li>
</ul>
<p><a name="7.4.0"></a></p>
<h1 id="7-4-0-2018-12-03"><a href="/Video-js-7-4/#7-4-0-2018-12-03" class="headerlink" title="7.4.0 (2018-12-03)"></a><a href="https://github.com/videojs/video.js/compare/v7.3.0...v7.4.0" target="_blank" rel="external">7.4.0</a> (2018-12-03)</h1><h3 id="Features"><a href="/Video-js-7-4/#Features" class="headerlink" title="Features"></a>Features</h3><ul>
<li>add ‘replay’ option to the PlayToggle component. (<a href="https://github.com/videojs/video.js/issues/5531" target="_blank" rel="external">#5531</a>) (<a href="https://github.com/videojs/video.js/commit/f178458" target="_blank" rel="external">f178458</a>), closes <a href="https://github.com/videojs/video.js/issues/4802" target="_blank" rel="external">#4802</a></li>
<li><strong>lang:</strong> Add the Occitan locale (<a href="https://github.com/videojs/video.js/issues/5578" target="_blank" rel="external">#5578</a>) (<a href="https://github.com/videojs/video.js/commit/0fb637d" target="_blank" rel="external">0fb637d</a>)</li>
<li><strong>lang:</strong> Add Welsh/Cymraeg (cy) translations (<a href="https://github.com/videojs/video.js/issues/5561" target="_blank" rel="external">#5561</a>) (<a href="https://github.com/videojs/video.js/commit/b2c1077" target="_blank" rel="external">b2c1077</a>)</li>
<li><strong>lang:</strong> copy language JSON files into dist dir (<a href="https://github.com/videojs/video.js/issues/5549" target="_blank" rel="external">#5549</a>) (<a href="https://github.com/videojs/video.js/commit/eb5de19" target="_blank" rel="external">eb5de19</a>), closes <a href="https://github.com/videojs/video.js/issues/5092" target="_blank" rel="external">#5092</a></li>
<li><strong>player:</strong> add playerreset event (<a href="https://github.com/videojs/video.js/issues/5335" target="_blank" rel="external">#5335</a>) (<a href="https://github.com/videojs/video.js/commit/0e5442f" target="_blank" rel="external">0e5442f</a>)</li>
<li>make menu background respect :focus-visible (<a href="https://github.com/videojs/video.js/issues/5558" target="_blank" rel="external">#5558</a>) (<a href="https://github.com/videojs/video.js/commit/e5e1e29" target="_blank" rel="external">e5e1e29</a>)</li>
<li>responsive caption settings (<a href="https://github.com/videojs/video.js/issues/5534" target="_blank" rel="external">#5534</a>) (<a href="https://github.com/videojs/video.js/commit/b67fe27" target="_blank" rel="external">b67fe27</a>)</li>
<li>support seeking during live playback via liveui option (<a href="https://github.com/videojs/video.js/issues/5511" target="_blank" rel="external">#5511</a>) (<a href="https://github.com/videojs/video.js/commit/2974ad3" target="_blank" rel="external">2974ad3</a>)</li>
</ul>
<h3 id="Bug-Fixes-2"><a href="/Video-js-7-4/#Bug-Fixes-2" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>add correct cursor pointer for the play toggle  (<a href="https://github.com/videojs/video.js/issues/5463" target="_blank" rel="external">#5463</a>) (<a href="https://github.com/videojs/video.js/commit/aed337a" target="_blank" rel="external">aed337a</a>)</li>
<li>default subtitles not enabled (<a href="https://github.com/videojs/video.js/issues/5608" target="_blank" rel="external">#5608</a>) (<a href="https://github.com/videojs/video.js/commit/8329e64" target="_blank" rel="external">8329e64</a>)</li>
<li><strong>tracks:</strong> don’t select tracks based on user pref if no langauge is set (<a href="https://github.com/videojs/video.js/issues/5556" target="_blank" rel="external">#5556</a>) (<a href="https://github.com/videojs/video.js/commit/c1cbce3" target="_blank" rel="external">c1cbce3</a>), closes <a href="https://github.com/videojs/video.js/issues/5553" target="_blank" rel="external">#5553</a></li>
<li>Don’t remove vjs-waiting until time changes (<a href="https://github.com/videojs/video.js/issues/5533" target="_blank" rel="external">#5533</a>) (<a href="https://github.com/videojs/video.js/commit/0060747" target="_blank" rel="external">0060747</a>)</li>
<li><strong>lang:</strong> add  is loading ru translation (<a href="https://github.com/videojs/video.js/issues/5630" target="_blank" rel="external">#5630</a>) (<a href="https://github.com/videojs/video.js/commit/0090b75" target="_blank" rel="external">0090b75</a>)</li>
<li><strong>lang:</strong> Occitan: harmonisation plural/singular (<a href="https://github.com/videojs/video.js/issues/5602" target="_blank" rel="external">#5602</a>) (<a href="https://github.com/videojs/video.js/commit/4842201" target="_blank" rel="external">4842201</a>)</li>
<li><strong>package:</strong> update <a href="https://github.com/videojs" target="_blank" rel="external">@videojs</a>/http-streaming to version 1.4.2 🚀 (<a href="https://github.com/videojs/video.js/issues/5543" target="_blank" rel="external">#5543</a>) (<a href="https://github.com/videojs/video.js/commit/dbaca33" target="_blank" rel="external">dbaca33</a>)</li>
<li><strong>package:</strong> update <a href="https://github.com/videojs" target="_blank" rel="external">@videojs</a>/http-streaming to version 1.5.0 🚀 (<a href="https://github.com/videojs/video.js/issues/5587" target="_blank" rel="external">#5587</a>) (<a href="https://github.com/videojs/video.js/commit/d95ef6f" target="_blank" rel="external">d95ef6f</a>)</li>
<li>duration reset and allow duration NaN or 0 for duration display (<a href="https://github.com/videojs/video.js/issues/5348" target="_blank" rel="external">#5348</a>) (<a href="https://github.com/videojs/video.js/commit/ab0e29a" target="_blank" rel="external">ab0e29a</a>), closes <a href="https://github.com/videojs/video.js/issues/5347" target="_blank" rel="external">#5347</a></li>
<li>not inline volume slider showing up after mouse hovering on it (<a href="https://github.com/videojs/video.js/issues/5503" target="_blank" rel="external">#5503</a>) (<a href="https://github.com/videojs/video.js/commit/7d127c8" target="_blank" rel="external">7d127c8</a>), closes <a href="https://github.com/videojs/video.js/issues/5502" target="_blank" rel="external">#5502</a> <a href="https://github.com/videojs/video.js/issues/5505" target="_blank" rel="external">#5505</a></li>
<li>vjs-lock-showing class gets removed from menu when no longer hovering on menu-button. (<a href="https://github.com/videojs/video.js/issues/5465" target="_blank" rel="external">#5465</a>) (<a href="https://github.com/videojs/video.js/commit/58f638e" target="_blank" rel="external">58f638e</a>), closes <a href="https://github.com/videojs/video.js/issues/1690" target="_blank" rel="external">#1690</a></li>
</ul>
<h3 id="Chores-2"><a href="/Video-js-7-4/#Chores-2" class="headerlink" title="Chores"></a>Chores</h3><ul>
<li>fix lint on pre-commit with lint-staged, use npm-merge-driver (<a href="https://github.com/videojs/video.js/issues/5591" target="_blank" rel="external">#5591</a>) (<a href="https://github.com/videojs/video.js/commit/be9e9a9" target="_blank" rel="external">be9e9a9</a>)</li>
<li>fix travis build (<a href="https://github.com/videojs/video.js/issues/5627" target="_blank" rel="external">#5627</a>) (<a href="https://github.com/videojs/video.js/commit/6c1056b" target="_blank" rel="external">6c1056b</a>), closes <a href="https://github.com/videojs/video.js/issues/5626" target="_blank" rel="external">#5626</a> <a href="https://github.com/videojs/video.js/issues/5616" target="_blank" rel="external">#5616</a></li>
<li>Move a11y, lang, browserify, and webpack out of grunt (<a href="https://github.com/videojs/video.js/issues/5589" target="_blank" rel="external">#5589</a>) (<a href="https://github.com/videojs/video.js/commit/db6e376" target="_blank" rel="external">db6e376</a>)</li>
<li>move copy, zip, and clean tasks to npm scripts (<a href="https://github.com/videojs/video.js/issues/5544" target="_blank" rel="external">#5544</a>) (<a href="https://github.com/videojs/video.js/commit/2d682a4" target="_blank" rel="external">2d682a4</a>)</li>
<li>remove grunt move to npm scripts (<a href="https://github.com/videojs/video.js/issues/5592" target="_blank" rel="external">#5592</a>) (<a href="https://github.com/videojs/video.js/commit/d72786f" target="_blank" rel="external">d72786f</a>)</li>
<li>switch from cross-var to cross-env (<a href="https://github.com/videojs/video.js/issues/5600" target="_blank" rel="external">#5600</a>) (<a href="https://github.com/videojs/video.js/commit/ab740bc" target="_blank" rel="external">ab740bc</a>)</li>
<li>switch to videojs-generate-karma-config (<a href="https://github.com/videojs/video.js/issues/5528" target="_blank" rel="external">#5528</a>) (<a href="https://github.com/videojs/video.js/commit/2e70450" target="_blank" rel="external">2e70450</a>)</li>
<li>update all the dev deps to their latest versions (<a href="https://github.com/videojs/video.js/issues/5645" target="_blank" rel="external">#5645</a>) (<a href="https://github.com/videojs/video.js/commit/db1369a" target="_blank" rel="external">db1369a</a>), closes <a href="https://github.com/videojs/video.js/issues/5644" target="_blank" rel="external">#5644</a> <a href="https://github.com/videojs/video.js/issues/5643" target="_blank" rel="external">#5643</a></li>
<li>update deps, remove coveralls, fix audit issues (<a href="https://github.com/videojs/video.js/issues/5555" target="_blank" rel="external">#5555</a>) (<a href="https://github.com/videojs/video.js/commit/11f1fb8" target="_blank" rel="external">11f1fb8</a>)</li>
<li>use relative urls in index.html (<a href="https://github.com/videojs/video.js/issues/5586" target="_blank" rel="external">#5586</a>) (<a href="https://github.com/videojs/video.js/commit/dec31e4" target="_blank" rel="external">dec31e4</a>)</li>
<li><strong>netlify:</strong> make docs build properly (<a href="https://github.com/videojs/video.js/issues/5636" target="_blank" rel="external">#5636</a>) (<a href="https://github.com/videojs/video.js/commit/a8828cd" target="_blank" rel="external">a8828cd</a>)</li>
<li><strong>package:</strong> update conventional-changelog-cli to version 2.0.11 (<a href="https://github.com/videojs/video.js/issues/5552" target="_blank" rel="external">#5552</a>) (<a href="https://github.com/videojs/video.js/commit/f236176" target="_blank" rel="external">f236176</a>)</li>
<li><strong>package:</strong> update grunt-cli to version 1.3.2 (<a href="https://github.com/videojs/video.js/issues/5550" target="_blank" rel="external">#5550</a>) (<a href="https://github.com/videojs/video.js/commit/2d27b6a" target="_blank" rel="external">2d27b6a</a>)</li>
<li><strong>package:</strong> update husky to version 1.1.3 (<a href="https://github.com/videojs/video.js/issues/5551" target="_blank" rel="external">#5551</a>) (<a href="https://github.com/videojs/video.js/commit/937e2bf" target="_blank" rel="external">937e2bf</a>)</li>
<li><strong>package:</strong> update npm-run-all to 4.1.5 to remove event-stream (<a href="https://github.com/videojs/video.js/issues/5614" target="_blank" rel="external">#5614</a>) (<a href="https://github.com/videojs/video.js/commit/3e52c4f" target="_blank" rel="external">3e52c4f</a>)</li>
<li><strong>package:</strong> update remark-stringify to version 6.0.1 (<a href="https://github.com/videojs/video.js/issues/5539" target="_blank" rel="external">#5539</a>) (<a href="https://github.com/videojs/video.js/commit/d46828a" target="_blank" rel="external">d46828a</a>)</li>
<li><strong>package:</strong> update rollup to version 0.67.1 (<a href="https://github.com/videojs/video.js/issues/5580" target="_blank" rel="external">#5580</a>) (<a href="https://github.com/videojs/video.js/commit/209d9f9" target="_blank" rel="external">209d9f9</a>)</li>
<li><strong>package:</strong> update videojs-generate-karma-config to version 5.0.0 🚀 (<a href="https://github.com/videojs/video.js/issues/5595" target="_blank" rel="external">#5595</a>) (<a href="https://github.com/videojs/video.js/commit/2162239" target="_blank" rel="external">2162239</a>)</li>
<li><strong>player:</strong> fix linting for a comment (<a href="https://github.com/videojs/video.js/issues/5588" target="_blank" rel="external">#5588</a>) (<a href="https://github.com/videojs/video.js/commit/b5e6bdc" target="_blank" rel="external">b5e6bdc</a>)</li>
<li><strong>travis:</strong> remove unused secret variables (<a href="https://github.com/videojs/video.js/issues/5577" target="_blank" rel="external">#5577</a>) (<a href="https://github.com/videojs/video.js/commit/15beea7" target="_blank" rel="external">15beea7</a>)</li>
</ul>
<h3 id="Documentation-2"><a href="/Video-js-7-4/#Documentation-2" class="headerlink" title="Documentation"></a>Documentation</h3><ul>
<li><strong>media-error:</strong> Correct error type documentation (<a href="https://github.com/videojs/video.js/issues/5566" target="_blank" rel="external">#5566</a>) (<a href="https://github.com/videojs/video.js/commit/441f0e1" target="_blank" rel="external">441f0e1</a>)</li>
<li>update starter template (<a href="https://github.com/videojs/video.js/issues/5570" target="_blank" rel="external">#5570</a>) (<a href="https://github.com/videojs/video.js/commit/287b267" target="_blank" rel="external">287b267</a>), closes <a href="https://github.com/1000/issues/0" target="_blank" rel="external">1000#0</a> <a href="https://github.com/videojs/video.js/issues/5562" target="_blank" rel="external">#5562</a></li>
<li>Update urls in README.md to point to v7.3.0 (<a href="https://github.com/videojs/video.js/issues/5536" target="_blank" rel="external">#5536</a>) (<a href="https://github.com/videojs/video.js/commit/79edf5b" target="_blank" rel="external">79edf5b</a>)</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;It’s time to have an overview of Video.js 7.4, first released early December. The big new feature for this release is a UI that allows yo
    
    </summary>
    
    
      <category term="a11y" scheme="http://blog.videojs.com/tags/a11y/"/>
    
      <category term="responsive" scheme="http://blog.videojs.com/tags/responsive/"/>
    
      <category term="languages" scheme="http://blog.videojs.com/tags/languages/"/>
    
      <category term="live-ui" scheme="http://blog.videojs.com/tags/live-ui/"/>
    
      <category term="focus-visible" scheme="http://blog.videojs.com/tags/focus-visible/"/>
    
  </entry>
  
  <entry>
    <title>Bugpost: Disconnects and Reconnects</title>
    <link href="http://blog.videojs.com/Bugpost-Disconnects-and-Reconnects/"/>
    <id>http://blog.videojs.com/Bugpost-Disconnects-and-Reconnects/</id>
    <published>2018-12-17T15:00:44.000Z</published>
    <updated>2019-01-18T19:57:55.569Z</updated>
    
    <content type="html"><![CDATA[<p>In my old apartment, whenever I nuked a bowl of oats in the microwave, my WIFI cut out. It was an annoyance, but I was hungry, the apartment was too small to move the router further from the microwave, and I didn’t want to buy anything that operated on a different frequency. So I’d start the microwave, watch whatever video was streaming on my laptop until the buffer ran out, then watch the loading spinner until the microwave gave the triple ding.</p>
<p>Thankfully, video players are usually pretty robust against such issues as network connectivity (and rogue microwaves), and the video resumed after the network recovered. But recently, we found that for some content played in Video.js, the video didn’t resume. Even worse, the loading spinner simply disappeared, leaving a frozen frame on screen.</p>
<p>You can see this behavior yourself by checking out Video.js 7.3.0, loading <a href="https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd" target="_blank" rel="external">https://dash.akamaized.net/akamai/bbb_30fps/bbb_30fps.mpd</a> as the source, and using Chrome Dev Tools to disconnect and reconnect the network.</p>
<p>Here’s a quick tour of what happened and how we fixed it.</p>
<h2 id="The-Loading-Spinner"><a href="/Bugpost-Disconnects-and-Reconnects/#The-Loading-Spinner" class="headerlink" title="The Loading Spinner"></a>The Loading Spinner</h2><p>To approach the bug, we started with the most glaring problem, the disappearance of the loading spinner. The spinner is managed by Video.js. In <a href="https://github.com/videojs/video.js/blob/v7.3.0/src/js/player.js#L1598" target="_blank" rel="external">the code</a>, the <code>vjs-waiting</code> class is added to the HTML element when the tech triggers a <code>waiting</code> event, and is removed on the next <code>timeupdate</code> event.</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * Retrigger the `waiting` event that was triggered by the &#123;@link Tech&#125;.</span><br><span class="line"> *</span><br><span class="line"> * @fires Player#waiting</span><br><span class="line"> * @listens Tech#waiting</span><br><span class="line"> * @private</span><br><span class="line"> */</span><br><span class="line">handleTechWaiting_() &#123;</span><br><span class="line">  this.addClass(&apos;vjs-waiting&apos;);</span><br><span class="line">  /**</span><br><span class="line">   * A readyState change on the DOM element has caused playback to stop.</span><br><span class="line">   *</span><br><span class="line">   * @event Player#waiting</span><br><span class="line">   * @type &#123;EventTarget~Event&#125;</span><br><span class="line">   */</span><br><span class="line">  this.trigger(&apos;waiting&apos;);</span><br><span class="line">  this.one(&apos;timeupdate&apos;, () =&gt; this.removeClass(&apos;vjs-waiting&apos;));</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>After logging the events emitted by the player, the issue became clear. Some browsers emitted a <code>timeupdate</code> event immediatley after the <code>waiting</code> event.</p>
<p>So <code>timeupdate</code> events themselves were not reliable, but what else could be used to make a better determination of if we’re waiting? We checked <code>player.currentTime()</code> on the <code>timeupdate</code> events, and found that when we caught the last <code>timeupdate</code> event, the one after the <code>waiting</code> event, the player was at the same time as the <code>timeupdate</code> event prior to the <code>waiting</code> event (and the same time as when the <code>waiting</code> event was triggered).</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">`timeupdate` triggered, player.currentTime = 11</span><br><span class="line">`timeupdate` triggered, player.currentTime = 11.250</span><br><span class="line">`waiting` triggered, player.currentTime = 11.250</span><br><span class="line">`timeupdate` triggered, player.currentTime = 11.250</span><br></pre></td></tr></table></figure>
<p>The fix was pretty easy. Simply record the player’s time when it gets the <code>waiting</code> event, and instead of removing the <code>vjs-waiting</code> class on the next <code>timeupdate</code>, remove the <code>vjs-waiting</code> class on the next <code>timeupdate</code> that has a different time from the one we recorded.</p>
<p>You can see the PR for that <a href="https://github.com/videojs/video.js/pull/5533" target="_blank" rel="external">here</a>, and it is available in Video.js 7.4.0.</p>
<h2 id="Resuming-Playback-after-Disconnecting"><a href="/Bugpost-Disconnects-and-Reconnects/#Resuming-Playback-after-Disconnecting" class="headerlink" title="Resuming Playback after Disconnecting"></a>Resuming Playback after Disconnecting</h2><p>With the loading spinner back, the next issue was to determine why, when the network reconnected, the video did not resume. First, we tested a few different pieces of content. The HLS source we tested did reconnect, but the DASH source didn’t. Worse, when using the DASH source, Chrome’s debug console froze, as it racked up request and console errors as fast as the computer could process them.</p>
<h3 id="Console-Crash"><a href="/Bugpost-Disconnects-and-Reconnects/#Console-Crash" class="headerlink" title="Console Crash"></a>Console Crash</h3><p>Imagine your console filled with the following two messages repeated thousands of times:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">GET https://dash.akamaized.net/akamai/bbb_30fps/bbb_a64k/bbb_a64k_8.m4a net::ERR_INTERNET_DISCONNECTED</span><br><span class="line">VIDEOJS: WARN: Problem encountered with the current HLS playlist. Trying again since it is the final playlist.</span><br></pre></td></tr></table></figure></p>
<p>When your console freezes, debugging can be tough. It’s like trying to watch a video when the microwave is on. So we tackled that issue first.</p>
<p>Looking at the error message, we were repeatedly retrying the last rendition. That is expected behavior, as we added it <a href="https://github.com/videojs/videojs-contrib-hls/pull/1039" target="_blank" rel="external">a long time ago</a> to our HLS playlist loader. However, when we added DASH support, we created a different playlist loader, and we never added the same logic for reloading the final DASH playlist.</p>
<p>After <a href="https://github.com/videojs/http-streaming/pull/277" target="_blank" rel="external">adding the throttle</a>, debugging became much easier, and we were able to use the console once again and dig into why DASH didn’t reconnect while HLS did.</p>
<h3 id="Multiple-Requests-Multiple-Problems"><a href="/Bugpost-Disconnects-and-Reconnects/#Multiple-Requests-Multiple-Problems" class="headerlink" title="Multiple Requests Multiple Problems"></a>Multiple Requests Multiple Problems</h3><p>The last problem proved to be the most difficult to debug. Initially, the thought was that demuxed content was the problem, as having a separate audio segment loader to load from the audio playlist could cause trouble when experiencing errors at the same time as the main segment loader tried to load from the video playlist. However, HLS can also have demuxed content, and after an example source proved to resume just fine, that approach was ruled out.</p>
<p>By examining Chrome’s network log, the DASH content, after a certain point, stopped requesting video segments, and only requested audio segments. But there were more than just two requests for DASH. The video segments themselves included two requests: one for the init segment, and the other for the video data.</p>
<p>Requests in VHS are managed by a module called <code>media-segment-request</code>, which is responsible for requesting everything required for a segment, whether it be the key, the init segment, the media data, or all of them, before letting the segment loader know that its requests are done. And for the video requests, the <code>media-segment-request</code> never called the done callback after the disconnect.</p>
<p>It turned out that if we received one error, we aborted the other requests in that group, and waited to call the <code>done</code> callback until those requests reported that they were aborted. However, according to the <a href="https://xhr.spec.whatwg.org/#the-abort%28%29-method" target="_blank" rel="external">XHR standard</a>, the abort algorithm may not be run if the request was unsent. In this case, when the network disconnected, the first request reported an error before the second had a chance to be sent. After we aborted the second request, we were stuck waiting for an error that would never come.</p>
<p>We fixed that by <a href="https://github.com/videojs/http-streaming/pull/286" target="_blank" rel="external">immediately calling back with an error on the first error we encounter</a> instead of waiting for each subsequent request to finish.</p>
<p>The problem should also have existed in HLS, but only in cases where the segments had an EXT-X-KEY or EXT-X-MAP tag to go along with the media request. In the content we tried, neither of those was present, so it appeared to be isolated to DASH content.</p>
<h2 id="Bug-Solved"><a href="/Bugpost-Disconnects-and-Reconnects/#Bug-Solved" class="headerlink" title="Bug Solved"></a>Bug Solved</h2><p>We hope that was somewhat useful in describing some of the bugs we encounter, how we go about investigation, and what the resolutions look like. We’d be happy to hear from you as well. You can find us on the #playback channel in the <a href="http://slack.videojs.com/" target="_blank" rel="external">Video.js Slack</a>, or navigating Issues and PRs at <a href="https://github.com/videojs/http-streaming" target="_blank" rel="external">https://github.com/videojs/http-streaming</a>.</p>
<p>Now to enjoy my oats and video, without any concerns about the playback resuming.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;In my old apartment, whenever I nuked a bowl of oats in the microwave, my WIFI cut out. It was an annoyance, but I was hungry, the apartm
    
    </summary>
    
    
      <category term="vhs" scheme="http://blog.videojs.com/tags/vhs/"/>
    
      <category term="videojs-http-streaming" scheme="http://blog.videojs.com/tags/videojs-http-streaming/"/>
    
      <category term="http-streaming" scheme="http://blog.videojs.com/tags/http-streaming/"/>
    
      <category term="playback" scheme="http://blog.videojs.com/tags/playback/"/>
    
      <category term="bugs" scheme="http://blog.videojs.com/tags/bugs/"/>
    
  </entry>
  
  <entry>
    <title>Introducing Video.js HTTP Streaming (VHS)</title>
    <link href="http://blog.videojs.com/Introducing-Video-js-HTTP-Streaming-VHS/"/>
    <id>http://blog.videojs.com/Introducing-Video-js-HTTP-Streaming-VHS/</id>
    <published>2018-11-08T11:33:01.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<blockquote>
<p>“How do I get my video to play with Video.js?”</p>
</blockquote>
<p>This is one of the most frequent questions we get when working on Video.js. And it’s a good question.</p>
<p>If someone checks out a copy of Video.js, their content may play on one browser and not another. To get cross browser support for a specific type of content, they must stumble upon a relevant source handler (for instance, <a href="https://github.com/videojs/videojs-contrib-hls" target="_blank" rel="external">videojs-contrib-hls</a> for HLS content). Only after including the source handler will their video play across all major browsers.</p>
<p>We want Video.js to be easy to use, and that isn’t the easiest setup. So we decided that it’s time to address the issue.</p>
<p>This was the motivation behind integrating <a href="https://github.com/videojs/http-streaming" target="_blank" rel="external">Video.js HTTP Streaming</a> (nicknamed VHS) inside of <a href="https://blog.videojs.com/video-js-7-is-here/">Video.js 7 by default</a>.</p>
<h2 id="What-is-VHS"><a href="/Introducing-Video-js-HTTP-Streaming-VHS/#What-is-VHS" class="headerlink" title="What is VHS?"></a>What is VHS?</h2><p><img src="/Introducing-Video-js-HTTP-Streaming-VHS/./vhs-logo.svg" alt=""></p>
<p>VHS is the successor to videojs-contrib-hls. It is a source handler forked from the <a href="https://github.com/videojs/videojs-contrib-hls" target="_blank" rel="external">videojs-contrib-hls</a> repository. While videojs-contrib-hls was originally designed to add HLS playback on all browsers, we realized that the engine could also play other formats just as well.</p>
<p>To prove this, we added a <a href="https://github.com/videojs/mpd-parser" target="_blank" rel="external">DASH manifest parser</a>, and with a few minor changes, VHS played DASH content with the same codebase and API as it used for HLS.</p>
<p>Even with the changing landscape of video technologies, Video.js will be ready. If a new streaming format gains popularity, only a few code changes will be necessary to add support to VHS. One engine and API for all formats.</p>
<h2 id="Why-is-VHS-included-by-default-in-Video-js"><a href="/Introducing-Video-js-HTTP-Streaming-VHS/#Why-is-VHS-included-by-default-in-Video-js" class="headerlink" title="Why is VHS included by default in Video.js?"></a>Why is VHS included by default in Video.js?</h2><blockquote class="pullquote right"><p>By including VHS by default in Video.js, you no longer have to worry about what browser supports what streaming technology.</p>
</blockquote>
<p>Video.js was built to abstract away differences in video APIs and features between web browsers, creating one simple API as close to the web standards as possible, and filling in feature gaps where possible. Over time, one area where browsers have diverged is in their support of different media formats. Some browsers may support native playback of DASH, others of HLS, and some support neither.</p>
<p>Previously, this would be managed by including source handlers and plugins, but we understand the importance of having a simple setup. By including VHS by default in Video.js, you no longer have to worry about what browser supports what streaming technology. It should just work.</p>
<h2 id="What-if-I-want-to-opt-out-of-using-VHS"><a href="/Introducing-Video-js-HTTP-Streaming-VHS/#What-if-I-want-to-opt-out-of-using-VHS" class="headerlink" title="What if I want to opt-out of using VHS?"></a>What if I want to opt-out of using VHS?</h2><p>If you would rather include a different source handler for HLS or DASH playback, Video.js still allows you to do that. <a href="https://blog.videojs.com/video-js-7-is-here/#VHS-and-Video-js">Video.js core</a> is the Video.js you know and love, without the inclusion of VHS. Everything should work as it used to.</p>
<h2 id="Contributions-and-Feedback-Welcome"><a href="/Introducing-Video-js-HTTP-Streaming-VHS/#Contributions-and-Feedback-Welcome" class="headerlink" title="Contributions and Feedback Welcome"></a>Contributions and Feedback Welcome</h2><p>As always, we’d love your contributions and feedback. The best way to reach us for comments, questions, requests, contributions, or just to say hello are the <a href="https://github.com/videojs/http-streaming" target="_blank" rel="external">VHS GitHub page</a> and the #playback channel on the <a href="http://slack.videojs.com/" target="_blank" rel="external">Video.js slack</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;blockquote&gt;
&lt;p&gt;“How do I get my video to play with Video.js?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is one of the most frequent questions we get when w
    
    </summary>
    
    
      <category term="vhs" scheme="http://blog.videojs.com/tags/vhs/"/>
    
      <category term="videojs-http-streaming" scheme="http://blog.videojs.com/tags/videojs-http-streaming/"/>
    
      <category term="http-streaming" scheme="http://blog.videojs.com/tags/http-streaming/"/>
    
      <category term="playback" scheme="http://blog.videojs.com/tags/playback/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 7.3: Responsive Layout, Fill Mode, createLogger</title>
    <link href="http://blog.videojs.com/Video-js-7-3-Responsive-Layout-Fill-Mode-createLogger/"/>
    <id>http://blog.videojs.com/Video-js-7-3-Responsive-Layout-Fill-Mode-createLogger/</id>
    <published>2018-10-29T17:44:42.000Z</published>
    <updated>2019-01-18T19:57:55.603Z</updated>
    
    <content type="html"><![CDATA[<p>Another month, another Video.js release: <a href="https://github.com/videojs/video.js/releases/tag/v7.3.0" target="_blank" rel="external">v7.3.0</a>. This release brings a long wanted feature: Responsive Layout.<br>In addition, Fill Mode has been promoted to a first-class feature and createLogger was added to make debugging and logging easier.</p>
<p>This is currently out as a pre-release and will be promoted to latest in about a week. Please try it out and <a href="https://github.com/videojs/video.js/issues/new" target="_blank" rel="external">report any issues you find</a>.</p>
<h2 id="Thanks"><a href="/Video-js-7-3-Responsive-Layout-Fill-Mode-createLogger/#Thanks" class="headerlink" title="Thanks"></a>Thanks</h2><p>I’d like to thank everyone that was involved in making changes that landed in this release. Any and all changes are really appreciated.</p>
<ul>
<li><a href="https://github.com/BrandonOCasey" target="_blank" rel="external">@BrandonOCasey</a></li>
<li><a href="https://github.com/chrisrng" target="_blank" rel="external">@chrisrng</a></li>
<li><a href="https://github.com/syranez" target="_blank" rel="external">@syranez</a></li>
<li><a href="https://github.com/misteroneill" target="_blank" rel="external">@misteroneill</a></li>
<li><a href="https://github.com/OwenEdwards" target="_blank" rel="external">@OwenEdwards</a></li>
</ul>
<h2 id="Responsive-Mode"><a href="/Video-js-7-3-Responsive-Layout-Fill-Mode-createLogger/#Responsive-Mode" class="headerlink" title="Responsive Mode"></a>Responsive Mode</h2><p><a href="https://docs.videojs.com/tutorial-layout.html#responsive-mode" target="_blank" rel="external">Responsive Mode</a> will make the player adjust UI components to the size of the player. It uses the <a href="https://github.com/videojs/video.js/pull/4864" target="_blank" rel="external"><code>playerresize</code></a> event that was added in <a href="https://github.com/videojs/video.js/releases/tag/v6.7.0" target="_blank" rel="external">v6.7.0</a> of Video.js, which allows us to know when the player changes sizes.</p>
<p>Responsive mode will set and change certain breakpoint classes like <code>vjs-layout-small</code> when the player size changed. These can be <a href="https://docs.videojs.com/tutorial-layout.html#customizing-breakpoints" target="_blank" rel="external">configured</a>. Depending on which class is currently on the player, the control bar and other UI elements can adapt. For example, with <code>vjs-layout-small</code>, the time controls will not show because the time tooltips on the progress bar are available and the captions button is more important. At a larger size, both can be shown without a problem.</p>
<p>You can find out how to enable <a href="https://docs.videojs.com/tutorial-layout.html#responsive-mode" target="_blank" rel="external">Responsive Mode</a> and more in our <a href="https://docs.videojs.com/tutorial-layout.html#responsive-mode" target="_blank" rel="external">docs page</a>. There is also an example playground in the <a href="https://github.com/videojs/video.js/blob/master/sandbox/responsive.html.example" target="_blank" rel="external">sandbox folder in the repo</a>.</p>
<h2 id="Fill-Mode"><a href="/Video-js-7-3-Responsive-Layout-Fill-Mode-createLogger/#Fill-Mode" class="headerlink" title="Fill Mode"></a>Fill Mode</h2><p><a href="https://docs.videojs.com/tutorial-layout.html#fill-mode" target="_blank" rel="external">Fill Mode</a> allows the Video.js player to resize dynamically, but stay contained within the bounds of the parent container. This is analogous to <a href="https://docs.videojs.com/tutorial-layout.html#fluid-mode" target="_blank" rel="external">Fluid Mode</a>, but sometimes you the container is already being sized properly.</p>
<p>Fill Mode is not a brand new mode, the class <code>vjs-fill</code> has been available in Video.js for quite <a href="https://github.com/videojs/video.js/commit/2fc8968002cf2f40128c39699c3ffbaac73fc9ed#diff-6be43b1f61c2cbcb90c6cb4a762ad527R64" target="_blank" rel="external">a while</a>. This finally makes it a first-class feature to go along with Fluid Mode.</p>
<h2 id="createLogger"><a href="/Video-js-7-3-Responsive-Layout-Fill-Mode-createLogger/#createLogger" class="headerlink" title="createLogger"></a>createLogger</h2><p>This is a new method on <code>videojs.log</code> that allows you to create a new logger with a specific name. It then creates a chain of names to make it easier to track which component logged this particular message. In particular, this can help plugin authors to log messages and then filter out only the messages that are associated with their plugin.</p>
<p><code>createLogger</code> returns a function with the same API as <code>videojs.log</code>. You can see it in action below.</p>
<h3 id="Examples"><a href="/Video-js-7-3-Responsive-Layout-Fill-Mode-createLogger/#Examples" class="headerlink" title="Examples"></a>Examples</h3><p>A new method, <code>player.log</code> was added which uses createLogger behind the scenes. It logs the player ID in addition to <code>VIDEOJS</code>:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> player = videojs(<span class="string">'myid'</span>);</span><br><span class="line"></span><br><span class="line">player.log(<span class="string">'foo'</span>);</span><br><span class="line"><span class="comment">// VIDEOJS: myid: foo</span></span><br></pre></td></tr></table></figure>
<p>You can also go further and create a sub logger:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> player = videojs(<span class="string">'myid'</span>);</span><br><span class="line"><span class="keyword">var</span> mylog = player.log.createLogger(<span class="string">'my-plugin'</span>);</span><br><span class="line"></span><br><span class="line">mylog.log(<span class="string">'foo'</span>);</span><br><span class="line"><span class="comment">// VIDEOJS: myid: my-plugin: foo</span></span><br></pre></td></tr></table></figure>
<p>If you want to log a warning or error for your custom plugin:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> player = videojs(<span class="string">'myid'</span>);</span><br><span class="line"><span class="keyword">var</span> mylog = player.log.createLogger(<span class="string">'my-plugin'</span>);</span><br><span class="line"></span><br><span class="line">mylog.log.warn(<span class="string">'foo'</span>);</span><br><span class="line"><span class="comment">// VIDEOJS: myid: my-plugin: WARN: foo</span></span><br><span class="line"></span><br><span class="line">mylog.log.error(<span class="string">'bar'</span>);</span><br><span class="line"><span class="comment">// VIDEOJS: vid1: my-plugin: ERROR: bar</span></span><br></pre></td></tr></table></figure>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Another month, another Video.js release: &lt;a href=&quot;https://github.com/videojs/video.js/releases/tag/v7.3.0&quot; target=&quot;_blank&quot; rel=&quot;external&quot;
    
    </summary>
    
    
      <category term="fluid" scheme="http://blog.videojs.com/tags/fluid/"/>
    
      <category term="responsive" scheme="http://blog.videojs.com/tags/responsive/"/>
    
      <category term="log" scheme="http://blog.videojs.com/tags/log/"/>
    
      <category term="fill" scheme="http://blog.videojs.com/tags/fill/"/>
    
      <category term="playerresize" scheme="http://blog.videojs.com/tags/playerresize/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 7.1 and 6.11: Autoplay and Fullscreen changes</title>
    <link href="http://blog.videojs.com/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/"/>
    <id>http://blog.videojs.com/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/</id>
    <published>2018-07-10T17:02:47.000Z</published>
    <updated>2019-01-18T19:57:55.601Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/header.png" alt=""></p>
<p>It’s been a while since the last release post. The <a href="https://github.com/videojs/video.js/releases/tag/v7.1.0" target="_blank" rel="external">7.1.0</a> and <a href="https://github.com/videojs/video.js/releases/tag/v6.11.0" target="_blank" rel="external">6.11.0</a> releases of Video.js are full of great features from contributors and maintainers.<br>The two big changes are related to autoplay – when will we stop talking about autoplay? – and fullscreen. Though, there’s plenty more in there.</p>
<p>Video.js 7.1.0 and 6.11.0 are out as <code>next</code> and <code>next-6</code> respectively on npm.</p>
<p>To get 7.1.0 via npm:<br><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install video.js@next</span><br></pre></td></tr></table></figure></p>
<p>And 6.11.0 via npm:<br><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install video.js@next-6</span><br></pre></td></tr></table></figure></p>
<h2 id="Autoplay"><a href="/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/#Autoplay" class="headerlink" title="Autoplay"></a>Autoplay</h2><p>We’ve been keeping track of changes happening around <a href="https://blog.videojs.com/Autoplay-Best-Practices-with-Video-js">autoplay</a> in browser vendors. We’ve also done a lot of work to make Video.js work as well as possible with the new autoplay policies. However, there were still some use cases that weren’t accounted for. To address those, we decided to extend the existing Video.js <code>autoplay</code> option to include a few new values: <code>muted</code>, <code>play</code>, <code>any</code>. The current boolean options will work as they do now and unknown options will be treated as they do now.</p>
<ul>
<li><code>muted</code> - this will mute the video element before calling <code>play()</code> on <code>loadstart</code>.</li>
<li><code>play</code> - this will call <code>play()</code> on <code>loadstart</code>. This is similar to the <code>autoplay</code> attribute but with a call to play instead of using the attribute.</li>
<li><code>any</code> - this will call <code>play()</code> on <code>loadstart</code> but if it fails, it will try and mute the player and try <code>play()</code>ing again.</li>
</ul>
<h2 id="Fullscreen"><a href="/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/#Fullscreen" class="headerlink" title="Fullscreen"></a>Fullscreen</h2><p>There are two fullscreen related changes in these releases.</p>
<p>The first one is one that was often request and it’s finally here: double click to toggle fullscreen. Double clicking inside the player area – outside of the control bar and modal dialogs – will enter or exit fullscreen playback.</p>
<p>The second change is to disable the fullscreen toggle if fullscreen is not available, for example, inside of an iframe without <code>allowfullscreen</code> attribute</p>
<p><img src="/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/./fs-enabled.png" alt="Fullscreen available"><br><img src="/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/./fs-disabled.png" alt="Fullscreen unavailable"></p>
<h2 id="Notable-Changes"><a href="/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/#Notable-Changes" class="headerlink" title="Notable Changes"></a>Notable Changes</h2><ul>
<li>Make audio tracks that are of “main-desc” kind show up with an Audio Description icon</li>
<li>Run our CSS through autoprefixer which reduces the output size a bit.</li>
<li>Make the mute toggle show up if muting is possible even if changing volume programmatically isn’t. For example, on iOS.</li>
<li>Make <code>setSource</code> be option for middleware.</li>
</ul>
<h2 id="Thanks"><a href="/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/#Thanks" class="headerlink" title="Thanks"></a>Thanks</h2><p>I’d like to thank everyone that contributed to this release!</p>
<ul>
<li><a href="https://github.com/DoomTay" target="_blank" rel="external">@DoomTay</a></li>
<li><a href="https://github.com/ayamamori" target="_blank" rel="external">@ayamamori</a></li>
<li><a href="https://github.com/edoardocavazza" target="_blank" rel="external">@edoardocavazza</a></li>
<li><a href="https://github.com/PrincipeSayan" target="_blank" rel="external">@PrincipeSayan</a></li>
<li><a href="https://github.com/bcdarius" target="_blank" rel="external">@bcdarius</a></li>
<li><a href="https://github.com/BrandonOCasey" target="_blank" rel="external">@BrandonOCasey</a></li>
<li><a href="https://github.com/OwenEdwards" target="_blank" rel="external">@OwenEdwards</a></li>
<li><a href="https://github.com/practual" target="_blank" rel="external">@practual</a></li>
<li><a href="https://github.com/Demivan" target="_blank" rel="external">@Demivan</a></li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;/Video-js-7-1-and-6-11-Autoplay-and-Fullscreen-changes/header.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;It’s been a while since the last release post
    
    </summary>
    
    
      <category term="autoplay" scheme="http://blog.videojs.com/tags/autoplay/"/>
    
      <category term="fullscreen" scheme="http://blog.videojs.com/tags/fullscreen/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 7 is here! 🎉</title>
    <link href="http://blog.videojs.com/Video-js-7-is-here/"/>
    <id>http://blog.videojs.com/Video-js-7-is-here/</id>
    <published>2018-05-11T17:31:52.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/Video-js-7-is-here/vjs 7 small.png" alt=""></p>
<p>I’m happy to announce that Video.js 7 is now out! It brings to Video.js support for HLS and experimental DASH support via the <a href="https://github.com/videojs/http-streaming" target="_blank" rel="external">Video.js HTTP Streaming (VHS)</a> project. Video.js 7 also drops support for some older Internet Explorer browsers only keeping support for IE11.</p>
<p>While it’s out, it’s still in pre-release for a short while and only available under the <code>next</code> tag on npm. Some time next week, we’ll flip the switch and make it latest.</p>
<p><img src="/Video-js-7-is-here/changes.png" alt="changes for removing IE8 code"><br>This release is pretty exciting because it means we were able to <a href="https://github.com/videojs/video.js/pull/5041" target="_blank" rel="external">remove a bunch of code</a> for old browsers and we can now start using newer web platform features that we had previously been avoiding like the <code>:not()</code> css selector. It’ll also free us to look forward at new features and not be held back by needing to support old browsers like IE8.</p>
<h2 id="Getting-Video-js-7"><a href="/Video-js-7-is-here/#Getting-Video-js-7" class="headerlink" title="Getting Video.js 7"></a>Getting Video.js 7</h2><p>You can get it from npm via<br><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install video.js@next</span><br></pre></td></tr></table></figure></p>
<p>or<br><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install video.js@7.0.0</span><br></pre></td></tr></table></figure></p>
<p>From <a href="https://github.com/videojs/video.js/releases/tag/v7.0.0" target="_blank" rel="external">GitHub Releases</a>,</p>
<p>Or from our or another CDN<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">https://vjs.zencdn.net/7.0.0/video.min.js</span><br><span class="line">https://vjs.zencdn.net/7.0.0/video-js.css</span><br></pre></td></tr></table></figure></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">https://unpkg.com/video.js@7.0.0/dist/video.min.js</span><br><span class="line">https://unpkg.com/video.js@7.0.0/dist/video-js.css</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">https://cdnjs.cloudflare.com/ajax/libs/video.js/7.0.0/video.min.js</span><br><span class="line">https://cdnjs.cloudflare.com/ajax/libs/video.js/7.0.0/video-js.css</span><br></pre></td></tr></table></figure>
<h2 id="VHS-and-Video-js"><a href="/Video-js-7-is-here/#VHS-and-Video-js" class="headerlink" title="VHS and Video.js"></a>VHS and Video.js</h2><p>Video.js will be bundling VHS by default for ease of use for new users. However, some people don’t want VHS or are using another plugin. For this, we have a separate build of Video.js which doesn’t include VHS.</p>
<p>You can get it from our CDN or another CDN<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://vjs.zencdn.net/7.0.0/alt/video.core.min.js</span><br></pre></td></tr></table></figure></p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://unpkg.com/video.js@7.0.0/dist/alt/video.core.min.js</span><br></pre></td></tr></table></figure>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://cdnjs.cloudflare.com/ajax/libs/video.js/7.0.0/alt/video.core.min.js</span><br></pre></td></tr></table></figure>
<p>Finally, expect a more detailed post about VHS in the weeks to come.</p>
<h2 id="What-the-future-holds"><a href="/Video-js-7-is-here/#What-the-future-holds" class="headerlink" title="What the future holds"></a>What the future holds</h2><p>Video.js hasn’t really had a roadmap for a long time. With this release, we think it’s time to take a step back and create a roadmap.</p>
<p>The roadmap will take into account currently open issues and internal and external feature requests. In addition, we’re going to look at currently available features and see if it’s worth refactoring them with the more modern web in-mind.</p>
<p>Later down the line, we’d also want to make a roadmap for a Video.js 8. Given that this release only adds VHS and removes old browsers, there’re plenty of already deprecated features that it’s time to remove.</p>
<h2 id="Updates-from-the-Video-js-7-roadmap"><a href="/Video-js-7-is-here/#Updates-from-the-Video-js-7-roadmap" class="headerlink" title="Updates from the Video.js 7 roadmap"></a>Updates from the <a href="https://blog.videojs.com/video-js-7-roadmap">Video.js 7 roadmap</a></h2><h3 id="Video-js-5-x"><a href="/Video-js-7-is-here/#Video-js-5-x" class="headerlink" title="Video.js 5.x"></a>Video.js 5.x</h3><p>As of this release, Video.js 5.x is now officially deprecated. This means that we will no longer work on it or back-port fixes to it but it’s still available for usage if you’re still using it. We do urge you to update to the latest 5.x, or better yet, upgrade to 6.x or 7.</p>
<h3 id="Build-Tools"><a href="/Video-js-7-is-here/#Build-Tools" class="headerlink" title="Build Tools"></a>Build Tools</h3><p>In the <a href="https://blog.videojs.com/video-js-7-roadmap">roadmap</a> post, we talked about potentially switching to webpack from Rollup for better support of importing VHS into Video.js. However, while doing <a href="https://github.com/videojs/video.js/pull/5033" target="_blank" rel="external">this work</a>, we found out that the filesize of Video.js will increase by about 20%, which isn’t a trivial amount, not to mention that the filesize is already going to increase from the default inclusion of VHS.</p>
<p>Eventually, after much work, we were able to figure out how to bundle VHS using Rollup as well and we are continuing to use Rollup for our builds.</p>
<h3 id="Google-Analytics"><a href="/Video-js-7-is-here/#Google-Analytics" class="headerlink" title="Google Analytics"></a>Google Analytics</h3><p>Video.js 7’s CDN builds will no longer send any data to Google Analytics via our stripped down pixel tracking.</p>
<p>Video.js 6 and below CDN builds will continue sending data, unless you opt out with <code>window.HELP_IMPROVE_VIDEOJS = false</code>, but versions 6.8 and above will honor the Do Not Track option that users can set in their headers before sending the data.</p>
<p>We are continuing to investigate our options for collecting our CDN logs in an open manner and will post updates when we have any.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;/Video-js-7-is-here/vjs 7 small.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;I’m happy to announce that Video.js 7 is now out! It brings to Video.js sup
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Autoplay Best Practices with Video.js</title>
    <link href="http://blog.videojs.com/Autoplay-Best-Practices-with-Video-js/"/>
    <id>http://blog.videojs.com/Autoplay-Best-Practices-with-Video-js/</id>
    <published>2018-04-17T14:49:43.000Z</published>
    <updated>2019-01-18T19:57:55.568Z</updated>
    
    <content type="html"><![CDATA[<h2 id="tl-dr"><a href="/Autoplay-Best-Practices-with-Video-js/#tl-dr" class="headerlink" title="tl;dr"></a>tl;dr</h2><ul>
<li>Never assume autoplay will work.</li>
<li>Using the <code>muted</code> attribute/option will improve the chances that autoplay will succeed.</li>
<li>Prefer programmatic autoplay via the <code>player.play()</code> method, avoiding the <code>autoplay</code> attribute/option.</li>
</ul>
<h2 id="Introduction"><a href="/Autoplay-Best-Practices-with-Video-js/#Introduction" class="headerlink" title="Introduction"></a>Introduction</h2><p>There has been a lot of chatter about autoplay lately and we wanted to take a few minutes to share some best practices when using autoplay with Video.js.</p>
<p>This post is meant to be a source of information - not an editorial or positional statement on autoplaying video. A lot of users hate autoplay because it’s annoying or it consumes precious bandwidth. And a lot of publishers providing content free of charge rely on autoplay for the preroll ads that finance their businesses. Browser vendors (and open source library authors) have to weigh these concerns based on the interests of their users, publishers across the web, and their own business. And users have to choose the browser that best reflects their preferences.</p>
<p>This post is not about ways to circumvent autoplay policies. That’s not possible and no one should waste their time attempting it. We think it’s uncontroversial to say that actively circumventing the browser’s built-in user experience or user preferences is harmful.</p>
<h2 id="Autoplay-Policies-in-the-Big-Browsers"><a href="/Autoplay-Best-Practices-with-Video-js/#Autoplay-Policies-in-the-Big-Browsers" class="headerlink" title="Autoplay Policies in the Big Browsers"></a>Autoplay Policies in the Big Browsers</h2><p>I’m not going to go into exhaustive detail on each browser’s specific algorithms because they are subject to change and it would defeat the core point of this post: <strong>never assume autoplay will work.</strong></p>
<h3 id="Safari"><a href="/Autoplay-Best-Practices-with-Video-js/#Safari" class="headerlink" title="Safari"></a>Safari</h3><p>As of Safari 11, which shipped in September 2017, Apple has <a href="https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/" target="_blank" rel="external">updated their autoplay policies</a> to prevent autoplay with sound on most websites.</p>
<h3 id="Chrome"><a href="/Autoplay-Best-Practices-with-Video-js/#Chrome" class="headerlink" title="Chrome"></a>Chrome</h3><p>Back in September 2017, Google announced that <a href="https://developers.google.com/web/updates/2017/09/autoplay-policy-changes" target="_blank" rel="external">Chrome’s autoplay policy would change in April 2018 with Chrome 66</a>, subject to a series of rules you can read about in the linked article.</p>
<h3 id="Firefox"><a href="/Autoplay-Best-Practices-with-Video-js/#Firefox" class="headerlink" title="Firefox"></a>Firefox</h3><p>With Firefox, Mozilla has taken the position of not having a firm autoplay policy for the time being. That may change in the future. That said, Firefox today <a href="https://support.mozilla.org/en-US/questions/1150702" target="_blank" rel="external">does allow users to disable autoplay</a> with a few configuration changes.</p>
<h3 id="IE11-and-Edge"><a href="/Autoplay-Best-Practices-with-Video-js/#IE11-and-Edge" class="headerlink" title="IE11 and Edge"></a>IE11 and Edge</h3><p>Microsoft’s browsers have no specific/known autoplay policy - at the time of writing, autoplay just works in IE11 and Edge.</p>
<h2 id="Refresher-on-How-to-Request-Autoplay-in-Video-js"><a href="/Autoplay-Best-Practices-with-Video-js/#Refresher-on-How-to-Request-Autoplay-in-Video-js" class="headerlink" title="Refresher on How to Request Autoplay in Video.js"></a>Refresher on How to Request Autoplay in Video.js</h2><p>Note how the title of this section uses the word “request.” That’s intentional because it should be thought of as a request. Remember, <strong>never assume autoplay will work.</strong></p>
<p>One of Video.js’ strengths is that it is designed around the native <code>&lt;video&gt;</code> element interface; so, it will defer to the underlying playback technology (in most cases, HTML5 video) and the browser. In other words, <em>if the browser allows it, Video.js allows it</em>.</p>
<p>There are two ways to enable autoplay when using Video.js:</p>
<ol>
<li><p>Use the <code>autoplay</code> attribute on either the <code>&lt;video&gt;</code> element or the new <code>&lt;video-js&gt;</code> element.</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">video</span> <span class="attr">autoplay</span> <span class="attr">src</span>=<span class="string">"https://path/to/source.mp4"</span>&gt;</span><span class="tag">&lt;/<span class="name">video</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">video-js</span> <span class="attr">autoplay</span> <span class="attr">src</span>=<span class="string">"https://path/to/source.mp4"</span>&gt;</span><span class="tag">&lt;/<span class="name">video-js</span>&gt;</span></span><br></pre></td></tr></table></figure>
</li>
<li><p>Use the <code>autoplay</code> option:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">videojs(<span class="string">'player'</span>, &#123;<span class="attr">autoplay</span>: <span class="literal">true</span>&#125;);</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h2 id="Recommended-Practices"><a href="/Autoplay-Best-Practices-with-Video-js/#Recommended-Practices" class="headerlink" title="Recommended Practices"></a>Recommended Practices</h2><p>By default, you can defer to the default behavior in Video.js. If autoplay succeeds, the Video.js player will begin playing. If autoplay fails, the Video.js player will behave as if autoplay were off - i.e. it will display the “big play button” component over the poster image (or a black box).</p>
<p>If that works for you, your job is done!</p>
<p><strong>TIP:</strong> If you want to use autoplay and improve the chances of it working, use the <code>muted</code> attribute (or the <code>muted</code> option, with Video.js).</p>
<p>Beyond that, there are some general practices that may be useful when dealing with autoplay: detecting whether autoplay is supported at all, or detecting whether autoplay succeeds or fails.</p>
<h3 id="Detecting-Autoplay-Support"><a href="/Autoplay-Best-Practices-with-Video-js/#Detecting-Autoplay-Support" class="headerlink" title="Detecting Autoplay Support"></a>Detecting Autoplay Support</h3><p>Similar to detecting successful or failed autoplay requests, it may be useful to perform autoplay feature detection on the browser before creating a player at all. In these cases, the <a href="https://github.com/video-dev/can-autoplay" target="_blank" rel="external">can-autoplay</a> library is the best solution. It provides a similar <code>Promise</code>-based API to the native <code>player.play()</code> method:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">canAutoplay.video().then(<span class="function"><span class="keyword">function</span>(<span class="params">obj</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (obj.result === <span class="literal">true</span>) &#123;</span><br><span class="line">    <span class="comment">// Can autoplay</span></span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// Can not autoplay</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<h3 id="Programmatic-Autoplay-and-Success-Failure-Detection"><a href="/Autoplay-Best-Practices-with-Video-js/#Programmatic-Autoplay-and-Success-Failure-Detection" class="headerlink" title="Programmatic Autoplay and Success/Failure Detection"></a>Programmatic Autoplay and Success/Failure Detection</h3><p>For those who care whether or not an autoplay request was successful, both Google and Apple have recommended the same practice for detecting autoplay success or rejection: listen to the <code>Promise</code> returned by the <code>player.play()</code> method (in browsers that support it) to determine if autoplay was successful or not.</p>
<p>This can be coupled with the <code>autoplay</code> attribute/option or performed programmatically by calling <code>player.play()</code>, but <strong>we recommend avoiding the <code>autoplay</code> attribute/option altogether and requesting autoplay programmatically</strong>:</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">video-js</span> <span class="attr">id</span>=<span class="string">"player"</span> <span class="attr">src</span>=<span class="string">"https://path/to/source.mp4"</span>&gt;</span><span class="tag">&lt;/<span class="name">video-js</span>&gt;</span></span><br></pre></td></tr></table></figure>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> player = videojs(<span class="string">'player'</span>);</span><br><span class="line"></span><br><span class="line">player.ready(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> promise = player.play();</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (promise !== <span class="literal">undefined</span>) &#123;</span><br><span class="line">    promise.then(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// Autoplay started!</span></span><br><span class="line">    &#125;).catch(<span class="function"><span class="keyword">function</span>(<span class="params">error</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// Autoplay was prevented.</span></span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<p><strong>NOTE:</strong> It’s important to understand that using this approach, the Video.js <code>player.autoplay()</code> method will return <code>undefined</code> or <code>false</code>. If you expect your users or integrators to rely on this method, consider the following section.</p>
<h4 id="Programmatic-Autoplay-with-the-autoplay-Attribute-Option"><a href="/Autoplay-Best-Practices-with-Video-js/#Programmatic-Autoplay-with-the-autoplay-Attribute-Option" class="headerlink" title="Programmatic Autoplay with the autoplay Attribute/Option"></a>Programmatic Autoplay with the <code>autoplay</code> Attribute/Option</h4><p>When building a player for others to use, you may not always have control over whether your users include the <code>autoplay</code> attribute/option on their instance of your player. Thankfully, combining this with programmatic autoplay doesn’t seem to have a significant effect on the behavior of playback.</p>
<p>Based on our experimentation, even if the browser handles the actual autoplay operation, calling <code>player.play()</code> after it’s begun playing (or failed to play) does not seem to cause current browsers to trigger an extra <code>&quot;play&quot;</code> event in either Chrome or Firefox. It does seem that Safari 11.1 triggers <code>&quot;playing&quot;</code> and <code>&quot;pause&quot;</code> events each time <code>player.play()</code> is called and autoplay fails.</p>
<p>Still, if you have full control, <strong>we recommend avoiding the <code>autoplay</code> attribute/option altogether and requesting autoplay programmatically</strong>.</p>
<p><strong>NOTE:</strong> Even if using the <code>autoplay</code> attribute/option <em>with</em> programmatic autoplay, the <code>player.autoplay()</code> method will return <code>undefined</code> until the player is ready.</p>
<h4 id="Example-Use-Case"><a href="/Autoplay-Best-Practices-with-Video-js/#Example-Use-Case" class="headerlink" title="Example Use-Case"></a>Example Use-Case</h4><p>At Brightcove, one thing we’ve done to improve the user experience of our Video.js-based player is to hide the “big play button” for players requesting autoplay until the autoplay either succeeds or fails. This prevents a periodic situation where the “big play button” flashes on the player for a moment before autoplay kicks in.</p>
<p>While our actual implementation has more complexity due to specific circumstances with our player, the gist of it is the same as <a href="https://jsbin.com/quqodek/edit?html,js,output" target="_blank" rel="external">this functional JSBin demonstration.</a></p>
<h2 id="Conclusion"><a href="/Autoplay-Best-Practices-with-Video-js/#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><p>There may be decision points in your code related to whether autoplay succeeds or not; however, the practical reality is that all the paragraphs before this boil down to a single, essential concept:</p>
<p><strong>Never assume that your request to autoplay will succeed.</strong></p>
<p>Keep that in mind and you’re golden. Even if the browsers stop allowing autoplay entirely, our hope is that recommending this approach will be somewhat future-proof.</p>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;tl-dr&quot;&gt;&lt;a href=&quot;/Autoplay-Best-Practices-with-Video-js/#tl-dr&quot; class=&quot;headerlink&quot; title=&quot;tl;dr&quot;&gt;&lt;/a&gt;tl;dr&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Never assume 
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>videojs-contrib-ads 6</title>
    <link href="http://blog.videojs.com/videojs-contrib-ads-6/"/>
    <id>http://blog.videojs.com/videojs-contrib-ads-6/</id>
    <published>2018-03-13T15:22:57.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>A major update to <a href="https://github.com/videojs/videojs-contrib-ads/" target="_blank" rel="external">videojs-contrib-ads</a> has been released. In this post, we’ll take a look at what videojs-contrib-ads offers and what has improved in version 6.</p>
<h2 id="What-is-contrib-ads"><a href="/videojs-contrib-ads-6/#What-is-contrib-ads" class="headerlink" title="What is contrib-ads?"></a>What is contrib-ads?</h2><p>Videojs-contrib-ads is a framework for creating Video.js ad plugins. Seamlessly integrating ad support into a video player can be a daunting task, especially if you have other plugins that may be effected. For example, playing ads may result in additional <a href="https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Media_events" target="_blank" rel="external">media events</a>. Imagine an analytics system that listens to “loadstart” events: it would start seeing double when extra <code>loadstart</code> events result from preroll ads. contrib-ads has a feature called <a href="https://github.com/videojs/videojs-contrib-ads#redispatch" target="_blank" rel="external">Redispatch</a> that makes sure ads do not trigger extra media events. This keeps things as simple as possible without breaking other plugins. <a href="https://github.com/videojs/videojs-contrib-ads#benefits" target="_blank" rel="external">Additional benefits of using contrib-ads are listed in the readme</a>.</p>
<h2 id="Version-6"><a href="/videojs-contrib-ads-6/#Version-6" class="headerlink" title="Version 6"></a>Version 6</h2><p>Version 6 of contrib-ads is a maintenance release that includes a major code refactor. The core of the project’s behavior is handled by a state machine that advances through various states as the player plays content, preroll ads, midroll ads, and postroll ads. The initial state machine was designed to implement a specific set of functionality when the project was first conceptualized. Over the years, the project became much more fully-featured and many new scenarios and edge-cases arose. In this refactor, the state machine has been updated to precisely match the modern feature-set. This has resulted in a more maintainable and reliable codebase.</p>
<h2 id="How-it-works"><a href="/videojs-contrib-ads-6/#How-it-works" class="headerlink" title="How it works"></a>How it works</h2><blockquote class="pullquote right"><p>Ad mode is <a href="https://github.com/videojs/videojs-contrib-ads#ad-mode-definition" target="_blank" rel="external">strictly defined</a> as <em>if content playback is blocked by the ad plugin</em>.</p>
</blockquote>
<p>contrib-ads has a concept called <em>ad mode</em>. Ad mode is <a href="https://github.com/videojs/videojs-contrib-ads#ad-mode-definition" target="_blank" rel="external">strictly defined</a> as <em>if content playback is blocked by the ad plugin</em>. This does not necessarily mean that an ad is playing. For example, if there is a preroll ad, after a play request we show a loading spinner until ad playback begins. This is considered part of ad mode. The public method <code>player.ads.isInAdMode()</code> can be used to check if we are in ad mode.</p>
<p>In version 6, the state machine was refactored to match this strict definition of ad mode. There are two types of states: content states and ad states. If contrib-ads is in an ad state, it is in ad mode.</p>
<p>Here is a diagram of the new states. Blue states are content states and yellow states are ad states:</p>
<p><img src="/videojs-contrib-ads-6/./ad-states.png" alt=""></p>
<p>For a history of how the state machine has evolved over time, <a href="https://github.com/videojs/videojs-contrib-ads/issues/320" target="_blank" rel="external">there is detailed information in this Github issue</a>. In this article we’re going to focus on how it works in version 6.</p>
<p>Let’s walk through the states for a simple preroll scenario. contrib-ads begins in the BeforePreroll state. This is considered a content state because content playback hasn’t been requested yet and so ads are not blocking playback. The ad plugin can asynchronously request ads from an ad server during this time, even though the plugin is in content mode. The ad plugin triggers the <code>adsready</code> event when it’s ready. Contrib-ads knows that once the play button is pressed, ads are already prepared.</p>
<p>Now the user clicks play. At this point ad mode begins and contrib-ads moves forward to the Preroll state. The Preroll state shows a loading spinner until ad playback begins. The Preroll state knows that the ad plugin is ready and that play was clicked, so triggers <code>readyforpreroll</code> to inform the ad plugin that it’s time to play an ad. Once ad playback begins, the control bar turns yellow and will not allow seeking. If the ad takes too long to begin playing, a timeout will occur and content will resume without further adieu. When the ad is complete, contrib-ads restores the content video. Only when content playback results in a <code>playing</code> event does ad mode end.</p>
<p>Now we’re in the ContentPlayback state. At this point, the ad plugin could play a midroll ad, causing a brief foray into the Midroll state, or content could continue without interruption.</p>
<p>When content ends, normally we would see an <code>ended</code> event right away. Instead, contrib-ads sends a <code>contentended</code> event, which is the ad plugin’s chance to play postroll ads. Perhaps the ad plugin has decided not to play postroll ad, so it responds by triggering <code>nopostroll</code>. contrib-ads knows that now we’re really done, so an <code>ended</code> event is triggered.</p>
<p>Finally, since content has ended for the first time, we now transition to the AdsDone state. There will be no more ads, even if the user seeks backwards and plays through the content again.</p>
<h2 id="Conclusion"><a href="/videojs-contrib-ads-6/#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><p>Ads may not be your favorite part of watching video online, but contrib-ads makes sure that they don’t break your site and that content plays even if ads fail. If you’re interested in learning more or contributing to the project, <a href="https://github.com/videojs/videojs-contrib-ads" target="_blank" rel="external">check it out on Github</a>!</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;A major update to &lt;a href=&quot;https://github.com/videojs/videojs-contrib-ads/&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;videojs-contrib-ads&lt;/a&gt; has be
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Video.js 7 Roadmap</title>
    <link href="http://blog.videojs.com/Video-js-7-Roadmap/"/>
    <id>http://blog.videojs.com/Video-js-7-Roadmap/</id>
    <published>2018-03-09T16:33:56.000Z</published>
    <updated>2019-01-18T19:57:55.604Z</updated>
    
    <content type="html"><![CDATA[<p><img src="/Video-js-7-Roadmap/woodland-road-falling-leaf-natural-38537.jpeg" alt=""></p>
<p>Today, I’m excited to announce the roadmap to Video.js 7! While this is a major version update, there is very little that is actually breaking. The two main changes are the addition of videojs-http-streaming, VHS for short, and the removal of support for older versions of Internet Explorer.</p>
<p><img src="/Video-js-7-Roadmap/vjs 7 small.png" alt="VJS 7"></p>
<h2 id="Video-js-HTTP-Streaming"><a href="/Video-js-7-Roadmap/#Video-js-HTTP-Streaming" class="headerlink" title="Video.js HTTP Streaming"></a>Video.js HTTP Streaming</h2><p><img src="/Video-js-7-Roadmap/VHS small.png" alt=""></p>
<p>VHS used to be videojs-contrib-hls, but as MPEG-DASH became more popular, we realized that we wanted to support it as well and that we can share a lot of the code between HLS and DASH implementations. Look for more details in an announcement post for VHS soon!<br>VHS will ship with Video.js by default because one of the guiding principles of Video.js is to make it easy for users to just put it on the page and have a player that works across browsers. With HLS and DASH becoming so popular, we thought it was about time for a plug and playable Video.js for the most common streaming formats.<br>In addition to having it be included by default, we’ll make sure to provide builds that exclude VHS for those that don’t need it or are using another playback engine like HLS.js.</p>
<h2 id="Old-IE"><a href="/Video-js-7-Roadmap/#Old-IE" class="headerlink" title="Old IE"></a>Old IE</h2><p><img src="/Video-js-7-Roadmap/IE8 small.png" alt="IE8"></p>
<p>Video.js has a long history of making best effort to support IE, starting with the Flash fallback originally created for IE8. When Video.js 5 was released, we had a lot of code in place to support IE8 and when Video.js 6 came around, with Flash on its way out, we moved Flash support to a separate project, videojs-flash. Now, based on usage data, we are planning to remove support for IE8, IE9, and IE10.<br>According to the data we’ve gathered, IE in total has a share of about 4%. Of those 4%, IE8, IE9, and IE10 combined make up barely 5%, and IE11 has around 91% usage. This means that combined IE8, IE9, and IE10 are barely 0.002% of the total usage of Video.js. Based on this incredibly small footprint, we believe it isn’t worth the substantial effort required to maintain support for these browsers. The good news is, for those concerned, Video.js 6 isn’t going away anytime soon and will be available for your old IE support needs.<br>In addition to the statistics, our tests currently take between 5 and 10 minutes to run on IE8. Removing this will allow us to greatly decrease the duration of our test suite. Even worse, sometimes the tests timeout and retry for up to 40 minutes but when they restart they pass on the first try. Not having to deal with these types of issues will allow us to increase our testing infrastructure and provide a better product.</p>
<blockquote class="pullquote right"><p><img src="/Video-js-7-Roadmap/browserstack logo small.png" alt=""><br>Thanks <a href="https://www.browserstack.com/" target="_blank" rel="external">Browserstack</a> for sponsoring browser-based testing for Video.js!</p>
</blockquote>
<h2 id="Video-js-5-x"><a href="/Video-js-7-Roadmap/#Video-js-5-x" class="headerlink" title="Video.js 5.x"></a>Video.js 5.x</h2><p>When Video.js 7 is released it’ll be the end-of-life for Video.js 5.x from a support perspective. Of course, we are not going to unpublish this version from npm or remove the files from the CDN, so you are free to continue using it. However, we urge you to update at your earliest convenience as we will no longer be accepting fixes.</p>
<h2 id="Google-Analytics"><a href="/Video-js-7-Roadmap/#Google-Analytics" class="headerlink" title="Google Analytics"></a>Google Analytics</h2><blockquote class="pullquote right"><p><img src="/Video-js-7-Roadmap/fastly small.png" alt=""><br>Thanks <a href="https://www.fastly.com/" target="_blank" rel="external">Fastly</a> for sponsoring vjs.zencdn.net</p>
</blockquote>
<p>Video.js provides CDN hosted files for Video.js, sponsored by <a href="https://www.fastly.com/" target="_blank" rel="external">Fastly</a> – thanks Fastly! These files currently have a stripped down pixel tracking for Google Analytics (GA) that sends limited information to a GA account we own. We did a terrible job communicating that this is happening and how users can opt out – set window.HELP_IMPROVE_VIDEOJS to false before loading in Video.js – or use another CDN like unpkg or CDNJS. Recently we made a change that makes this tracking pixel honor the Do Not Track flag set by users in the browser, however, this isn’t going to affect previously released versions of Video.js<br><img src="/Video-js-7-Roadmap/remove GA.png" alt=""><br>In addition, starting with Video.js 7.0 (and probably back ported to newer versions of 6.x) we will <em>no longer</em> include this tracking pixel in our CDN builds. Instead, we are investigating our options for using the CDN logs via Fastly. We expect to share more details as we get closer to the Video.js 7 release date and have a better idea of what we will be doing.</p>
<h2 id="Build-Tools"><a href="/Video-js-7-Roadmap/#Build-Tools" class="headerlink" title="Build Tools"></a>Build Tools</h2><p><img src="/Video-js-7-Roadmap/rollup to webpack.png" alt=""></p>
<p>Currently, Video.js uses rollup to combine all the Video.js files into two files for different build systems. One that excludes dependencies, for use in bundlers, and another that includes dependencies for a UMD file that can be used on a page as a <code>&lt;script&gt;</code>. We are looking to transition our build and test tooling from rollup and browserify to Webpack 4.0 to provide more flexibility in our builds and to do a better job at being able to build with VHS (as many people remember <a href="https://github.com/videojs/videojs-contrib-hls/issues/600" target="_blank" rel="external">the infamous issue 600 on the contrib-hls repo</a>).<br>In addition, we’ll be looking into allowing custom builds when bundling Video.js. For example, if one doesn’t want VHS or doesn’t want visible controls, a surprisingly large part of the player, they can set <code>VJS_VHS=false</code> <code>VJS_CONTROLS=false</code> when they’re bundling their application to keep these pieces out of the build.</p>
<h2 id="Timeline"><a href="/Video-js-7-Roadmap/#Timeline" class="headerlink" title="Timeline"></a>Timeline</h2><p>We are still working on a lot of what was mentioned above but our hope is to have the first pre-release of 7.0 before the end of March.</p>
<p>We’re pretty excited about this not-so-major update and hope you will be too!</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;/Video-js-7-Roadmap/woodland-road-falling-leaf-natural-38537.jpeg&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Today, I’m excited to announce the roadmap to
    
    </summary>
    
    
      <category term="IE8" scheme="http://blog.videojs.com/tags/IE8/"/>
    
      <category term="IE" scheme="http://blog.videojs.com/tags/IE/"/>
    
      <category term="google analytics" scheme="http://blog.videojs.com/tags/google-analytics/"/>
    
      <category term="VHS" scheme="http://blog.videojs.com/tags/VHS/"/>
    
      <category term="HLS" scheme="http://blog.videojs.com/tags/HLS/"/>
    
      <category term="DASH" scheme="http://blog.videojs.com/tags/DASH/"/>
    
      <category term="webpack" scheme="http://blog.videojs.com/tags/webpack/"/>
    
      <category term="rollup" scheme="http://blog.videojs.com/tags/rollup/"/>
    
  </entry>
  
  <entry>
    <title>videojs-vr Is Now Under The Video.js Org</title>
    <link href="http://blog.videojs.com/videojs-vr-now-under-the-video-js-org/"/>
    <id>http://blog.videojs.com/videojs-vr-now-under-the-video-js-org/</id>
    <published>2018-02-21T11:36:00.000Z</published>
    <updated>2019-01-18T19:57:55.607Z</updated>
    
    <content type="html"><![CDATA[<p>Brightcove and Video.js have adopted the videojs-vr plugin as a first class plugin.<br>It’s out now with support for Video.js 6!</p>
<h2 id="Where-did-it-come-from"><a href="/videojs-vr-now-under-the-video-js-org/#Where-did-it-come-from" class="headerlink" title="Where did it come from?"></a>Where did it come from?</h2><p>This plugin has a long history and has had many maintainers.<br>It started as <a href="https://github.com/slawrence/videojs-vr" target="_blank" rel="external">slawrence/videojs-vr</a>. From there it became <a href="https://github.com/metacdn/videojs-vr" target="_blank" rel="external">metacdn/videojs-vr</a>. Then there was a private collaberation between <a href="https://streamshark.io" target="_blank" rel="external">StreamShark.io</a>, <a href="https://www.brightcove.com" target="_blank" rel="external">Brightcove</a>, and <a href="http://corp.hapyak.com/" target="_blank" rel="external">HapYak</a>. Eventually we decided to treat this plugin like a first class citizen. So we updated it to the <a href="http://docs.videojs.com/tutorial-plugins.html#writing-an-advanced-plugin" target="_blank" rel="external">advanced plugin API</a>, fixed a few long-standing issues, documented other issues along the way, and moved it to the Video.js Organization.</p>
<h2 id="How-do-you-know-a-video-is-360-VR"><a href="/videojs-vr-now-under-the-video-js-org/#How-do-you-know-a-video-is-360-VR" class="headerlink" title="How do you know a video is 360/VR?"></a>How do you know a video is 360/VR?</h2><h3 id="On-desktop-players"><a href="/videojs-vr-now-under-the-video-js-org/#On-desktop-players" class="headerlink" title="On desktop players"></a>On desktop players</h3><p>In a non-browser environment this question is easily answered, because there is a generally agreed upon standard. The video itself should have metadata indicating that the video is a 360/VR video and how to display it. Even outside of the browser though it is a bit tricky because most programs (even ffmpeg) don’t support the insertion of this metadata. In fact a lot of them will strip said metadata as they think it is invalid. That is where a project called <a href="https://github.com/google/spatial-media" target="_blank" rel="external">Spatial Media Metadata Injector</a> comes in. <a href="https://github.com/google/spatial-media" target="_blank" rel="external">Spatial Media Metadata Injector</a> injects  360/VR metadata into the video without changing anything else.<br>That allows players like VLC to know that a video is 360/VR.</p>
<h3 id="How-does-videojs-vr-do-it"><a href="/videojs-vr-now-under-the-video-js-org/#How-does-videojs-vr-do-it" class="headerlink" title="How does videojs-vr do it?"></a>How does videojs-vr do it?</h3><p>The browser does not expose video metadata in an API so we would have to parse it ourselves, which isn’t really an option. So in videojs-vr we have a <code>projection</code> option that can be passed in during plugin initialization.</p>
<p>The first and default setting for <code>projection</code> is <code>&#39;AUTO&#39;</code>. Setting <code>projection</code> to <code>&#39;AUTO&#39;</code> tells videojs-vr to look at <code>player.mediainfo.projection</code>. <code>player.mediainfo.projection</code> will have to be set by some external plugin/script which is told by a server that the current video is 360/VR. The <code>player.mediainfo.projection</code> of a video can be any of the following:</p>
<ul>
<li><code>&#39;360&#39;</code>, <code>&#39;Sphere&#39;</code>, or <code>&#39;equirectangular&#39;</code>: The video is a sphere</li>
<li><code>&#39;Cube&#39;</code> or <code>&#39;360_CUBE&#39;</code>: The video is a cube</li>
<li><code>&#39;NONE&#39;</code>: This video is not a 360 video, the videojs-vr plugin should do nothing. this would not have to be set as it will be assumed if no projection exists.</li>
<li><code>&#39;360_LR&#39;</code>: Used for side-by-side 360 videos</li>
<li><code>&#39;360_TB&#39;</code>: Used for top-to-bottom 360 videos</li>
</ul>
<p>Otherwise, the <code>projection</code> can manually be set on plugin initialization to any of the above values. The plugin can then be disposed and re-initialized for each video with a different setting.</p>
<h2 id="What-happens-after-after-we-know-a-video-is-360-VR"><a href="/videojs-vr-now-under-the-video-js-org/#What-happens-after-after-we-know-a-video-is-360-VR" class="headerlink" title="What happens after after we know a video is 360/VR?"></a>What happens after after we know a video is 360/VR?</h2><p>Using the current projection value we determine what we need to show on our <a href="https://github.com/mrdoob/three.js" target="_blank" rel="external">three.js</a> canvas. From there we use the polyfilled (via <a href="https://github.com/googlevr/webvr-polyfill" target="_blank" rel="external">webvr-polyfill</a> or real <a href="https://developer.mozilla.org/en-US/docs/Web/API/VRDisplay" target="_blank" rel="external">VRDisplay API</a> to set up controls. If the device has a VIVE, Oculus, etc plugged in we use that. If not we display the video in 360 mode where the mouse/keyboard/accelerometer control the video. On mobile devies there is also a button to go into cardboard mode which will show the video as two smaller videos separated by a line. This is so that the video can be viewed using pseudo VR headsets (such as google cardboard) and a phone. While the video is playing we use animation frames to animate the VideoTexture on the three.js canvas. That allows us to show the correct portion of the video based on the controls that the user is inputting.</p>
<h2 id="Why-is-it-so-huge"><a href="/videojs-vr-now-under-the-video-js-org/#Why-is-it-so-huge" class="headerlink" title="Why is it so huge?"></a>Why is it so huge?</h2><p>We all agree that the plugin is huge, but due to the fact that all browsers do not natively support the VRDisplay API, we have to include a lot of big dependencies in our project. Mainly the size comes from the following:</p>
<ol>
<li><a href="https://github.com/mrdoob/three.js" target="_blank" rel="external">three.js</a> which we use to create the VR/360 canvas, and implementing it on our own would be painful</li>
<li><a href="https://github.com/googlevr/webvr-polyfill" target="_blank" rel="external">webvr-polyfill</a> which polyfills VR features for browsers that don’t currently support VR (outside of experimental flags and builds)</li>
</ol>
<h2 id="Debugging"><a href="/videojs-vr-now-under-the-video-js-org/#Debugging" class="headerlink" title="Debugging"></a>Debugging</h2><p>Every object from three.js and webvr manager (from webvr-boilerplate) is available on the instance of the VR plugin that will is returned by <code>player.vr()</code>.</p>
<h2 id="Known-Issues"><a href="/videojs-vr-now-under-the-video-js-org/#Known-Issues" class="headerlink" title="Known Issues"></a>Known Issues</h2><ul>
<li>Multiple players on the same page will share controls, panning in one video will pan in the other.</li>
</ul>
<h2 id="The-Future"><a href="/videojs-vr-now-under-the-video-js-org/#The-Future" class="headerlink" title="The Future"></a>The Future</h2><ul>
<li>Implementing player level controls rather than window controls. This will allow individual videos to be controlled separately based on the current focus.</li>
<li>A menu so that multiple VR displays can be used rather than just the first one that we find.</li>
</ul>
<h2 id="To-see-the-code-submit-an-issue-suggest-a-feature-or-submit-a-pr"><a href="/videojs-vr-now-under-the-video-js-org/#To-see-the-code-submit-an-issue-suggest-a-feature-or-submit-a-pr" class="headerlink" title="To see the code, submit an issue, suggest a feature, or submit a pr"></a>To see the code, submit an issue, suggest a feature, or submit a pr</h2><p>See the github repo <a href="https://github.com/videojs/videojs-vr" target="_blank" rel="external">videojs-vr</a></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Brightcove and Video.js have adopted the videojs-vr plugin as a first class plugin.&lt;br&gt;It’s out now with support for Video.js 6!&lt;/p&gt;
&lt;h2 
    
    </summary>
    
    
      <category term="vr, 360, plugins" scheme="http://blog.videojs.com/tags/vr-360-plugins/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 6.7.1 released</title>
    <link href="http://blog.videojs.com/Video-js-6-7-1-released/"/>
    <id>http://blog.videojs.com/Video-js-6-7-1-released/</id>
    <published>2018-02-01T15:40:55.000Z</published>
    <updated>2019-01-18T19:57:55.601Z</updated>
    
    <content type="html"><![CDATA[<p>Video.js 6.7.1 was released this week. This comes a month and a half since the first <a href="https://github.com/videojs/video.js/releases/tag/v6.6.0" target="_blank" rel="external">6.6.0 release</a> (which we forgot to blog about) and only a week since the latest patch release (<a href="https://github.com/videojs/video.js/releases/tag/v6.6.3" target="_blank" rel="external">6.6.3</a>, which is now latest).</p>
<p>6.7 has two awesome new features and a couple helpers:</p>
<ul>
<li>a working <code>playerresize</code> event</li>
<li>a new mediator type for middleware</li>
<li><code>getPlayer</code> and <code>getAllPlayers</code> helper on <code>videojs</code>.</li>
</ul>
<h2 id="Netlify"><a href="/Video-js-6-7-1-released/#Netlify" class="headerlink" title="Netlify"></a>Netlify</h2><p>Recently, we also switched over all our online properties to run on <a href="https://www.netlify.com/" target="_blank" rel="external">Netlify</a>. This is great because it gives us HTTPS via <a href="https://letsencrypt.org/" target="_blank" rel="external">Let’s Encrypt</a> but also allows us much better automation for the website, docs website, and blog. Since the docs website is tied to the main Video.js repo and has a build per PR, we also had Netlify generate an example page for the PR based on the sandbox examples. <a href="https://deploy-preview-4916--videojs-docs.netlify.com/test-example/" target="_blank" rel="external">Here’s the example page</a> for a <a href="https://github.com/videojs/video.js/pull/4916" target="_blank" rel="external">recent PR</a>.</p>
<h2 id="playerresize"><a href="/Video-js-6-7-1-released/#playerresize" class="headerlink" title="playerresize"></a><code>playerresize</code></h2><p>This new event will fire each time the player is resized. It will fire when going fullscreen and when exiting fullscreen and when resizing the player via the dimension methods or if the player is in fluid mode and the window is resized.<br>It uses the new <a href="https://github.com/WICG/ResizeObserver" target="_blank" rel="external">ResizeObserver</a> in Chrome 64 and wherever it is available. If it isn’t available, a polyfill can be passed in or it will use its fallback. The fallback uses an absolutely positioned, hidden iframe that’s the size of the player and then retriggers the iframe’s <code>resize</code> event on a debounced handler.<br>Also, I wanted to note that the <code>resize</code> player event does not refer to the size of the player itself but rather to the native <a href="https://html.spec.whatwg.org/multipage/media.html#event-media-resize" target="_blank" rel="external"><code>resize</code> event</a>, which is triggered when the videoHeight or videoWidth has changed.</p>
<h2 id="Mediator-type-for-middleware"><a href="/Video-js-6-7-1-released/#Mediator-type-for-middleware" class="headerlink" title="Mediator type for middleware"></a>Mediator type for middleware</h2><p>This is the first major feature for middleware since they were released in 6.0. The  main reason for the mediator is for middleware to be able to cancel requests to <code>play()</code>. Thus, they are currently limited to <code>play()</code> and <code>pause()</code> calls currently. Once we iron out the details we hope to enable it for further functionality.<br>The mediator middleware allows you to intercept the calls to the mediator methods, like <code>play()</code>, and then prevent the calls from occuring on the tech. This is important for methods like <code>play()</code> because while calling <code>pause()</code> immediately after <code>play()</code> may succeed in “cancelling” playback, it also has some unintended side-effects in a few cases. The mediator middleware can decide whether <code>play()</code> should go through, thus eliminating the need to call <code>pause()</code>. Afterwards, all middleware will be notified whether the call was terminated or it will be given the return value. In the case of <code>play()</code>, it will be the play promise itself.</p>
<p>Here’s a simple example:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line">videojs.use(<span class="string">'*'</span>, (player) =&gt; (&#123;</span><br><span class="line">  setSource(src, next) &#123;</span><br><span class="line">    next(<span class="literal">null</span>, src);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  callPlay() &#123;</span><br><span class="line">    <span class="comment">// return this value to terminate the method call</span></span><br><span class="line">    <span class="keyword">return</span> videojs.middleware.TERMINATOR;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  play(terminated, playPromise) &#123;</span><br><span class="line">    <span class="keyword">if</span> (terminated) &#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="built_in">console</span>.error(terminated, <span class="string">'play was terminated'</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    playPromise</span><br><span class="line">    .then(<span class="function"><span class="params">()</span> =&gt;</span> <span class="built_in">console</span>.log(<span class="string">'play succeeded!'</span>))</span><br><span class="line">    .catch(<span class="function"><span class="params">()</span> =&gt;</span> <span class="built_in">console</span>.log(<span class="string">'play failed :('</span>));</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<h2 id="Player-helpers"><a href="/Video-js-6-7-1-released/#Player-helpers" class="headerlink" title="Player helpers"></a>Player helpers</h2><p>These are to make it easier to manage your players and reduce unintended side-effects. A lot of times, a player is being created automatically via <code>data-setup</code> but then to refer to it via code, <code>videojs()</code> is called. In some cases, this will actually initialize the player because it ended up running before the auto setup. Now, <code>videojs.getPlayer()</code> can be used instead and it will never create the player. It is the preferred way of getting the player once it has been created.<br><code>videojs.getAllPlayers()</code> is just a nice way of getting a list of all the players that are currently available on the page.</p>
<h2 id="Committers"><a href="/Video-js-6-7-1-released/#Committers" class="headerlink" title="Committers"></a>Committers</h2><ul>
<li>Gary Katsevman <a href="https://github.com/gkatsev" target="_blank" rel="external">@gkatsev</a></li>
<li>Pat O’Neill <a href="https://github.com/misteroneill" target="_blank" rel="external">@misteroneill</a></li>
<li><a href="https://github.com/ldayananda" target="_blank" rel="external">@ldayananda</a></li>
<li><a href="https://github.com/mister-ben" target="_blank" rel="external">@mister-ben</a></li>
</ul>
<h2 id="Raw-CHANGELOG"><a href="/Video-js-6-7-1-released/#Raw-CHANGELOG" class="headerlink" title="Raw CHANGELOG"></a>Raw CHANGELOG</h2><p><a name="6.7.1"></a></p>
<h2 id="6-7-1-2018-01-31"><a href="/Video-js-6-7-1-released/#6-7-1-2018-01-31" class="headerlink" title="6.7.1 (2018-01-31)"></a><a href="https://github.com/videojs/video.js/compare/v6.7.0...v6.7.1" target="_blank" rel="external">6.7.1</a> (2018-01-31)</h2><h3 id="Bug-Fixes"><a href="/Video-js-6-7-1-released/#Bug-Fixes" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li><strong>middleware</strong>: do a null check in mediator methods (<a href="https://github.com/videojs/video.js/issues/4913" target="_blank" rel="external">#4913</a>) (<a href="https://github.com/videojs/video.js/commit/7670db6" target="_blank" rel="external">7670db6</a>)</li>
</ul>
<p><a name="6.7.0"></a></p>
<h1 id="6-7-0-2018-01-30"><a href="/Video-js-6-7-1-released/#6-7-0-2018-01-30" class="headerlink" title="6.7.0 (2018-01-30)"></a><a href="https://github.com/videojs/video.js/compare/v6.6.3...v6.7.0" target="_blank" rel="external">6.7.0</a> (2018-01-30)</h1><h3 id="Features"><a href="/Video-js-6-7-1-released/#Features" class="headerlink" title="Features"></a>Features</h3><ul>
<li>Add <code>getPlayer</code> method to Video.js. (<a href="https://github.com/videojs/video.js/issues/4836" target="_blank" rel="external">#4836</a>) (<a href="https://github.com/videojs/video.js/commit/a15e616" target="_blank" rel="external">a15e616</a>)</li>
<li>Add <code>videojs.getAllPlayers</code> to get an array of players. (<a href="https://github.com/videojs/video.js/issues/4842" target="_blank" rel="external">#4842</a>) (<a href="https://github.com/videojs/video.js/commit/6a00577" target="_blank" rel="external">6a00577</a>)</li>
<li>add mediator middleware type for play() (<a href="https://github.com/videojs/video.js/issues/4868" target="_blank" rel="external">#4868</a>) (<a href="https://github.com/videojs/video.js/commit/bf3eb45" target="_blank" rel="external">bf3eb45</a>)</li>
<li>playerresize event in all cases (<a href="https://github.com/videojs/video.js/issues/4864" target="_blank" rel="external">#4864</a>) (<a href="https://github.com/videojs/video.js/commit/9ceb4e4" target="_blank" rel="external">9ceb4e4</a>)</li>
</ul>
<h3 id="Bug-Fixes-1"><a href="/Video-js-6-7-1-released/#Bug-Fixes-1" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>do not patch canplaytype on android chrome (<a href="https://github.com/videojs/video.js/issues/4885" target="_blank" rel="external">#4885</a>) (<a href="https://github.com/videojs/video.js/commit/f03ac5e" target="_blank" rel="external">f03ac5e</a>)</li>
</ul>
<h3 id="Chores"><a href="/Video-js-6-7-1-released/#Chores" class="headerlink" title="Chores"></a>Chores</h3><ul>
<li>generate a test example on netlify for PRs (<a href="https://github.com/videojs/video.js/issues/4912" target="_blank" rel="external">#4912</a>) (<a href="https://github.com/videojs/video.js/commit/8b54737" target="_blank" rel="external">8b54737</a>)</li>
<li><strong>package:</strong> update dependencies (<a href="https://github.com/videojs/video.js/issues/4908" target="_blank" rel="external">#4908</a>) (<a href="https://github.com/videojs/video.js/commit/dcab42e" target="_blank" rel="external">dcab42e</a>)</li>
</ul>
<h3 id="Documentation"><a href="/Video-js-6-7-1-released/#Documentation" class="headerlink" title="Documentation"></a>Documentation</h3><ul>
<li>Update COLLABORATOR_GUIDE.md and CONTRIBUTING.md to include label meanings (<a href="https://github.com/videojs/video.js/issues/4874" target="_blank" rel="external">#4874</a>) (<a href="https://github.com/videojs/video.js/commit/a345971" target="_blank" rel="external">a345971</a>)</li>
</ul>
<h3 id="Tests"><a href="/Video-js-6-7-1-released/#Tests" class="headerlink" title="Tests"></a>Tests</h3><ul>
<li>add project and build names to browserstack (<a href="https://github.com/videojs/video.js/issues/4903" target="_blank" rel="external">#4903</a>) (<a href="https://github.com/videojs/video.js/commit/41fd5cb" target="_blank" rel="external">41fd5cb</a>)</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Video.js 6.7.1 was released this week. This comes a month and a half since the first &lt;a href=&quot;https://github.com/videojs/video.js/release
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Video.js 6.5.0 Release</title>
    <link href="http://blog.videojs.com/Video-js-6-5-0-Release/"/>
    <id>http://blog.videojs.com/Video-js-6-5-0-Release/</id>
    <published>2017-11-27T17:16:06.000Z</published>
    <updated>2019-01-18T19:57:55.598Z</updated>
    
    <content type="html"><![CDATA[<p>November 17th marked the pre-release of Video.js 6.5.0. It comes shortly after the <a href="https://blog.videojs.com/video-js-6-4-0-release/">release of 6.4.0</a>, which has now been promoted to latest! This is a pretty exciting release because we finally got our own element! I like to call it the I Can’t Believe It’s Not Custom Elements because it isn’t an actual custom element but it’s not a standard HTML element either. Also, a nice and smooth progress bar thanks to a first time contributor; thanks <a href="https://github.com/vhmth" target="_blank" rel="external">@vhmth</a>!. A pretty major memory leak fix, and many code refactors and bug fixes.<br>I’d like to thank everyone who contributed and the four first time contributors to Video.js: <a href="https://github.com/vhmth" target="_blank" rel="external">@vhmth</a>, <a href="https://github.com/FirefoxMetzger" target="_blank" rel="external">@FirefoxMetzger</a>, <a href="https://github.com/EhsanCh" target="_blank" rel="external">@EhsanCh</a>, and <a href="https://github.com/shahlabs" target="_blank" rel="external">@shahlabs</a>.<br>This post comes a week late because it was Thanksgiving week in the US after release and I was on break, if you celebrate Turkey day 🦃, hope you had a good one!</p>
<h2 id="Notable-Changes"><a href="/Video-js-6-5-0-Release/#Notable-Changes" class="headerlink" title="Notable Changes"></a>Notable Changes</h2><ul>
<li>I Can’t Believe It’s Not Custom Elements with a <code>&lt;video-js&gt;</code> element. It works exactly like the <code>&lt;video&gt;</code> embed but without requiring you to use the <code>&lt;video&gt;</code> element and the benefits and drawbacks that come with it. It also adds the <code>video-js</code> class name automatically for you, so, there’s no need to add it.</li>
<li>A smooth progress bar!<br><img src="/Video-js-6-5-0-Release/./before.gif" alt="before the change"><br><img src="/Video-js-6-5-0-Release/./after.gif" alt="after the change"></li>
<li>After much spelunking in the code base and developer tools, we’ve plugged most of the memory leaks with retained DOM elements in Video.js!</li>
<li>Many code refactorings from our old code style to the new one by <a href="https://github.com/kocoten1992" target="_blank" rel="external">@kocoten1992</a>!</li>
<li>Previously, you could accidentally seek or toggle playback using the middle or right clicks. Now, just go ahead and try it!</li>
<li>An accessibility fix with regards to title tooltips and menu items.</li>
<li>Better handling of <code>play()</code> in our new asynchronous world, especially immediately after changing the source.</li>
</ul>
<h2 id="Committers"><a href="/Video-js-6-5-0-Release/#Committers" class="headerlink" title="Committers"></a>Committers</h2><ul>
<li>Vinay <a href="https://github.com/vhmth" target="_blank" rel="external">@vhmth</a> First PR</li>
<li>Ilya Piatrenka <a href="https://github.com/odisei369" target="_blank" rel="external">@odisei369</a></li>
<li>Brandon Casey <a href="https://github.com/brandonocasey" target="_blank" rel="external">@brandonocasey</a></li>
<li><a href="https://github.com/FirefoxMetzger" target="_blank" rel="external">@FirefoxMetzger</a> First PR</li>
<li>Ehsan Chavoshi <a href="https://github.com/EhsanCh" target="_blank" rel="external">@EhsanCh</a> First PR</li>
<li>Chuong <a href="https://github.com/kocoten1992" target="_blank" rel="external">@kocoten1992</a></li>
<li>Martin Bachwerk <a href="https://github.com/arski" target="_blank" rel="external">@arski</a></li>
<li>Pat O’Neill <a href="https://github.com/misteroneill" target="_blank" rel="external">@misteroneill</a></li>
<li>Labdhi Shah <a href="https://github.com/shahlabs" target="_blank" rel="external">@shahlabs</a> First PR</li>
</ul>
<h2 id="Raw-Changelog"><a href="/Video-js-6-5-0-Release/#Raw-Changelog" class="headerlink" title="Raw Changelog"></a>Raw Changelog</h2><p><a name="6.5.0"></a></p>
<h3 id="6-5-0-2017-11-17"><a href="/Video-js-6-5-0-Release/#6-5-0-2017-11-17" class="headerlink" title="6.5.0 (2017-11-17)"></a><a href="https://github.com/videojs/video.js/compare/v6.4.0...v6.5.0" target="_blank" rel="external">6.5.0</a> (2017-11-17)</h3><h3 id="Features"><a href="/Video-js-6-5-0-Release/#Features" class="headerlink" title="Features"></a>Features</h3><ul>
<li>add a version method to all advanced plugin instances (<a href="https://github.com/videojs/video.js/issues/4714" target="_blank" rel="external">#4714</a>) (<a href="https://github.com/videojs/video.js/commit/acf4153" target="_blank" rel="external">acf4153</a>)</li>
<li>allow embeds via <video-js> element (<a href="https://github.com/videojs/video.js/issues/4640" target="_blank" rel="external">#4640</a>) (<a href="https://github.com/videojs/video.js/commit/d8aadd5" target="_blank" rel="external">d8aadd5</a>)</video-js></li>
</ul>
<h3 id="Bug-Fixes"><a href="/Video-js-6-5-0-Release/#Bug-Fixes" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li>Avoid empty but shown title attribute with menu items and clickable components (<a href="https://github.com/videojs/video.js/issues/4746" target="_blank" rel="external">#4746</a>) (<a href="https://github.com/videojs/video.js/commit/dc588dd" target="_blank" rel="external">dc588dd</a>)</li>
<li><strong>Player#play:</strong> Wait for loadstart in play() when changing sources instead of just ready. (<a href="https://github.com/videojs/video.js/issues/4743" target="_blank" rel="external">#4743</a>) (<a href="https://github.com/videojs/video.js/commit/26b0d2c" target="_blank" rel="external">26b0d2c</a>)</li>
<li>being able to toggle playback with middle click (<a href="https://github.com/videojs/video.js/issues/4756" target="_blank" rel="external">#4756</a>) (<a href="https://github.com/videojs/video.js/commit/7a776ee" target="_blank" rel="external">7a776ee</a>), closes <a href="https://github.com/videojs/video.js/issues/4689" target="_blank" rel="external">#4689</a></li>
<li>make the progress bar progress smoothly (<a href="https://github.com/videojs/video.js/issues/4591" target="_blank" rel="external">#4591</a>) (<a href="https://github.com/videojs/video.js/commit/acc641a" target="_blank" rel="external">acc641a</a>)</li>
<li>only allow left click dragging on progress bar and volume control (<a href="https://github.com/videojs/video.js/issues/4613" target="_blank" rel="external">#4613</a>) (<a href="https://github.com/videojs/video.js/commit/79b4355" target="_blank" rel="external">79b4355</a>)</li>
<li>only print element not in DOM warning on player creation (<a href="https://github.com/videojs/video.js/issues/4755" target="_blank" rel="external">#4755</a>) (<a href="https://github.com/videojs/video.js/commit/bbea5cc" target="_blank" rel="external">bbea5cc</a>)</li>
<li>trigger timeupdate during seek (<a href="https://github.com/videojs/video.js/issues/4754" target="_blank" rel="external">#4754</a>) (<a href="https://github.com/videojs/video.js/commit/1fcd5ae" target="_blank" rel="external">1fcd5ae</a>)</li>
</ul>
<h3 id="Chores"><a href="/Video-js-6-5-0-Release/#Chores" class="headerlink" title="Chores"></a>Chores</h3><ul>
<li><strong>lang:</strong> update Persian translations (<a href="https://github.com/videojs/video.js/issues/4741" target="_blank" rel="external">#4741</a>) (<a href="https://github.com/videojs/video.js/commit/95d7832" target="_blank" rel="external">95d7832</a>)</li>
</ul>
<h3 id="Code-Refactoring"><a href="/Video-js-6-5-0-Release/#Code-Refactoring" class="headerlink" title="Code Refactoring"></a>Code Refactoring</h3><ul>
<li>player.controls() (<a href="https://github.com/videojs/video.js/issues/4731" target="_blank" rel="external">#4731</a>) (<a href="https://github.com/videojs/video.js/commit/d447e9f" target="_blank" rel="external">d447e9f</a>)</li>
<li>player.listenForUserActivity (<a href="https://github.com/videojs/video.js/issues/4719" target="_blank" rel="external">#4719</a>) (<a href="https://github.com/videojs/video.js/commit/c16fedf" target="_blank" rel="external">c16fedf</a>)</li>
<li>player.userActive() (<a href="https://github.com/videojs/video.js/issues/4716" target="_blank" rel="external">#4716</a>) (<a href="https://github.com/videojs/video.js/commit/6cbe3ed" target="_blank" rel="external">6cbe3ed</a>)</li>
<li>player.usingNativeControls() (<a href="https://github.com/videojs/video.js/issues/4749" target="_blank" rel="external">#4749</a>) (<a href="https://github.com/videojs/video.js/commit/eb909f0" target="_blank" rel="external">eb909f0</a>)</li>
</ul>
<h3 id="Documentation"><a href="/Video-js-6-5-0-Release/#Documentation" class="headerlink" title="Documentation"></a>Documentation</h3><ul>
<li><strong>readme:</strong> fixed a typo (<a href="https://github.com/videojs/video.js/issues/4730" target="_blank" rel="external">#4730</a>) (<a href="https://github.com/videojs/video.js/commit/46a7df2" target="_blank" rel="external">46a7df2</a>)</li>
</ul>
<h3 id="Performance-Improvements"><a href="/Video-js-6-5-0-Release/#Performance-Improvements" class="headerlink" title="Performance Improvements"></a>Performance Improvements</h3><ul>
<li>null out els on dispose to minimize detached els (<a href="https://github.com/videojs/video.js/issues/4745" target="_blank" rel="external">#4745</a>) (<a href="https://github.com/videojs/video.js/commit/2da7af1" target="_blank" rel="external">2da7af1</a>)</li>
</ul>
<h3 id="Tests"><a href="/Video-js-6-5-0-Release/#Tests" class="headerlink" title="Tests"></a>Tests</h3><ul>
<li>clean up test warnings (<a href="https://github.com/videojs/video.js/issues/4752" target="_blank" rel="external">#4752</a>) (<a href="https://github.com/videojs/video.js/commit/3aae4b2" target="_blank" rel="external">3aae4b2</a>)</li>
<li>update tests to use qunit 2 assert format (<a href="https://github.com/videojs/video.js/issues/4753" target="_blank" rel="external">#4753</a>) (<a href="https://github.com/videojs/video.js/commit/06641e8" target="_blank" rel="external">06641e8</a>)</li>
<li>warning, if the element is not in the DOM (<a href="https://github.com/videojs/video.js/issues/4723" target="_blank" rel="external">#4723</a>) (<a href="https://github.com/videojs/video.js/commit/c213737" target="_blank" rel="external">c213737</a>)</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;November 17th marked the pre-release of Video.js 6.5.0. It comes shortly after the &lt;a href=&quot;https://blog.videojs.com/video-js-6-4-0-relea
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Video.js 6.4.0 Release</title>
    <link href="http://blog.videojs.com/Video-js-6-4-0-Release/"/>
    <id>http://blog.videojs.com/Video-js-6-4-0-Release/</id>
    <published>2017-11-02T16:01:38.000Z</published>
    <updated>2019-01-18T19:57:55.598Z</updated>
    
    <content type="html"><![CDATA[<p>Hello everyone, it’s been a while! Yesterday, I pre-released Video.js 6.4.0. It’s a pretty big release with 27 merged Pull Requests from 13 authors and 7 of them were contributors!<br>I’d like to thank everyone who contributed but particularly those seven. Six of them made their first PRs with Video.js: <a href="https://github.com/estim" target="_blank" rel="external">@estim</a>, <a href="https://github.com/seggev319" target="_blank" rel="external">@seggev319</a>, <a href="https://github.com/nicolaslevy" target="_blank" rel="external">@nicolaslevy</a>, <a href="https://github.com/MarcAMo" target="_blank" rel="external">@MarcAMo</a>, <a href="https://github.com/knilob" target="_blank" rel="external">@knilob</a>, <a href="https://github.com/odisei369" target="_blank" rel="external">@odisei369</a>. And <a href="https://github.com/kocoten1992" target="_blank" rel="external">@kocoten1992</a> returned with some great PRs to refactor things.</p>
<p>In this release, we fixed a bunch of bugs, refactored some things, updated some tests. We also added some new features.</p>
<p>As with other releases, this is released as <code>next</code> for a short while before being promoted to <code>latest</code>.<br>You can get these releases on <a href="https://github.com/videojs/video.js/releases/tag/v6.4.0" target="_blank" rel="external">GitHub Releases</a> or from <a href="https://www.npmjs.com/package/video.js" target="_blank" rel="external">npm</a></p>
<h2 id="Notable-Changes"><a href="/Video-js-6-4-0-Release/#Notable-Changes" class="headerlink" title="Notable Changes"></a>Notable Changes</h2><ul>
<li>Hebrew translations are now available. Russian and Polish translations were updated as well.</li>
<li>The Progress Control can now be disabled. This is useful for when you don’t want users to be able to interact with it but still want to show play progress.<ul>
<li>The Progress Control will also be fully filled out when the video ends so that we aren’t slightly short or long due to weirdnesses in duration and currentTime.</li>
</ul>
</li>
<li>It’s now possible to add a <code>hook</code> that gets automatically removed once called with <code>hookOnce</code>. This mirrors our <code>on</code> and <code>once</code> event methods.</li>
<li>If controls are disabled before the modal dialog is opened, the controls stay closed when the dialog is closed.</li>
<li><code>player.src()</code> will now return an empty string when no source is set to match <code>player.currentSrc()</code> and the native video element.</li>
<li>Video.js will now warn when the element it is given isn’t in the DOM. This was done as part of a “first-timers-only” issue which we hope to do more off in the future.</li>
</ul>
<h2 id="Google-Analytics-note"><a href="/Video-js-6-4-0-Release/#Google-Analytics-note" class="headerlink" title="Google Analytics note"></a>Google Analytics note</h2><p>We’ve updated the <a href="https://github.com/videojs/video.js#quick-start" target="_blank" rel="external">README</a> of the project to be explicit about our usage of Google Analytics on the <code>vjs.zencdn.net</code> hosted version of Video.js. It is a stripped down version of the <a href="https://github.com/videojs/cdn/blob/master/src/analytics.js" target="_blank" rel="external">Google Analytics pixel</a> and sends data on 1% of those loads.<br>It can be opted out of by adding the following to the page before the <code>zencdn</code>-hosted version of Video.js is loaded<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="javascript"><span class="built_in">window</span>.HELP_IMPROVE_VIDEOJS = <span class="literal">false</span>;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<p>Our GitHub releases and npm releases <em>do not</em> include Google Analytics. Neither do 3rd-party CDNs like unpkg or CDNjs.</p>
<h2 id="Committers"><a href="/Video-js-6-4-0-Release/#Committers" class="headerlink" title="Committers"></a>Committers</h2><ul>
<li>Gary Katsevman <a href="https://github.com/gkatsev" target="_blank" rel="external">@gkatsev</a></li>
<li>Pat O’Neill <a href="https://github.com/misteroneill" target="_blank" rel="external">@misteroneill</a></li>
<li>Brandon Casey <a href="https://github.com/BrandonOCasey" target="_blank" rel="external">@BrandonOCasey</a></li>
<li><a href="https://github.com/estim" target="_blank" rel="external">@estim</a> First PR</li>
<li><a href="https://github.com/seggev319" target="_blank" rel="external">@seggev319</a> First PR</li>
<li><a href="https://github.com/mister-ben" target="_blank" rel="external">@mister-ben</a></li>
<li>Chuong <a href="https://github.com/kocoten1992" target="_blank" rel="external">@kocoten1992</a></li>
<li>Nicolas Levy <a href="https://github.com/nicolaslevy" target="_blank" rel="external">@nicolaslevy</a> First PR</li>
<li>Marc A. Modrow <a href="https://github.com/MarcAMo" target="_blank" rel="external">@MarcAMo</a> First two PRs</li>
<li>Matt McClure <a href="https://github.com/mmcc" target="_blank" rel="external">@mmcc</a></li>
<li>Bo Link <a href="https://github.com/knilob" target="_blank" rel="external">@knilob</a> First PR</li>
<li>Joe Forbes <a href="https://github.com/forbesjo" target="_blank" rel="external">@forbesjo</a></li>
<li>Ilya Piatrenka <a href="https://github.com/odisei369" target="_blank" rel="external">@odisei369</a> First PR</li>
</ul>
<h2 id="Full-Changelog"><a href="/Video-js-6-4-0-Release/#Full-Changelog" class="headerlink" title="Full Changelog"></a>Full Changelog</h2><p><a name="6.4.0"></a></p>
<h3 id="6-4-0-2017-11-01"><a href="/Video-js-6-4-0-Release/#6-4-0-2017-11-01" class="headerlink" title="6.4.0 (2017-11-01)"></a><a href="https://github.com/videojs/video.js/compare/v6.3.3...v6.4.0" target="_blank" rel="external">6.4.0</a> (2017-11-01)</h3><h3 id="Features"><a href="/Video-js-6-4-0-Release/#Features" class="headerlink" title="Features"></a>Features</h3><ul>
<li><strong>lang:</strong> add Hebrew translation (<a href="https://github.com/videojs/video.js/issues/4675" target="_blank" rel="external">#4675</a>) (<a href="https://github.com/videojs/video.js/commit/32caf35" target="_blank" rel="external">32caf35</a>)</li>
<li><strong>lang:</strong> Update for Russian translation (<a href="https://github.com/videojs/video.js/issues/4663" target="_blank" rel="external">#4663</a>) (<a href="https://github.com/videojs/video.js/commit/45e21fd" target="_blank" rel="external">45e21fd</a>)</li>
<li>Add videojs.hookOnce method to allow single-run hooks. (<a href="https://github.com/videojs/video.js/issues/4672" target="_blank" rel="external">#4672</a>) (<a href="https://github.com/videojs/video.js/commit/85fe685" target="_blank" rel="external">85fe685</a>)</li>
<li>add warning if the element given to Video.js is not in the DOM (<a href="https://github.com/videojs/video.js/issues/4698" target="_blank" rel="external">#4698</a>) (<a href="https://github.com/videojs/video.js/commit/6f713ca" target="_blank" rel="external">6f713ca</a>)</li>
<li>allow progress controls to be disabled (<a href="https://github.com/videojs/video.js/issues/4649" target="_blank" rel="external">#4649</a>) (<a href="https://github.com/videojs/video.js/commit/a3c254e" target="_blank" rel="external">a3c254e</a>)</li>
<li>set the play progress seek bar to 100% on ended (<a href="https://github.com/videojs/video.js/issues/4648" target="_blank" rel="external">#4648</a>) (<a href="https://github.com/videojs/video.js/commit/5e9655f" target="_blank" rel="external">5e9655f</a>)</li>
</ul>
<h3 id="Bug-Fixes"><a href="/Video-js-6-4-0-Release/#Bug-Fixes" class="headerlink" title="Bug Fixes"></a>Bug Fixes</h3><ul>
<li><strong>css:</strong> update user-select none (<a href="https://github.com/videojs/video.js/issues/4678" target="_blank" rel="external">#4678</a>) (<a href="https://github.com/videojs/video.js/commit/43ddc72" target="_blank" rel="external">43ddc72</a>)</li>
<li>aria-labelledby attribute has an extra space (<a href="https://github.com/videojs/video.js/issues/4708" target="_blank" rel="external">#4708</a>) (<a href="https://github.com/videojs/video.js/commit/855adf3" target="_blank" rel="external">855adf3</a>), closes <a href="https://github.com/videojs/video.js/issues/4688" target="_blank" rel="external">#4688</a></li>
<li>Don’t enable player controls if they where disabled when ModalDialog closes. (<a href="https://github.com/videojs/video.js/issues/4690" target="_blank" rel="external">#4690</a>) (<a href="https://github.com/videojs/video.js/commit/afea980" target="_blank" rel="external">afea980</a>)</li>
<li>don’t throttle duration change updates (<a href="https://github.com/videojs/video.js/issues/4635" target="_blank" rel="external">#4635</a>) (<a href="https://github.com/videojs/video.js/commit/9cf9800" target="_blank" rel="external">9cf9800</a>)</li>
<li>Events#off threw if Object.prototype had extra enumerable properties, don’t remove all events if off receives a falsey value (<a href="https://github.com/videojs/video.js/issues/4669" target="_blank" rel="external">#4669</a>) (<a href="https://github.com/videojs/video.js/commit/7963913" target="_blank" rel="external">7963913</a>)</li>
<li>make parseUrl helper always have a protocl (<a href="https://github.com/videojs/video.js/issues/4673" target="_blank" rel="external">#4673</a>) (<a href="https://github.com/videojs/video.js/commit/bebca9c" target="_blank" rel="external">bebca9c</a>), closes <a href="https://github.com/videojs/video.js/issues/3100" target="_blank" rel="external">#3100</a></li>
<li>Make sure we remove vjs-ended from the play toggle in all appropriate cases. (<a href="https://github.com/videojs/video.js/issues/4661" target="_blank" rel="external">#4661</a>) (<a href="https://github.com/videojs/video.js/commit/0287f6e" target="_blank" rel="external">0287f6e</a>)</li>
<li>player.src() should return empty string if no source is set (<a href="https://github.com/videojs/video.js/issues/4711" target="_blank" rel="external">#4711</a>) (<a href="https://github.com/videojs/video.js/commit/9acbcd8" target="_blank" rel="external">9acbcd8</a>)</li>
</ul>
<h3 id="Chores"><a href="/Video-js-6-4-0-Release/#Chores" class="headerlink" title="Chores"></a>Chores</h3><ul>
<li><strong>gh-release:</strong> no console log on success (<a href="https://github.com/videojs/video.js/issues/4657" target="_blank" rel="external">#4657</a>) (<a href="https://github.com/videojs/video.js/commit/e8511a5" target="_blank" rel="external">e8511a5</a>)</li>
<li><strong>lang:</strong> Update Polish (<a href="https://github.com/videojs/video.js/issues/4686" target="_blank" rel="external">#4686</a>) (<a href="https://github.com/videojs/video.js/commit/ee2a49c" target="_blank" rel="external">ee2a49c</a>)</li>
<li><strong>package:</strong> update babelify to version 8.0.0 (<a href="https://github.com/videojs/video.js/issues/4684" target="_blank" rel="external">#4684</a>) (<a href="https://github.com/videojs/video.js/commit/db2f14c" target="_blank" rel="external">db2f14c</a>)</li>
<li>add comment about avoiding helvetica font (<a href="https://github.com/videojs/video.js/issues/4679" target="_blank" rel="external">#4679</a>) (<a href="https://github.com/videojs/video.js/commit/cb638d0" target="_blank" rel="external">cb638d0</a>)</li>
<li>add GA note to primary readme (<a href="https://github.com/videojs/video.js/issues/4481" target="_blank" rel="external">#4481</a>) (<a href="https://github.com/videojs/video.js/commit/e2af322" target="_blank" rel="external">e2af322</a>)</li>
<li>Add package-lock.json file. (<a href="https://github.com/videojs/video.js/issues/4641" target="_blank" rel="external">#4641</a>) (<a href="https://github.com/videojs/video.js/commit/ec5b603" target="_blank" rel="external">ec5b603</a>)</li>
</ul>
<h3 id="Code-Refactoring"><a href="/Video-js-6-4-0-Release/#Code-Refactoring" class="headerlink" title="Code Refactoring"></a>Code Refactoring</h3><ul>
<li>component.ready() (<a href="https://github.com/videojs/video.js/issues/4693" target="_blank" rel="external">#4693</a>) (<a href="https://github.com/videojs/video.js/commit/b40858b" target="_blank" rel="external">b40858b</a>)</li>
<li>player.dimension() (<a href="https://github.com/videojs/video.js/issues/4704" target="_blank" rel="external">#4704</a>) (<a href="https://github.com/videojs/video.js/commit/ad1b47b" target="_blank" rel="external">ad1b47b</a>)</li>
<li>player.hasStarted() (<a href="https://github.com/videojs/video.js/issues/4680" target="_blank" rel="external">#4680</a>) (<a href="https://github.com/videojs/video.js/commit/cde8335" target="_blank" rel="external">cde8335</a>)</li>
<li>player.techGet_() (<a href="https://github.com/videojs/video.js/issues/4687" target="_blank" rel="external">#4687</a>) (<a href="https://github.com/videojs/video.js/commit/a1748aa" target="_blank" rel="external">a1748aa</a>)</li>
</ul>
<h3 id="Documentation"><a href="/Video-js-6-4-0-Release/#Documentation" class="headerlink" title="Documentation"></a>Documentation</h3><ul>
<li><strong>lang:</strong> update translations needed doc (<a href="https://github.com/videojs/video.js/issues/4702" target="_blank" rel="external">#4702</a>) (<a href="https://github.com/videojs/video.js/commit/93e7670" target="_blank" rel="external">93e7670</a>)</li>
</ul>
<h3 id="Tests"><a href="/Video-js-6-4-0-Release/#Tests" class="headerlink" title="Tests"></a>Tests</h3><ul>
<li>fix modal dialog test for showing controls (<a href="https://github.com/videojs/video.js/issues/4707" target="_blank" rel="external">#4707</a>) (<a href="https://github.com/videojs/video.js/commit/45a6b30" target="_blank" rel="external">45a6b30</a>), closes <a href="https://github.com/videojs/video.js/issues/4706" target="_blank" rel="external">#4706</a></li>
<li>get rid of redundant test logging (<a href="https://github.com/videojs/video.js/issues/4682" target="_blank" rel="external">#4682</a>) (<a href="https://github.com/videojs/video.js/commit/983a573" target="_blank" rel="external">983a573</a>)</li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Hello everyone, it’s been a while! Yesterday, I pre-released Video.js 6.4.0. It’s a pretty big release with 27 merged Pull Requests from 
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Video.js 6.0 Release!</title>
    <link href="http://blog.videojs.com/Video-js-6-0-Release/"/>
    <id>http://blog.videojs.com/Video-js-6-0-Release/</id>
    <published>2017-04-03T17:56:51.000Z</published>
    <updated>2019-01-18T19:57:55.598Z</updated>
    
    <content type="html"><![CDATA[<p>After months of hard work, I am proud to annouce the release of Video.js 6.0 🎉!</p>
<p>This release is pretty exciting. It greatly <a href="http://blog.videojs.com/Feature-Spotlight-Accessibility/">improves the accessibility</a> of the controls and components, and we are committed to making Video.js the most accessible player we can. Video.js also provides some shiny, and awesome, new features for developers in <a href="http://blog.videojs.com/Feature-Spotlight-Middleware/">middleware</a> and <a href="http://blog.videojs.com/Feature-Spotlight-Advanced-Plugins/">advanced plugins</a>. Video.js 6.0 is also the first release where <a href="http://blog.videojs.com/Video-js-removes-Flash-from-core-player/">Flash is unbundled from core</a> – though, it is still available as a plugin, if necessary.</p>
<p>Today’s release is a pre-release and will stay that way for about a week or two before being promoted to <code>latest</code>. Just to make sure that any last bugs, if any, are ironed out.</p>
<h2 id="Things-you-should-know"><a href="/Video-js-6-0-Release/#Things-you-should-know" class="headerlink" title="Things you should know"></a>Things you should know</h2><p>Most things have not changed between 5.x and 6.x. In fact, in most of our work in plugins we maintain, the majority of the work was to use new methods and fallback to old methods because they were logging deprecation warnings. Those plugins would’ve continued working otherwise.</p>
<p>However, there are definitely some changes that are breaking and would require action on your part. For example, if you require Flash, that’s something that would now need to be included manually.</p>
<p>One of the other big changes is that source selection is now asynchronous. This was necessary for middleware support and most likely won’t affect users if they are waiting for the player to be ready before interacting with the player.</p>
<p>These are written up on our <a href="https://github.com/videojs/video.js/wiki/Video.js-6-Migration-Guide" target="_blank" rel="external">wiki</a>. We’ll make sure to update it if there’s anything that we missed.</p>
<h2 id="Feedback-Wanted"><a href="/Video-js-6-0-Release/#Feedback-Wanted" class="headerlink" title="Feedback Wanted"></a>Feedback Wanted</h2><p>If you are using Video.js and have comments or questions, please drop by on <a href="http://slack.videojs.com" target="_blank" rel="external">Slack</a>. If you find a bug, please open an <a href="https://github.com/videojs/video.js/issues/new" target="_blank" rel="external">issue on GitHub</a>, preferably with a <a href="https://css-tricks.com/reduced-test-cases/" target="_blank" rel="external">reduced test case</a>.</p>
<h2 id="5-x-Support"><a href="/Video-js-6-0-Release/#5-x-Support" class="headerlink" title="5.x Support"></a>5.x Support</h2><p>We’re still going to be supporting the Video.js 5.x release line. This will mostly be bug fixes but features will be considered on a case-by-case basis.</p>
<p>If IE8 support is still required, it is probably best to stick to 5.x.</p>
<h2 id="npm-tags"><a href="/Video-js-6-0-Release/#npm-tags" class="headerlink" title="npm tags"></a>npm tags</h2><p>Once Video.js 6 is promoted to latest, it’ll take over the <code>next</code> and <code>latest</code> tags on npm. The 5.x release line will then be given its own set of tags: <code>latest-5</code> and <code>next-5</code>.</p>
<h2 id="Code-of-Condunct"><a href="/Video-js-6-0-Release/#Code-of-Condunct" class="headerlink" title="Code of Condunct"></a>Code of Condunct</h2><p>We strive to be open and inclusive and so we have adopted a <a href="https://github.com/videojs/video.js/blob/master/CODE_OF_CONDUCT.md" target="_blank" rel="external">Code of Conduct</a>, based on <a href="http://contributor-covenant.org" target="_blank" rel="external">Contributor Covenant</a> that applies to all Video.js projects.</p>
<h2 id="Conclusion"><a href="/Video-js-6-0-Release/#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><p>We are super excited for this release! Please take it for a spin from <code>next</code> tag on npm or from the <a href="http://vjs.zencdn.net/6.0.0/video.js" target="_blank" rel="external">CDN</a>. And please come chat with us on <a href="http://slack.videojs.com" target="_blank" rel="external">Slack</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;After months of hard work, I am proud to annouce the release of Video.js 6.0 🎉!&lt;/p&gt;
&lt;p&gt;This release is pretty exciting. It greatly &lt;a hr
    
    </summary>
    
    
      <category term="middleware" scheme="http://blog.videojs.com/tags/middleware/"/>
    
      <category term="video.js 6.0" scheme="http://blog.videojs.com/tags/video-js-6-0/"/>
    
      <category term="accessibility" scheme="http://blog.videojs.com/tags/accessibility/"/>
    
      <category term="a11y" scheme="http://blog.videojs.com/tags/a11y/"/>
    
      <category term="plugins" scheme="http://blog.videojs.com/tags/plugins/"/>
    
      <category term="Flash" scheme="http://blog.videojs.com/tags/Flash/"/>
    
      <category term="html5" scheme="http://blog.videojs.com/tags/html5/"/>
    
  </entry>
  
  <entry>
    <title>Feature Spotlight: Middleware</title>
    <link href="http://blog.videojs.com/Feature-Spotlight-Middleware/"/>
    <id>http://blog.videojs.com/Feature-Spotlight-Middleware/</id>
    <published>2017-03-27T15:04:41.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<p>Middleware is one of the cool new features that is coming to Video.js in version 6.0</p>
<p>With middleware, you are now able to interact with and change how the player and the tech talk to each other. The tech is Video.js’s abstraction from the player, separating the player API from the playback technology. With techs, we can plug things like a Flash fallback or a Youtube embed into Video.js without changing the external API or the look-and-feel of the player.</p>
<blockquote class="pullquote right"><p>Video.js middleware are like Express middleware but routes are based on video MIME types.</p>
</blockquote>
<p>A lot of Video.js users may be familiar with middleware from projects like Express. Video.js middleware isn’t that different from those. In both cases you register your middleware against a particular route to call down the chain when the route is triggered. In Express, routes are based on the url paths. In Video.js, these routes are based on the video MIME type. And, like Express, there are “star” (<code>*</code>) middleware that match all routes.</p>
<p>There are two important pieces to be aware of with middleware:</p>
<ol>
<li>dynamic source handling</li>
<li>intercepting the player and tech interactions.</li>
</ol>
<h2 id="A-Video-Catalog"><a href="/Feature-Spotlight-Middleware/#A-Video-Catalog" class="headerlink" title="A Video Catalog"></a>A Video Catalog</h2><p>With the dynamic source handling, you could load video with a custom type and source and resolve it asynchronously. A good example for this is a video catalog system. The page can be rendered with a specific catalog ID and a special MIME type, like so:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">video</span> <span class="attr">controls</span> <span class="attr">class</span>=<span class="string">"video-js"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">source</span> <span class="attr">src</span>=<span class="string">"123"</span> <span class="attr">type</span>=<span class="string">"video/my-catalog"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">video</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<p>Then, you could register a middleware for that route – the type <code>video/my-catalog</code>.<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// middleware methods get the player instance as an argument</span></span><br><span class="line">videojs.use(<span class="string">'video/my-catalog'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">player</span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// middleware are expected to return an object with the methods on it.</span></span><br><span class="line">  <span class="comment">// It can be a plain object or an instance of something.</span></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// setSource allows you to tell Video.js whether you're going to be handling the source or not</span></span><br><span class="line">    setSource(srcObj, next) &#123;</span><br><span class="line">      <span class="keyword">const</span> id = srcObj.src;</span><br><span class="line"></span><br><span class="line">      videojs.xhr(&#123;</span><br><span class="line">        uri: <span class="string">'/getVideo?id='</span> + id</span><br><span class="line">      &#125;, <span class="function"><span class="keyword">function</span>(<span class="params">err, res, body</span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// pass null as the first argument to say everything is going fine and we can handle it.</span></span><br><span class="line">        next(<span class="literal">null</span>, &#123;</span><br><span class="line">          src: body.sourceUrl,</span><br><span class="line">          type: body.sourceType</span><br><span class="line">        &#125;)</span><br><span class="line">      &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>Then, when Video.js initializes, it’ll go through and call the middleware that are set for <code>video/my-catalog</code>.</p>
<h2 id="Server-Side-Ad-Insertion"><a href="/Feature-Spotlight-Middleware/#Server-Side-Ad-Insertion" class="headerlink" title="Server-Side Ad Insertion"></a>Server-Side Ad Insertion</h2><p>Server Side Ad Insertion (SSAI) is a great fit for middleware. It showcases the ability to intercept the play and tech interactions. For example, you have a 30 seconds ad followed by a five minute video in your HLS manifest. You want the timeline to display the ad time and the content time appropriate when each is playing. Right now, the duration displayed will be the combined duration of five minutes and 30 seconds (<code>5:30</code>). The solution is to add a middleware that knows when the ad is being played and tells the player that the duration is 30 seconds and when the content is playing that the duration is five minutes.<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// register a star-middleware because HLS has two mimetypes</span></span><br><span class="line">videojs.use(<span class="string">'*'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">player</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    setSource(srcObj, next) &#123;</span><br><span class="line">      <span class="keyword">const</span> type = srcObj.type;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (type !== <span class="string">'application/x-mpegurl'</span> &amp;&amp; type !== <span class="string">'application/vnd.apple.mpegurl'</span>) &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// call next with an error to signal you cannot handle the source</span></span><br><span class="line">        next(<span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'Source is not an HLS source'</span>));</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">// in here we know we're playing back an HLS source.</span></span><br><span class="line">        <span class="comment">// We don't want to do anything special for it, so, pass along the source along with a null.</span></span><br><span class="line">        next(<span class="literal">null</span>, srcObj);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// this method gets called on the tech and then up the middleware chain providing the values as you go along</span></span><br><span class="line">    duration(durationFromTech) &#123;</span><br><span class="line">      <span class="keyword">if</span> (areWeCurrentlyPlayingAnAd(durationFromTech)) &#123;</span><br><span class="line">        <span class="comment">// since we're now in an ad, return the ad duration</span></span><br><span class="line">        <span class="comment">// in a real example you'd calculate this based on your playlist</span></span><br><span class="line">        <span class="comment">// rather than hardcode a value in here</span></span><br><span class="line">        <span class="keyword">return</span> <span class="number">30</span>;</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// we're playing back content, so, return that duration</span></span><br><span class="line">        <span class="keyword">return</span> <span class="number">5</span> * <span class="number">60</span>;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<h2 id="Playbackrate-Adjustment-A-Case-Study"><a href="/Feature-Spotlight-Middleware/#Playbackrate-Adjustment-A-Case-Study" class="headerlink" title="Playbackrate Adjustment - A Case Study"></a>Playbackrate Adjustment - A Case Study</h2><p>A simple but interesting middleware to look at is the <a href="https://github.com/videojs/videojs-playbackrate-adjuster" target="_blank" rel="external">playbackrate-adjuster</a>. This middleware will change the times of the controls depending on the current rate. For example, if you’re playing back a 20 minute video and change the rate to 2x, the controls will adjust to display 10 minutes. Let’s take a look at the code.<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">videojs.use(<span class="string">'*'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">player</span>) </span>&#123;</span><br><span class="line">  <span class="comment">/* ... */</span></span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    setSource(srcObj, next) &#123;</span><br><span class="line">      next(<span class="literal">null</span>, srcObj);</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    duration(dur) &#123;</span><br><span class="line">      <span class="keyword">return</span> dur / player.playbackRate();</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* ... */</span></span><br><span class="line">  &#125;;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>So, here, we attach a star-middleware because we want to have it applied to any video, regardless of the MIME type. In <code>setSource</code>, we also call <code>next</code> directly with <code>null</code> and the <code>srcObj</code> because we want to use this middleware with any and all sources. We also set up our <code>duration</code> method to take in the duration from the previous middleware and divide it by the playback rate we get from the player.</p>
<p>If you look at the <a href="https://github.com/videojs/videojs-playbackrate-adjuster/blob/master/src/js/index.js" target="_blank" rel="external">code</a> you can see some other methods next to duration. They’re there to make sure other methods that rely on timing get updated. The two methods to notice are <code>currentTime</code> and <code>setCurrentTime</code>. <code>currentTime</code> gets called when we want to know what the current time is. <code>setCurrentTime</code> is called when we’re seeking. Because the user is seeking in the shifted time, we want to apply our change operation in reverse. Instead of dividing it, we want to multiply it.<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">currentTime(ct) &#123;</span><br><span class="line">  <span class="keyword">return</span> ct / player.playbackRate();</span><br><span class="line">&#125;,</span><br><span class="line"></span><br><span class="line">setCurrentTime(ct) &#123;</span><br><span class="line">  <span class="keyword">return</span> ct * player.playbackRate();</span><br><span class="line">&#125;,</span><br></pre></td></tr></table></figure></p>
<p>If you were to apply what we’ve done so far, you’ll notice that the nothing changes, the control bar is still showing a duration of 20 minutes. This is because as far as Video.js knows, nothing has changed. So, we need to tell Video.js that the duration has changed. We can do that by storing the tech that Video.js gives us after source selection is complete.<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">videojs.use(<span class="string">'*'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">player</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> tech;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    setTech(newTech) &#123;</span><br><span class="line">      tech = newTech;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">/* ... */</span></span><br><span class="line">  &#125;;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>And then, when the <code>ratechange</code> event triggers, we tell Video.js that the duration has changed and Video.js will update the controls accordingly:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">videojs.use(<span class="string">'*'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">player</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">let</span> tech;</span><br><span class="line"></span><br><span class="line">  player.on(<span class="string">'ratechange'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    tech.trigger(<span class="string">'durationchange'</span>);</span><br><span class="line">    tech.trigger(<span class="string">'timeupdate'</span>);</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">   <span class="comment">/* ... */</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>You can see a <a href="https://videojs.github.io/videojs-playbackrate-adjuster/" target="_blank" rel="external">live example here</a> and the <a href="https://github.com/videojs/videojs-playbackrate-adjuster/blob/master/src/js/index.js" target="_blank" rel="external">complete code here</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Middleware is one of the cool new features that is coming to Video.js in version 6.0&lt;/p&gt;
&lt;p&gt;With middleware, you are now able to interact
    
    </summary>
    
    
      <category term="middleware" scheme="http://blog.videojs.com/tags/middleware/"/>
    
      <category term="video.js 6.0" scheme="http://blog.videojs.com/tags/video-js-6-0/"/>
    
  </entry>
  
  <entry>
    <title>Video.js removes Flash from core player</title>
    <link href="http://blog.videojs.com/Video-js-removes-Flash-from-core-player/"/>
    <id>http://blog.videojs.com/Video-js-removes-Flash-from-core-player/</id>
    <published>2017-02-08T19:17:21.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>In August of 2016, we <a href="http://blog.videojs.com/the-end-of-html-first/">announced</a> our intention of removing Flash as a part of the core Video.js project.<br>As Html5 video becomes the standard playback tech and Flash fades into obsolescence, it is time<br>to remove Flash from the core player and move it to a separate code base.  This will give us the ability<br>to allow developers to continue to support legacy browsers by adding the tech themselves, while allowing<br>us to minimize legacy code in Video.js and decrease the footprint of the player.</p>
<p>This follows in the footsteps of Chrome, Safari and Firefox which are all taking steps to deprecate Flash.</p>
<p>Chrome: <a href="https://blog.chromium.org/2016/12/roll-out-plan-for-html5-by-default.html" target="_blank" rel="external">Chrome 56 disables flash by default</a></p>
<p>Safari: <a href="https://webkit.org/blog/6589/next-steps-for-legacy-plug-ins/" target="_blank" rel="external">Safari makes Flash a legacy plugin</a></p>
<p>Firefox: <a href="https://blog.mozilla.org/futurereleases/2016/07/20/reducing-adobe-flash-usage-in-firefox/" target="_blank" rel="external">Reducing Adobe Flash Usage in Firefox</a></p>
<p>As of the Video.js 6.0 release, the dream of a Flashless future will come closer to a reality.</p>
<p>In the meantime, the separate <a href="https://github.com/videojs/videojs-flash" target="_blank" rel="external">videojs-flash</a> project has been created for Flash tech support.<br>When the <a href="https://github.com/videojs/videojs-flash" target="_blank" rel="external">videojs-flash</a> plugin is added to the player, the Flash tech is added to the tech order.</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"path/video.js/dist/video-js.css"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"path/video.js/dist/video.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"path/videojs-flash/dist/videojs-flash.js"</span>&gt;</span><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">video</span>  <span class="attr">id</span>=<span class="string">'vid'</span> <span class="attr">class</span>=<span class="string">'video-js'</span> <span class="attr">controls</span> <span class="attr">height</span>=<span class="string">300</span> <span class="attr">width</span>=<span class="string">600</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">source</span> <span class="attr">src</span>=<span class="string">"video.mp4"</span> <span class="attr">type</span>=<span class="string">"video/mp4"</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">video</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="tag">&lt;<span class="name">script</span>&gt;</span><span class="undefined"></span></span><br><span class="line"><span class="javascript">  <span class="keyword">var</span> player = videojs(<span class="string">'vid'</span>);</span></span><br><span class="line"><span class="undefined"></span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br></pre></td></tr></table></figure>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;In August of 2016, we &lt;a href=&quot;http://blog.videojs.com/the-end-of-html-first/&quot;&gt;announced&lt;/a&gt; our intention of removing Flash as a part of
    
    </summary>
    
    
      <category term="video.js 6.0" scheme="http://blog.videojs.com/tags/video-js-6-0/"/>
    
      <category term="Flash" scheme="http://blog.videojs.com/tags/Flash/"/>
    
      <category term="html5" scheme="http://blog.videojs.com/tags/html5/"/>
    
  </entry>
  
  <entry>
    <title>Feature Spotlight: Accessibility</title>
    <link href="http://blog.videojs.com/Feature-Spotlight-Accessibility/"/>
    <id>http://blog.videojs.com/Feature-Spotlight-Accessibility/</id>
    <published>2017-02-03T15:10:33.000Z</published>
    <updated>2019-01-18T19:57:55.569Z</updated>
    
    <content type="html"><![CDATA[<h3 id="Accessibility-The-most-important-feature-you-never-knew-about"><a href="/Feature-Spotlight-Accessibility/#Accessibility-The-most-important-feature-you-never-knew-about" class="headerlink" title="Accessibility! The most important feature you never knew about."></a>Accessibility! The most important feature you never knew about.</h3><p>In the Video.js organization we try hard to have good accessibility. Like most other software, any change can affect the system in unintended ways. For example <code>MuteToggle</code> and <code>VolumeControl</code> were married into <code>VolumeMenuButton</code> in Video.js 5. While this change did allow these controls to work in tandem visually, it also did something unintended. It broke accessibility. In this post we will go over what broke, what the fix was, what accessibility is, and how to test and make sure it works.</p>
<blockquote>
<p>Feel free to skip to the <a href="/Feature-Spotlight-Accessibility/#The-problem-and-the-solution">last section</a> if you already know what accessibility is.</p>
</blockquote>
<h3 id="Accessibility-What’s-that"><a href="/Feature-Spotlight-Accessibility/#Accessibility-What’s-that" class="headerlink" title="Accessibility? What’s that?"></a>Accessibility? What’s that?</h3><p>Accessible software has support for users with vision, hearing, movement/dexterity, or other impairments. It also helps users that want to use the keyboard to navigate. Out of the box web applications have some accessibility due to the nature of HTML, but this is only the case if you are using native elements in intended ways. If you cannot use native DOM elements, like <code>&lt;button&gt;</code>, and instead must use a <code>&lt;div&gt;</code> for buttons, then you need worry about accessibility in your page.</p>
<p>Supporting users with hearing impairment is not something that we can do directly for the users of Video.js. Instead we must indirectly support these users by adding support for captions in videos. In Video.js we have had support for captions and subtitles for some time, internally they are called <code>TextTracks</code>. In fact Video.js has had support for <code>WebVTT</code> format <code>TextTrack</code>, which is much more accessible, since version 4.</p>
<p>Supporting users with vision impairment is harder, but partly in our control. To support this group of users our player must be accessible to screen readers. A screen reader is an application that reads elements off of the screen to the user (as the name implies). On top of reading from the screen it also allows the user to interact with the page using only the keyboard or specific gestures on a touchscreen (without using a mouse or needing to directly touch visible items). HTML has certain rules that must be followed so that a page can be accessible. We will go over the basics of these rules in the next section. Screen readers are further supported by having description tracks that can be read out during video playback. Description tracks are a sub-type of <code>TextTrack</code>, and as previously stated we cannot automatically add them to videos, we can only have support for them in the Video.js.</p>
<p>See the <a href="/Feature-Spotlight-Accessibility/#resources">resources section at the end of this post</a> for a list of screen readers.</p>
<h3 id="How-do-you-make-a-web-application-screen-reader-accessible"><a href="/Feature-Spotlight-Accessibility/#How-do-you-make-a-web-application-screen-reader-accessible" class="headerlink" title="How do you make a web application screen reader accessible?"></a>How do you make a web application screen reader accessible?</h3><p>If you use the native elements for the purposes that they were intended, you will already have most of the work done.This is why the use of the native element is the recommended way to make anything accessible for a screen reader. For instance if you use a <code>&lt;button&gt;</code> element you will get the following accessibility attributes (without them actually being on the button):</p>
<ul>
<li><code>tabIndex</code> which allows users to tab to the button</li>
<li><code>role=&quot;button&quot;</code> which tells the screen reader that this is a button</li>
<li>The space and the enter key will both press the button</li>
</ul>
<p>In some cases, such as in Video.js, it will not be possible to use the native <code>&lt;button&gt;</code> element. You will have to mimic the accessible functionality from the list above and use a <code>div</code>. Here is a list of what you will have to add:</p>
<ul>
<li>You have to add the <code>role=&quot;button&quot;</code> attribute to classify it as a button.</li>
<li>You have to add a <code>tabIndex</code> which will allow the <code>div</code> to be navigated to using the <code>tab</code> key</li>
<li>You have to add handling for the space and enter key that press the button</li>
</ul>
<blockquote class="pullquote right"><p>A list of <code>role</code> attribute values can be found on <a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques#Composite_roles" target="_blank" rel="external">Mozilla Developer Network</a>.</p>
</blockquote>
<p>After mimicking or adding native accessibility on the controls and content in your webpage, the next thing to look over are <code>aria</code> attributes. For instance, we use <code>aria-live=&quot;polite&quot;</code> for our <code>ProgressBar</code> slider. By default <code>aria-live</code> is set <code>off</code>, which means updates to controls should not be read to the user unless they un-focus and re-focus an element. The value of <code>polite</code> which we use allows us to convey the position of the slider to screen reader without them having to change focus on the control. This is useful because the <code>ProgressBar</code> is always updating while a video is playing. A value of <code>polite</code> will also wait to convey said updates until the screen reader is done reading other information to the user.</p>
<blockquote class="pullquote right"><p>For a more complete list of <a href="https://www.w3.org/TR/wai-aria-1.1/" target="_blank" rel="external">ARIA attributes see the specification</a>.</p>
</blockquote>
<p>Finally you need to add an accessible “name” to an element so that it can be referred to. A good example of this is can be seen in the <code>MuteToggle</code> control. Since it is not a simple “button” we include <code>innerHTML</code>/<code>innerText</code> of “Mute” or “Unmute” in a way that is hidden from most users but announced to screen readers. In Video.js we refer to the accessible name and the action that a control performs as “control text”. Control text also updates the <code>title</code> attribute of an element in most cases, which is important for visual accessibility. When the action the a control performs changes so does the control text. This will allow the screen reader to refer to the <code>MuteToggle</code> as “Mute Toggle” rather than “button”. It will also convey the current action of the <code>MuteToggle</code>. In this case that will be either “Mute” or “Unmute” depending on what the button would do when pressed (ie the state of the button).</p>
<p>Here are some examples of accessibility straight from Video.js:</p>
<ul>
<li>The <code>MuteToggle</code> <code>&lt;button&gt;</code>:<ul>
<li>Has <code>aria-live</code> set to <code>polite</code>, rather than the default value of <code>off</code>. <code>aria-live</code> with any value other than <code>off</code> indicates that <code>innerText</code>/<code>innerHTML</code> updates can be sent to the screen reader without the user needing to move focus off of the control. The value of <code>polite</code> means that the screen reader should wait until it is done speaking to convey these updates to the user.</li>
<li>Has control text of “Mute” or “Unmute” which indicates the current status of the button to the use</li>
</ul>
</li>
<li>The <code>VolumeBar</code> slider <code>&lt;div&gt;</code>:<ul>
<li>Has a <code>role</code> attribute with a value of <code>slider</code>. Like this: <code>role=&quot;slider&quot;</code></li>
<li>Has a <code>tabIndex</code> attribute as it is not a native control element</li>
<li>Has <code>EventHandlers</code> that listen for:<ul>
<li>The up and right arrow keys to increase the volume and the slider percentage</li>
<li>The down and left arrow keys to decrease the volume and the slider percentage</li>
</ul>
</li>
<li>Has <code>aria-label</code> of “volume level” which is an accessible label that the screen reader will use to refer to it</li>
<li>Has <code>aria-valuenow</code> and <code>aria-valuetext</code> properties that update to indicate the current volume level (so the screen reader can read it)</li>
<li>Has <code>aria-live</code> set to <code>polite</code>, rather than the default value of <code>off</code>. <code>aria-live</code> with any value other than <code>off</code> indicates that <code>innerText</code>/<code>innerHTML</code> updates can be sent to the screen reader without the user needing to move focus off of the control. The value of <code>polite</code> means that the screen reader should wait until it is done speaking to convey these updates to the user.</li>
</ul>
</li>
</ul>
<h3 id="The-problem-and-the-solution"><a href="/Feature-Spotlight-Accessibility/#The-problem-and-the-solution" class="headerlink" title="The problem and the solution"></a>The problem and the solution</h3><p>Now let’s talk about how screen reader accessibility broke in Video.js 5. First <code>VolumeMenuButton</code> replaced <code>MuteToggle</code> and <code>VolumeControl</code> on the <code>ControlBar</code>. <code>VolumeMenuButton</code> was set to mimic <code>MuteToggle</code> when clicked. It would also show the <code>VolumeControl</code> on mouseover or focus. This was a problem because a <code>VolumeControl</code> was a now a child of a button, and buttons should not contain other controls. To the screen reader and to the DOM there are two <code>MuteToggle button</code> controls. When visually there is a <code>VolumeControl</code> and a <code>MuteToggle</code>. Below you can see a gif of this behavior in action :</p>
<p><img src="/Feature-Spotlight-Accessibility/before-the-fix.gif" alt="macOS `VoiceOver` Before The Fix"></p>
<p>The solution to this problem was to use a regular <code>div</code> to house the <code>MuteToggle</code> and <code>VolumeControl</code>. This regular <code>div</code> would have no role or control text so that it would be invisible to a screen reader. From that point forward we just needed to mimic the old UI. For those who are wondering, this new <code>Component</code> is called the <code>VolumePanel</code>. See the new behavior in a gif below:</p>
<p><img src="/Feature-Spotlight-Accessibility/after-the-fix.gif" alt="macOS `VoiceOver` After The Fix"></p>
<h3 id="Outlines"><a href="/Feature-Spotlight-Accessibility/#Outlines" class="headerlink" title="Outlines"></a>Outlines</h3><p>Another big accessibility fix for controls comes from the removal of one small css rule:</p>
<figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-tag">outline</span>: <span class="selector-tag">none</span>;</span><br></pre></td></tr></table></figure>
<p>Why did we do it? With feedback from the community and <a href="http://www.outlinenone.com/" target="_blank" rel="external">external resources</a>, we learned that outlines should always be on. Without outlines there is no visual indication of keyboard focus on control elements and without that, keyboard users who are not visually impaired have a hard time using the controls.</p>
<h3 id="Wrap-up"><a href="/Feature-Spotlight-Accessibility/#Wrap-up" class="headerlink" title="Wrap up"></a>Wrap up</h3><p>Hopefully this post has given you some insight into making a web application accessible. If you find any issues or have any suggestions for our accessibility or in general feel free to <a href="https://github.com/videojs/video.js/blob/master/CONTRIBUTING.md" target="_blank" rel="external">contribute to Video.js</a>.</p>
<p>If you want to keep up to date on the current state of accessibility work see the a11y label on <a href="https://github.com/videojs/video.js/pulls?q=is%3Apr+is%3Aopen+label%3Aa11y" target="_blank" rel="external">PRs</a> and <a href="https://github.com/videojs/video.js/issues?q=is%3Aissue+is%3Aopen+label%3Aa11y" target="_blank" rel="external">issues</a>.</p>
<h3 id="Resources"><a href="/Feature-Spotlight-Accessibility/#Resources" class="headerlink" title="Resources"></a>Resources</h3><p>Here are some popular screen readers that are actually used in the wild:</p>
<ul>
<li><a href="http://www.apple.com/accessibility/mac/vision/" target="_blank" rel="external">VoiceOver for macOS</a></li>
<li><a href="https://www.freedomscientific.com/Downloads/JAWS" target="_blank" rel="external">JAWS for Windows</a></li>
<li><a href="http://www.nvaccess.org/" target="_blank" rel="external">NVDA for Windows</a></li>
</ul>
<p>Resources for learning more about web accessibility:</p>
<ul>
<li><a href="http://webaim.org/" target="_blank" rel="external">WebAIM</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/Accessibility" target="_blank" rel="external">Mozilla Developer Network</a></li>
<li><a href="http://www.outlinenone.com/" target="_blank" rel="external">Outline None</a></li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;h3 id=&quot;Accessibility-The-most-important-feature-you-never-knew-about&quot;&gt;&lt;a href=&quot;/Feature-Spotlight-Accessibility/#Accessibility-The-most-imp
    
    </summary>
    
    
      <category term="video.js 6.0" scheme="http://blog.videojs.com/tags/video-js-6-0/"/>
    
      <category term="accessibility" scheme="http://blog.videojs.com/tags/accessibility/"/>
    
      <category term="a11y" scheme="http://blog.videojs.com/tags/a11y/"/>
    
  </entry>
  
  <entry>
    <title>Feature Spotlight: Advanced Plugins</title>
    <link href="http://blog.videojs.com/Feature-Spotlight-Advanced-Plugins/"/>
    <id>http://blog.videojs.com/Feature-Spotlight-Advanced-Plugins/</id>
    <published>2017-01-26T14:41:32.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<blockquote class="pullquote right"><p><strong>Note:</strong> Advanced plugins are being introduced in Video.js 6.0 and are only supported from that version forward.</p>
</blockquote>
<p>If you’ve been a Video.js user for a while, you’re likely familiar with the concept of plugins: functions that become methods of any player you create. If you’re not familiar with Video.js plugins, we have a comprehensive <a href="http://docs.videojs.com/docs/guides/plugins.html" target="_blank" rel="external">plugins guide</a> available.</p>
<p>These plugins - which we’ll call <em>basic plugins</em> - are lightweight and offer complete control of the player. That’s really useful and <strong>it isn’t changing</strong> - existing plugins should continue to work!</p>
<p>But what if you want a richer set of features? Or more guidance on how to structure your plugin? Or more tools out of the box that help manage complex plugin-rich players?</p>
<p>Well, until Video.js 6.0, you had to figure things out on your own.</p>
<h2 id="Introducing-Advanced-Plugins"><a href="/Feature-Spotlight-Advanced-Plugins/#Introducing-Advanced-Plugins" class="headerlink" title="Introducing Advanced Plugins"></a>Introducing Advanced Plugins</h2><p>One of Video.js’ strengths is its rich ecosystem of plugins; so, in the last few months, we wanted to focus our efforts on improving the plugin author experience.</p>
<p>While projects like <a href="https://github.com/videojs/generator-videojs-plugin" target="_blank" rel="external">the plugin generator</a> and <a href="https://github.com/videojs/spellbook" target="_blank" rel="external">videojs-spellbook</a> make becoming a plugin author easier than ever, the Video.js team thought it was important to provide a foundational API and set of conventions on which the future of Video.js plugins could be built.</p>
<p>Our solution is <em>advanced plugins</em>.</p>
<h3 id="Advanced-Plugins-are-Component-Like"><a href="/Feature-Spotlight-Advanced-Plugins/#Advanced-Plugins-are-Component-Like" class="headerlink" title="Advanced Plugins are Component-Like"></a>Advanced Plugins are Component-Like</h3><p>One of the design goals for advanced plugins was to provide an API that was reminiscent of the existing components system. We achieved this in a number of ways. </p>
<p>At the lowest level, this included a name change for the plugin registration function from <code>videojs.plugin</code> to <code>videojs.registerPlugin</code> (taking a naming cue from <code>videojs.registerComponent</code> and <code>videojs.registerTech</code>).</p>
<p>Beyond a simple registration method name change, advanced plugins are <em>class-based</em>. A trivial example of an advanced plugin might look something like this:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> Plugin = videojs.getPlugin(<span class="string">'plugin'</span>);</span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">HelloWorld</span> <span class="keyword">extends</span> <span class="title">Plugin</span> </span>&#123;</span><br><span class="line">  <span class="keyword">constructor</span>(player) &#123;</span><br><span class="line">    <span class="keyword">super</span>(player);</span><br><span class="line">    <span class="keyword">this</span>.player.addClass(<span class="string">'hello-world'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">videojs.registerPlugin(<span class="string">'helloWorld'</span>, HelloWorld);</span><br></pre></td></tr></table></figure>
<p>This plugin can be initialized in the same way as a basic plugin - via a player method whose name matches the registered name of the plugin.</p>
<p>In the case of advanced plugins, this method is a factory function, which instantiates the plugin class and returns an instance.</p>
<p>It’s useful to know that the player method that is created will <em>always</em> be a function. If a player already has an instance of an advanced plugin, its associated method will simply return the pre-existing instance rather than re-initialize it:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> player = videojs(<span class="string">'my-player'</span>);</span><br><span class="line"><span class="keyword">const</span> instance = player.helloWorld();</span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'true'</span></span><br><span class="line">videojs.log(instance === player.helloWorld());</span><br></pre></td></tr></table></figure>
<p>The <code>helloWorld</code> method will return this plugin object until it is disposed - after which it will create a new plugin instance again.</p>
<h3 id="Events"><a href="/Feature-Spotlight-Advanced-Plugins/#Events" class="headerlink" title="Events"></a>Events</h3><p>Similar to components, advanced plugins can listen to and trigger events via the <code>on</code>, <code>one</code>, <code>off</code>, and <code>trigger</code> methods.</p>
<p>This provides a loosely coupled communication channel for plugins and other objects (components, players, etc) to manage their own state and respond to changes in the state of one another.</p>
<h4 id="Additional-Event-Data"><a href="/Feature-Spotlight-Advanced-Plugins/#Additional-Event-Data" class="headerlink" title="Additional Event Data"></a>Additional Event Data</h4><p>The Video.js event system allows additional data to be passed to listeners as a <em>second argument</em> when triggering events (the first argument is the event object itself).</p>
<p>Plugin events pass a consistent set of properties in this object (including any custom properties passed to <code>trigger</code>):</p>
<ul>
<li><code>instance</code>: The plugin instance, which triggered the event.</li>
<li><code>name</code>: The name of the plugin as a string (e.g. <code>&#39;helloWorld&#39;</code>).</li>
<li><code>plugin</code>: The plugin class/constructor function (e.g. <code>HelloWorld</code>).</li>
</ul>
<p>For example, a listener for an event on a plugin can expect something like this:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> player = videojs(<span class="string">'my-player'</span>);</span><br><span class="line"><span class="keyword">const</span> instance = player.helloWorld();</span><br><span class="line"></span><br><span class="line">instance.on(<span class="string">'some-custom-event'</span>, (e, data) =&gt; &#123;</span><br><span class="line">  videojs.log(data.instance === instance); <span class="comment">// true</span></span><br><span class="line">  videojs.log(data.name === <span class="string">'helloWorld'</span>); <span class="comment">// true</span></span><br><span class="line">  videojs.log(data.plugin === videojs.getPlugin(<span class="string">'helloWorld'</span>)); <span class="comment">// true</span></span><br><span class="line">  videojs.log(data.foo); <span class="comment">// "bar"</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">instance.trigger(<span class="string">'some-custom-event'</span>, &#123;<span class="attr">foo</span>: <span class="string">'bar'</span>&#125;);</span><br></pre></td></tr></table></figure>
<h3 id="Lifecycle"><a href="/Feature-Spotlight-Advanced-Plugins/#Lifecycle" class="headerlink" title="Lifecycle"></a>Lifecycle</h3><p>Another similarity between plugins and components is the concept of a lifecycle - more specifically, setup and teardown processes.</p>
<p>We get the setup feature as a side effect of normal object creation in JavaScript, but we are left to our own devices when it comes to object destruction and ensuring that references between objects are cleaned up to avoid leaking memory.</p>
<p>Video.js components have long had a <code>dispose</code> method and event that deal with removing a component from the DOM and memory. Advanced plugins have the same feature:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> player = videojs(<span class="string">'my-player'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> firstInstance = player.helloWorld();</span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'true'</span></span><br><span class="line">videojs.log(firstInstance === player.helloWorld());</span><br><span class="line"></span><br><span class="line">firstInstance.on(<span class="string">'dispose'</span>, () =&gt; videojs.log(<span class="string">'disposing a helloWorld instance'</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'disposing a helloWorld instance'</span></span><br><span class="line">firstInstance.dispose();</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> secondInstance = player.helloWorld(); </span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'false'</span></span><br><span class="line">videojs.log(firstInstance === secondInstance);</span><br></pre></td></tr></table></figure>
<h4 id="The-pluginsetup-Event"><a href="/Feature-Spotlight-Advanced-Plugins/#The-pluginsetup-Event" class="headerlink" title="The pluginsetup Event"></a>The <code>pluginsetup</code> Event</h4><p>Plugins do have one lifecycle feature that components do not: the <code>pluginsetup</code> event.</p>
<p>This event is triggered on a player when a plugin is initialized on it:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> player = videojs(<span class="string">'my-player'</span>);</span><br><span class="line"></span><br><span class="line">player.on(<span class="string">'pluginsetup'</span>, (e, hash) =&gt; &#123;</span><br><span class="line">  <span class="keyword">if</span> (hash.name === <span class="string">'helloWorld'</span>) &#123;</span><br><span class="line">    videojs.log(<span class="string">'A helloWorld instance was created!'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'A helloWorld instance was created!'</span></span><br><span class="line">player.helloWorld();</span><br></pre></td></tr></table></figure>
<h3 id="React-inspired-Statefulness"><a href="/Feature-Spotlight-Advanced-Plugins/#React-inspired-Statefulness" class="headerlink" title="React-inspired Statefulness"></a>React-inspired Statefulness</h3><p>One of the exciting additions in Video.js for both advanced plugins and components is React-inspired statefulness. Essentially, this means that all plugin objects and component objects have a <code>state</code> property, which is a plain object that can be used to store variable state for that object. Then, there is a <code>setState</code> method that updates this object and triggers a <code>statechanged</code> event.</p>
<p>This system allows plugins and components to use their evented nature to communicate in-memory state changes through a consistent API:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// A static property of the constructor can be used to pre-populate state </span></span><br><span class="line"><span class="comment">// for all instances.</span></span><br><span class="line">HelloWorld.defaultState = &#123;<span class="attr">color</span>: <span class="string">'red'</span>&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">const</span> player = videojs(<span class="string">'my-player'</span>);</span><br><span class="line"><span class="keyword">const</span> instance = player.helloWorld();</span><br><span class="line"></span><br><span class="line">instance.on(<span class="string">'statechanged'</span>, (e) =&gt; &#123;</span><br><span class="line">  <span class="keyword">const</span> &#123;color&#125; = e.changes;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (color) &#123;</span><br><span class="line">    videojs.log(<span class="string">`The helloWorld color changed from "<span class="subst">$&#123;color.<span class="keyword">from</span>&#125;</span>" to "<span class="subst">$&#123;color.to&#125;</span>"!`</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'The helloWorld color changed from "red" to "blue"!'</span></span><br><span class="line">instance.setState(&#123;<span class="attr">color</span>: <span class="string">'blue'</span>&#125;);</span><br></pre></td></tr></table></figure>
<h2 id="Player-Plugin-Awareness"><a href="/Feature-Spotlight-Advanced-Plugins/#Player-Plugin-Awareness" class="headerlink" title="Player Plugin Awareness"></a>Player Plugin Awareness</h2><p>Finally, we couldn’t add new plugin infrastructure without working on one of the more pernicious problems of managing complex combinations of plugins: the player can’t report which plugins it has initialized - or not. To this end, the player has two new methods: <code>hasPlugin</code> and <code>usingPlugin</code>. These methods work for <em>both</em> types of plugins.</p>
<h3 id="The-hasPlugin-Method"><a href="/Feature-Spotlight-Advanced-Plugins/#The-hasPlugin-Method" class="headerlink" title="The hasPlugin Method"></a>The <code>hasPlugin</code> Method</h3><p>This method reports whether a plugin matching a given name is available on the player:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> player = videojs(<span class="string">'my-player'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'true'</span></span><br><span class="line">videojs.log(player.hasPlugin(<span class="string">'helloWorld'</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'false'</span></span><br><span class="line">videojs.log(player.hasPlugin(<span class="string">'fooBar'</span>));</span><br></pre></td></tr></table></figure>
<p>This method ignores whether or not the plugin has been initialized and merely reports whether or not it has been registered.</p>
<h3 id="The-usingPlugin-Method"><a href="/Feature-Spotlight-Advanced-Plugins/#The-usingPlugin-Method" class="headerlink" title="The usingPlugin Method"></a>The <code>usingPlugin</code> Method</h3><p>This method reports not only whether a plugin is available on a player, but whether it is currently active on the player:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">const</span> player = videojs(<span class="string">'my-player'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'false'</span></span><br><span class="line">videojs.log(player.usingPlugin(<span class="string">'helloWorld'</span>));</span><br><span class="line"></span><br><span class="line">player.helloWorld();</span><br><span class="line"></span><br><span class="line"><span class="comment">// Logs: 'true'</span></span><br><span class="line">videojs.log(player.usingPlugin(<span class="string">'helloWorld'</span>));</span><br></pre></td></tr></table></figure>
<p>One caveat to note here. While this works for both types of plugins, only advanced plugins can change this value more than once. A basic plugin has no built-in lifecycle or events; so, it’s not possible to determine whether one has been “disposed”.</p>
<h2 id="Go-Forth-and-Code"><a href="/Feature-Spotlight-Advanced-Plugins/#Go-Forth-and-Code" class="headerlink" title="Go Forth and Code"></a>Go Forth and Code</h2><p>We hope these additions and improvements to the plugin architecture will make writing Video.js plugins more pleasurable and remove some of the low-level legwork involved in ensuring plugins aren’t creating memory leaks and other problems.</p>
<p>The design of advanced plugins is such that we can add features as 6.0 matures and we get more community feedback. As always, we strongly encourage our users <a href="https://github.com/videojs/video.js/blob/master/CONTRIBUTING.md" target="_blank" rel="external">to give back to the Video.js project</a> in whatever way they can.</p>
<p>For a more complete discussion of plugins generally, visit the <a href="http://docs.videojs.com/docs/guides/plugins.html" target="_blank" rel="external">Video.js plugins guide</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;blockquote class=&quot;pullquote right&quot;&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Advanced plugins are being introduced in Video.js 6.0 and are only supported f
    
    </summary>
    
    
      <category term="video.js 6.0" scheme="http://blog.videojs.com/tags/video-js-6-0/"/>
    
      <category term="plugins" scheme="http://blog.videojs.com/tags/plugins/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 6.0.0-RC.0: The first Release Candidate</title>
    <link href="http://blog.videojs.com/Video-js-6-0-0-RC-0-The-first-RC/"/>
    <id>http://blog.videojs.com/Video-js-6-0-0-RC-0-The-first-RC/</id>
    <published>2017-01-23T16:59:11.000Z</published>
    <updated>2019-01-18T19:57:55.598Z</updated>
    
    <content type="html"><![CDATA[<h2 id="The-first-Release-Candidate-for-6-0-has-been-released"><a href="/Video-js-6-0-0-RC-0-The-first-RC/#The-first-Release-Candidate-for-6-0-has-been-released" class="headerlink" title="The first Release Candidate for 6.0 has been released"></a>The first Release Candidate for 6.0 has been released</h2><p>Last week, we began wrapping up months of effort to make Video.js even better with the first Release Candidate (RC) of Video.js 6.0. In order to make it better, however, we had to make a <a href="https://github.com/videojs/video.js/compare/v5.16.0...v6.0.0-RC.0" target="_blank" rel="external">few breaking changes</a> and we also made a lot of improvements under the hood.</p>
<h2 id="How-to-try-it-out"><a href="/Video-js-6-0-0-RC-0-The-first-RC/#How-to-try-it-out" class="headerlink" title="How to try it out"></a>How to try it out</h2><p>The RC is now published on npm under the <code>beta</code> tag with verion <code>6.0.0-RC.0</code>.</p>
<figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm install video.js@beta</span><br></pre></td></tr></table></figure>
<p>Please try it out and let us know how it is on <a href="https://github.com/videojs/video.js/issues" target="_blank" rel="external">GitHub</a>.</p>
<h2 id="What-to-look-forward-to"><a href="/Video-js-6-0-0-RC-0-The-first-RC/#What-to-look-forward-to" class="headerlink" title="What to look forward to"></a>What to look forward to</h2><ul>
<li>We’re finally removing Flash from core as outlined in <a href="http://blog.videojs.com/the-end-of-html-first/">a previous post</a>.</li>
<li>Plugins are being updated to a React-inspired component architecture. The old style is staying around.</li>
<li>We’re recommitting to accessiblity by fixing the accessibilty of our volume control and bringing back outlines!</li>
<li>Middleware. A brand new feature to interface between Video.js’s techs and the player.</li>
</ul>
<h2 id="Feature-Spotlights"><a href="/Video-js-6-0-0-RC-0-The-first-RC/#Feature-Spotlights" class="headerlink" title="Feature Spotlights"></a>Feature Spotlights</h2><p>Over the coming weeks, we’ll post feature spotlights talking about the big things that are happening.<br>We might also revisit some old features.</p>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;The-first-Release-Candidate-for-6-0-has-been-released&quot;&gt;&lt;a href=&quot;/Video-js-6-0-0-RC-0-The-first-RC/#The-first-Release-Candidate-for-6
    
    </summary>
    
    
      <category term="video.js 6.0" scheme="http://blog.videojs.com/tags/video-js-6-0/"/>
    
  </entry>
  
  <entry>
    <title>Introducing Thumbcoil</title>
    <link href="http://blog.videojs.com/Introducing-Thumbcoil/"/>
    <id>http://blog.videojs.com/Introducing-Thumbcoil/</id>
    <published>2016-10-19T16:47:37.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<blockquote class="pullquote right"><p>A <strong>transmuxer</strong> takes media contained in some file format, extracts the raw compressed video and audio from inside (a process called demuxing) and repackages the compressed data  into another format (termed remuxing) without performing any re-compression.</p>
</blockquote>
<h2 id="In-the-Beginning"><a href="/Introducing-Thumbcoil/#In-the-Beginning" class="headerlink" title="In the Beginning"></a>In the Beginning</h2><p>While building <a href="https://github.com/videojs/mux.js" target="_blank" rel="external">Mux.js</a> - the transmuxer at the heart of <a href="https://github.com/videojs/videojs-contrib-hls" target="_blank" rel="external">videojs-contrib-hls</a> - we faced a problem: How do we determine if the output from Mux.js is correct?</p>
<p>Early on we managed to figure out how to coax FFmpeg into creating <a href="https://en.wikipedia.org/wiki/MPEG-4_Part_14" target="_blank" rel="external">MP4s</a> from <a href="https://en.wikipedia.org/wiki/MPEG_transport_stream" target="_blank" rel="external">MPEG2-TS</a> segments that would play back in a browser with <a href="https://en.wikipedia.org/wiki/Media_Source_Extensions" target="_blank" rel="external">Media Source Extensions</a> (MSE) which at the time meant only Chrome. However, we needed a simple way to compare the output of our transmuxer with what was produced by FFmpeg. The comparison had to be aware of the MP4 format since the two outputs are extremely unlikely to be byte-identical.</p>
<blockquote class="pullquote left"><p>MP4 files are composed of <strong>boxes</strong> - hierarchical logical units that, conveniently, all start with a 32-bit length and a 32-bit box-type. Boxes will often contain other sub-boxes.</p>
</blockquote>
<p>The answer to that problem was to build an “mp4-inspector” - a tool that would parse MP4 and display a sort of JSON-like dump of any relevant boxes and their contents. By generating a dump of the output from Mux.js and comparing it to a known-good fragment generated with FFmpeg, we could see where our transmuxer’s output differed.</p>
<p>The “mp4-inspector” was built as a web page so that we can have a graphical color-coded diff of the two segments. Over time the page gained a video element and we started appending the results of transmuxing segments directly into the video element’s MediaSource to aid in instant feedback and validation of changes to Mux.js.</p>
<h2 id="A-Brave-New-World"><a href="/Introducing-Thumbcoil/#A-Brave-New-World" class="headerlink" title="A Brave New World"></a>A Brave New World</h2><blockquote class="pullquote right"><p>A <strong>media container</strong> such as MP4 encapsulates the video and audio stream. It has metadata describing the streams, timing information for each frame, and the stream data itself.</p>
</blockquote>
<p>As development continued, we would sometimes encounter streams that would fail in new and interesting ways. Some of these failures were, admittedly, due to bugs in Mux.js. As Mux.js itself became more robust, failures were increasingly caused by problems with the streams or issues with a particular implementation of the <a href="http://www.w3.org/TR/2014/CR-media-source-20140717/" target="_blank" rel="external">MSE specification</a>.</p>
<p>It eventually dawned on us that we really needed to learn more about what was happening inside of those videos. We needed to see not just what was happening at the media container level but we had to go deeper - we needed to peek into the video data itself. For that purpose we created <a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a>.</p>
<blockquote class="pullquote left"><p>Inside of a container, video and audio are contained in data called <strong>bitstreams</strong>. Bitstreams are the data produced by encoders to represent the audio signals or video frames. Some common bitstreams are <a href="https://en.wikipedia.org/wiki/Advanced_Audio_Coding" target="_blank" rel="external">AAC</a> for audio and <a href="https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC" target="_blank" rel="external">H.264</a> for video.</p>
</blockquote>
<h2 id="Thumbcoil"><a href="/Introducing-Thumbcoil/#Thumbcoil" class="headerlink" title="Thumbcoil"></a>Thumbcoil</h2><p><a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a> is a suite of tools designed to give you a peek into the internals of H.264 video bitstreams contained inside either an MP4 or MPEG2-TS container file. Using the tools in <a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a> you can get a detailed view of the internal structure of the two supported media container formats.</p>
<p>In addition, the tools have the ability to show you the information contained within the most important NAL-units that make up the H.264 bitstream. Ever wonder what kind of secret information the video encoder has squirreled away for decoders to use? Now, with <a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a>, you can finally see for yourself!</p>
<h2 id="Motivation"><a href="/Introducing-Thumbcoil/#Motivation" class="headerlink" title="Motivation"></a>Motivation</h2><blockquote class="pullquote right"><p>An H.264 encoded bitstream is composed of what are called <strong>NAL</strong>, or network abstraction layer, units. NALs are a simple packet format designed to use bits as efficiently as possible.</p>
</blockquote>
<p>Believe it or not, there are very few good tools to generate a somewhat graphical display of the structure of media containers and the data that they contain. Debugging problems with video playback is usually a tedious task involving various esoteric <em>FFmpeg</em> and <em>FFprobe</em> incantations. Unfortunately at it’s best, <em>FFprobe</em> is only able to print out a small portion of the data we were interested in.</p>
<p>The exact data inside of the various parameter sets for instance is not available via the command-line. Inside of FFprobe, that data is parsed and stored but there is no easy way to dump that information in a human readable form.</p>
<blockquote class="pullquote left"><p>In H.264, there are two special types of NAL-units - the SPS or <strong>seq_parameter_set</strong> and the PPS or <strong>pic_parameter_set</strong>. These two NAL units contain a lot of information. The decoders require this information to reconstruct the video.</p>
</blockquote>
<p><a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a> not only provides parameter set information in excruciating detail but also keeps the information with its surrounding context - the boxes it was contained by or the frame it was specified along with. This context is often very important to understanding issues or peculiarities in streams.</p>
<h2 id="Built-Upon-Fancy-Stuff"><a href="/Introducing-Thumbcoil/#Built-Upon-Fancy-Stuff" class="headerlink" title="Built Upon Fancy Stuff"></a>Built Upon Fancy Stuff</h2><p>One of the more interesting things about how <a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a> parses parameter sets is that is builds what is internally called a “codec” for each NAL unit type. These codecs are specified using what is essentially a fancy <a href="https://en.wikipedia.org/wiki/Parser_combinator" target="_blank" rel="external">parser combinator</a>-type setup.</p>
<blockquote class="pullquote right"><p>Much of the data in the two parameter sets are stored using a method called <a href="https://en.wikipedia.org/wiki/Exponential-Golomb_coding" target="_blank" rel="external"><strong>exponential-golomb encoding.</strong></a> This method uses a variable number of bits to store numbers and is particularly suited to values that tends to be small.</p>
</blockquote>
<p>Each function used to build the codec returns an object with two functions: <em>decode</em> and <em>encode</em>. This means that we can specify the format of, say, a seq_parameter_set NAL unit just once and then we can both parse from and write to the bitstream for that particular NAL unit.</p>
<p>The “grammar” used to specify NAL unit codecs is very similar to the grammar used by the H.264 specification (ISO/IEC 14496-10). The data-types that the codecs in <a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a> understand are, with some extensions, merely the same types defined in the specification such as signed- and unsigned- exponential golomb encoded integers.</p>
<p>In addition to the parameter sets, <a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a> provides insight into the structure of the slice layers themselves by parsing the slice_header data though we stop short of parsing any of the actual slice_data because things quickly become more difficult and less useful as you descend into that madness.</p>
<h2 id="But-what-is-the-deal-with-the-name"><a href="/Introducing-Thumbcoil/#But-what-is-the-deal-with-the-name" class="headerlink" title="But what is the deal with the name?"></a>But what is the deal with the name?</h2><p>“<a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a>“ doesn’t mean anything, really. It’s an inside joke that is funny to exactly 3 people in the world - myself included. The odd name does have one benefit in that it makes for a short and easy to remember domain-name: <a href="http://thumb.co.il" target="_blank" rel="external">thumb.co.il</a>.</p>
<p>As with all Video.js projects, <a href="http://thumb.co.il" target="_blank" rel="external">Thumbcoil</a> is open-source software and we welcome suggestions, issues, and contributions at <a href="https://github.com/videojs/thumbcoil" target="_blank" rel="external">https://github.com/videojs/thumbcoil</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;blockquote class=&quot;pullquote right&quot;&gt;&lt;p&gt;A &lt;strong&gt;transmuxer&lt;/strong&gt; takes media contained in some file format, extracts the raw compressed 
    
    </summary>
    
    
      <category term="thumbcoil" scheme="http://blog.videojs.com/tags/thumbcoil/"/>
    
      <category term="mse" scheme="http://blog.videojs.com/tags/mse/"/>
    
      <category term="hls" scheme="http://blog.videojs.com/tags/hls/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 5.12.0 and 5.11.5 releases</title>
    <link href="http://blog.videojs.com/Video-js-5-12-0-and-5-11-5-releases/"/>
    <id>http://blog.videojs.com/Video-js-5-12-0-and-5-11-5-releases/</id>
    <published>2016-08-25T19:28:03.000Z</published>
    <updated>2019-01-18T19:57:55.577Z</updated>
    
    <content type="html"><![CDATA[<p>Today, there are two releases of video.js.<br>The first, is a patch release for the 5.11 branch. With this release, we’re also updating 5.11 to stable and publishing it to the CDN.</p>
<p>The 5.12 release is a pre-release. It’s a pretty big milestone too. Video.js finally outputs non-pre-built files so bundlers like webpack can decide what to do with them.</p>
<h2 id="Notable-Changes"><a href="/Video-js-5-12-0-and-5-11-5-releases/#Notable-Changes" class="headerlink" title="Notable Changes"></a>Notable Changes</h2><p>This release is mostly a maintenance and build-change release.</p>
<ul>
<li>Lint the entire codebase with our <a href="https://github.com/videojs/standard" target="_blank" rel="external">linter</a> and run the linter as a pre-push git hook.</li>
<li>Fix CSS issues in IE8.</li>
<li>Updated dependencies using Greenkeeper.io</li>
<li>Make video.js provide ES5 source files for bundlers like webpack and browserify to use. This also makes video.js requirable in node.<ul>
<li>Video.js still provides a pre-build dist files for the CSS and JavaScript for those that aren’t using bundlers.</li>
</ul>
</li>
<li>We’ve added a grunt task called <code>check-translations</code> that will output a <a href="https://github.com/videojs/video.js/blob/master/docs/translations-needed.md" target="_blank" rel="external">list of translations missing</a> from language files based on the <a href="https://github.com/videojs/video.js/blob/master/lang/en.json" target="_blank" rel="external"><code>en.json</code></a> file which serves as a template. If you know another lanugage, this would be an easy and quick way to get started contriburing to video.js!</li>
</ul>
<h2 id="Known-Issues"><a href="/Video-js-5-12-0-and-5-11-5-releases/#Known-Issues" class="headerlink" title="Known Issues"></a>Known Issues</h2><p>No new known issues but we have started looking into the <a href="http://blog.videojs.com/Video-js-5-11-0-Prelease/#Known-Issues">known issues from the last release</a>.</p>
<h2 id="Looking-forward"><a href="/Video-js-5-12-0-and-5-11-5-releases/#Looking-forward" class="headerlink" title="Looking forward"></a>Looking forward</h2><p>Going forward, we’re <a href="https://github.com/videojs/video.js/issues/3503" target="_blank" rel="external">looking into</a> switching to <a href="https://github.com/conventional-changelog/standard-version" target="_blank" rel="external">standard-version</a>. This will allow us to accept PRs more easily and have the changelog generated for us. Also, this will make it easier for other core contributors to accept PRs. We’ve previously been using the <a href="https://github.com/contrib/contrib" target="_blank" rel="external">contrib</a> tool for accepting PRs and have the CHANGELOG generated automatically at that time but getting new people started with it for merging PRs was not the easiest experience.</p>
<h2 id="Raw-Changelog"><a href="/Video-js-5-12-0-and-5-11-5-releases/#Raw-Changelog" class="headerlink" title="Raw Changelog"></a>Raw Changelog</h2><ul>
<li>@misteroneill, @BrandonOCasey, and @pagarwal123 updates all the code to pass the linter (<a href="https://github.com/videojs/video.js/pull/3459" target="_blank" rel="external">view</a>)</li>
<li>@misteroneill added ghooks to run linter on git push (<a href="https://github.com/videojs/video.js/pull/3459" target="_blank" rel="external">view</a>)</li>
<li>@BrandonOCasey removed unused base-styles.js file (<a href="https://github.com/videojs/video.js/pull/3486" target="_blank" rel="external">view</a>)</li>
<li>@erikyuzwa, @gkatsev updated CSS build to inlcude the IE8-specific CSS from a separate file instead of it being inside of sass (<a href="https://github.com/videojs/video.js/pull/3380" target="_blank" rel="external">view</a>) (<a href="https://github.com/erikyuzwa/video.js/pull/1" target="_blank" rel="external">view2</a>)</li>
<li>@gkatsev added null checks around navigator.userAgent (<a href="https://github.com/videojs/video.js/pull/3502" target="_blank" rel="external">view</a>)</li>
<li>greenkeeper updated karma dependencies (<a href="https://github.com/videojs/video.js/pull/3523" target="_blank" rel="external">view</a>)</li>
<li>@BrandonOCasey updated language docs to link to IANA language registry (<a href="https://github.com/videojs/video.js/pull/3493" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev removed unused dependencies (<a href="https://github.com/videojs/video.js/pull/3516" target="_blank" rel="external">view</a>)</li>
<li>@misteroneill enabled and updated videojs-standard and fixed an issue with linting (<a href="https://github.com/videojs/video.js/pull/3508" target="_blank" rel="external">view</a>)</li>
<li>@misteroneill updated tests to qunit 2.0 (<a href="https://github.com/videojs/video.js/pull/3509" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev added slack badge to README (<a href="https://github.com/videojs/video.js/pull/3527" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev reverted back to qunitjs 1.x to unbreak IE8. Added es5-shim to tests (<a href="https://github.com/videojs/video.js/pull/3533" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev updated build system to open es5 folder for bundles and dist folder other users (<a href="https://github.com/videojs/video.js/pull/3445" target="_blank" rel="external">view</a>)</li>
<li>greenkeeper updated uglify (<a href="https://github.com/videojs/video.js/pull/3547" target="_blank" rel="external">view</a>)</li>
<li>greenkeeper updated grunt-concurrent (<a href="https://github.com/videojs/video.js/pull/3532" target="_blank" rel="external">view</a>)</li>
<li>greenkeeper updated karma-chrome-launcher (<a href="https://github.com/videojs/video.js/pull/3553" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev added tests for webpack and browserify bundling and node.js requiring (<a href="https://github.com/videojs/video.js/pull/3558" target="_blank" rel="external">view</a>)</li>
<li>@rlchung fixed tests that weren’t disposing players when they finished (<a href="https://github.com/videojs/video.js/pull/3524" target="_blank" rel="external">view</a>)</li>
</ul>
<h2 id="Git-diffstats"><a href="/Video-js-5-12-0-and-5-11-5-releases/#Git-diffstats" class="headerlink" title="Git diffstats"></a>Git diffstats</h2><p>These are deltas between 5.11.5 and 5.12.0 with the <code>dist</code> folder ignored.<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br></pre></td><td class="code"><pre><span class="line">.babelrc                                           |   4 -</span><br><span class="line">.gitignore                                         |   1 -</span><br><span class="line">.jshintrc                                          |  49 ++</span><br><span class="line">.npmignore                                         |   1 -</span><br><span class="line">.travis.yml                                        |   2 +-</span><br><span class="line">CHANGELOG.md                                       |  26 -</span><br><span class="line">Gruntfile.js                                       |   2 +-</span><br><span class="line">README.md                                          |   2 -</span><br><span class="line">build/grunt.js                                     | 131 ++-</span><br><span class="line">build/tasks/cdn-links.js                           |   2 +-</span><br><span class="line">build/tasks/languages.js                           |  35 -</span><br><span class="line">build/tasks/saucelabs.js                           |  24 +</span><br><span class="line">component.json                                     |   2 +-</span><br><span class="line">docs/guides/languages.md                           | 164 +++-</span><br><span class="line">docs/translations-needed.md                        | 363 --------</span><br><span class="line">lang/de.json                                       |   8 +-</span><br><span class="line">lang/en.json                                       |   2 -</span><br><span class="line">lang/fr.json                                       |  19 +-</span><br><span class="line">package.json                                       |  80 +-</span><br><span class="line">src/css/_utilities.scss                            |   2 +-</span><br><span class="line">src/css/components/_control-bar.scss               |  16 +</span><br><span class="line">src/css/components/_fullscreen.scss                |   2 +</span><br><span class="line">src/css/components/_play-pause.scss                |   2 +</span><br><span class="line">src/css/components/_progress.scss                  |   2 +-</span><br><span class="line">src/css/components/menu/_menu.scss                 |   3 +-</span><br><span class="line">src/css/ie8.css                                    |  30 -</span><br><span class="line">src/js/base-styles.js                              |  18 +</span><br><span class="line">src/js/button.js                                   |  28 +-</span><br><span class="line">src/js/clickable-component.js                      |  29 +-</span><br><span class="line">src/js/component.js                                |  79 +-</span><br><span class="line">.../audio-track-controls/audio-track-button.js     |  11 +-</span><br><span class="line">.../audio-track-controls/audio-track-menu-item.js  |  18 +-</span><br><span class="line">src/js/control-bar/control-bar.js                  |  39 +-</span><br><span class="line">src/js/control-bar/fullscreen-toggle.js            |   2 +-</span><br><span class="line">src/js/control-bar/live-display.js                 |   2 +-</span><br><span class="line">src/js/control-bar/mute-toggle.js                  |  20 +-</span><br><span class="line">src/js/control-bar/play-toggle.js                  |   8 +-</span><br><span class="line">.../playback-rate-menu-button.js                   |  27 +-</span><br><span class="line">.../playback-rate-menu/playback-rate-menu-item.js  |  10 +-</span><br><span class="line">.../progress-control/load-progress-bar.js          |  22 +-</span><br><span class="line">.../progress-control/mouse-time-display.js         |  22 +-</span><br><span class="line">.../progress-control/play-progress-bar.js          |   6 +-</span><br><span class="line">.../progress-control/progress-control.js           |   5 +-</span><br><span class="line">src/js/control-bar/progress-control/seek-bar.js    |  41 +-</span><br><span class="line">.../progress-control/tooltip-progress-bar.js       |  10 +-</span><br><span class="line">.../spacer-controls/custom-control-spacer.js       |   4 +-</span><br><span class="line">.../caption-settings-menu-item.js                  |  18 +-</span><br><span class="line">.../text-track-controls/captions-button.js         |  13 +-</span><br><span class="line">.../text-track-controls/chapters-button.js         |  57 +-</span><br><span class="line">.../chapters-track-menu-item.js                    |  18 +-</span><br><span class="line">.../text-track-controls/descriptions-button.js     |  15 +-</span><br><span class="line">.../off-text-track-menu-item.js                    |  25 +-</span><br><span class="line">.../text-track-controls/subtitles-button.js        |   4 +-</span><br><span class="line">.../text-track-controls/text-track-button.js       |  17 +-</span><br><span class="line">.../text-track-controls/text-track-menu-item.js    |  36 +-</span><br><span class="line">.../time-controls/current-time-display.js          |  13 +-</span><br><span class="line">.../control-bar/time-controls/duration-display.js  |  15 +-</span><br><span class="line">.../time-controls/remaining-time-display.js        |   7 +-</span><br><span class="line">src/js/control-bar/track-button.js                 |   7 +-</span><br><span class="line">src/js/control-bar/volume-control/volume-bar.js    |  12 +-</span><br><span class="line">.../control-bar/volume-control/volume-control.js   |  10 +-</span><br><span class="line">src/js/control-bar/volume-menu-button.js           |  19 +-</span><br><span class="line">src/js/error-display.js                            |   5 +-</span><br><span class="line">src/js/event-target.js                             |  17 +-</span><br><span class="line">src/js/extend.js                                   |   7 +-</span><br><span class="line">src/js/fullscreen-api.js                           |   6 +-</span><br><span class="line">src/js/media-error.js                              |  57 +-</span><br><span class="line">src/js/menu/menu-button.js                         |  31 +-</span><br><span class="line">src/js/menu/menu-item.js                           |  10 +-</span><br><span class="line">src/js/menu/menu.js                                |  63 +-</span><br><span class="line">src/js/modal-dialog.js                             |  20 +-</span><br><span class="line">src/js/player.js                                   | 383 ++++-----</span><br><span class="line">src/js/plugins.js                                  |   2 +-</span><br><span class="line">src/js/popup/popup-button.js                       |  10 +-</span><br><span class="line">src/js/popup/popup.js                              |  11 +-</span><br><span class="line">src/js/poster-image.js                             |   7 +-</span><br><span class="line">src/js/setup.js                                    |  40 +-</span><br><span class="line">src/js/slider/slider.js                            |  34 +-</span><br><span class="line">src/js/tech/flash-rtmp.js                          |  25 +-</span><br><span class="line">src/js/tech/flash.js                               | 157 ++--</span><br><span class="line">src/js/tech/html5.js                               | 347 +++-----</span><br><span class="line">src/js/tech/loader.js                              |  20 +-</span><br><span class="line">src/js/tech/tech.js                                | 210 +++--</span><br><span class="line">src/js/tracks/audio-track-list.js                  |   5 +-</span><br><span class="line">src/js/tracks/audio-track.js                       |  10 +-</span><br><span class="line">src/js/tracks/html-track-element-list.js           |   4 +-</span><br><span class="line">src/js/tracks/html-track-element.js                |   8 +-</span><br><span class="line">src/js/tracks/text-track-cue-list.js               |  12 +-</span><br><span class="line">src/js/tracks/text-track-display.js                | 144 ++--</span><br><span class="line">src/js/tracks/text-track-list-converter.js         |  28 +-</span><br><span class="line">src/js/tracks/text-track-list.js                   |   6 +-</span><br><span class="line">src/js/tracks/text-track-settings.js               | 347 ++++----</span><br><span class="line">src/js/tracks/text-track.js                        |  51 +-</span><br><span class="line">src/js/tracks/track-enums.js                       |  29 +-</span><br><span class="line">src/js/tracks/track-list.js                        |  12 +-</span><br><span class="line">src/js/tracks/track.js                             |  13 +-</span><br><span class="line">src/js/tracks/video-track-list.js                  |   4 +-</span><br><span class="line">src/js/tracks/video-track.js                       |  10 +-</span><br><span class="line">src/js/utils/browser.js                            |  32 +-</span><br><span class="line">src/js/utils/buffer.js                             |   9 +-</span><br><span class="line">src/js/utils/dom.js                                |  95 +--</span><br><span class="line">src/js/utils/events.js                             | 429 +++++-----</span><br><span class="line">src/js/utils/fn.js                                 |   6 +-</span><br><span class="line">src/js/utils/format-time.js                        |   2 +-</span><br><span class="line">src/js/utils/guid.js                               |   2 +-</span><br><span class="line">src/js/utils/log.js                                |  14 +-</span><br><span class="line">src/js/utils/merge-options.js                      |  14 +-</span><br><span class="line">src/js/utils/stylesheet.js                         |   7 +-</span><br><span class="line">src/js/utils/time-ranges.js                        |  68 +-</span><br><span class="line">src/js/utils/to-title-case.js                      |   2 +-</span><br><span class="line">src/js/utils/url.js                                |  29 +-</span><br><span class="line">src/js/video.js                                    |  53 +-</span><br><span class="line">test/api/api.js                                    | 421 +++++-----</span><br><span class="line">test/globals-shim.js                               |   2 -</span><br><span class="line">test/index.html                                    |   2 -</span><br><span class="line">test/karma.conf.js                                 |  17 +-</span><br><span class="line">test/require/browserify.js                         |   8 -</span><br><span class="line">test/require/node.js                               |   9 -</span><br><span class="line">test/require/webpack.js                            |   8 -</span><br><span class="line">test/unit/button.test.js                           |  32 +-</span><br><span class="line">test/unit/clickable-component.test.js              |  31 +-</span><br><span class="line">test/unit/close-button.test.js                     |  22 +-</span><br><span class="line">test/unit/component.test.js                        | 639 +++++++--------</span><br><span class="line">test/unit/controls.test.js                         | 101 ++-</span><br><span class="line">test/unit/events.test.js                           | 240 +++---</span><br><span class="line">test/unit/extend.test.js                           |  20 +-</span><br><span class="line">test/unit/media-error.test.js                      |  69 --</span><br><span class="line">test/unit/menu.test.js                             |  54 +-</span><br><span class="line">test/unit/modal-dialog.test.js                     | 138 ++--</span><br><span class="line">test/unit/player.test.js                           | 912 ++++++++++-----------</span><br><span class="line">test/unit/plugins.test.js                          | 196 +++--</span><br><span class="line">test/unit/poster.test.js                           |  68 +-</span><br><span class="line">test/unit/setup.test.js                            |  20 +-</span><br><span class="line">test/unit/tech/flash-rtmp.test.js                  |  68 +-</span><br><span class="line">test/unit/tech/flash.test.js                       | 203 ++---</span><br><span class="line">test/unit/tech/html5.test.js                       | 491 +++++------</span><br><span class="line">test/unit/tech/tech-faker.js                       |  86 +-</span><br><span class="line">test/unit/tech/tech.test.js                        | 438 +++++-----</span><br><span class="line">test/unit/test-helpers.js                          |  71 +-</span><br><span class="line">test/unit/tracks/audio-track-list.test.js          | 108 ++-</span><br><span class="line">test/unit/tracks/audio-track.test.js               |  88 +-</span><br><span class="line">test/unit/tracks/audio-tracks.test.js              |  70 +-</span><br><span class="line">test/unit/tracks/html-track-element-list.test.js   |  50 +-</span><br><span class="line">test/unit/tracks/html-track-element.test.js        |  68 +-</span><br><span class="line">test/unit/tracks/text-track-controls.test.js       | 202 ++---</span><br><span class="line">test/unit/tracks/text-track-cue-list.test.js       |  79 +-</span><br><span class="line">test/unit/tracks/text-track-list-converter.test.js |  67 +-</span><br><span class="line">test/unit/tracks/text-track-list.test.js           |  23 +-</span><br><span class="line">test/unit/tracks/text-track-settings.test.js       | 178 ++--</span><br><span class="line">test/unit/tracks/text-track.test.js                | 203 +++--</span><br><span class="line">test/unit/tracks/text-tracks.test.js               | 401 +++++----</span><br><span class="line">test/unit/tracks/track-baseline.js                 |  37 +-</span><br><span class="line">test/unit/tracks/track-list.test.js                | 104 ++-</span><br><span class="line">test/unit/tracks/track.test.js                     |  16 +-</span><br><span class="line">test/unit/tracks/video-track-list.test.js          | 111 ++-</span><br><span class="line">test/unit/tracks/video-track.test.js               |  87 +-</span><br><span class="line">test/unit/tracks/video-tracks.test.js              |  71 +-</span><br><span class="line">test/unit/utils/dom.test.js                        | 426 ++++------</span><br><span class="line">test/unit/utils/fn.test.js                         |  13 +-</span><br><span class="line">test/unit/utils/format-time.test.js                |  48 +-</span><br><span class="line">test/unit/utils/log.test.js                        |  26 +-</span><br><span class="line">test/unit/utils/merge-options.test.js              |  16 +-</span><br><span class="line">test/unit/utils/time-ranges.test.js                |  49 +-</span><br><span class="line">test/unit/utils/to-title-case.test.js              |  10 +-</span><br><span class="line">test/unit/utils/url.test.js                        | 103 ++-</span><br><span class="line">test/unit/video.test.js                            | 186 ++---</span><br><span class="line">166 files changed, 5233 insertions(+), 6541 deletions(-)</span><br></pre></td></tr></table></figure></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Today, there are two releases of video.js.&lt;br&gt;The first, is a patch release for the 5.11 branch. With this release, we’re also updating 5
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
      <category term="webpack" scheme="http://blog.videojs.com/tags/webpack/"/>
    
      <category term="releases" scheme="http://blog.videojs.com/tags/releases/"/>
    
      <category term="babel" scheme="http://blog.videojs.com/tags/babel/"/>
    
  </entry>
  
  <entry>
    <title>The End of &quot;HTML-First&quot;</title>
    <link href="http://blog.videojs.com/the-end-of-html-first/"/>
    <id>http://blog.videojs.com/the-end-of-html-first/</id>
    <published>2016-08-10T15:58:44.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>When video.js was <a href="https://github.com/videojs/video.js/commit/abe9252bbb7d255dd4671cf0afd93d980c2bf6df" target="_blank" rel="external">first released</a> all the way back in 2010, Flash was the only way to play video in Firefox, IE, and the Android browser. And when you <em>could</em> use HTML video, it was <a href="http://diveinto.html5doctor.com/video.html" target="_blank" rel="external">really complicated to get right</a> and broken in all sorts of scenarios (live streaming, anyone?). Those problems were a big part of why we wrote video.js in the first place. The HTML standard provided a simple, powerful, and universal API for video: why use anything else?</p>
<p>The superiority of HTML video is pretty well established these days and <a href="http://caniuse.com/#feat=video" target="_blank" rel="external">browser support for <code>video</code></a> reflects that. If you have your videos in MP4 format, video.js will play them natively in HTML on every modern desktop and mobile browser out there. In <a href="http://blog.videojs.com/Video-js-5-The-Only-Thing-That%E2%80%99s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/">video.js 5.0</a>, we started the process of deprecating the last holdout in our supported browsers: the dreaded Internet Explorer 8. If you’re saying to yourself “Wha?! You still support IE8??”, I share your shock and horror. It’s no fun but we’ve been holding out for the couple folks who want to use video on their sites and still have to support ancient clients. There’s <a href="http://docs.videojs.com/docs/guides/setup.html#step-1-include-the-video-js-javascript-and-css-files-in-the-head-of-your-page-" target="_blank" rel="external">a couple more hoops</a> to jump through however, and you should start emotionally preparing yourself for the end of IE8 support if you’re one of the people using it. With IE8 heading out to pasture, including a Flash fallback by default in video.js is starting to look a little silly.</p>
<p>So here’s what we’re thinking: move Flash support out of the core of video.js and into our <a href="https://github.com/videojs/ie8" target="_blank" rel="external">legacy-compatiblity shim</a> around the time <a href="https://chrome.googleblog.com/2016/08/flash-and-chrome.html" target="_blank" rel="external">Chrome begins deprecating Flash</a> this December. We’ll keep it around for awhile to support some more complex usage (say, live streaming in IE10) but the heart of video.js will go from “HTML-first” to “HTML-only.” That should mean more focus from the core committers on some amazing <strong>new</strong> stuff like improving our plugin framework, enhancing our support for <a href="http://videojs.github.io/videojs-contrib-hls/" target="_blank" rel="external">HLS</a> and <a href="http://videojs.github.io/videojs-contrib-dash/" target="_blank" rel="external">DASH</a>, and making advanced features like <a href="https://github.com/videojs/videojs-contrib-ads" target="_blank" rel="external">ads</a> easier to integrate and better for viewers.</p>
<p>How does that sound? Let us know in this <a href="https://github.com/videojs/video.js/issues/3520" target="_blank" rel="external">issue</a>, ping <a href="https://twitter.com/videojs" target="_blank" rel="external">@videojs</a> on Twitter, or come say “hi” in our <a href="http://slack.videojs.com/" target="_blank" rel="external">Slack channel</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;When video.js was &lt;a href=&quot;https://github.com/videojs/video.js/commit/abe9252bbb7d255dd4671cf0afd93d980c2bf6df&quot; target=&quot;_blank&quot; rel=&quot;exte
    
    </summary>
    
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
      <category term="html5 video" scheme="http://blog.videojs.com/tags/html5-video/"/>
    
      <category term="flash" scheme="http://blog.videojs.com/tags/flash/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 5.11.0 Prelease</title>
    <link href="http://blog.videojs.com/Video-js-5-11-0-Prelease/"/>
    <id>http://blog.videojs.com/Video-js-5-11-0-Prelease/</id>
    <published>2016-07-22T15:46:51.000Z</published>
    <updated>2019-01-18T19:57:55.577Z</updated>
    
    <content type="html"><![CDATA[<p>Today sees the prerelease of version 5.11.0. I wanted to take a moment to talk about some of the changes, additions, and known issues.</p>
<p>This is a pre-release only. It’s available on npm under the <code>next</code> tag and also available on the CDN under the fully qualified version number: <code>//vjs.zencdn.net/5.11.0/video.js</code>. It’ll stay in pre-release state for around a week or more to make sure that there aren’t any glaring bugs, so, please give it a shot and <a href="https://github.com/videojs/video.js/issues/new" target="_blank" rel="external">open issues</a> if you find anything.</p>
<h2 id="Notable-Changes"><a href="/Video-js-5-11-0-Prelease/#Notable-Changes" class="headerlink" title="Notable Changes"></a>Notable Changes</h2><ul>
<li>In version 5.0, we wanted to deprecate <code>videojs.players</code> property in favor of of the <code>videojs.getPlayers()</code> getter. However, it’s proved to be very useful and it is now being un-deprecated so it will no longer print deprecations in the console.</li>
<li>If the player is created without a source set and a user hits play, video.js will now wait for the a source to be provided before starting playback. This eliminates an error that happens when we try to play an empty source.</li>
<li>Our custom captions settings dialog was updated to be more accessible by using more aria attributes and better option names in drop downs.</li>
</ul>
<h2 id="Known-Issues"><a href="/Video-js-5-11-0-Prelease/#Known-Issues" class="headerlink" title="Known Issues"></a>Known Issues</h2><ul>
<li>In video.js 5.10, to be able to better respond to the source of the video element changing directly without going through video.js, we <a href="https://github.com/videojs/video.js/pull/3285" target="_blank" rel="external">disposed SourceHandlers on subsequent loadstarts</a> and <a href="https://github.com/videojs/video.js/pull/3314" target="_blank" rel="external">cleared out the current source</a>. However, this causes an <a href="https://github.com/videojs/video.js/issues/3428" target="_blank" rel="external">issue with videojs-contrib-dash</a>. A contributor investigated and found out that the two PRs mentioned before cause the issue. If a video is created with an MPEG-DASH source element, we end up seeing a <code>loadstart</code> event because of the source element and then when Dash.js kicks in and starts playback using MSE, we get another <code>loadstart</code> event. Since we see the second <code>loadstat</code> event we dispose of the SourceHandler, that is, videojs-contrib-dash and Dash.js, and the video doesn’t play. A work around, while we figure out a correct solution, would be not to use source elements with DASH sources and only use the video.js API in the meantime.</li>
</ul>
<h2 id="Raw-Changelog"><a href="/Video-js-5-11-0-Prelease/#Raw-Changelog" class="headerlink" title="Raw Changelog"></a>Raw Changelog</h2><ul>
<li>@BrandonOCasey Document audio/video track usage (<a href="https://github.com/videojs/video.js/pull/3295" target="_blank" rel="external">view</a>)</li>
<li>@hartman Correct documentation to refer to nativeTextTracks option (<a href="https://github.com/videojs/video.js/pull/3309" target="_blank" rel="external">view</a>)</li>
<li>@nickygerritsen Also pass tech options to canHandleSource (<a href="https://github.com/videojs/video.js/pull/3303" target="_blank" rel="external">view</a>)</li>
<li>@misteroneill Un-deprecate the videojs.players property (<a href="https://github.com/videojs/video.js/pull/3299" target="_blank" rel="external">view</a>)</li>
<li>@nickygerritsen Add title to all clickable components (<a href="https://github.com/videojs/video.js/pull/3296" target="_blank" rel="external">view</a>)</li>
<li>@nickygerritsen Update Dutch language file (<a href="https://github.com/videojs/video.js/pull/3297" target="_blank" rel="external">view</a>)</li>
<li>@hartman Add descriptions and audio button to adaptive classes (<a href="https://github.com/videojs/video.js/pull/3312" target="_blank" rel="external">view</a>)</li>
<li>@MattiasBuelens Retain details from tech error (<a href="https://github.com/videojs/video.js/pull/3313" target="_blank" rel="external">view</a>)</li>
<li>@nickygerritsen Fix test for tooltips in IE8 (<a href="https://github.com/videojs/video.js/pull/3327" target="_blank" rel="external">view</a>)</li>
<li>@mboles added loadstart event to jsdoc (<a href="https://github.com/videojs/video.js/pull/3370" target="_blank" rel="external">view</a>)</li>
<li>@hartman added default print styling (<a href="https://github.com/videojs/video.js/pull/3304" target="_blank" rel="external">view</a>)</li>
<li>@ldayananda updated videojs to not do anything if no src is set (<a href="https://github.com/videojs/video.js/pull/3378" target="_blank" rel="external">view</a>)</li>
<li>@nickygerritsen removed unused tracks when changing sources. Fixes ##3000 (<a href="https://github.com/videojs/video.js/pull/3002" target="_blank" rel="external">view</a>)</li>
<li>@vit-koumar updated Flash tech to return Infinity from duration instead of -1 (<a href="https://github.com/videojs/video.js/pull/3128" target="_blank" rel="external">view</a>)</li>
<li>@alex-phillips added ontextdata to Flash tech (<a href="https://github.com/videojs/video.js/pull/2748" target="_blank" rel="external">view</a>)</li>
<li>@MattiasBuelens updated components to use durationchange only (<a href="https://github.com/videojs/video.js/pull/3349" target="_blank" rel="external">view</a>)</li>
<li>@misteroneill improved Logging for IE &lt; 11 (<a href="https://github.com/videojs/video.js/pull/3356" target="_blank" rel="external">view</a>)</li>
<li>@vdeshpande updated control text of modal dialog (<a href="https://github.com/videojs/video.js/pull/3400" target="_blank" rel="external">view</a>)</li>
<li>@ldayananda fixed mouse handling on menus by using mouseleave over mouseout (<a href="https://github.com/videojs/video.js/pull/3404" target="_blank" rel="external">view</a>)</li>
<li>@mister-ben updated language to inherit correctly and respect the attribute on the player (<a href="https://github.com/videojs/video.js/pull/3426" target="_blank" rel="external">view</a>)</li>
<li>@sashyro fixed nativeControlsForTouch option (<a href="https://github.com/videojs/video.js/pull/3410" target="_blank" rel="external">view</a>)</li>
<li>@tbasse fixed techCall null check against tech (<a href="https://github.com/videojs/video.js/pull/2676" target="_blank" rel="external">view</a>)</li>
<li>@rbran100 checked src and currentSrc in handleTechReady to work around mixed content issues in chrome (<a href="https://github.com/videojs/video.js/pull/3287" target="_blank" rel="external">view</a>)</li>
<li>@OwenEdwards fixed caption settings dialog labels for accessibility (<a href="https://github.com/videojs/video.js/pull/3281" target="_blank" rel="external">view</a>)</li>
<li>@OwenEdwards removed spurious head tags in the simple-embed example (<a href="https://github.com/videojs/video.js/pull/3438" target="_blank" rel="external">view</a>)</li>
<li>@ntadej added a null check to errorDisplay usage (<a href="https://github.com/videojs/video.js/pull/3440" target="_blank" rel="external">view</a>)</li>
<li>@misteroneill fixed logging issues on IE by separating fn.apply and stringify checks (<a href="https://github.com/videojs/video.js/pull/3444" target="_blank" rel="external">view</a>)</li>
<li>@misteroneill fixed npm test from running coveralls locally (<a href="https://github.com/videojs/video.js/pull/3449" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev added es6-shim to tests. Fixes Flash duration test (<a href="https://github.com/videojs/video.js/pull/3453" target="_blank" rel="external">view</a>)</li>
<li>@misteroneill corrects test assertions for older IEs in the log module (<a href="https://github.com/videojs/video.js/pull/3454" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev fixed setting lang by looping through loop element variable and not constant tag (<a href="https://github.com/videojs/video.js/pull/3455" target="_blank" rel="external">view</a>)</li>
</ul>
<h2 id="Git-diffstats"><a href="/Video-js-5-11-0-Prelease/#Git-diffstats" class="headerlink" title="Git diffstats"></a>Git diffstats</h2><p>These are deltas between 5.11.0 and 5.10.7<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line">CHANGELOG.md                                       |    33 +</span><br><span class="line">build/grunt.js                                     |     3 +-</span><br><span class="line">component.json                                     |     2 +-</span><br><span class="line">docs/examples/simple-embed/index.html              |     3 -</span><br><span class="line">docs/guides/audio-tracks.md                        |    69 +</span><br><span class="line">docs/guides/languages.md                           |    12 +-</span><br><span class="line">docs/guides/text-tracks.md                         |   184 +</span><br><span class="line">docs/guides/tracks.md                              |   186 +-</span><br><span class="line">docs/guides/video-tracks.md                        |    70 +</span><br><span class="line">docs/index.md                                      |     2 +-</span><br><span class="line">lang/en.json                                       |     1 +</span><br><span class="line">lang/nl.json                                       |    19 +-</span><br><span class="line">package.json                                       |     7 +-</span><br><span class="line">src/css/_print.scss                                |     5 +</span><br><span class="line">src/css/components/_adaptive.scss                  |     9 +-</span><br><span class="line">src/css/components/_captions-settings.scss         |    26 +-</span><br><span class="line">src/css/video-js.scss                              |     2 +</span><br><span class="line">src/js/clickable-component.js                      |    12 +-</span><br><span class="line">.../control-bar/time-controls/duration-display.js  |     8 +-</span><br><span class="line">.../time-controls/remaining-time-display.js        |     1 +</span><br><span class="line">src/js/menu/menu-button.js                         |     4 +-</span><br><span class="line">src/js/modal-dialog.js                             |     2 +-</span><br><span class="line">src/js/player.js                                   |    68 +-</span><br><span class="line">src/js/tech/flash-rtmp.js                          |     3 +-</span><br><span class="line">src/js/tech/flash.js                               |    21 +-</span><br><span class="line">src/js/tech/html5.js                               |    73 +-</span><br><span class="line">src/js/tech/tech.js                                |    16 +-</span><br><span class="line">src/js/tracks/text-track-settings.js               |   176 +-</span><br><span class="line">src/js/utils/browser.js                            |     3 +</span><br><span class="line">src/js/utils/create-deprecation-proxy.js           |    50 -</span><br><span class="line">src/js/utils/log.js                                |   124 +-</span><br><span class="line">src/js/video.js                                    |    16 +-</span><br><span class="line">test/globals-shim.js                               |     1 +</span><br><span class="line">test/unit/button.test.js                           |     5 +-</span><br><span class="line">test/unit/player.test.js                           |    22 +-</span><br><span class="line">test/unit/plugins.test.js                          |    20 +-</span><br><span class="line">test/unit/tech/flash.test.js                       |    51 +-</span><br><span class="line">test/unit/tech/html5.test.js                       |    16 +-</span><br><span class="line">test/unit/tech/tech.test.js                        |    17 +-</span><br><span class="line">test/unit/tracks/text-track-settings.test.js       |    51 +-</span><br><span class="line">test/unit/tracks/text-track.test.js                |    13 +-</span><br><span class="line">test/unit/utils/create-deprecation-proxy.test.js   |    45 -</span><br><span class="line">test/unit/utils/log.test.js                        |   104 +-</span><br><span class="line">103 files changed, 971 insertions(+), 55554 deletions(-)</span><br></pre></td></tr></table></figure></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Today sees the prerelease of version 5.11.0. I wanted to take a moment to talk about some of the changes, additions, and known issues.&lt;/p
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
      <category term="releases" scheme="http://blog.videojs.com/tags/releases/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 5&#39;s fluid mode and playlist picker</title>
    <link href="http://blog.videojs.com/Video-js-5-s-fluid-mode-and-playlist-picker/"/>
    <id>http://blog.videojs.com/Video-js-5-s-fluid-mode-and-playlist-picker/</id>
    <published>2016-06-01T14:50:06.000Z</published>
    <updated>2019-01-18T19:57:55.577Z</updated>
    
    <content type="html"><![CDATA[<h2 id="How-it-works"><a href="/Video-js-5-s-fluid-mode-and-playlist-picker/#How-it-works" class="headerlink" title="How it works"></a>How it works</h2><p>In video.js 5.0, we added support for truly fluid layouts with video.js.<br>You can see an example of it on the <a href="//videojs.com">video.js website</a>.</p>
<p>It is done by using <a href="http://alistapart.com/article/creating-intrinsic-ratios-for-video" target="_blank" rel="external">intrinsic ratios</a>. Video.js does the heavy lifting for you.</p>
<h2 id="How-to-use-it-in-video-js"><a href="/Video-js-5-s-fluid-mode-and-playlist-picker/#How-to-use-it-in-video-js" class="headerlink" title="How to use it in video.js"></a>How to use it in video.js</h2><p>In video.js, to make a player fluid, you can either set the <code>fluid</code> option<br><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> player = videojs(<span class="string">'preview-player'</span>, &#123;</span><br><span class="line">  fluid: <span class="literal">true</span></span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure></p>
<p>Or you can add one of the fluid classes to the player: <code>.vjs-fluid</code>, <code>.vjs-4-3</code>, <code>.vjs-16-9</code>:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">video</span> <span class="attr">id</span>=<span class="string">"preview-player"</span> <span class="attr">class</span>=<span class="string">"video-js vjs-fluid"</span> <span class="attr">controls</span> <span class="attr">data-setup</span>=<span class="string">&#123;&#125;</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<p><code>.vjs-4-3</code> maintains a 4:3 aspect ratio for the video and <code>.vjs-16-9</code> maintains a 16:9 one.  <code>.vjs-fluid</code> is a bit more special. It waits for the video metadata to load and then uses the video width and video height to calculate the correct aspect ratio to use for the video.</p>
<h2 id="Playlist-picker"><a href="/Video-js-5-s-fluid-mode-and-playlist-picker/#Playlist-picker" class="headerlink" title="Playlist picker"></a>Playlist picker</h2><p>This works great if you only have the player by itself. What if you are trying to a attach a playlist to the video element and keep it at the same height Like we did on the <a href="//videojs.com/advanced/">advanced example page</a> on the video.js website?<br><img src="/Video-js-5-s-fluid-mode-and-playlist-picker/videojs-with-playlist.png" alt=""></p>
<p>We <em>could</em> calculate how much the padding top should be depending on the width of the playlist picker or the container element but then each time a video changes we would need to recalculate the height of the playlist picker. Instead, we can rely on video.js to do all the work.</p>
<h3 id="Attaching-the-playlist-picker"><a href="/Video-js-5-s-fluid-mode-and-playlist-picker/#Attaching-the-playlist-picker" class="headerlink" title="Attaching the playlist picker"></a>Attaching the playlist picker</h3><p>For this example, We’re using the <a href="https://github.com/brightcove/videojs-playlist-ui" target="_blank" rel="external">videojs-playlist-ui</a> and <a href="https://github.com/brightcove/videojs-playlist" target="_blank" rel="external">videojs-playlist</a> plugins for the playlist functionality.<br>We then wrap the player in a container and put the playlist-ui element in there as well.<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">section</span> <span class="attr">class</span>=<span class="string">"main-preview-player"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">video</span> <span class="attr">id</span>=<span class="string">"preview-player"</span> <span class="attr">class</span>=<span class="string">"video-js vjs-fluid"</span> <span class="attr">controls</span> <span class="attr">preload</span>=<span class="string">"auto"</span> <span class="attr">crossorigin</span>=<span class="string">"anonymous"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">"vjs-no-js"</span>&gt;</span>To view this video please enable JavaScript, and consider upgrading to a web browser that <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"http://videojs.com/html5-video-support/"</span> <span class="attr">target</span>=<span class="string">"_blank"</span>&gt;</span>supports HTML5 video<span class="tag">&lt;/<span class="name">a</span>&gt;</span><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">video</span>&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="tag">&lt;<span class="name">ol</span> <span class="attr">class</span>=<span class="string">"vjs-playlist"</span>&gt;</span><span class="tag">&lt;/<span class="name">ol</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">section</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<p>Now we can relatively quickly make them align together with some CSS:<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.video-js</span> &#123;</span><br><span class="line">  <span class="attribute">width</span>: <span class="number">70%</span>;</span><br><span class="line">  <span class="attribute">float</span>: left;</span><br><span class="line">&#125;</span><br><span class="line"><span class="selector-class">.vjs-playlist</span> &#123;</span><br><span class="line">  <span class="attribute">width</span>: <span class="number">30%</span>;</span><br><span class="line">  <span class="attribute">float</span>: right;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p><img src="/Video-js-5-s-fluid-mode-and-playlist-picker/videojs-playlist-not-fluid.png" alt=""></p>
<h3 id="How-to-make-it-fluid"><a href="/Video-js-5-s-fluid-mode-and-playlist-picker/#How-to-make-it-fluid" class="headerlink" title="How to make it fluid"></a>How to make it fluid</h3><p>As you can see in the preceeding screenshot, it isn’t aligned correctly with the player like in the screenshot above.<br>Video.js calculates the aspect ratio and then adds a stylesheet to the page:<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.preview-player-dimensions</span><span class="selector-class">.vjs-fluid</span> &#123;</span><br><span class="line">  <span class="attribute">padding-top</span>: <span class="number">41.66666666666667%</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>That percentage results in a 2.4 aspect ratio which matches that of the oceans clip.</p>
<p>So, to make sure that the playlist picker is the same height, we can just add the player dimensions class to it:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">ol</span> <span class="attr">class</span>=<span class="string">"vjs-playlist preview-player-dimensions vjs-fluid"</span>&gt;</span><span class="tag">&lt;/<span class="name">ol</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<h3 id="How-to-make-it-line-up"><a href="/Video-js-5-s-fluid-mode-and-playlist-picker/#How-to-make-it-line-up" class="headerlink" title="How to make it line up"></a>How to make it line up</h3><p>One of the easiest ways of making these two things line up correctly is to use flexbox. It’ll make the player and playlist picker grow to fill up as much space as needed. Also, the playlist picker collapse underneath the player if the width of the page is too small.<br>Flexbox is <a href="http://caniuse.com/#feat=flexbox" target="_blank" rel="external">available</a> on a lot of platforms. However, some browsers were implementing flexbox as the specification for it was evolving. It’s probably best to run this css through something like <a href="https://github.com/postcss/autoprefixer" target="_blank" rel="external">autoprefixer</a>. Using autoprefixer won’t make it work on browsers that don’t support flexbox but will significantly increase platform support.</p>
<p>First, we set <code>display</code> to <code>flex</code> and add some properties for wrapping and sizing:<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.main-preview-player</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: flex;</span><br><span class="line">  <span class="attribute">flex-wrap</span>: wrap;</span><br><span class="line">  <span class="attribute">justify-content</span>: space-between;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p><code>flex-wrap</code> allows playlist picker to wrap to the next line if the width of the container is too small.<br>Then we want to position the player and playlist picker relative to the container and set some default and minimum sizes:<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.video-js</span>,</span><br><span class="line"><span class="selector-class">.vjs-playlist</span> &#123;</span><br><span class="line">  <span class="attribute">position</span>: relative;</span><br><span class="line">  <span class="attribute">min-width</span>: <span class="number">300px</span>;</span><br><span class="line">  <span class="attribute">min-height</span>: <span class="number">150px</span>;</span><br><span class="line">  <span class="attribute">height</span>: <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>And finally, we want to apply the flex setting to the player and playlist picker:<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.video-js</span> &#123;</span><br><span class="line">  <span class="attribute">flex</span>: <span class="number">3</span> <span class="number">1</span> <span class="number">70%</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.vjs-playlist</span> &#123;</span><br><span class="line">  <span class="attribute">flex</span>: <span class="number">1</span> <span class="number">1</span> <span class="number">30%</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>This tells the player to grow and take up 3x the space as the playlist picker and defaults to 70% of the width. The playlist picker itself defaults to 30% of the width and is allowed to grow and shrink as necessary.<br>Now if we load this in a browser we see a problem. The playlist isn’t the right height:<br><img src="/Video-js-5-s-fluid-mode-and-playlist-picker/videojs-playlist-small.png" alt=""><br>This is because the playlist-ui plugin sets its own padding on the element that ends up overriding the <code>preview-player-dimensions</code> <code>padding-top</code>. We can fix this by forcing the <code>padding-top</code> we want. However, while this solves our height problem, where are our items? Oh, you need to scroll to get them. That seems less than ideal.<br><img src="/Video-js-5-s-fluid-mode-and-playlist-picker/videojs-playlist-padding.png" alt=""><br>This happens because our <code>padding-top</code> is inside the playlist picker; it pushed all the elements down requiring scrolling to get to them.</p>
<h3 id="The-final-solution"><a href="/Video-js-5-s-fluid-mode-and-playlist-picker/#The-final-solution" class="headerlink" title="The final solution"></a>The final solution</h3><p>Ultimately, what we need to do is wrap the playlist element in a container that flexes so that the <code>padding-top</code> doesn’t push the playlist items down.<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"playlist-container  preview-player-dimensions vjs-fluid"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">ol</span> <span class="attr">class</span>=<span class="string">"vjs-playlist"</span>&gt;</span><span class="tag">&lt;/<span class="name">ol</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<p>We also change the <code>vjs-playlist</code> references to <code>playlist-container</code> and absolutely position the playlist picker inside its container:<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.playlist-container</span> &#123;</span><br><span class="line">  <span class="attribute">position</span>: relative;</span><br><span class="line">  <span class="attribute">min-width</span>: <span class="number">300px</span>;</span><br><span class="line">  <span class="attribute">min-height</span>: <span class="number">150px</span>;</span><br><span class="line">  <span class="attribute">height</span>: <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.playlist-container</span> &#123;</span><br><span class="line">  <span class="attribute">flex</span>: <span class="number">1</span> <span class="number">1</span> <span class="number">30%</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.vjs-playlist</span> &#123;</span><br><span class="line">  <span class="attribute">margin</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">position</span>: absolute;</span><br><span class="line">  <span class="attribute">top</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">bottom</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">left</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">right</span>: <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
<p>Now we have what we were looking for:<br><img src="/Video-js-5-s-fluid-mode-and-playlist-picker/videojs-with-playlist.png" alt=""></p>
<h3 id="All-together-now"><a href="/Video-js-5-s-fluid-mode-and-playlist-picker/#All-together-now" class="headerlink" title="All together now"></a>All together now</h3><p><img src="/Video-js-5-s-fluid-mode-and-playlist-picker/responsive-playlist.gif" alt=""><br>The HTML:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">section</span> <span class="attr">class</span>=<span class="string">"main-preview-player"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">video</span> <span class="attr">id</span>=<span class="string">"preview-player"</span> <span class="attr">class</span>=<span class="string">"video-js vjs-fluid"</span> <span class="attr">controls</span> <span class="attr">preload</span>=<span class="string">"auto"</span> <span class="attr">crossorigin</span>=<span class="string">"anonymous"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">p</span> <span class="attr">class</span>=<span class="string">"vjs-no-js"</span>&gt;</span>To view this video please enable JavaScript, and consider upgrading to a web browser that <span class="tag">&lt;<span class="name">a</span> <span class="attr">href</span>=<span class="string">"http://videojs.com/html5-video-support/"</span> <span class="attr">target</span>=<span class="string">"_blank"</span>&gt;</span>supports HTML5 video<span class="tag">&lt;/<span class="name">a</span>&gt;</span><span class="tag">&lt;/<span class="name">p</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">video</span>&gt;</span></span><br><span class="line"></span><br><span class="line">  <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"playlist-container  preview-player-dimensions vjs-fluid"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">ol</span> <span class="attr">class</span>=<span class="string">"vjs-playlist"</span>&gt;</span><span class="tag">&lt;/<span class="name">ol</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">section</span>&gt;</span></span><br></pre></td></tr></table></figure></p>
<p>And the CSS:<br><figure class="highlight css"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="selector-class">.main-preview-player</span> &#123;</span><br><span class="line">  <span class="attribute">display</span>: flex;</span><br><span class="line">  <span class="attribute">flex-wrap</span>: wrap;</span><br><span class="line">  <span class="attribute">justify-content</span>: space-between;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.video-js</span>,</span><br><span class="line"><span class="selector-class">.playlist-container</span> &#123;</span><br><span class="line">  <span class="attribute">position</span>: relative;</span><br><span class="line">  <span class="attribute">min-width</span>: <span class="number">300px</span>;</span><br><span class="line">  <span class="attribute">min-height</span>: <span class="number">150px</span>;</span><br><span class="line">  <span class="attribute">height</span>: <span class="number">0</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.video-js</span> &#123;</span><br><span class="line">  <span class="attribute">flex</span>: <span class="number">3</span> <span class="number">1</span> <span class="number">70%</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.playlist-container</span> &#123;</span><br><span class="line">  <span class="attribute">flex</span>: <span class="number">1</span> <span class="number">1</span> <span class="number">30%</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="selector-class">.vjs-playlist</span> &#123;</span><br><span class="line">  <span class="attribute">margin</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">position</span>: absolute;</span><br><span class="line">  <span class="attribute">top</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">bottom</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">left</span>: <span class="number">0</span>;</span><br><span class="line">  <span class="attribute">right</span>: <span class="number">0</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure></p>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;How-it-works&quot;&gt;&lt;a href=&quot;/Video-js-5-s-fluid-mode-and-playlist-picker/#How-it-works&quot; class=&quot;headerlink&quot; title=&quot;How it works&quot;&gt;&lt;/a&gt;How i
    
    </summary>
    
    
      <category term="videojs 5" scheme="http://blog.videojs.com/tags/videojs-5/"/>
    
      <category term="fluid" scheme="http://blog.videojs.com/tags/fluid/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 5: The Only Thing That’s Changed Is Everything...except for like 3 things that didn&#39;t (including the name).</title>
    <link href="http://blog.videojs.com/Video-js-5-The-Only-Thing-That%E2%80%99s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/"/>
    <id>http://blog.videojs.com/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/</id>
    <published>2015-09-29T14:00:16.000Z</published>
    <updated>2019-01-18T19:57:55.577Z</updated>
    
    <content type="html"><![CDATA[<p>First and foremost, <strong>THANK YOU</strong> to the 25 contributors who completed and merged <strong>146 pull requests</strong> and updated just about every line of code in the project. And thank you to the hundreds of issue commenters and plugin authors who helped shape this latest version. For a widget, we’ve got a pretty awesome community.</p>
<p>For 5.0 we have some interesting new features, and we made A LOT of new technology choices. This will include an exhaustive dive into those choices, because… why not?</p>
<ul>
<li>Redesigned and rebuilt the UI<ul>
<li>Using a flex-box-based controls layout for easier add-ons</li>
<li>Improved accessibility of the controls</li>
<li>Switched from LESS to SASS</li>
<li>Switched to Material Icons</li>
</ul>
</li>
<li>Rebuilt the library in ES6/Babel/Browserify including Modules and Classes</li>
<li>Added support for responsive layouts including auto-sizing to the video content</li>
<li>Added support for HLS in desktop browsers <strong>without Flash</strong></li>
<li>Improved audio-only support</li>
<li>Added 6 more language translations bringing the total to 25</li>
<li>Switched from Closure Compiler to UglifyJS (we STOPPED mangling object properties)</li>
<li>Switched to JSDoc for documentation</li>
<li>Switched to BrowserStack for automated browser testing</li>
<li>Switched to Fastly for our CDN</li>
<li>New definition around plugins</li>
<li>New <a href="http://codepen.io/heff/pen/EarCt/left/?editors=010" target="_blank" rel="external">player skin designer</a> on Codepen</li>
<li>New definition around playback technologies (“techs”)</li>
<li>New project governance model</li>
<li>New Website and Logo!</li>
</ul>
<p>If you’re a Video.js user or lover of <a href="http://semver.org/" target="_blank" rel="external">semver</a>, you’re probably looking at the <a href="https://github.com/videojs/video.js/blob/872459837b21c1e3d05fa86df4022f5a2b17ea1c/CHANGELOG.md#500-2015-09-29" target="_blank" rel="external">changelog</a> and dying inside (or out). You’re probably already thinking about how little you want to do the mega-upgrade dance every time the major version is bumped. To be clear, there will be at least <em>some</em> upgrade cost between major versions because that’s just how things go. <strong>However</strong>, from 5.0 on, we plan on being a lot more liberal with major versions to avoid stop-the-world mega releases like this.</p>
<p>The fact is, this release <a href="https://github.com/videojs/video.js/wiki/5.0-Change-Details" target="_blank" rel="external">cleaned up a lot of technical debt</a> and cruft over years of maintaining a popular open source library. Working with the codebase is fun again (not like it wasn’t before, Judgy McJudgerson) and we think we’ve bought ourselves at least 6 months before we have to upgrade to ES9000. In all seriousness, we plan on being quicker with releases, both breaking and non, in order to make incremental upgrades less painful and, well, quicker. Besides, Chrome and Firefox are going to be in the thousands soon for their releases, and we want some of that fun.</p>
<h2 id="Redesigned-and-rebuilt-UI"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Redesigned-and-rebuilt-UI" class="headerlink" title="Redesigned and rebuilt UI"></a>Redesigned and rebuilt UI</h2><p><a href="http://www.videojs.com" target="_blank" rel="external"><img src="http://66.media.tumblr.com/7936bfddeddf68058784eb6d815cd631/tumblr_inline_nveuwhsdFu1qzc111_540.png" alt=""></a></p>
<p>Video.js has had an all-CSS skin (including for Flash) since it was created in 2010 (the <a href="http://videojs.github.io/video.js/" target="_blank" rel="external">first version</a> was <em>literally</em> all CSS, no images, fonts, or svgs. And still works today!) Over those years we’ve seen some very creative customizations and learned a lot about what users are hoping to do with player design when they’re able to use native web techologies. For 5.0 we’ve both simplified the default layout and added more flexibility than ever before.</p>
<h3 id="Flex-Box-Layout"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Flex-Box-Layout" class="headerlink" title="Flex Box Layout"></a>Flex Box Layout</h3><p>One of our biggest challenges with the layout of the controls is keeping the control bar flexible and able to accomodate any new buttons that a plugin author might want to add. In 4.0 we used CSS floats to allow a new button to be appended to the control bar and flow into space. This however led to a very awkward tab order for anyone navigating the controls with the tab key. In 5.0 we were finally able to take advantage of <a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/" target="_blank" rel="external">flex box</a>, which improves on the flexibility of the previous version while also maintaining the right tab order. In IE8 (because yeah, we still support that) we fall back to <code>display:table</code>, which works surprisingly well.</p>
<h3 id="Improved-accessibility"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Improved-accessibility" class="headerlink" title="Improved accessibility"></a>Improved accessibility</h3><p>Accessibility has been a <a href="http://www.3playmedia.com/2015/04/30/video-jss-approach-to-video-player-accessibility/" target="_blank" rel="external">hot topic as of late</a>, with <a href="http://www.w3.org/WAI/intro/wcag" target="_blank" rel="external">new regulations</a> helping push the industry forward and defining what accessbility means for a player. The tab-order mentioned previously was an eye sore in our accessiblity support, and we’re all happy to have that fixed in 5.0. Addtionally, after <a href="https://github.com/videojs/video.js/issues/841" target="_blank" rel="external">a long debate</a>, we switched our Button elements to use the actual HTML button tag instead of divs. Using divs previously gave us a large degree of safety from external styles clobbering our own styles. This can be a big problem for html-based widgets that are dropped into other frameworks that add styles directly to native elements (<em>ahem</em> Foundation). In the end however the accessibility experts in our community made a strong enough case, pointing out that there’s still a number of devices that do not handle ARIA roles and javascript enhanced divs well enough to fully rely on them.</p>
<h3 id="Switched-from-LESS-to-SASS"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Switched-from-LESS-to-SASS" class="headerlink" title="Switched from LESS to SASS"></a>Switched from LESS to SASS</h3><p>The original decision to use <a href="http://lesscss.org/" target="_blank" rel="external">Less</a> over <a href="http://sass-lang.com" target="_blank" rel="external">Sass</a> in version 4 was largely driven by the fact that it could be run in the browser. We knew we wanted to start using a preprocessor, but we still wanted to provide things like the skin designer which meant we needed to be able to do all pre-processing on the client. Less was totally appropriate for the job and allowed us to start modernizing the skin in appearance and tooling.</p>
<p>Since then, thanks to <a href="https://github.com/kripken/emscripten" target="_blank" rel="external">Emscripten</a>, Sass has joined Less in the browser. This meant that we were free to use whichever of the two we liked, so all the contributors put on Less or Sass branded boxing gloves and fought until two gloves were still standing, which turned out to be Sass. Aside from the battle royale, there were a few reasons we decided to go with Sass for the new base skin in version 5.</p>
<ul>
<li><strong>Familiarity</strong>. Core contributors that started working on the new base skin were a little more experienced with Sass and simply preferred it.</li>
<li><strong>Speed</strong>. On top of allowing us to use Sass without requiring Ruby, <a href="https://github.com/sass/libsass" target="_blank" rel="external">LibSass</a> is <em>fast</em>.</li>
<li><strong>Popularity</strong>. Your parents are right, not everything’s a popularity contest… but it is when you want to pick between two basically equivalent* tools. We wanted to pick something that more devs would be familiar with, and that seems to be Sass. On that note, it was also requested fairly often on the issue tracker.</li>
<li><strong>Community</strong>. This goes hand in hand with popularity, but the Sass community is large and growing, with currently popular projects using it (and <a href="http://blog.getbootstrap.com/2015/08/19/bootstrap-4-alpha/" target="_blank" rel="external">switching to it</a>) and new tooling popping up every day along side industry standards such as <a href="http://compass-style.org/" target="_blank" rel="external">Compass</a> and <a href="http://bourbon.io" target="_blank" rel="external">Bourbon</a>.</li>
</ul>
<p>Big changes that we made during the switch that are unrelated to the tooling:</p>
<ul>
<li>We broke apart the source files.</li>
<li>As mentioned above, we switched to a Flexbox-based layout. “What about IE8,” you say again? Tables. <a href="https://github.com/videojs/video.js/blob/a5dad5ade29a0ae33e0b80c600f1a06c953aff52/src/css/components/_control-bar.scss#L55-L58" target="_blank" rel="external">Srsly</a>.</li>
<li>Improved support for responsive layouts.</li>
<li>We simplified the amount of customization we explicitly allow in the source to encourage people to build <em>on top</em> of the base skin, not edit it directly.</li>
<li>On the simplification note, we tried to simplify the base skin as much as possible. Our goal was to allow designers to build <em>anything</em> on top of the base without having to entirely start from scratch.</li>
<li>And more!</li>
</ul>
<h3 id="Switched-to-Material-Icons"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Switched-to-Material-Icons" class="headerlink" title="Switched to Material Icons"></a>Switched to Material Icons</h3><p>The switch to an icon font in version 4 was a huge win for Video.js. It allowed designers to do things as basic as style component icon colors with <em>just CSS</em>. It simplified the code base by allowing us not not worry about things like image sprites or other image optimizations. The only recurring issue we ran into was the process around adding new icons to the set, which ultimately involved just uploading the font back to <a href="https://icomoon.io/" target="_blank" rel="external">IcoMoon</a> and re-exporting.</p>
<p>In version 5, we’ve switched everything about our icon set. First we went with a new set of icons: Google’s <a href="https://www.google.com/design/icons/" target="_blank" rel="external">Material Icons</a>. This was a big step forward in terms of appearance, but we had the same issue as far as adding new icons. To fix that process we created new <a href="https://github.com/videojs/font" target="_blank" rel="external">Font tooling</a> for the project.</p>
<p>The tooling is really simple, but it allows anyone to write out a JSON configuration file pointing to any SVGs they have access to. The output of that tool is the font files themselves along with a new SCSS partial that gets imported into our Sass workflow in the core project at build.</p>
<p>We primarily use the Material icons, but occasionally we have to pull in a social media icon from another set, which this process greatly simplifies. See icons missing in the set that you’d like to use? Give the tool a try and let us know what you think!</p>
<h2 id="Rebuilt-the-library-in-ES6-Babel-Browserify-including-Modules-and-Classes"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Rebuilt-the-library-in-ES6-Babel-Browserify-including-Modules-and-Classes" class="headerlink" title="Rebuilt the library in ES6/Babel/Browserify including Modules and Classes"></a>Rebuilt the library in ES6/Babel/Browserify including Modules and Classes</h2><p>5.0 comes with bit of enlightenment as we ditch our not-built-here syndrome and make a leap to post-modern development practices.</p>
<p>When we started work on the new version we originally planned to just use browserify and CommonJS modules, but when we took a closer look at the great work being done on <a href="https://babeljs.io" target="_blank" rel="external">Babel</a>, it only made sense to jump again to ES6 modules and save ourselves another code transition down the road, while at the same time gaining a lot of great new JavaScript features.</p>
<p>Side-stepping any argument of the validity of JavaScript Classes, Video.js has always used classes for the internal UI framework. We used a custom class implementation that was of course incompatible with other custom implementations, so the move to ES6 opens the door for some potential interoperability with other frameworks as more people use ES6 classes specifically.</p>
<p>With the move to modules we’ve also opened the door to using more of the glorious ecosystem that is <a href="https://www.npmjs.com" target="_blank" rel="external">npm</a>. We’ve started to toss out some of the non-core internal libraries that required us to be experts in just about everything, and replace them with other community-built modules. So far this includes libraries like <a href="https://lodash.com" target="_blank" rel="external">lodash</a> and <a href="https://github.com/raynos/xhr" target="_blank" rel="external">raynos/xhr</a>, and we’re actively looking for opportunies where we can share more code.</p>
<h3 id="What-does-this-mean-for-the-end-user"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#What-does-this-mean-for-the-end-user" class="headerlink" title="What does this mean for the end user?"></a>What does this mean for the end user?</h3><p>This should make it easier for end-users of videojs, especially if they use browserify themselves. With this change, users can just<br><code>require(&#39;video.js&#39;)</code> in their <code>app.js</code> or whenever they need it to instantiate players. In addition, plugins that were written<br>using browserify themselves can be added very easily using browserify and <code>require</code> as well. Of course, you can use Babel and<br>ES6 modules as well. For example, your <code>app.js</code> could look like the following, assuming browserify and babel for ES6 syntax:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// import videojs</span></span><br><span class="line"><span class="keyword">import</span> videojs <span class="keyword">from</span> <span class="string">'video.js'</span>;</span><br><span class="line"><span class="comment">// import several plugins.</span></span><br><span class="line"><span class="comment">// Each requires videojs itself and registers itself accordingly.</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'videojs-playlist'</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="string">'videojs-thumbnail'</span>;</span><br><span class="line"><span class="comment">// this isn't ready yet, unfortunately</span></span><br><span class="line"><span class="keyword">import</span> <span class="string">'videojs-contrib-hls'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// make a player</span></span><br><span class="line"><span class="keyword">let</span> player = videojs(<span class="string">'my-video'</span>);</span><br><span class="line"><span class="comment">// initialize some plugins</span></span><br><span class="line">player.playlist(myplaylist);</span><br><span class="line">player.thumbnail(myThumbnailConfig);</span><br></pre></td></tr></table></figure>
<h2 id="Added-support-for-responsive-layouts-including-auto-sizing-to-the-video-content"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Added-support-for-responsive-layouts-including-auto-sizing-to-the-video-content" class="headerlink" title="Added support for responsive layouts including auto-sizing to the video content"></a>Added support for responsive layouts including auto-sizing to the video content</h2><p><a href="https://www.youtube.com/watch?v=0AEFvF2bHtw&amp;feature=youtu.be&amp;t=50m37s" target="_blank" rel="external">Check out this video from the SF Vid Tech meetup for quick overview.</a></p>
<p><em>Proper</em> support for responsive layouts has been a long time request. We’ve had tips and guides for how to make it work in the old version, but now it’s seamlessly built into the player. First we have two easy CSS classes you can just add to the embed code, <code>vjs-16-9</code> and <code>vjs-4-3</code>.</p>
<p><code>&lt;video class=&quot;video-js vjs-16-9 vjs-default-skin&quot; ...&gt;&lt;/video&gt;;</code></p>
<p>Or you can set the player to a fluid layout in the options and it will <strong>automatically update to match the aspect ratio of the content.</strong>, whether you set a width, height, or neither.</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> myPlayer = videojs(id, &#123; <span class="attr">fluid</span>: <span class="literal">true</span>, <span class="attr">preload</span>: <span class="string">'metadata'</span> &#125;);</span><br></pre></td></tr></table></figure>
<p>This was very tricky to implement, but well worth the effort. We have a <a href="http://jsbin.com/qucinu/edit?html,output" target="_blank" rel="external">jsbin example page</a> where you can try out different options.</p>
<h2 id="Added-support-for-HTTP-Live-Streaming-in-desktop-browsers-WITHOUT-Flash"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Added-support-for-HTTP-Live-Streaming-in-desktop-browsers-WITHOUT-Flash" class="headerlink" title="Added support for HTTP Live Streaming in desktop browsers WITHOUT Flash"></a>Added support for HTTP Live Streaming in desktop browsers WITHOUT Flash</h2><p>We’ve been chasing down the last excuses for using Flash for video for awhile now and have reached some major milestones. <a href="http://videojs.github.io/videojs-contrib-hls/" target="_blank" rel="external">videojs-contrib-hls</a> 1.0 (it’s about time!) will use <a href="https://w3c.github.io/media-source/" target="_blank" rel="external">Media Source Extensions</a>, an advanced video element API, to provide HLS playback in Chrome and Microsoft Edge. Besides the enhanced debuggability of doing everything in Javascript, most of the computation has been moved to a web worker and is hardware accelerated on platforms that support it. That means even 60fps or 4k streams should play back without a stutter and your battery will get less of a workout, too. As part of that work, we’ve split off the code we use to repackage HLS video into a separate project in the video.js org: <a href="https://github.com/videojs/mux.js" target="_blank" rel="external">mux.js</a>. If you’re interested in how video works down at the bit level, check it out! We’re always looking for new contributors.</p>
<h2 id="Switched-from-Closure-Compiler-to-Uglify-We-STOPPED-mangling-object-properties"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Switched-from-Closure-Compiler-to-Uglify-We-STOPPED-mangling-object-properties" class="headerlink" title="Switched from Closure Compiler to Uglify (We STOPPED mangling object properties)"></a>Switched from Closure Compiler to Uglify (We STOPPED mangling object properties)</h2><p>In version 4.0 we introduced Google’s Closure Compiler into our build chain. It’s <strong>advanced optimizations mode</strong> saved us 25% in filesize over UglifyJS at the time. The downsides were that it required us to write the code in very specific ways and mangled internal object properties, which made contributing, debugging, and writing plugins much more difficult. The reality today is that with gzip and improved bandwidth, video.js users are pushing us less and less to squeeze the last bit of filesize out of the library. So for 5.0 we’ve switched back to UglifyJS. Plugin authors rejoice!</p>
<h2 id="Improved-audio-only-support"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Improved-audio-only-support" class="headerlink" title="Improved audio-only support"></a>Improved audio-only support</h2><p>Hey did you know? Video.js also supports the HTML5 audio tag. Try it out and let us know what you think.</p>
<p><code>&lt;audio id=&quot;my_audio_1&quot; class=&quot;video-js vjs-default-skin&quot; controls data-setup=&quot;{}&quot;&gt;&lt;source src=&quot;MY_AUDIO_FILE.mp3&quot; type=&quot;audio/mp3&quot;&gt;&lt;/source&gt;&lt;/audio&gt;</code></p>
<h2 id="Added-6-more-language-translations"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Added-6-more-language-translations" class="headerlink" title="Added 6 more language translations"></a>Added 6 more language translations</h2><p>Ever since we implemented localization in Video.js there’s been a wave of contributions from all over the world. With 5.0 comes Danish, Bosnian, Serbian, Croatian, Finnish, and Turkish. This brings the number of lanugages supported to 25!</p>
<h2 id="New-definition-around-plugins"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#New-definition-around-plugins" class="headerlink" title="New definition around plugins"></a>New definition around plugins</h2><p>Plugins mostly have not changed from how they worked in Videojs 4.x. You still register and use them the same way.<br>The only major change is that if you are instantiating a plugin inside the config of a player, this plugin will get run<br>before the player is ready. This is so that if plugins are doing some UI work or adding themselves as children of the player<br>they can do so early on. This means that plugins that require the player to be ready would need to handle that themselves or<br>else not support instantiation via the player config. Ex:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">videojs(<span class="string">'my-video'</span>, &#123;</span><br><span class="line">  plugins: &#123;</span><br><span class="line">    playlists: &#123;&#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>
<p>As part of the update to videojs 5 and our switch from Google’s Closure Compiler to Uglify,<br>we’ve been focusing on making the plugin experience better.<br>We’ve made sure to export some of the utility functions that we use inside our own codebase to make writing plugins easier.<br>This way plugins don’t need to include extra code themselves if a function, merge, for example, is available from videojs.</p>
<p>Also, we’re encouraging plugin authors to publish their plugins on npm. If the plugins are tagged with <code>videojs-plugin</code>,<br>they’ll show up on our <a href="http://videojs.com/plugins/" target="_blank" rel="external">spiffy new plugins listing page</a>.</p>
<h2 id="New-player-skin-designer-on-Codepen"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#New-player-skin-designer-on-Codepen" class="headerlink" title="New player skin designer on Codepen"></a>New player skin designer on Codepen</h2><p>We’re taking a slightly different approach with <a href="http://codepen.io/heff/pen/EarCt/left/?editors=010" target="_blank" rel="external">the designer</a> now. Instead of exposing all CSS properties from the default skin, we’ve set up a template starter that has fewer options and allows you to get at the more common customizations more easily.</p>
<p>It’s also using <a href="http://codepen.io" target="_blank" rel="external">Codepen</a>, which is a great service and much better than hosting the designer ourselves. If you use it to make a cool skin, be sure to let us know. Tweet at @videojs or comment on the designer.</p>
<p><a href="http://codepen.io/heff/pen/EarCt/left/?editors=010" target="_blank" rel="external">http://codepen.io/heff/pen/EarCt/left/?editors=010</a></p>
<h2 id="New-project-governance-model"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#New-project-governance-model" class="headerlink" title="New project governance model"></a>New project governance model</h2><p>Jumping right on that band wagon, we’re implementing a governance model for the project that’s similar to <a href="https://github.com/nodejs/node/blob/20dae2a90610d7b6243dffc3c88a0cd2dfbcb7ce/GOVERNANCE.md" target="_blank" rel="external">Node.js/io.js</a> and <a href="http://rfc.zeromq.org/spec:22" target="_blank" rel="external">0MQ’s C4.1</a>. Along with some better structure around the project it comes with a lower bar for becoming an official maintainer of the project. We’re aiming to have a more diverse set of people and companies representing the leadership of Video.js.</p>
<h2 id="Improved-the-definition-of-a-playback-technology-or-“tech”"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Improved-the-definition-of-a-playback-technology-or-“tech”" class="headerlink" title="Improved the definition of a playback technology or “tech”"></a>Improved the definition of a playback technology or “tech”</h2><p>The creator of our most popular plugin (<a href="https://github.com/eXon/videojs-youtube" target="_blank" rel="external">the YouTube plugin</a>) took on the task of improving the relationship between the player and techs. “Tech” is the term we use to describe the translation layer between the player API and the underlying video objects, which can be the HTML5 video element, plugins like <a href="https://github.com/videojs/video-js-swf" target="_blank" rel="external">Flash</a> and <a href="https://github.com/Afterster/videojs-silverlight" target="_blank" rel="external">Silverlight</a>, or other players like <a href="https://github.com/eXon/videojs-youtube" target="_blank" rel="external">Youtube</a> and <a href="https://github.com/eXon/videojs-vimeo" target="_blank" rel="external">Vimeo</a>. If you’ve built a tech or are intersted in building one, check out the changes in 5.0.</p>
<h2 id="Switched-to-JSDoc-from-a-home-grown-docs-parser"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Switched-to-JSDoc-from-a-home-grown-docs-parser" class="headerlink" title="Switched to JSDoc from a home-grown docs parser"></a>Switched to JSDoc from a home-grown docs parser</h2><p>In the last version we had a <a href="https://github.com/videojs/doc-generator" target="_blank" rel="external">custom built docs generator</a> that used <a href="http://esprima.org" target="_blank" rel="external">esprima</a> to parse the AST and create a lot of the API docs just from the code, with JSDoc tags filling in the rest. That could still be a good project, but it’s become too much to maintain and too limited for plugin authors.</p>
<p>For 5.0 we’ve switched to <a href="https://github.com/jsdoc3/jsdoc" target="_blank" rel="external">jsdoc</a>. Check out the <a href="http://docs.videojs.com" target="_blank" rel="external">new docs site</a>. Anyone want to help us design it? :)</p>
<h2 id="Switched-to-BrowserStack-for-automated-browser-testing"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Switched-to-BrowserStack-for-automated-browser-testing" class="headerlink" title="Switched to BrowserStack for automated browser testing"></a>Switched to BrowserStack for automated browser testing</h2><p>For 5.0 we have moved from <a href="https://saucelabs.com" target="_blank" rel="external">Sauce Labs</a> to <a href="https://www.browserstack.com" target="_blank" rel="external">BrowserStack</a> as our browser provider for automated testing. BrowserStack is a cross-browser testing tool that provides desktop and mobile browsers and are currently rolling out support for real mobile devices. We moved to BrowserStack to reduce the amount of timeout errors, build time and false positives we were seeing in our builds previously. This stability has allowed us to expand our testing coverage to include iOS, Android and all supported versions of Internet Explorer.</p>
<h2 id="Switched-to-Fastly-for-our-CDN"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#Switched-to-Fastly-for-our-CDN" class="headerlink" title="Switched to Fastly for our CDN"></a>Switched to Fastly for our CDN</h2><p>The CDN-hosted version of Video.js at vjs.zencdn.net is downloaded over 2 BILLION times every month, even with agressive browser-side caching. Video.js is relatively small in file size but that’s still 34 TB per month. We were previously piggy-backing on Brightcove’s Akamai account, but Fastly offered to host the library for free. We gave it a shot and fell in love. In full disclosure, our testing found that Fastly didn’t perform quite as well as Akamai internationally, but Fastly’s user interface, API, and real-time purge are things of beauty and make our <a href="http://github.com/videojs/cdn" target="_blank" rel="external">CDN deploy process</a> much simpler.</p>
<h2 id="New-Website-and-Logo"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#New-Website-and-Logo" class="headerlink" title="New Website and Logo!"></a>New Website and Logo!</h2><p><img src="http://67.media.tumblr.com/cb1841277ee68c248443e42c0391e286/tumblr_inline_nvf06qcRca1qzc111_540.png" alt="Video.js Logo"></p>
<p>We simplified it a bit. What do you think?</p>
<p>If you don’t feel comfortable contributing to Video.js we can always use help on <a href="http://videojs.com" target="_blank" rel="external">the website</a>. It gets <strong>over 200,000 unique views</strong> every month. Contribute at <a href="https://github.com/videojs/videojs.com" target="_blank" rel="external">the website repo</a>.</p>
<h1 id="HALP"><a href="/Video-js-5-The-Only-Thing-That’s-Changed-Is-Everything-except-for-like-3-things-that-didn-t-including-the-name/#HALP" class="headerlink" title="HALP!"></a>HALP!</h1><p>It’s our community that keeps Video.js actually decent and <strong>truly free</strong> (Apache 2), so don’t be shy. Jump in and submit a bug, build a plugin, or design a skin.</p>
<p>In conclusion, it’s been a good year of a lot of good work. Thanks!</p>
<p><span class="no-fancybox"><br><a href="https://news.ycombinator.com/item?id=10298267" target="_blank" rel="external"><img width="18" src="http://66.media.tumblr.com/1e6ec3eacf62a57d0543b01cb4454527/tumblr_inline_nvesinCDHy1qzc111_500.gif"></a><a href="https://twitter.com/videojs/status/648921250882977792" target="_blank" rel="external"><img width="18" src="http://66.media.tumblr.com/2872e2376c584d2abe4293d442e367e2/tumblr_inline_nvesehMSl91qzc111_540.png"></a><br></span><br><img src="http://feeds.feedburner.com/~r/video-js/~4/ASsV6seqM8A" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;First and foremost, &lt;strong&gt;THANK YOU&lt;/strong&gt; to the 25 contributors who completed and merged &lt;strong&gt;146 pull requests&lt;/strong&gt; and upd
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>It&#39;s here: 5.0 release candidates!</title>
    <link href="http://blog.videojs.com/It-s-here-5-0-release-candidates/"/>
    <id>http://blog.videojs.com/It-s-here-5-0-release-candidates/</id>
    <published>2015-06-08T19:59:42.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<p>Today we&rsquo;re releasing our first official 5.0 release candidate. We&rsquo;re really excited to get this into the wild, but a lot has changed under hood. It should be stable for normal usage, but we&rsquo;ve got a limited number of test devices (and testers for that matter), so what we need now is for people to bang on 5.0 and let us know what breaks!</p>
<p>You can either grab the master branch from Github and run <code>grunt</code> to create your own build, or we&rsquo;ll push each new release candidate to the CDN. We&rsquo;re going to be moving quickly and pushing new candidates when we uncover / fix bugs, so be sure to check for new versions! As of this post, the newest release is <a href="http://vjs.zencdn.net/5.0.0-rc.2/video.js" target="_blank" rel="external">5.0-rc.2</a>. If you&rsquo;d like to see a demo, we&rsquo;ve got one up on <a href="http://jsbin.com/halokodoxo/1/edit?html,output" target="_blank" rel="external">JSBin</a>.</p>
<h2 id="What-rsquo-s-different"><a href="/It-s-here-5-0-release-candidates/#What-rsquo-s-different" class="headerlink" title="What&rsquo;s different?"></a>What&rsquo;s different?</h2><h3 id="New-Base-Theme"><a href="/It-s-here-5-0-release-candidates/#New-Base-Theme" class="headerlink" title="New Base Theme"></a>New Base Theme</h3><p>The most obvious difference you&rsquo;ll see when you load up the release candidate is most likely going to be the new base theme. We&rsquo;ve worked hard to simplify the theme and make it possible to do as much as possible with purely CSS.</p>
<p><img src="https://cloudup.com/c0dLiQlBE8F+" alt="screenshot"></p>
<p>There are elements in the control bar that aren&rsquo;t shown by default, but can be by simply overriding a little CSS. For example, if you&rsquo;d rather use an inline volume control instead of the popup menu, you could make these changes:</p>
<p><code>css
.video-js .vjs-volume-menu-button { display: none; }
.video-js .vjs-mute-control, .video-js .vjs-volume-control { display: flex; }</code></p>
<p>This just hides the <code>.vjs-volume-menu-button</code> control, and unhides the mute control / inline volume control. Other things that are available but hidden by default are a time divider (<code>.vjs-time-devider</code>), total duration (<code>.vjs-duration</code>), and a spacer (<code>.vjs-custom-control-spacer</code>).</p>
<h3 id="ES6"><a href="/It-s-here-5-0-release-candidates/#ES6" class="headerlink" title="ES6"></a>ES6</h3><p>Thanks to the incredible <a href="http://babeljs.io" target="_blank" rel="external">Babel project</a>, we&rsquo;re able to write ES2015 and have it transpiled to ES5. It&rsquo;s fantastic, and means we get glorious things such as string interpolation, so reading our codebase <code>just got a whole lot ${_.sample([&#39;better&#39;, &#39;awesomer&#39;, &#39;more fantastic&#39;, &#39;less plus-y&#39;])}</code>.</p>
<p>On our Wiki we have a page devoted to <a href="https://github.com/videojs/video.js/wiki/ES6-Features-used-in-the-source" target="_blank" rel="external">ES6 features we use extensively</a>. There are probably a few little things missing, but if you familiarize yourself with those features you should feel comfortable reading the Video.js source.</p>
<p>We&rsquo;re also using <a href="http://browserify.org" target="_blank" rel="external">Browserify</a> (with a Babelify transform), so now we&rsquo;re able to take advantage of all the browser packages NPM has to offer. One big area this has allowed us to improve is utility functions, which are now provided by <a href="http://lodash.com" target="_blank" rel="external">Lodash</a>.</p>
<h3 id="Plugins"><a href="/It-s-here-5-0-release-candidates/#Plugins" class="headerlink" title="Plugins"></a>Plugins</h3><p>Plugins are initialized earlier than before, giving plugin developers even more control over the player experience. They&rsquo;re now initialized before other components are added (like the control bar), but after the player div is created. Keep in mind you&rsquo;ll now need to wait for the <code>ready</code> event to do things such as append items to the control bar.</p>
<p>The plugin-development world should have also gotten more predictable since we&rsquo;ve gotten a little less aggressive with our minification. Keep in mind that when you want to subclass a component externally (not using ES2015), you&rsquo;ll want to use <a href="https://github.com/videojs/video.js/wiki/5.0-Change-Details#switched-to-es6-classes-updated-how-you-subclass-components" target="_blank" rel="external"><code>videojs.extends</code></a>.</p>
<p>You can find more information on our <a href="https://github.com/videojs/video.js/wiki/5.0-Change-Details" target="_blank" rel="external">5.0 change details</a> wiki page.</p>
<h1 id="Want-to-be-helpful"><a href="/It-s-here-5-0-release-candidates/#Want-to-be-helpful" class="headerlink" title="Want to be helpful?"></a>Want to be helpful?</h1><p>Use it! We&rsquo;ve spent months using this player in very specific ways while development, but there&rsquo;s always the issue of &ldquo;not being able to <a href="http://en.wiktionary.org/wiki/see_the_forest_for_the_trees" target="_blank" rel="external">see the forest for the trees</a>&rdquo;. If you find issues while testing the player, please let us know on the <a href="https://github.com/videojs/video.js/issues" target="_blank" rel="external">issue tracker</a>.<br><img src="http://feeds.feedburner.com/~r/video-js/~4/lLH3vkDw9AY" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Today we&amp;rsquo;re releasing our first official 5.0 release candidate. We&amp;rsquo;re really excited to get this into the wild, but a lot has
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
      <category term="release" scheme="http://blog.videojs.com/tags/release/"/>
    
      <category term="videojs" scheme="http://blog.videojs.com/tags/videojs/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 4.12 - The last of the 4 minors</title>
    <link href="http://blog.videojs.com/Video-js-4-12-The-last-of-the-4-minors/"/>
    <id>http://blog.videojs.com/Video-js-4-12-The-last-of-the-4-minors/</id>
    <published>2015-02-18T13:32:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<h2 id="Much-improved-WebVTT-support"><a href="/Video-js-4-12-The-last-of-the-4-minors/#Much-improved-WebVTT-support" class="headerlink" title="Much improved WebVTT support"></a>Much improved WebVTT support</h2><p>We added basic WebVTT support really early on, which we were pretty proud of. As browsers added support, however, our shim started to lag a bit, or at the very least, cause issues with browsers that required native support (here’s looking at you, iOS).</p>
<p>So, we’re happy to announce that our text track support is vastly improved with this version! Instead of continuing to try and build out our own WebVTT parser, we’ve pulled in Mozilla’s fantastic work, <a href="https://github.com/mozilla/vtt.js" target="_blank" rel="external">VTT.js</a>. This is the WebVTT implementation used in Firefox / Gecko, so we’re confident that this is a substantial leap forward for Video.js and our accessibility efforts.</p>
<h2 id="Don’t-use-captions-Feeling-disappointed"><a href="/Video-js-4-12-The-last-of-the-4-minors/#Don’t-use-captions-Feeling-disappointed" class="headerlink" title="Don’t use captions? Feeling disappointed?"></a>Don’t use captions? Feeling disappointed?</h2><p>You shouldn’t feel disappointed, this is a great day! This release includes a lot of fixes, and although fixes are always exciting to the people affected, other people can feel a hefty dose of “meh”. We’re excited to say, however, that this release is exciting for another, very important reason.</p>
<p>This is the <strong>last minor</strong> release in the version 4 family. There might be a few patches, but from now on, master is officially version 5.0-in-waiting. Party.</p>
<p><img src="http://media.giphy.com/media/d89VuJ4GflFfO/giphy.gif" alt="party"></p>
<h4 id="Notable-updates-and-fixes-for-4-12"><a href="/Video-js-4-12-The-last-of-the-4-minors/#Notable-updates-and-fixes-for-4-12" class="headerlink" title="Notable updates and fixes for 4.12"></a>Notable updates and fixes for 4.12</h4><ul>
<li>The hide / show methods now toggle a class (<code>.vjs-hidden</code>) instead of applying inline styles. Make sure to update your stylesheet as well!</li>
<li>A new <code>.vjs-scrubbing</code> class gets applied while, you guessed it, scrubbing so menus can be prevented from erroneously showing on hover.</li>
<li>Improved url parsing in IE9.</li>
<li>Ever wondered what version you’re using? Now there’s a VERSION key. Woot.</li>
<li>New <code>.vjs-ended</code> class that’s added when playback reaches the end of the timeline (also known as: ended).</li>
<li>Player networkState and readyState properties available across techs</li>
<li>Video.js is now exported as a named AMD module</li>
<li>Mobile scrolling improvements</li>
<li>And more! Fixes galore!</li>
</ul>
<h2 id="Translation-party-continues"><a href="/Video-js-4-12-The-last-of-the-4-minors/#Translation-party-continues" class="headerlink" title="Translation party continues"></a>Translation party continues</h2><p>We’re now up to <strong>19</strong> community submitted translations! Entirely new translations in this release include:</p>
<ul>
<li>Traditional Chinese</li>
<li>Vietnamese</li>
<li>Czech</li>
<li>Catalan</li>
<li>Bulgarian</li>
<li>Turkish</li>
</ul>
<h2 id="Video-js-in-the-wild"><a href="/Video-js-4-12-The-last-of-the-4-minors/#Video-js-in-the-wild" class="headerlink" title="Video.js in the wild"></a>Video.js in the wild</h2><p>To be terribly honest, there is a level of starstruck over a few of these. Normally we just do one, but hey…</p>
<h4 id="Social-Media"><a href="/Video-js-4-12-The-last-of-the-4-minors/#Social-Media" class="headerlink" title="Social Media"></a>Social Media</h4><ul>
<li><a href="http://instagram.com/p/aye9QFmB96" target="_blank" rel="external">Instagram</a></li>
<li><a href="https://twitter.com/ActuallyNPH/status/560049149836808192" target="_blank" rel="external">Twitter</a></li>
<li><a href="http://sh1ps-testing.tumblr.com/post/111334784868/lorem-ipsum-and-stuff" target="_blank" rel="external">Tumblr</a></li>
</ul>
<h4 id="Global-News-Outlets"><a href="/Video-js-4-12-The-last-of-the-4-minors/#Global-News-Outlets" class="headerlink" title="Global News Outlets"></a>Global News Outlets</h4><ul>
<li><a href="http://graphics.wsj.com/data-mining-of-emotions/" target="_blank" rel="external">Wall Street Journal</a></li>
<li><a href="http://www.theguardian.com/film/video/2015/feb/17/whiplash-should-win-best-picture-oscars-2015-video" target="_blank" rel="external">The Guardian</a></li>
<li><a href="http://www.bloomberg.com/news/videos/2015-02-13/a-harvard-mad-scientist-invented-ice-cream-that-has-skin" target="_blank" rel="external">Bloomberg</a></li>
<li><a href="http://www.dbtv.no/3827291177001#Dette_har_statsbudsjettet_%C3%A5_si_for_din_%C3%B8konomi" target="_blank" rel="external">Dagbladet</a></li>
</ul>
<h2 id="New-plugins-from-the-community"><a href="/Video-js-4-12-The-last-of-the-4-minors/#New-plugins-from-the-community" class="headerlink" title="New plugins from the community"></a>New plugins from the community</h2><ul>
<li><a href="https://github.com/matthojo/videojs-Background" target="_blank" rel="external">videojs-Background</a>: A plugin that allows for videos to be displayed as a full background to any element.</li>
<li><a href="https://github.com/space87/videojs-BrightCove-tracking" target="_blank" rel="external">videojs-brightcoveAnalytics</a>: Allow tracking of views/impressions &amp; engagement data in videojs for Brightcove videos</li>
<li><a href="https://github.com/spchuang/videojs-caption" target="_blank" rel="external">videojs-caption</a>: Have the most flexibility and power for displaying caption videojs</li>
<li><a href="https://github.com/walsh9/videojs-transcript" target="_blank" rel="external">videojs-transcript</a>: Display an interactive transcript from caption or subtitle tracks.</li>
<li><a href="https://github.com/theonion/videojs-autoplay-toggle" target="_blank" rel="external">videojs-autoplay-toggle</a>: adds an autoplay toggle which will persist to cookies or localstorage.</li>
<li><a href="https://github.com/cladera/videojs-offset" target="_blank" rel="external">videojs-offset</a>: Allows you to play a segment of the video.</li>
<li><a href="https://github.com/mente/videojs-youtube-progress" target="_blank" rel="external">videojs-youtube-progress</a>: Preserve progress seeker when control bar is hidden.</li>
<li><a href="https://github.com/FbF/projectorjs" target="_blank" rel="external">projectorjs</a>: A small no-dependencies JavaScript library that enables the display of overlays on native HTML5 video elements, or (optionally) video elements powered by videojs.</li>
<li><a href="https://github.com/collab-project/videojs-record" target="_blank" rel="external">videojs-record</a>: A video.js plugin for recording audio/video files.</li>
<li><a href="https://github.com/Dash-Industry-Forum/dash.js/tree/v1.2.0/contrib/videojs" target="_blank" rel="external">videojs-dashjs</a>: Loads dash.js as a tech to support MPEG-DASH videos.</li>
<li><a href="https://github.com/Afterster/videojs-silverlight" target="_blank" rel="external">videojs-silverlight</a>: Allows you to play WMV, WMA, MP4, MP3, WAV and FLAC medias through Silverlight within Video.js.</li>
<li><a href="https://github.com/Afterster/videojs-vlc" target="_blank" rel="external">videojs-vlc</a>: Allows you to play all media through VLC web plug-in within Video.js.</li>
<li><a href="https://github.com/Afterster/videojs-aurora" target="_blank" rel="external">videojs-aurora</a>: Allows you to play WAV, OGG, MP3, M4A, AAC and FLAC medias through Aurora.js within Video.js.</li>
<li><a href="https://github.com/Afterster/videojs-java" target="_blank" rel="external">videojs-java</a>: Allows you to play AIFF, AVI, GSM, MID, MPG, MP2, MOV, AU and WAV medias through Java within Video.js.</li>
</ul>
<h2 id="Raw-list-of-changes"><a href="/Video-js-4-12-The-last-of-the-4-minors/#Raw-list-of-changes" class="headerlink" title="Raw list of changes"></a>Raw list of changes</h2><ul>
<li>@PeterDaveHello added a Traditional Chinese translation (<a href="https://github.com/videojs/video.js/pull/1729" target="_blank" rel="external">view</a>)</li>
<li>@mmcc updated the hide/show functions to use a class instead of inline styles (<a href="https://github.com/videojs/video.js/pull/1681" target="_blank" rel="external">view</a>)</li>
<li>@mister-ben added better handling of the additional videojs() arguments when the player is already initialized (<a href="https://github.com/videojs/video.js/pull/1730" target="_blank" rel="external">view</a>)</li>
<li>@anhskohbo added a Vietnamese translation (<a href="https://github.com/videojs/video.js/pull/1734" target="_blank" rel="external">view</a>)</li>
<li>@Sxmanek added a Czech translation (<a href="https://github.com/videojs/video.js/pull/1739" target="_blank" rel="external">view</a>)</li>
<li>@jcaron23 added the vjs-scrubbing CSS class and prevented menus from showing while scrubbing (<a href="https://github.com/videojs/video.js/pull/1741" target="_blank" rel="external">view</a>)</li>
<li>@dmlap fixed URL parsing in IE9 (<a href="https://github.com/videojs/video.js/pull/1765" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev Fixed issue where ManualTimeUpdatesOff was not de-registering events (<a href="https://github.com/videojs/video.js/pull/1793" target="_blank" rel="external">view</a>)</li>
<li>@brycefisher Added a guide on player disposal (<a href="https://github.com/videojs/video.js/pull/1803" target="_blank" rel="external">view</a>)</li>
<li>@toniher added a Catalan translation (<a href="https://github.com/videojs/video.js/pull/1794" target="_blank" rel="external">view</a>)</li>
<li>@mmcc added a VERSION key to the videojs object (<a href="https://github.com/videojs/video.js/pull/1798" target="_blank" rel="external">view</a>)</li>
<li>@mmcc fixed an issue with text track hiding introduced in #1681 (<a href="https://github.com/videojs/video.js/pull/1804" target="_blank" rel="external">view</a>)</li>
<li>@dmlap exported video.js as a named AMD module (<a href="https://github.com/videojs/video.js/pull/1844" target="_blank" rel="external">view</a>)</li>
<li>@dmlap fixed poster hiding when the loadstart event does not fire (<a href="https://github.com/videojs/video.js/pull/1834" target="_blank" rel="external">view</a>)</li>
<li>@chikathreesix fixed an object delete error in Chrome (<a href="https://github.com/videojs/video.js/pull/1858" target="_blank" rel="external">view</a>)</li>
<li>@steverandy fixed an issue with scrolling over the player on touch devices (<a href="https://github.com/videojs/video.js/pull/1809" target="_blank" rel="external">view</a>)</li>
<li>@mmcc improved tap sensitivity (<a href="https://github.com/videojs/video.js/pull/1830" target="_blank" rel="external">view</a>)</li>
<li>@mister-ben added a vjs-ended class when playback reaches the end of the timeline (<a href="https://github.com/videojs/video.js/pull/1857" target="_blank" rel="external">view</a>)</li>
<li>@dmlap Add network and ready state properties (<a href="https://github.com/videojs/video.js/pull/1854" target="_blank" rel="external">view</a>)</li>
<li>@woollybogger exported the hasClass function (<a href="https://github.com/videojs/video.js/pull/1839" target="_blank" rel="external">view</a>)</li>
<li>@DevGavin fixed the Chinese translation (<a href="https://github.com/videojs/video.js/pull/1841" target="_blank" rel="external">view</a>)</li>
<li>@iSimonWeb added font-path variable (<a href="https://github.com/videojs/video.js/pull/1847" target="_blank" rel="external">view</a>)</li>
<li>@shoshomiga added a Bulgarian translation (<a href="https://github.com/videojs/video.js/pull/1849" target="_blank" rel="external">view</a>)</li>
<li>@ragecub3 added a Turkish translation (<a href="https://github.com/videojs/video.js/pull/1853" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev greatly improved text track support and implemented vtt.js as the webvtt parser (<a href="https://github.com/videojs/video.js/pull/1749" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev fixed captions showing by default in Chrome and Safari (<a href="https://github.com/videojs/video.js/pull/1865" target="_blank" rel="external">view</a>)</li>
<li>@mister-ben fixed a woff warning in Firefox (<a href="https://github.com/videojs/video.js/pull/1870" target="_blank" rel="external">view</a>)<img src="http://feeds.feedburner.com/~r/video-js/~4/RLR00vEFKVQ" alt=""></li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;h2 id=&quot;Much-improved-WebVTT-support&quot;&gt;&lt;a href=&quot;/Video-js-4-12-The-last-of-the-4-minors/#Much-improved-WebVTT-support&quot; class=&quot;headerlink&quot; tit
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 4.9 - Now &lt;audio&gt; can join the party!</title>
    <link href="http://blog.videojs.com/Video-js-4-9-Now-can-join-the-party/"/>
    <id>http://blog.videojs.com/Video-js-4-9-Now-can-join-the-party/</id>
    <published>2014-10-02T20:49:00.000Z</published>
    <updated>2019-01-18T19:57:55.577Z</updated>
    
    <content type="html"><![CDATA[<h3 id="HTML5-Audio-support"><a href="/Video-js-4-9-Now-can-join-the-party/#HTML5-Audio-support" class="headerlink" title="HTML5 Audio support"></a>HTML5 Audio support</h3><p>A common request we&rsquo;ve seen is to be able to use Video.js with an <code>&amp;lt;audio&amp;gt;</code> tag, and now you can! Usage is almost identical, you can just include a <code>data-setup={}</code> attribute on an <code>&amp;lt;audio&amp;gt;</code> tag or initialize via Javascript.</p>
<pre><code>&amp;lt;audio id=&quot;audio_example&quot; class=&quot;video-js vjs-default-skin&quot; controls 
  preload=&quot;auto&quot; width=&quot;600&quot; height=&quot;600&quot; 
  poster=&quot;/img/awesome-album-art.png&quot; data-setup=&apos;{}&apos;&amp;gt;
  &amp;lt;source src=&quot;/audio/awesome-music.mp3&quot; type=&apos;audio/mp3&apos;/&amp;gt;
&amp;lt;/audio&amp;gt;
</code></pre><p>The only differences in behavior are that the poster image and controls are never hidden. This allows you to keep up something like album art during playback rather than a black video element. Since there&rsquo;s no interesting content to hide (other than the poster image), we leave the controls showing to mimic a familiar audio player experience.</p>
<p><img src="https://cloudup.com/cp544DZlhuV+" alt="Audio Screenshot"></p>
<p><strong>Note</strong>: The Flash fallback still doesn&rsquo;t support audio-only sources, but we&rsquo;d like to add that in the future. In the meantime, audio playback with MP3 and Ogg sources should work fine in any (modern) browser that&rsquo;s not IE8, so enjoy!</p>
<h3 id="More-translations"><a href="/Video-js-4-9-Now-can-join-the-party/#More-translations" class="headerlink" title="More translations!"></a>More translations!</h3><p>We&rsquo;ve been really excited by the continued support in terms of new translations. This release contains Brazilian Portuguese, Japanese, Italian, French, and Korean, as well as some improvements to the previous Spanish translation. We&rsquo;d love to see the trend continue, so if you&rsquo;re fluent in a language please consider <a href="https://github.com/videojs/video.js/blob/master/CONTRIBUTING.md" target="_blank" rel="external">submitting</a> improvements or whole new localizations!</p>
<h3 id="Video-js-in-the-wild"><a href="/Video-js-4-9-Now-can-join-the-party/#Video-js-in-the-wild" class="headerlink" title="Video.js in the wild"></a>Video.js in the wild</h3><p><a href="http://coursera.org" target="_blank" rel="external">Coursera</a> is an education platform that offers free courses online from some of the world&rsquo;s top institutions. They&rsquo;ve built great tools for video interaction on top of Video.js, and are even going to talk about some of the work they&rsquo;re doing at October&rsquo;s <a href="http://sfvideo.org" target="_blank" rel="external">SF Video Meetup</a>.</p>
<p><img src="https://cloudup.com/cotq6_EJ69v+" alt="Coursera Screenshot"></p>
<h3 id="New-Plugins"><a href="/Video-js-4-9-Now-can-join-the-party/#New-Plugins" class="headerlink" title="New Plugins"></a>New Plugins</h3><p><a href="https://github.com/collab-project/videojs-wavesurfer" target="_blank" rel="external">videojs-wavesurfer</a> - Adds a navigable waveform for audio files, using the excellent wavesurfer.js library.</p>
<h3 id="Full-list-of-changes"><a href="/Video-js-4-9-Now-can-join-the-party/#Full-list-of-changes" class="headerlink" title="Full list of changes"></a>Full list of changes</h3><ul>
<li>@deedos added a Brazilian Portuguese translation (<a href="https://github.com/videojs/video.js/pull/1520" target="_blank" rel="external">view</a>)</li>
<li>@baloneysandwiches added a hasClass method (<a href="https://github.com/videojs/video.js/pull/1464" target="_blank" rel="external">view</a>)</li>
<li>@mynameisstephen fixed an issue where slider event listeners were not being cleaned up (<a href="https://github.com/videojs/video.js/pull/1475" target="_blank" rel="external">view</a>)</li>
<li>@alexrqs cleaned up the Spanish translation (<a href="https://github.com/videojs/video.js/pull/1494" target="_blank" rel="external">view</a>)</li>
<li>@t2y added a Japanese translation (<a href="https://github.com/videojs/video.js/pull/1497" target="_blank" rel="external">view</a>)</li>
<li>@chikathreesix fixed an issue where data-setup options could be missed (<a href="https://github.com/videojs/video.js/pull/1514" target="_blank" rel="external">view</a>)</li>
<li>@seniorflexdeveloper added new translations and translation updates (<a href="https://github.com/videojs/video.js/pull/1530" target="_blank" rel="external">view</a>)</li>
<li>@chikathreesix exported the videojs.Flash.embed method (<a href="https://github.com/videojs/video.js/pull/1533" target="_blank" rel="external">view</a>)</li>
<li>@doublex fixed an issue with IE7 backwards compatibility (<a href="https://github.com/videojs/video.js/pull/1542" target="_blank" rel="external">view</a>)</li>
<li>@mmcc made it possible to override the font-size of captions and subtitles (<a href="https://github.com/videojs/video.js/pull/1547" target="_blank" rel="external">view</a>)</li>
<li>@philipgiuliani added an Italian translation (<a href="https://github.com/videojs/video.js/pull/1550" target="_blank" rel="external">view</a>)</li>
<li>@twentyrogersc fixed the return value when setting the poster source (<a href="https://github.com/videojs/video.js/pull/1552" target="_blank" rel="external">view</a>)</li>
<li>@heff updated to swf v4.5.0 to fix event issues (<a href="https://github.com/videojs/video.js/pull/1554" target="_blank" rel="external">view</a>)</li>
<li>@rpless made the VolumeMenuButton volume more accesible via tab navigation (<a href="https://github.com/videojs/video.js/pull/1519" target="_blank" rel="external">view</a>)</li>
<li>@mmcc added support for audio tags (html5 audio only) (<a href="https://github.com/videojs/video.js/pull/1540" target="_blank" rel="external">view</a>)<img src="http://feeds.feedburner.com/~r/video-js/~4/gKkF36A9CFY" alt=""></li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;h3 id=&quot;HTML5-Audio-support&quot;&gt;&lt;a href=&quot;/Video-js-4-9-Now-can-join-the-party/#HTML5-Audio-support&quot; class=&quot;headerlink&quot; title=&quot;HTML5 Audio suppo
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 4.8.0 released...Prost!</title>
    <link href="http://blog.videojs.com/Video-js-4-8-0-released-Prost/"/>
    <id>http://blog.videojs.com/Video-js-4-8-0-released-Prost/</id>
    <published>2014-09-03T16:50:09.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>This isn&rsquo;t the flashiest minor release ever, but it&rsquo;s hot off the press and ready for use. As mentioned in the last (few) release posts, we&rsquo;re making a concerted effort to be more consistent with releases, so hopefully the trend of bite-sized, scheduled releases will continue.</p>
<h3 id="Translations"><a href="/Video-js-4-8-0-released-Prost/#Translations" class="headerlink" title="Translations"></a>Translations</h3><p>We only just released localization with <a href="/Video-js-4-8-0-released-Prost//post/93989313276/video-js-v4-7-0-built-mostly-by-new-contributors">version 4.7</a>, but we&rsquo;ve already had two pull-requests for new translations! The German translation is included with this release, and you&rsquo;ll find the French translation in the next patch release. If you&rsquo;re fluent in another language, you can help Video.js be even more internationally accessible by submitting a <a href="https://github.com/videojs/video.js/blob/master/CONTRIBUTING.md" target="_blank" rel="external">pull request</a> translating just 24 words / phrases. <code>&amp;lt;/shameless_plug&amp;gt;</code></p>
<h3 id="Video-js-in-the-wild"><a href="/Video-js-4-8-0-released-Prost/#Video-js-in-the-wild" class="headerlink" title="Video.js in the wild"></a>Video.js in the wild</h3><p><a href="http://www.heavybit.com/" target="_blank" rel="external">Heavybit Industries</a> has a speaker series they host at their office, and they&rsquo;ve been kind enough to start posting these sessions online in their <a href="http://www.heavybit.com/library" target="_blank" rel="external">library</a>. The experience they&rsquo;ve built using Video.js is impressive, including syncing the video progress with a transcript below the player.</p>
<p><img src="https://i.cloudup.com/STyw7zm_1R.png" alt="Heavybit Screenshot"></p>
<h3 id="New-plugins"><a href="/Video-js-4-8-0-released-Prost/#New-plugins" class="headerlink" title="New plugins"></a>New plugins</h3><ul>
<li><a href="https://github.com/SunnyLi/videojs-ass" target="_blank" rel="external">videojs-ass</a>: Adds Advanced SubStation Alpha subtitles support.</li>
<li><a href="https://github.com/Hussnain1/Video.js-HD-Toggle-Plugin" target="_blank" rel="external">videojs-hdtoggle</a>: HD button which toggles between HD and non-HD source.</li>
</ul>
<h3 id="Full-list-of-changes"><a href="/Video-js-4-8-0-released-Prost/#Full-list-of-changes" class="headerlink" title="Full list of changes"></a>Full list of changes</h3><ul>
<li>@andekande added a German translation (<a href="https://github.com/videojs/video.js/pull/1426" target="_blank" rel="external">view</a>)</li>
<li>@mattosborn fixed a bug where getting the video element src would overwrite it (<a href="https://github.com/videojs/video.js/pull/1430" target="_blank" rel="external">view</a>)</li>
<li>@songpete fixed a bug where keyboard events were bubbling and causing additional actions (<a href="https://github.com/videojs/video.js/pull/1455" target="_blank" rel="external">view</a>)</li>
<li>@knabar made the inactivity timeout configurable (<a href="https://github.com/videojs/video.js/pull/1409" target="_blank" rel="external">view</a>)</li>
<li>@seniorflexdeveloper added language files to the distribution for including specific languages (<a href="https://github.com/videojs/video.js/pull/1453" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev improved handling of null and NaN dimension values (<a href="https://github.com/videojs/video.js/pull/1449" target="_blank" rel="external">view</a>)</li>
<li>@gkatsev fixed an issue where the controls would break if Flash was initialized too quickly (<a href="https://github.com/videojs/video.js/pull/1470" target="_blank" rel="external">view</a>)</li>
<li>@mmcc fixed an issue where if no playback tech was supported the error could not be caught (<a href="https://github.com/videojs/video.js/pull/1473" target="_blank" rel="external">view</a>)<img src="http://feeds.feedburner.com/~r/video-js/~4/si_kAdmtIKI" alt=""></li>
</ul>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;This isn&amp;rsquo;t the flashiest minor release ever, but it&amp;rsquo;s hot off the press and ready for use. As mentioned in the last (few) rel
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
  </entry>
  
  <entry>
    <title>Video.js v4.7.0 - Built mostly by NEW contributors! Also Google chooses Video.js</title>
    <link href="http://blog.videojs.com/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/"/>
    <id>http://blog.videojs.com/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/</id>
    <published>2014-08-06T14:42:00.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>We&rsquo;re continuing to work hard on improving the contributor experience around the Video.js project and it&rsquo;s paying off. Over half of the changelog is thanks to brand new contributors! Issues and pull requests are getting addressed faster than ever, and I was even allowed to give <a href="http://www.oscon.com/oscon2014/public/schedule/speaker/104522" target="_blank" rel="external">a talk at OSCON</a> on some of the strategies we&rsquo;re using. If you&rsquo;re instersted in getting involved, join the #videojs IRC room or post an issue to let us know.</p>
<h2 id="Google-Chooses-Video-js-for-Google-Media-Framework"><a href="/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/#Google-Chooses-Video-js-for-Google-Media-Framework" class="headerlink" title="Google Chooses Video.js for Google Media Framework"></a>Google Chooses Video.js for Google Media Framework</h2><p>Google recently <a href="http://googleadsdeveloper.blogspot.com/2014/07/google-media-framework-making-online.html" target="_blank" rel="external">announced a new framework</a> for building video experiences and monetization. There are versions of the framework for native iOS and Android apps, and for the browser they chose to use Video.js. Check out <a href="https://github.com/googleads/videojs-ima" target="_blank" rel="external">their video.js plugin</a>, and as it says in their announcement, &ldquo;Stay tuned as well for a deeper dive into Video.js with IMA soon!&rdquo;</p>
<h2 id="Localization"><a href="/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/#Localization" class="headerlink" title="Localization"></a>Localization</h2><p>In this release we&rsquo;ve built the infrastructure for displaying text in other languages. Examples of text include error messages and text used for accessibility. This feature can extend to plugins as well.</p>
<p>Today you can include other languages by including the JSON translations object from the language you want with the player, like in this example for Spanish (es).</p>
<p><code>videojs.options.languages[&#39;es&#39;] = { [translations object] }</code></p>
<p>You can find translations files in <a href="https://github.com/videojs/video.js/tree/master/lang" target="_blank" rel="external">the lang folder</a> of the project. We don&rsquo;t have many translations yet, but we&rsquo;re looking for translators if you&rsquo;d like to help!</p>
<h2 id="Multiple-buffered-regions"><a href="/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/#Multiple-buffered-regions" class="headerlink" title="Multiple buffered regions"></a>Multiple buffered regions</h2><p>With HTML5 video you can skip ahead in the video and the browser will start downloading the part of the file needed for the new position, which is different from how Flash video works by default. Flash will download from the start to the end of the file so you can only skip ahead once it has download that part of the video.</p>
<p>In the HTML5 video API we&rsquo;re given the <code>buffered</code> property which returns a list of time ranges that the browser has downloaded data for. Early on in HTML5 video, browsers only ever reported one time range, but now we have a direct view of what&rsquo;s been downloaded.</p>
<p>In the newest version of the video.js skin you can see the specific regions.</p>
<p><img src="http://67.media.tumblr.com/1420d1b8ee1c54b4eb876b95a5417fd7/tumblr_inline_n9usu442h91qzc111.png" alt=""></p>
<p>We&rsquo;ve kept it subtle so it&rsquo;s not too big of a change. We&rsquo;d love to hear your thoughts on it.</p>
<h2 id="DASH-Everywhere-ish"><a href="/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/#DASH-Everywhere-ish" class="headerlink" title="DASH Everywhere-ish"></a>DASH Everywhere-ish</h2><p>If you haven&rsquo;t seen it yet, check out <a href="http://blog.videojs.com/post/92536319027/dash-everywhere-ish-hack-project">the post</a> on Tom Johson&rsquo;s work getting DASH supported in Video.js, using Flash or the new Media Source Extensions. MPEG-DASH is an adaptive streaming format that Netflix and YouTube are using to stream video to cutting-edge browsers. It has the potential to replace Apple&rsquo;s HTTP Live Streaming format as the main format used for adaptive streaming.</p>
<h2 id="Video-js-on-Conan"><a href="/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/#Video-js-on-Conan" class="headerlink" title="Video.js on Conan!"></a>Video.js on Conan!</h2><p>Conan O’Brien&rsquo;s TeamCoco site is using Video.js with a nicely customized skin and ads integration. <a href="http://teamcoco.com" target="_blank" rel="external">Check it out!</a></p>
<p><a href="http://teamcoco.com/video/conan-dave-franco-tinder-remote" target="_blank" rel="external"><img src="http://65.media.tumblr.com/383082cd857bce0c6abc825e0f4878a8/tumblr_inline_n9utibJ00S1qzc111.png" alt=""></a></p>
<h2 id="New-Skin-by-Cabin"><a href="/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/#New-Skin-by-Cabin" class="headerlink" title="New Skin by Cabin"></a>New Skin by Cabin</h2><p>The team at <a href="http://madebycabin.com" target="_blank" rel="external">Cabin</a> put together a simple and clean <a href="https://github.com/cabin/videojs-sublime-skin" target="_blank" rel="external">new skin for video.js</a>.</p>
<p><img src="http://67.media.tumblr.com/484bf82546666982023e64d49d4a6096/tumblr_inline_n9usohnTgG1qzc111.png" alt=""></p>
<h2 id="New-Plugins"><a href="/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/#New-Plugins" class="headerlink" title="New Plugins"></a>New Plugins</h2><p>A lot of great new plugins have been released!</p>
<ul>
<li><a href="https://github.com/googleads/videojs-ima" target="_blank" rel="external">videojs-ima</a>: Easily integrate the Google IMA SDK into Video.js to enable advertising on your video content.</li>
<li><a href="https://github.com/space87/videojs-BrightCove-tracking" target="_blank" rel="external">videojs-brightcoveAnyaltics</a>: Allow tracking of views/impressions &amp; engagement data in videojs for Brightcove videos</li>
<li><a href="https://github.com/Mewte/videojs-logobrand" target="_blank" rel="external">videojs-logobrand</a>: Add a logo/brand image to the player that appears/disappears with the controls. (also useful as a basic plugin template for learning how Video.JS plugins work.)</li>
<li><a href="https://github.com/aervans/videojs-seek" target="_blank" rel="external">videojs-seek</a>: Seeks to a specific time point specified by a query string parameter.</li>
<li><a href="https://github.com/dirkjanm/videojs-preroll" target="_blank" rel="external">videojs-preroll</a>: Simple preroll plugin that displays an advertisement before the main video</li>
<li><a href="https://github.com/erasche/videojs-framebyframe" target="_blank" rel="external">videojs-framebyframe</a>: Adds buttons for stepping through a video frame by frame</li>
<li><a href="https://github.com/CharlotteDunois/videojs-loopbutton" target="_blank" rel="external">videojs-loopbutton</a>: Adds a loop button to the player</li>
<li><a href="https://github.com/Catofes/videojsABdm" target="_blank" rel="external">videojs-ABdm</a>: Use CommentCoreLibrary to show comments (which is called as DanMu) during playing.</li>
<li><a href="https://github.com/ctd1500/videojs-hotkeys" target="_blank" rel="external">videojs-hotkeys</a>: A plugin for Video.js that enables keyboard hotkeys when the player has focus.</li>
</ul>
<h2 id="New-Release-Schedule"><a href="/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/#New-Release-Schedule" class="headerlink" title="New Release Schedule"></a>New Release Schedule</h2><p>As part of improving the contributor experience we&rsquo;re moving to scheduled releases. We&rsquo;ll now put out a release every other Tuesday as long as there&rsquo;s new changes to release. This will help give everyone a better idea of when specific features and fixes will become available.</p>
<h2 id="Full-list-from-the-change-log"><a href="/Video-js-v4-7-0-Built-mostly-by-NEW-contributors-Also-Google-chooses-Video-js/#Full-list-from-the-change-log" class="headerlink" title="Full list from the change log"></a>Full list from the change log</h2><ul>
<li>Added cross-browser isArray for cross-frame support. fixes #1195 (<a href="https://github.com/videojs/video.js/pull/1218" target="_blank" rel="external">view</a>)</li>
<li>Fixed support for webvtt chapters. Fixes #676. (<a href="https://github.com/videojs/video.js/pull/1221" target="_blank" rel="external">view</a>)</li>
<li>Fixed issues around webvtt cue time parsing. Fixed #877, fixed #183. (<a href="https://github.com/videojs/video.js/pull/1236" target="_blank" rel="external">view</a>)</li>
<li>Fixed an IE11 issue where clicking on the video wouldn&rsquo;t show the controls (<a href="https://github.com/videojs/video.js/pull/1291" target="_blank" rel="external">view</a>)</li>
<li>Added a composer.json for PHP packages (<a href="https://github.com/videojs/video.js/pull/1241" target="_blank" rel="external">view</a>)</li>
<li>Exposed the vertical option for slider controls (<a href="https://github.com/videojs/video.js/pull/1303" target="_blank" rel="external">view</a>)</li>
<li>Fixed an error when disposing a tech using manual timeupdates (<a href="https://github.com/videojs/video.js/pull/1312" target="_blank" rel="external">view</a>)</li>
<li>Exported missing Player API methods (remainingTime, supportsFullScreen, enterFullWindow, exitFullWindow, preload) (<a href="https://github.com/videojs/video.js/pull/1328" target="_blank" rel="external">view</a>)</li>
<li>Added a base for running saucelabs tests from grunt (<a href="https://github.com/videojs/video.js/pull/1215" target="_blank" rel="external">view</a>)</li>
<li>Added additional browsers for saucelabs testing (<a href="https://github.com/videojs/video.js/pull/1216" target="_blank" rel="external">view</a>)</li>
<li>Added support for listening to multiple events through a types array (<a href="https://github.com/videojs/video.js/pull/1231" target="_blank" rel="external">view</a>)</li>
<li>Exported the vertical option for the volume slider (<a href="https://github.com/videojs/video.js/pull/1378" target="_blank" rel="external">view</a>)</li>
<li>Fixed Component trigger function arguments and docs (<a href="https://github.com/videojs/video.js/pull/1310" target="_blank" rel="external">view</a>)</li>
<li>Now copying all attributes from the original video tag to the generated video element (<a href="https://github.com/videojs/video.js/pull/1321" target="_blank" rel="external">view</a>)</li>
<li>Added files to be ignored in the bower.json (<a href="https://github.com/videojs/video.js/pull/1337" target="_blank" rel="external">view</a>)</li>
<li>Fixed an error that could happen if Flash was diposed before the ready callback was fired (<a href="https://github.com/videojs/video.js/pull/1340" target="_blank" rel="external">view</a>)</li>
<li>The up and down arrows can now be used to control sliders in addition to left and right (<a href="https://github.com/videojs/video.js/pull/1345" target="_blank" rel="external">view</a>)</li>
<li>Added a player.currentType() function to get the MIME type of the current source (<a href="https://github.com/videojs/video.js/pull/1320" target="_blank" rel="external">view</a>)</li>
<li>Fixed a potential conflict with other event listener shims (<a href="https://github.com/videojs/video.js/pull/1363" target="_blank" rel="external">view</a>)</li>
<li>Added support for multiple time ranges in the load progress bar (<a href="https://github.com/videojs/video.js/pull/1253" target="_blank" rel="external">view</a>)</li>
<li>Added vjs-waiting and vjs-seeking css classnames and updated the spinner to use them (<a href="https://github.com/videojs/video.js/pull/1351" target="_blank" rel="external">view</a>)</li>
<li>Now restoring the original video tag attributes on a tech change to support webkit-playsinline (<a href="https://github.com/videojs/video.js/pull/1369" target="_blank" rel="external">view</a>)</li>
<li>Fixed an issue where the user was unable to scroll/zoom page if touching the video (<a href="https://github.com/videojs/video.js/pull/1373" target="_blank" rel="external">view</a>)</li>
<li>Added &ldquo;sliding&rdquo; class for when slider is sliding to help with handle styling (<a href="https://github.com/videojs/video.js/pull/1385" target="_blank" rel="external">view</a>)</li>
</ul>
<p>Cheers,</p>
<p>-heff</p>
<p><a href="https://twitter.com/videojs/status/497112744500285440" target="_blank" rel="external">Discuss on Twitter</a> | <a href="https://news.ycombinator.com/item?id=8144578" target="_blank" rel="external">Discuss on Hacker News</a><br><img src="http://feeds.feedburner.com/~r/video-js/~4/xPnVQ6QJIk0" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;We&amp;rsquo;re continuing to work hard on improving the contributor experience around the Video.js project and it&amp;rsquo;s paying off. Over h
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
  </entry>
  
  <entry>
    <title>DASH Everywhere-ish (hack project)</title>
    <link href="http://blog.videojs.com/DASH-Everywhere-ish-hack-project/"/>
    <id>http://blog.videojs.com/DASH-Everywhere-ish-hack-project/</id>
    <published>2014-07-22T11:01:00.000Z</published>
    <updated>2019-01-18T19:57:55.569Z</updated>
    
    <content type="html"><![CDATA[<p>A couple of times a year Brightcove has an internal hackweek where engineers work on any project they&rsquo;d like. In the latest hackweek (2014-07-14) <a href="https://github.com/seniorflexdeveloper" target="_blank" rel="external">Tom Johnson</a> decided to see if he could get DASH supported in as many places as possible, by combining a few of the existing DASH player implementations with Video.js.</p>
<p><a href="http://dashif.org/mpeg-dash/" target="_blank" rel="external">MPEG-DASH</a> (Dynamic Adaptive Streaming over HTTP) is a streaming format similar to Apple&rsquo;s <a href="https://developer.apple.com/streaming/" target="_blank" rel="external">HTTP Live Streaming (HLS)</a>. It allows you to provide multiple versions of a video at different bitrates, and then the player can switch between those versions depending on the user&rsquo;s bandwidth (which is more complicated than you might think).</p>
<p>The two DASH playback implementations used were <a href="https://github.com/Dash-Industry-Forum/dash.js" target="_blank" rel="external">Dash.js</a> and <a href="https://github.com/castlabs/dashas" target="_blank" rel="external">Dash.as</a>. They were combined using video.js&rsquo;s playback tech architecture, which means you can include <a href="https://github.com/videojs/video.js/wiki/Plugins" target="_blank" rel="external">plugins</a> and custom skins and they&rsquo;ll work the same with either playback method.</p>
<p><a href="http://mixxture.com/players/brightcove/dash/demo.html" target="_blank" rel="external">See the results.</a></p>
<h3 id="Browser-Device-Coverage"><a href="/DASH-Everywhere-ish-hack-project/#Browser-Device-Coverage" class="headerlink" title="Browser/Device Coverage"></a>Browser/Device Coverage</h3><p>Using a combination of DASH.AS and DASH.JS will give us the following browser/device coverage:</p>
<h4 id="DASH-JS-media-source-extensions-support"><a href="/DASH-Everywhere-ish-hack-project/#DASH-JS-media-source-extensions-support" class="headerlink" title="DASH.JS (media source extensions support)"></a>DASH.JS (media source extensions support)</h4><ul>
<li>Internet Explorer: 11+</li>
<li>Chrome: 23+</li>
<li>FireFox: 25+ (upcoming version)</li>
<li>Safari (Desktop): 8+ (OSX Yosemite - Fall 2014)</li>
<li>iOS: No</li>
<li>Android: 4.2+ (Chrome)</li>
</ul>
<h4 id="DASH-AS"><a href="/DASH-Everywhere-ish-hack-project/#DASH-AS" class="headerlink" title="DASH.AS"></a>DASH.AS</h4><p>Fallback to any environment that supports Flash Player 10.3</p>
<h3 id="iOS"><a href="/DASH-Everywhere-ish-hack-project/#iOS" class="headerlink" title="iOS"></a>iOS</h3><p>As you can see, the one remaining holdout is iOS and there&rsquo;s currently no word when or if that will happen. Seeing media source extensions support in Safari 8 gives some hope, but my understanding is the requirements for getting support built into iOS are much more significant. My guess is it will happen eventually, but not for a while (and hopefully in-line playback + the fullscreen API will be supported at the same time).</p>
<p>Today, to provide adaptive streaming everywhere, you still need either DASH + HLS, or just HLS (you can use the <a href="https://github.com/videojs/videojs-contrib-hls" target="_blank" rel="external">video.js HLS plugin</a> to support HLS in more browsers).</p>
<h2 id="Tom-rsquo-s-Notes"><a href="/DASH-Everywhere-ish-hack-project/#Tom-rsquo-s-Notes" class="headerlink" title="Tom&rsquo;s Notes"></a>Tom&rsquo;s Notes</h2><p>The demo shows that for environments which support <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaSource" target="_blank" rel="external">Media Source Extensions</a> (MSE) we use a full Javscript implementation via <a href="https://github.com/Dash-Industry-Forum/dash.js" target="_blank" rel="external">Dash.js</a> and as a fallback we use Flash built around <a href="http://sourceforge.net/adobe/osmf/home/Home/" target="_blank" rel="external">OSMF</a> and <a href="https://github.com/castlabs/dashas" target="_blank" rel="external">Dash.as</a>, an open-source plugin provided by <a href="http://castlabs.com" target="_blank" rel="external">Castlabs</a>.</p>
<blockquote>
<p><em>Tom has been working on <a href="https://github.com/seniorflexdeveloper/videojs-osmf" target="_blank" rel="external">videojs-osmf</a> on the side, which helped make this possible.</em></p>
</blockquote>
<h3 id="DASH-AS-Requirements"><a href="/DASH-Everywhere-ish-hack-project/#DASH-AS-Requirements" class="headerlink" title="DASH.AS Requirements"></a>DASH.AS Requirements</h3><h4 id="Player"><a href="/DASH-Everywhere-ish-hack-project/#Player" class="headerlink" title="Player"></a>Player</h4><ul>
<li>Environment must support Flash Player 10.3+</li>
<li>Video.js OSMF Tech (<a href="https://github.com/seniorflexdeveloper/videojs-osmf" target="_blank" rel="external">videojs-osmf</a>)</li>
<li>CastLabs Dash.AS plugin for OSMF (<a href="https://github.com/castlabs/dashas" target="_blank" rel="external">dash.as</a>)</li>
</ul>
<h4 id="Server-Host"><a href="/DASH-Everywhere-ish-hack-project/#Server-Host" class="headerlink" title="Server/Host"></a>Server/Host</h4><ul>
<li>Since the requests are fired from within Flash, a crossdomain.xml file is required.*   Ability to serve byte range requests via query string (myFile.mp4?range=0-1000 || myFile.m4s?bytes=0-1000) is necessary because Flash Player restricts use of the ‘Range’ request header. Castlabs has an .htaccess file which uses mod_rewrite to achieve this. Akamai edge servers accept the bytes query string var as well.</li>
</ul>
<h4 id="Notes"><a href="/DASH-Everywhere-ish-hack-project/#Notes" class="headerlink" title="Notes"></a>Notes</h4><ul>
<li>Something we may want to modify is handling the request/response portions of the workload outside of the Flash Player similar to the Video.js HLS solution. This would remove the need for having a crossdomain.xml, which cannot be normally expected to exist in a DASH focused environment.</li>
<li>Akamai edgesuite appear to be an exception to the above rule, as those domains do in fact have the crossdomain from it’s use as a serving platform under Akamai HD. The Akamai param syntax is ‘myFile.m4s?bytes=XXXX-YYYY’.</li>
<li>In it’s current form the Dash.AS manifest parser is very rigid. We may want to look into implementing a version of the DASH.JS manifest parsing on the AS side, as it is a lot more flexible in terms of structure recognition.</li>
<li>Deeper class inspection shows that the Dash.AS plugin is based on using Netstream in data generation mode, similar to our HLS solution. There may be better way to share the codebase between the two to reduce code duplication.</li>
</ul>
<h3 id="DASH-JS-Requirements"><a href="/DASH-Everywhere-ish-hack-project/#DASH-JS-Requirements" class="headerlink" title="DASH.JS Requirements"></a>DASH.JS Requirements</h3><h4 id="Player-1"><a href="/DASH-Everywhere-ish-hack-project/#Player-1" class="headerlink" title="Player"></a>Player</h4><ul>
<li>Environment must support <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaSource" target="_blank" rel="external">Media Source Extensions</a></li>
<li>DASH Industry Forum DASH.JS library (<a href="https://github.com/Dash-Industry-Forum/dash.js" target="_blank" rel="external">dash.js</a>)</li>
<li>Video.js Dash.js Tech (<a href="https://github.com/Dash-Industry-Forum/dash.js/blob/development/contrib/videojs/videojs-tech-dashjs.js" target="_blank" rel="external">videojs-tech-dashjs</a>)</li>
</ul>
<h4 id="Server-Host-1"><a href="/DASH-Everywhere-ish-hack-project/#Server-Host-1" class="headerlink" title="Server/Host"></a>Server/Host</h4><ul>
<li>Open CORS headers: Access-Control-Allow-Origin: *</li>
<li>Accept use of the Range request header: Access-Control-Allow-Headers:Range, Options</li>
</ul>
<h4 id="Notes-1"><a href="/DASH-Everywhere-ish-hack-project/#Notes-1" class="headerlink" title="Notes"></a>Notes</h4><ul>
<li>Dash.js MPD parsing is significantly more robust in comparison to the Dash.AS solution.</li>
<li>Most streams tested are Akamai based, we should probably try more local and non-Akamai hosted options moving forward.*   In my testing I did see a Youtube DASH/MSE example, and those streams were confirmed to work within Dash.JS as well.</li>
<li>Dash.JS streaming lifecycle and segment loading lifecycle tend to be directly coupled and don’t necessarily fire the element media events at the time expected. For example is duration. While known at the parse complete stage of the manifest load cycle, is not reported to the player until the first of the segments is received.</li>
</ul>
<h3 id="Tech-Compatibility"><a href="/DASH-Everywhere-ish-hack-project/#Tech-Compatibility" class="headerlink" title="Tech Compatibility"></a>Tech Compatibility</h3><p>The independant techs work well together. A slight modification had to be made to the Dash.AS library to insure that it only checked for resources which 1. had a URL and 2. url contained the file extension of either ‘mpd’ or ‘m4s’ for DASH manifests/segments.</p>
<p><strong>NOTE:</strong> Dash.JS tech should be loaded into DOM prior to OSMF tech to insure the OSMF tech is the fallback scenario for DASH playback.<br><img src="http://feeds.feedburner.com/~r/video-js/~4/Wn1NGaDuYmo" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;A couple of times a year Brightcove has an internal hackweek where engineers work on any project they&amp;rsquo;d like. In the latest hackwee
    
    </summary>
    
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
      <category term="html5 video" scheme="http://blog.videojs.com/tags/html5-video/"/>
    
  </entry>
  
  <entry>
    <title>Video.js version 4.6.0 released! It&#39;s been a productive month.</title>
    <link href="http://blog.videojs.com/Video-js-version-4-6-0-released-It-s-been-a-productive-month/"/>
    <id>http://blog.videojs.com/Video-js-version-4-6-0-released-It-s-been-a-productive-month/</id>
    <published>2014-05-20T17:29:00.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>The video.js community has been in full force lately and it&rsquo;s resulted in a lot of great features and fixes, including UI updates, better error messages, and even a <a href="https://github.com/addyosmani/video-js" target="_blank" rel="external">Video.js Polymer element</a> built by <a href="https://twitter.com/addyosmani" target="_blank" rel="external">Addy Osmani</a> himself.</p>
<h3 id="New-Live-UI"><a href="/Video-js-version-4-6-0-released-It-s-been-a-productive-month/#New-Live-UI" class="headerlink" title="New Live UI"></a>New Live UI</h3><p><img src="http://66.media.tumblr.com/18c6ec3dd9a1e04440345bf5ca6630f9/tumblr_inline_n5ue8gvi1Y1qzc111.png" alt=""></p>
<p>Video.js has supported different forms of live video for a while, but a recent update has made the user experience a little clearer. Specifically, a &lsquo;LIVE&rsquo; badge is added to the controls and the seek bar is hidden when seeking isn&rsquo;t permitted.</p>
<h3 id="Clearer-Errors"><a href="/Video-js-version-4-6-0-released-It-s-been-a-productive-month/#Clearer-Errors" class="headerlink" title="Clearer Errors"></a>Clearer Errors</h3><p>A big effort went into improving error situations that developers and viewers might encounter. In cases where the viewer&rsquo;s browser supports neither JavaScript nor HTML5 Video, a more helpful message is shown that informs the viewer how they can support video playback.</p>
<p><img src="http://66.media.tumblr.com/ce08d85f3a1538eecd1d58eccddaa0b6/tumblr_inline_n5ue7u9l4H1qzc111.png" alt=""></p>
<p>In cases where a common media error occurs (e.g. the file doesn&rsquo;t exist or the network fails), an &ldquo;X&rdquo; icon is displayed showing that playback can&rsquo;t continue, and a message is shown describing the issue. Additionally an error message is logged to the javascript console.</p>
<p><img src="http://67.media.tumblr.com/72b11aeeab66657ec39c09366bd19f0e/tumblr_inline_n5ue8z9ZFH1qzc111.png" alt=""></p>
<p>For developers, better logging functions have been added including <code>videojs.log.error()</code>, and they&rsquo;re being used throughout the code base to provide better information and help track down issues.</p>
<h3 id="IE11-Fullscreen"><a href="/Video-js-version-4-6-0-released-It-s-been-a-productive-month/#IE11-Fullscreen" class="headerlink" title="IE11 Fullscreen"></a>IE11 Fullscreen</h3><p>Video.js relies on native browser fullscreen even when Flash is used. IE11 is the first version of Internet Explorer to support native browser fullscreen, and video.js has now been updated to take advantage of that feature and provide a better fullscreen experience for those users.</p>
<h3 id="Playback-Rate-Switching"><a href="/Video-js-version-4-6-0-released-It-s-been-a-productive-month/#Playback-Rate-Switching" class="headerlink" title="Playback Rate Switching"></a>Playback Rate Switching</h3><p>If you ever wanted to speed up or slow down the rate of a video, now you can! HTML5 video browsers have been adding support for playback rate switching, and video.js now has an optional UI component that will let you select the speed. Flash however does not support playback rate switching, so unfortunately it&rsquo;s not a feature that users on older browsers (e.g. IE8) can use.</p>
<p><a href="http://jsbin.com/vikun/1/edit" target="_blank" rel="external">See a demo.</a></p>
<h3 id="New-community-plugins"><a href="/Video-js-version-4-6-0-released-It-s-been-a-productive-month/#New-community-plugins" class="headerlink" title="New community plugins"></a>New community plugins</h3><p>The latest plugins to be added to the <a href="https://github.com/videojs/video.js/wiki/Plugins" target="_blank" rel="external">video.js plugins list</a>.</p>
<ul>
<li><a href="https://github.com/slawrence/videojs-vr" target="_blank" rel="external">videojs-vr</a>: Project video onto different geometric shapes (Sphere, Cube, Cylinder) and view in 3d with optional Oculus Rift support</li>
<li><a href="https://github.com/nicetip/videojs-speed" target="_blank" rel="external">video-speed</a>: Adds customizable video-speed control</li>
<li><a href="https://github.com/CtrHellenicStudies/OpenVideoAnnotation" target="_blank" rel="external">OpenVideoAnnotation</a> - create annotations in video-js using annotator</li>
<li><a href="https://github.com/brightcove/videojs-overlay" target="_blank" rel="external">videojs-overlay</a>: display simple HTML overlays during video playback</li>
<li><a href="https://github.com/addyosmani/video-js" target="_blank" rel="external">video.js-polymer</a>: A video.js element for the Polymer web components framework</li>
</ul>
<p>If you&rsquo;d like a head-start on the scaffolding for a new video.js plugin, check out the <a href="https://github.com/dmlap/generator-videojs-plugin" target="_blank" rel="external">Yeoman video.js plugin generator</a>.</p>
<h2 id="Full-list-from-the-change-log"><a href="/Video-js-version-4-6-0-released-It-s-been-a-productive-month/#Full-list-from-the-change-log" class="headerlink" title="Full list from the change log"></a>Full list from the change log</h2><ul>
<li>Updated the UI to support live video (<a href="https://github.com/videojs/video.js/pull/1121" target="_blank" rel="external">view</a>)</li>
<li>The UI now resets after a source change (<a href="https://github.com/videojs/video.js/pull/1124" target="_blank" rel="external">view</a>)</li>
<li>Now assuming smart CSS defaults for sliders to prevent reflow on player init (<a href="https://github.com/videojs/video.js/pull/1122" target="_blank" rel="external">view</a>)</li>
<li>Fixed the title element placement in menus (<a href="https://github.com/videojs/video.js/pull/1114" target="_blank" rel="external">view</a>)</li>
<li>Fixed title support for menu buttons (<a href="https://github.com/videojs/video.js/pull/1128" target="_blank" rel="external">view</a>)</li>
<li>Fixed extra mousemove events on Windows caused by certain apps, not users (<a href="https://github.com/videojs/video.js/pull/1068" target="_blank" rel="external">view</a>)</li>
<li>Fixed error due to undefined tech when no source is supported (<a href="https://github.com/videojs/video.js/pull/1172" target="_blank" rel="external">view</a>)</li>
<li>Fixed the progress bar not finishing when manual timeupdate events are used (<a href="https://github.com/videojs/video.js/pull/1173" target="_blank" rel="external">view</a>)</li>
<li>Added a more informative and styled fallback message for non-html5 browsers (<a href="https://github.com/videojs/video.js/pull/1181" target="_blank" rel="external">view</a>)</li>
<li>Added the option to provide an array of child components instead of an object (<a href="https://github.com/videojs/video.js/pull/1093" target="_blank" rel="external">view</a>)</li>
<li>Fixed casing on webkitRequestFullscreen (<a href="https://github.com/videojs/video.js/pull/1101" target="_blank" rel="external">view</a>)</li>
<li>Made tap events on mobile less sensitive to touch moves (<a href="https://github.com/videojs/video.js/pull/1111" target="_blank" rel="external">view</a>)</li>
<li>Fixed the default flag for captions/subtitles tracks (<a href="https://github.com/videojs/video.js/pull/1153" target="_blank" rel="external">view</a>)</li>
<li>Fixed compilation failures with LESS v1.7.0 and GRUNT v0.4.4 (<a href="https://github.com/videojs/video.js/pull/1180" target="_blank" rel="external">view</a>)</li>
<li>Added better error handling across the library (<a href="https://github.com/videojs/video.js/pull/1197" target="_blank" rel="external">view</a>)</li>
<li>Updated captions/subtiles file fetching to support cross-origin requests in older IE browsers (<a href="https://github.com/videojs/video.js/pull/1095" target="_blank" rel="external">view</a>)</li>
<li>Added support for playback rate switching (<a href="https://github.com/videojs/video.js/pull/1132" target="_blank" rel="external">view</a>)</li>
<li>Fixed an issue with the loadstart event order that caused the big play button to not hide (<a href="https://github.com/videojs/video.js/pull/1209" target="_blank" rel="external">view</a>)</li>
<li>Modernized the fullscreen API and added support for IE11 (<a href="https://github.com/videojs/video.js/pull/1205" target="_blank" rel="external">view</a>)</li>
<li>Added cross-browser testing with SauceLabs, and added Karma as the default test runner (<a href="https://github.com/videojs/video.js/pull/1187" target="_blank" rel="external">view</a>)</li>
<li>Fixed saucelabs integration to run on commits in TravisCI (<a href="https://github.com/videojs/video.js/pull/1214" target="_blank" rel="external">view</a>)</li>
<li>Added a clearer error message when a tech is undefined (<a href="https://github.com/videojs/video.js/pull/1210" target="_blank" rel="external">view</a>)</li>
<li>Added a cog icon to the font icons (<a href="https://github.com/videojs/video.js/pull/1211" target="_blank" rel="external">view</a>)</li>
<li>Added a player option to offset the subtitles/captions timing (<a href="https://github.com/videojs/video.js/pull/1212" target="_blank" rel="external">view</a>)</li>
</ul>
<p>The new version is available on <a href="http://www.videojs.com" target="_blank" rel="external">videojs.com</a> and  has been added to the CDN.</p>
<p>Cheers,</p>
<p>-<a href="http://blog.heff.me" target="_blank" rel="external">heff</a><br><img src="http://feeds.feedburner.com/~r/video-js/~4/Ho_lv_Coqlc" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;The video.js community has been in full force lately and it&amp;rsquo;s resulted in a lot of great features and fixes, including UI updates, 
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Video.js version 4.5.0 released! Nothing to see here, move along</title>
    <link href="http://blog.videojs.com/Video-js-version-4-5-0-released-Nothing-to-see-here-move-along/"/>
    <id>http://blog.videojs.com/Video-js-version-4-5-0-released-Nothing-to-see-here-move-along/</id>
    <published>2014-03-27T18:49:04.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>Well, sort of… this release is the result of a lot of hard work to speed up the version release process, meaning they&rsquo;ll be coming a lot faster now with smaller sets of changes.</p>
<p>In this release we&rsquo;ve added support for the <a href="http://component.io" target="_blank" rel="external">Component(1)</a> package manager, fixed the captions positioning when the controls are hidden, and helped Android devices know when they can support HLS. ;-) There were a few other changes as well but a lot of the work this round was done on the processes around the project. If you&rsquo;ve spent time in the github issues, you&rsquo;ll hopefully notice an improvement in the response rate on issues and the speed in which bugs get fixed.</p>
<h3 id="New-plugins"><a href="/Video-js-version-4-5-0-released-Nothing-to-see-here-move-along/#New-plugins" class="headerlink" title="New plugins"></a>New plugins</h3><ul>
<li><a href="https://github.com/theonion/videojs-vast-plugin" target="_blank" rel="external">videojs-vast</a>: A VideoJS plugin to play pre-roll videos from a VAST feed</li>
<li><a href="https://github.com/brandonaaskov/videojs-comscore" target="_blank" rel="external">videojs-comscore</a>: Reports to comScore using their latest Streaming Tag SDK</li>
</ul>
<h3 id="Video-js-in-the-wild"><a href="/Video-js-version-4-5-0-released-Nothing-to-see-here-move-along/#Video-js-in-the-wild" class="headerlink" title="Video.js in the wild"></a>Video.js in the wild</h3><p><a href="http://www.toyota-europe.com/cars/new_cars/yaris/index.tmex" target="_blank" rel="external">Toyota Europe!</a> (click a video on that page) I was in Paris a few weeks ago and stopped by the Toyota store on Champs-Elysées. Next to the cars are multimedia touch screens that tell you details and allow you to watch videos. The video player looked kind of familiar, and sure enough it was video.js with a very nice custom skin. It turns out the Toyota Europe website uses video.js as well. Very cool.</p>
<p>If you find video.js on an interesting site somewhere, let us know in the comments.</p>
<h2 id="Full-list-from-the-change-log"><a href="/Video-js-version-4-5-0-released-Nothing-to-see-here-move-along/#Full-list-from-the-change-log" class="headerlink" title="Full list from the change log"></a>Full list from the change log</h2><ul>
<li>Added component(1) support (<a href="https://github.com/videojs/video.js/pull/1032" target="_blank" rel="external">view</a>)</li>
<li>Captions now move down when controls are hidden (<a href="https://github.com/videojs/video.js/pull/1053" target="_blank" rel="external">view</a>)</li>
<li>Added the .less source file to the distribution files (<a href="https://github.com/videojs/video.js/pull/1056" target="_blank" rel="external">view</a>)</li>
<li>Changed src() to return the current selected source (<a href="https://github.com/videojs/video.js/pull/968" target="_blank" rel="external">view</a>)</li>
<li>Added a grunt task for opening the next issue that needs addressing (<a href="https://github.com/videojs/video.js/pull/1059" target="_blank" rel="external">view</a>)</li>
<li>Fixed Android 4.0+ devices&rsquo; check for HLS support (<a href="https://github.com/videojs/video.js/pull/1084" target="_blank" rel="external">view</a>)</li>
</ul>
<p>The new version is available on <a href="http://www.videojs.com" target="_blank" rel="external">videojs.com</a> and  has been added to the CDN.</p>
<p>Cheers,</p>
<p>-heff<br><img src="http://feeds.feedburner.com/~r/video-js/~4/GpehQHGlbCM" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Well, sort of… this release is the result of a lot of hard work to speed up the version release process, meaning they&amp;rsquo;ll be coming 
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Video.js version 4.4.0 released - Now supporting RequireJS and Browserify</title>
    <link href="http://blog.videojs.com/Video-js-version-4-4-0-released-Now-supporting-RequireJS-and-Browserify/"/>
    <id>http://blog.videojs.com/Video-js-version-4-4-0-released-Now-supporting-RequireJS-and-Browserify/</id>
    <published>2014-02-19T17:49:00.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>Version 4.4.0 is here with over 20 updates and fixes. The most notable addition may be support for AMD and CommonJS module loaders, meaning you can now include Video.js using <a href="http://requirejs.org" target="_blank" rel="external">RequireJS</a> or <a href="http://browserify.org" target="_blank" rel="external">Browserify</a>. Video.js can be installed through <a href="http://www.npmjs.org/package/video.js" target="_blank" rel="external">npm</a> already, and we&rsquo;ll soon add support for <a href="http://bower.io" target="_blank" rel="external">bower</a> and <a href="http://component.io" target="_blank" rel="external">component(1)</a> as well.</p>
<h3 id="New-plugins"><a href="/Video-js-version-4-4-0-released-Now-supporting-RequireJS-and-Browserify/#New-plugins" class="headerlink" title="New plugins"></a>New plugins</h3><p>The <a href="https://github.com/videojs/video.js/wiki/Plugins" target="_blank" rel="external">plugin list</a> continues to grow, with more in the works. Checkout the new <a href="http://theonion.github.io/videojs-endcard/" target="_blank" rel="external">endcard plugin</a> built by <a href="http://www.theonion.com" target="_blank" rel="external">The Onion</a>.</p>
<ul>
<li><a href="https://github.com/spchuang/videojs-markers" target="_blank" rel="external">videojs-markers</a> <a href="http://jsbin.com/befob/7/edit" target="_blank" rel="external">[demo]</a> - Add customizable markers on the progress bar</li>
<li><a href="https://github.com/several27/videojs-youtube-videowall" target="_blank" rel="external">videojs-youtube-videowall</a> - <a href="http://jsbin.com/tave/3" target="_blank" rel="external">[demo]</a> - Display video wall of related youtube videos after the video finishes</li>
<li><a href="http://theonion.github.io/videojs-endcard/" target="_blank" rel="external">videojs-endcard</a> - Simple, customizable end card solution for VideoJS</li>
<li><a href="https://github.com/rsadwick/videojs-akamai-analytics" target="_blank" rel="external">videojs-akamai-analytics</a> - Akamai Sola Analytics for video.js</li>
<li><a href="https://github.com/cladera/videojs-stereopanner" target="_blank" rel="external">videojs-stereopanner</a> - Adds stereo channel panning functions</li>
</ul>
<h3 id="Video-js-in-the-wild"><a href="/Video-js-version-4-4-0-released-Now-supporting-RequireJS-and-Browserify/#Video-js-in-the-wild" class="headerlink" title="Video.js in the wild"></a>Video.js in the wild</h3><p>The <a href="https://play.brightcove.com" target="_blank" rel="external">Brightcove Play 2014</a> website recently went live with Video.js as the player. We&rsquo;re also hard at work building Brightcove&rsquo;s next-gen player with Video.js at the core, so stay tuned.</p>
<h2 id="Full-list-from-the-changelog"><a href="/Video-js-version-4-4-0-released-Now-supporting-RequireJS-and-Browserify/#Full-list-from-the-changelog" class="headerlink" title="Full list from the changelog"></a>Full list from the changelog</h2><ul>
<li>Made the poster updateable after initialization (<a href="https://github.com/videojs/video.js/pull/838" target="_blank" rel="external">view</a>)</li>
<li>Exported more textTrack functions (<a href="https://github.com/videojs/video.js/pull/815" target="_blank" rel="external">view</a>)</li>
<li>Moved player ID generation to support video tags with no IDs (<a href="https://github.com/videojs/video.js/pull/845" target="_blank" rel="external">view</a>)</li>
<li>Moved to using QUnit as a dependency (<a href="https://github.com/videojs/video.js/pull/850" target="_blank" rel="external">view</a>)</li>
<li>Added the util namespace for public utility functions (<a href="https://github.com/videojs/video.js/pull/862" target="_blank" rel="external">view</a>)</li>
<li>Fixed an issue with calling duration before Flash is loaded (<a href="https://github.com/videojs/video.js/pull/861" target="_blank" rel="external">view</a>)</li>
<li>Added player methods to externs so they can be overridden (<a href="https://github.com/videojs/video.js/pull/878" target="_blank" rel="external">view</a>)</li>
<li>Fixed html5 playback when switching between media techs (<a href="https://github.com/videojs/video.js/pull/887" target="_blank" rel="external">view</a>)</li>
<li>Fixed Firefox+Flash mousemove events so controls don&rsquo;t hide permanently (<a href="https://github.com/videojs/video.js/pull/899" target="_blank" rel="external">view</a>)</li>
<li>Fixed a test for touch detection (<a href="https://github.com/videojs/video.js/pull/962" target="_blank" rel="external">view</a>)</li>
<li>Updated the src file list for karma tests (<a href="https://github.com/videojs/video.js/pull/948" target="_blank" rel="external">view</a>)</li>
<li>Added more tests for API properties after minification (<a href="https://github.com/videojs/video.js/pull/906" target="_blank" rel="external">view</a>)</li>
<li>Updated projet to use npm version of videojs-swf (<a href="https://github.com/videojs/video.js/pull/930" target="_blank" rel="external">view</a>)</li>
<li>Added support for dist zipping on windows (<a href="https://github.com/videojs/video.js/pull/944" target="_blank" rel="external">view</a>)</li>
<li>Fixed iOS fullscreen issue (<a href="https://github.com/videojs/video.js/pull/977" target="_blank" rel="external">view</a>)</li>
<li>Fixed touch event bubbling (<a href="https://github.com/videojs/video.js/pull/992" target="_blank" rel="external">view</a>)</li>
<li>Fixed ARIA role attribute for button and slider (<a href="https://github.com/videojs/video.js/pull/988" target="_blank" rel="external">view</a>)</li>
<li>Fixed and issue where a component&rsquo;s dispose event would bubble up (<a href="https://github.com/videojs/video.js/pull/981" target="_blank" rel="external">view</a>)</li>
<li>Quieted down deprecation warnings (<a href="https://github.com/videojs/video.js/pull/971" target="_blank" rel="external">view</a>)</li>
<li>Update seek handle to display the current time (<a href="https://github.com/videojs/video.js/pull/902" target="_blank" rel="external">view</a>)</li>
<li>Added requirejs and browserify support (UMD) (<a href="https://github.com/videojs/video.js/pull/998" target="_blank" rel="external">view</a>)</li>
</ul>
<p>The new version is available on <a href="http://www.videojs.com" target="_blank" rel="external">videojs.com</a> and  has been added to the CDN.</p>
<p>Cheers,</p>
<p>-heff<br><img src="http://feeds.feedburner.com/~r/video-js/~4/ZZPGdmp690s" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Version 4.4.0 is here with over 20 updates and fixes. The most notable addition may be support for AMD and CommonJS module loaders, meani
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Video.js version 4.3.0 released w/ shiny new API docs</title>
    <link href="http://blog.videojs.com/Video-js-version-4-3-0-released-w-shiny-new-API-docs/"/>
    <id>http://blog.videojs.com/Video-js-version-4-3-0-released-w-shiny-new-API-docs/</id>
    <published>2013-11-05T19:29:00.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>The biggest change in this update is actually an overhaul of the <a href="https://github.com/videojs/video.js/tree/v4.3.0/docs/api" target="_blank" rel="external">API docs</a>. The best example of the new docs is the <a href="https://github.com/videojs/video.js/blob/v4.3.0/docs/api/vjs.Player.md" target="_blank" rel="external">Player doc</a>, which is the API most video.js users will work with.</p>
<p>The new docs are now automatically generated from the code and code comments, making it easier to keep them up to date with what&rsquo;s currently in the codebase.</p>
<p>One interesting note about the doc-generator is that it uses <a href="http://esprima.org" target="_blank" rel="external">esprima</a>, a tool that reads javascript files and gives back the &ldquo;abstract syntax tree&rdquo; of the code.</p>
<p>For the following javascript:</p>
<pre class="prettify">
var hi;
</pre>

<p>Esprima would generate:</p>
<pre class="prettify">
{
    "type": "Program",
    "body": [
        {
            "type": "VariableDeclaration",
            "declarations": [
                {
                    "type": "VariableDeclarator",
                    "id": {
                        "type": "Identifier",
                        "name": "hi"
                    },
                    "init": null
                }
            ],
            "kind": "var"
        }
    ]
}
</pre>

<p>We&rsquo;re using the AST of the video.js codebase to generate the majority of the information in the docs, which means it requires fewer comments and less work to keep the docs really great as we continue to build. If you&rsquo;re interested in seeing how we&rsquo;re handling that, check out the <a href="https://github.com/videojs/doc-generator" target="_blank" rel="external">doc-generator</a> repo (it&rsquo;s currently only useful with the video.js codebase, but it could be extended to support more).</p>
<h2 id="New-CSS-Options"><a href="/Video-js-version-4-3-0-released-w-shiny-new-API-docs/#New-CSS-Options" class="headerlink" title="New CSS Options"></a>New CSS Options</h2><p>Additional updates include new loading spinner icon options, and a new class for centering the big play button.</p>
<p>Many users have been clear that they&rsquo;d prefer the big play button in the center of the video. While we feel the trend is still moving towards getting the play button out of the way of the content, we wanted to make this feature easier to customize. You can now use the <code>vjs-big-play-centered</code> class on your video tag to center the play button.</p>
<p>To try the new spinner icon options, check out the <a href="http://designer.videojs.com" target="_blank" rel="external">designer</a> and change the icon name used by the spinner class.</p>
<h2 id="Even-more-plugins"><a href="/Video-js-version-4-3-0-released-w-shiny-new-API-docs/#Even-more-plugins" class="headerlink" title="Even more plugins!"></a>Even more plugins!</h2><p>Finally, the most exciting developments are actually happening in the video.js community, with more and more plugins being built. We&rsquo;re up to 26 in the <a href="https://github.com/videojs/video.js/wiki/Plugins" target="_blank" rel="external">plugins list</a>, with more on the way.</p>
<p>If you have some code you&rsquo;ve built on top of video.js that you think might be valuable to others, please share it on the plugins list, or post an issue on the video.js repo if you have questions about the plugin process.</p>
<h2 id="Full-list-from-the-changelog"><a href="/Video-js-version-4-3-0-released-w-shiny-new-API-docs/#Full-list-from-the-changelog" class="headerlink" title="Full list from the changelog"></a>Full list from the changelog</h2><ul>
<li>Added Karma for cross-browser unit testing (<a href="https://github.com/videojs/video.js/pull/714" target="_blank" rel="external">view</a>)</li>
<li>Unmuting when the volume is changed (<a href="https://github.com/videojs/video.js/pull/720" target="_blank" rel="external">view</a>)</li>
<li>Fixed an accessibility issue with the big play button (<a href="https://github.com/videojs/video.js/pull/777" target="_blank" rel="external">view</a>)</li>
<li>Exported user activity methods (<a href="https://github.com/videojs/video.js/pull/783" target="_blank" rel="external">view</a>)</li>
<li>Added a classname to center the play button and new spinner options (<a href="https://github.com/videojs/video.js/pull/784" target="_blank" rel="external">view</a>)</li>
<li>Added API doc generation (<a href="https://github.com/videojs/video.js/pull/801" target="_blank" rel="external">view</a>)</li>
<li>Added support for codecs in Flash mime types (<a href="https://github.com/videojs/video.js/pull/805" target="_blank" rel="external">view</a>)</li>
</ul>
<p>The new version is available on <a href="http://www.videojs.com" target="_blank" rel="external">videojs.com</a> and  has been added to the CDN.</p>
<p>Cheers,</p>
<p>-heff<br><img src="http://feeds.feedburner.com/~r/video-js/~4/HFDZaCSgXYI" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;The biggest change in this update is actually an overhaul of the &lt;a href=&quot;https://github.com/videojs/video.js/tree/v4.3.0/docs/api&quot; targe
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>The Guardian uses Video.js in feature article</title>
    <link href="http://blog.videojs.com/The-Guardian-uses-Video-js-in-feature-article/"/>
    <id>http://blog.videojs.com/The-Guardian-uses-Video-js-in-feature-article/</id>
    <published>2013-11-05T18:15:11.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>It&rsquo;s always nice to find Video.js in the wild, but this <a href="http://www.theguardian.com/world/interactive/2013/nov/01/snowden-nsa-files-surveillance-revelations-decoded" target="_blank" rel="external">article from The Guradian</a> is an especially cool use case. Most of the players don&rsquo;t use controls at all, but rather play/pause based on the user scrolling the page. The ones that do use controls are styled with a white on light gray theme that matches the rest of the page really well.</p>
<p><strong>The article begins with a full-width video that includes controls.</strong><br><img src="http://66.media.tumblr.com/14295587c4d822fd6db3a57be2b555cd/tumblr_inline_mvr6sfqy3m1qzxjzy.png" alt="Big Player"></p>
<p><strong>Most of the videos are short dialogs that are triggered based on scrolling to a certain point in the page. These have no controls other than an external play/pause button.</strong><br><img src="http://65.media.tumblr.com/b45334a76c06433a43a13cbc375fd14b/tumblr_inline_mvr6tukViN1qzxjzy.png" alt="No Controls"></p>
<p><strong>Smaller player with controls.</strong><br><img src="http://67.media.tumblr.com/b7f7111f67442c0afbee754793cc5a0f/tumblr_inline_mvlmf2N5AG1qzxjzy.png" alt="Small Player"><br><img src="http://feeds.feedburner.com/~r/video-js/~4/5makkI_uMys" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;It&amp;rsquo;s always nice to find Video.js in the wild, but this &lt;a href=&quot;http://www.theguardian.com/world/interactive/2013/nov/01/snowden-n
    
    </summary>
    
    
      <category term="gallery" scheme="http://blog.videojs.com/tags/gallery/"/>
    
  </entry>
  
  <entry>
    <title>4.2.2 Patch Release</title>
    <link href="http://blog.videojs.com/4-2-2-Patch-Release/"/>
    <id>http://blog.videojs.com/4-2-2-Patch-Release/</id>
    <published>2013-10-15T18:26:00.000Z</published>
    <updated>2019-01-18T19:57:55.568Z</updated>
    
    <content type="html"><![CDATA[<p>Two bugs have been squashed with this patch:</p>
<ul>
<li>An issue most commonly seen in Firefox where video playback would break when a race condition would occur during video loading (<a href="https://github.com/videojs/video.js/issues/756" target="_blank" rel="external">#756</a>)</li>
<li>An issue where the duration would get stuck at 0:00 when loading the player dynamically (<a href="https://github.com/videojs/video.js/issues/775" target="_blank" rel="external">#775</a>)</li>
</ul>
<p><a href="https://github.com/videojs/video.js/pull/776/files" target="_blank" rel="external">See the changes made</a></p>
<p>This version can be downloaded on <a href="http://www.videojs.com" target="_blank" rel="external">videojs.com</a>, is available on the CDN, and the existing /4.2/ CDN version has been  updated to 4.2.2. (may take time to propagate to your area)</p>
<p>Cheers,</p>
<p>-heff<br><img src="http://feeds.feedburner.com/~r/video-js/~4/I0mpf2qGi7g" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Two bugs have been squashed with this patch:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An issue most commonly seen in Firefox where video playback would break when a 
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Running Video.js unit tests in real browsers with Karma</title>
    <link href="http://blog.videojs.com/Running-Video-js-unit-tests-in-real-browsers-with-Karma/"/>
    <id>http://blog.videojs.com/Running-Video-js-unit-tests-in-real-browsers-with-Karma/</id>
    <published>2013-09-18T23:21:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>If you’ve ever cloned the video.js repository, either to contribute or to build your own version, you’ve no doubt run the video.js unit tests. Until just recently, though, we only had support for running unit tests with grunt, using the PhantomJS browser. Well, that’s changed, with the first phase of our integration with Karma. Now, you’ll be able to run your tests in real browsers.</p>
<p>Setting things up is a snap. After you pull down the latest from video.js and run <code>npm install</code>, simply copy the test/karma.conf.js.example file to test/karma.conf.js, add the browsers you wish to test to the browsers array, and run <code>grunt karma:dev</code>. That’s it. Of course, there are more options that you can configure, but if you want to get the ball rolling quickly, just add browsers, and run the tests. See the test/karma.conf.js.example file for more  instructions.</p>
<p>For our next phases of integration, we’re planning to include support for running tests on mobile devices, as well as running these  tests in a publicly-available location, so that anyone can tell at a glance how things are going.</p>
<p>You can learn more about Karma <a href="https://npmjs.org/package/karma" target="_blank" rel="external">here</a>.</p>
<p>Cheers!</p>
<p>-Jim</p>
<p><img src="http://feeds.feedburner.com/~r/video-js/~4/Iv1mc-5p_Og" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;If you’ve ever cloned the video.js repository, either to contribute or to build your own version, you’ve no doubt run the video.js unit t
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Unauthorized modification of Video.js CDN files</title>
    <link href="http://blog.videojs.com/Unauthorized-modification-of-Video-js-CDN-files/"/>
    <id>http://blog.videojs.com/Unauthorized-modification-of-Video-js-CDN-files/</id>
    <published>2013-09-15T11:23:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p><strong>UPDATE 2013-09-19:</strong></p>
<p>The CDN continues to be secure and we have taken significant steps to ensure it never falls under a similar attack again.</p>
<ul>
<li>Access to the CDN has been restricted to a few key individuals</li>
<li>A third-party service is now monitoring changes made to the CDN</li>
<li>Processes have been defined for responding to any such future issues</li>
</ul>
<p>The original source of this event was the <a href="https://isc.sans.edu/forums/diary/Suspect+Sendori+software/16466" target="_blank" rel="external">Sendori Auto-update Hack</a>, which possibly affected millions of people including, unfortunately, an admin of the CDN.</p>
<hr>
<p>On the morning of September 14, 2013 at 6:25am PDST, we discovered that certain versions of video.js being served from our content delivery network (CDN) had been modified by an unknown attacker. The file was changed to contain malicious code that would attempt to install malware on any Windows or Macintosh computer that loaded the video.js file.  The malware has been identified to be a variant of <a href="https://www.virustotal.com/en/file/ea3be0fb4367e038c602a3de5811821d2367f3326ab2a12f469db4cda06fafa7/analysis/" target="_blank" rel="external">Trojan.PWS.Stealer.1932 or Trojan.Ransom.ED</a>.  We quickly reverted to safe versions of the video.js file, and took steps to ensure that the issue could not reoccur.</p>
<p>The specific files affected were:</p>
<p>vjs.zencdn.net/c/video.js</p>
<p>vjs.zencdn.net/4.0/video.js</p>
<p>vjs.zencdn.net/4.1/video.js</p>
<p>No patch-level versions (e.g. vjs.zencdn.net/4.1.0/video.js) were affected, and neither was the latest version (4.2). Users who host their own copy of Video.js were also not affected.</p>
<p>Potential Impact: Any browsers that loaded the affected files during the compromised period may have prompted users to install malicious software on their computers.</p>
<p>It has been determined that the files were originally modified at 4:30am PDST. The files were repaired at 7:15am PDST and completed propagation to CDN edge caches around the world at 7:51am PDST.</p>
<p>Rest assured that video.js is once again safe to load.  We are currently investigating the root cause. Once we fully understand the nature of the incident, we will provide an update with additional information.</p>
<p>Keeping our users safe is one of our top priorities, and we sincerely apologize to anyone who was negatively impacted by this event.<br><img src="http://feeds.feedburner.com/~r/video-js/~4/wMwHep00UvY" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;strong&gt;UPDATE 2013-09-19:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The CDN continues to be secure and we have taken significant steps to ensure it never falls un
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Video.js 4.2.0 released! RTMP, CSS designer, and stability</title>
    <link href="http://blog.videojs.com/Video-js-4-2-0-released-RTMP-CSS-designer-and-stability/"/>
    <id>http://blog.videojs.com/Video-js-4-2-0-released-RTMP-CSS-designer-and-stability/</id>
    <published>2013-09-06T15:51:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>Happy September! The 4.2.0 release of Video.js has a few interesting updates, and a bunch of stability and polish.</p>
<h2 id="RTMP-Support"><a href="/Video-js-4-2-0-released-RTMP-CSS-designer-and-stability/#RTMP-Support" class="headerlink" title="RTMP Support"></a>RTMP Support</h2><p>First of all, thanks to an impressive collaboration of community members, we now have RTMP support (in <em>beta</em>). <a href="http://jsbin.com/cayake" target="_blank" rel="external">Check out the example</a>.</p>
<p>It&rsquo;s still pretty basic support for RTMP, but we think it will cover a lot of the general use cases. The feature support includes:</p>
<ul>
<li>Single stream (no client-side adaptive support)</li>
<li>Flash only, HTML5 video doesn&rsquo;t support RTMP (but HLS is supported on iOS devices)</li>
<li>On-demand only. We haven&rsquo;t updated the UI to support live yet.</li>
</ul>
<p>To load an RTMP stream in a Video.js player, you&rsquo;ll use a source tag in the same way you would other source types:</p>
<pre class="prettify" style="word-wrap: break-word;">
&lt;source src="rtmp://your.streaming.provider.net/cfx/st/&amp;mp4:path/to/video.mp4" type="rtmp/mp4"&gt;
</pre>

<p>The connection and stream parts are determined by splitting the URL on the first ampersand (&amp;) or the last slash (/).</p>
<pre class="prettify">
[http://myurl.com/streaming&amp;/is/fun](http://myurl.com/streaming&amp;/is/fun) --&gt;
  connection: [http://myurl.com/streaming](http://myurl.com/streaming)
  stream: /is/fun

-or-

[http://myurl.com/streaming/is/fun](http://myurl.com/streaming/is/fun) --&gt;
  connection: [http://myurl.com/streaming/is](http://myurl.com/streaming/is)
  stream: fun
</pre>

<p>The available source types include <code>rtmp/mp4</code> or <code>rtmp/flv</code>.</p>
<p>RTMP has been a much requested feature over the years and it&rsquo;s great to finally have it in the player. Thanks to everyone involved in that work.</p>
<h2 id="Player-Skin-Designer"><a href="/Video-js-4-2-0-released-RTMP-CSS-designer-and-stability/#Player-Skin-Designer" class="headerlink" title="Player Skin Designer"></a>Player Skin Designer</h2><p>If you missed the <a href="http://blog.videojs.com/post/55553002104/new-player-skin-designer-for-video-js">previous blog post</a>, be sure to check out the <a href="http://designer.videojs.com" target="_blank" rel="external">new interface for designing the player skin</a>. It really shows off the customizability of the video.js controls, which are built completely in HTML and CSS.</p>
<p>With the 4.2 release the styles in the designer have been brought up-to-date with the latest player styles.</p>
<h2 id="Control-Bar-Updates"><a href="/Video-js-4-2-0-released-RTMP-CSS-designer-and-stability/#Control-Bar-Updates" class="headerlink" title="Control Bar Updates"></a>Control Bar Updates</h2><p>Also in <a href="http://blog.videojs.com/post/57828375480/hiding-and-showing-video-player-controls">a previous post</a>, I described a number of updates that were made to the control bar to fix cross browser/device issues and improve the overall functionality. As of 4.2.0 all of those updates have made it into the stable release.</p>
<h2 id="Other-Updates"><a href="/Video-js-4-2-0-released-RTMP-CSS-designer-and-stability/#Other-Updates" class="headerlink" title="Other Updates"></a>Other Updates</h2><p>Along with previous updates there&rsquo;s been a number of patches and enhancements along the way. Here&rsquo;s a full list:</p>
<ul>
<li>Added LESS as a CSS preprocessor for the default skin (<a href="https://github.com/videojs/video.js/pull/644" target="_blank" rel="external">view</a>)</li>
<li>Exported MenuButtons for use in the API (<a href="https://github.com/videojs/video.js/pull/648" target="_blank" rel="external">view</a>)</li>
<li>Fixed ability to remove listeners added with one() (<a href="https://github.com/videojs/video.js/pull/659" target="_blank" rel="external">view</a>)</li>
<li>Updated buffered() to account for multiple loaded ranges (<a href="https://github.com/videojs/video.js/pull/643" target="_blank" rel="external">view</a>)</li>
<li>Exported createItems() for custom menus (<a href="https://github.com/videojs/video.js/pull/654" target="_blank" rel="external">view</a>)</li>
<li>Preventing media events from bubbling up the DOM (<a href="https://github.com/videojs/video.js/pull/630" target="_blank" rel="external">view</a>)</li>
<li>Major reworking of the control bar and many issues fixed (<a href="https://github.com/videojs/video.js/pull/672" target="_blank" rel="external">view</a>)</li>
<li>Fixed an issue with minifiying the code on Windows systems (<a href="https://github.com/videojs/video.js/pull/683" target="_blank" rel="external">view</a>)</li>
<li>Added support for RTMP streaming through Flash (<a href="https://github.com/videojs/video.js/pull/605" target="_blank" rel="external">view</a>)</li>
<li>Made tech.features available to external techs (<a href="https://github.com/videojs/video.js/pull/705" target="_blank" rel="external">view</a>)</li>
<li>Minor code improvements (<a href="https://github.com/videojs/video.js/pull/706" target="_blank" rel="external">view</a>)</li>
<li>Updated time formatting to support NaN and Infinity (<a href="https://github.com/videojs/video.js/pull/627" target="_blank" rel="external">view</a>)</li>
<li>Fixed an <code>undefined</code> error in cases where no tech is loaded (<a href="https://github.com/videojs/video.js/pull/632" target="_blank" rel="external">view</a>)</li>
<li>Exported addClass and removeClass for player components (<a href="https://github.com/videojs/video.js/pull/661" target="_blank" rel="external">view</a>)</li>
<li>Made the fallback message customizable (<a href="https://github.com/videojs/video.js/pull/638" target="_blank" rel="external">view</a>)</li>
<li>Fixed an issue with the loading spinner placement and rotation (<a href="https://github.com/videojs/video.js/pull/694" target="_blank" rel="external">view</a>)</li>
<li>Fixed an issue with fonts being flaky in IE8</li>
</ul>
<p>The latest version can be found on <a href="http://www.videojs.com" target="_blank" rel="external">videojs.com</a> through the download link or the CDN hosted version.</p>
<p>Cheers,</p>
<p>-heff<br><img src="http://feeds.feedburner.com/~r/video-js/~4/V_IGILu3P_0" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Happy September! The 4.2.0 release of Video.js has a few interesting updates, and a bunch of stability and polish.&lt;/p&gt;
&lt;h2 id=&quot;RTMP-Suppo
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Hiding and Showing Video Player Controls</title>
    <link href="http://blog.videojs.com/Hiding-and-Showing-Video-Player-Controls/"/>
    <id>http://blog.videojs.com/Hiding-and-Showing-Video-Player-Controls/</id>
    <published>2013-08-09T18:51:47.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<p>Last week I decided to tackle a number of outstanding issues around the control bar, and then proceeded to fall down a rabbit hole of related player updates. I&rsquo;ve thankfully resurfaced now, and figured I&rsquo;d write about a few of the updates that came from it.</p>
<p>One of the expected behaviors of the player&rsquo;s control bar is that it will fade out after a couple of seconds when the user is inactive while watching a video. Previously, the way we achieved this with video.js was through a bit of a CSS trick. When the user&rsquo;s mouse would move out of the video player area, the control bar would be given the classname <code>vjs-fade-out</code>. This class had a visibility transition with an added 2 second delay.</p>
<pre class="prettyprint">
.vjs-fade-out {
  display: block;
  visibility: hidden;
  opacity: 0;

  -webkit-transition: visibility 1.5s, opacity 1.5s;
     -moz-transition: visibility 1.5s, opacity 1.5s;
      -ms-transition: visibility 1.5s, opacity 1.5s;
       -o-transition: visibility 1.5s, opacity 1.5s;
          transition: visibility 1.5s, opacity 1.5s;

  /* Wait a moment before fading out the control bar */
  -webkit-transition-delay: 2s;
     -moz-transition-delay: 2s;
      -ms-transition-delay: 2s;
       -o-transition-delay: 2s;
          transition-delay: 2s;
}
</pre>

<p>When the user&rsquo;s mouse moved back over the player, the class would be removed, canceling any delayed fade-out. This provided a similar experience to how you might expect the controls fading to work, and only took a few lines of javascript to add/remove the class.</p>
<pre class="prettyprint">
player.on('mouseout', function(){ 
  controlBar.addClass('vjs-fade-out'); 
});

player.on('mouseover', function(){ 
  controlBar.removeClass('vjs-fade-out'); 
});
</pre>

<p>There&rsquo;s a few drawbacks though that have made it necessary to move away from this approach.</p>
<ol>
<li>Controls don&rsquo;t fade out in fullscreen mode because the mouse can never move out of the player area.</li>
<li>There is no mouse on mobile devices so different events and interactions are needed to show/hide the controls.</li>
</ol>
<p>In addition to these issues, we want it to be possible for any player component or plugin to hook into the same trigger that hides the controls. Components like social sharing icons should fade out in the same way that the controls do.</p>
<h2 id="User-State"><a href="/Hiding-and-Showing-Video-Player-Controls/#User-State" class="headerlink" title="User State"></a>User State</h2><p>One of the first things that is being added is a <code>userActive</code> property on the player, that can be either <code>true</code> or <code>false</code>. What this does is abstract the controls hiding out to what it is we&rsquo;re actually concerned with, that is, whether the user is currently interacting with the player or just passively watching the video. This also decouples the control bar from tracking the user activity itself, and allows other components to more easily behave the same way as the control bar, through a player-level state.</p>
<p>That actual property is <code>player.userActive()</code> and returns either <code>true</code> or <code>false</code>. When this value is changed, it triggers an event on the player.</p>
<pre class="prettyprint">
player.userActive(true)
    // -&gt; 'useractive' event triggered
player.userActive(false)
    // -&gt; 'userinactive' event triggered
</pre>

<p>A CSS classname of either <code>vjs-user-active</code> or <code>vjs-user-inactive</code> is also added to the player element. The classname is what&rsquo;s actually used now to hide and show the control bar.</p>
<pre class="prettyprint">
.vjs-default-skin.vjs-user-inactive .vjs-control-bar {
  display: block;
  visibility: hidden;
  opacity: 0;

  -webkit-transition: visibility 1.5s, opacity 1.5s;
     -moz-transition: visibility 1.5s, opacity 1.5s;
      -ms-transition: visibility 1.5s, opacity 1.5s;
       -o-transition: visibility 1.5s, opacity 1.5s;
          transition: visibility 1.5s, opacity 1.5s;
}
</pre>

<p>The 2 second delay has been removed from the CSS, and instead will be built into the process of setting the userActive state to false through a javascript timeout. Anytime a mouse event occurs on the player, this timeout will reset. e.g.</p>
<pre class="prettyprint">
var resetDelay, inactivityTimeout;

resetDelay = function(){
    clearTimeout(inactivityTimeout);
    inactivityTimeout = setTimeout(function(){
        player.userActive(false);
    }, 2000);
};

player.on('mousemove', function(){
    resetDelay();
})
</pre>

<p>The mousemove event is called very rapidly while the mouse is moving, and we want to bog down the player process as little as possible during this action, so we&rsquo;re using a technique <a href="http://ejohn.org/blog/learning-from-twitter/" target="_blank" rel="external">written about by John Resig</a>.</p>
<p>Instead of resetting the timeout for every <code>mousemove</code>, the <code>mousemove</code> event will instead set a variable that can be picked up by a javascript interval that&rsquo;s running at a controlled pace.</p>
<pre class="prettyprint">
var userActivity, activityCheck;

player.on('mousemove', function(){
    userActivity = true;
});

activityCheck = setInterval(function() {

  // Check to see if the mouse has been moved
  if (userActivity) {

    // Reset the activity tracker
    userActivity = false;

    // If the user state was inactive, set the state to active
    if (player.userActive() === false) {
      player.userActive(true);
    }

    // Clear any existing inactivity timeout to start the timer over
    clearTimeout(inactivityTimeout);

    // In X seconds, if no more activity has occurred 
    // the user will be considered inactive
    inactivityTimeout = setTimeout(function() {
      // Protect against the case where the inactivity timeout can trigger
      // before the next user activity is picked up  by the 
      // activityCheck loop.
      if (!userActivity) {
        this.userActive(false);
      }
    }, 2000);
  }
}, 250);
</pre>

<p>That may be a lot to follow, and it&rsquo;s a bit simplified from what&rsquo;s actually in the player now, but essentially it allows us to take some of the processing weight off of the browser while the mouse is moving.</p>
<h2 id="Hiding-controls-in-fullscreen"><a href="/Hiding-and-Showing-Video-Player-Controls/#Hiding-controls-in-fullscreen" class="headerlink" title="Hiding controls in fullscreen"></a>Hiding controls in fullscreen</h2><p>Thanks to the new userActive state and the javascript timeout for the delay, the controls no longer require the mouse to move outside of the player area in order to hide, and can now hide in fullscreen mode the same way they do when the player is in the page. This also means we can now hide the mouse cursor in the same way we do the controls, so that it doesn&rsquo;t sit over the player while watching in fullscreen.</p>
<pre class="prettyprint">
.vjs-fullscreen.vjs-user-inactive {
  cursor: none;
}
</pre>

<h2 id="Hiding-controls-on-touch-devices"><a href="/Hiding-and-Showing-Video-Player-Controls/#Hiding-controls-on-touch-devices" class="headerlink" title="Hiding controls on touch devices"></a>Hiding controls on touch devices</h2><p>The expected behavior on touch devices is a little different than in desktop browsers. There is no <code>mousemove</code> event to help determine if the user is active or inactive, so typically a longer delay is added before the controls are faded out. Also, while a click on the video itself in desktop browsers will typically toggle between play and pause, a tap on the video on mobile devices will toggle the controls visibility.</p>
<p>Luckily the framework we&rsquo;ve set up around userActive has made this last part easy enough to set up.</p>
<pre class="prettyprint">
video.on('tap', function(){
  if (player.userActive() === true) {
    player.userActive(false);
  } else {
    player.userActive(true);
  }
});
</pre>

<p>Manually toggling userActive between true and false will apply the appropriate classnames and trigger the events needed to show and hide the controls as you&rsquo;d expect on a mobile device.</p>
<p>The <code>tap</code> event is actually a custom made event, similar to the tap event you&rsquo;ll find in <a href="http://jquerymobile.com" target="_blank" rel="external">jQuery mobile</a>, <a href="http://eightmedia.github.io/hammer.js/" target="_blank" rel="external">Hammer.js</a>, and other mobile touch libraries. A tap event occurs whenever a <code>touchstart</code> event is fired with the associated <code>touchend</code> event firing within 250 milliseconds. If the <code>touchend</code> event takes longer to fire, or if a <code>touchmove</code> event happens between the two, it is not considered a <code>tap</code>.</p>
<h2 id="Conclusion"><a href="/Hiding-and-Showing-Video-Player-Controls/#Conclusion" class="headerlink" title="Conclusion"></a>Conclusion</h2><p>I hope this has given some insight into how that piece of the controls operate in Video.js, and how you can mimic the same interaction if you&rsquo;re building your own plugins for Video.js. Feedback is always appreciated.</p>
<p>Cheers,</p>
<p>-heff<br><img src="http://feeds.feedburner.com/~r/video-js/~4/70tJSFYIq9Y" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Last week I decided to tackle a number of outstanding issues around the control bar, and then proceeded to fall down a rabbit hole of rel
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>New Player Skin Designer for Video.js</title>
    <link href="http://blog.videojs.com/New-Player-Skin-Designer-for-Video-js/"/>
    <id>http://blog.videojs.com/New-Player-Skin-Designer-for-Video-js/</id>
    <published>2013-07-15T19:44:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p><a href="http://designer.videojs.com" title="Video Player Skin Designer" target="_blank" rel="external"><img src="http://65.media.tumblr.com/e1ce78f8543d5e1fffd65e35cfd41b3e/tumblr_inline_mq1y4zEiqe1qz4rgp.png" alt=""></a></p>
<p>Last week Brightcove had an internal hack week where everyone could work on any project they wanted. One of the projects that came out of that was a new <a href="http://designer.videojs.com" title="Video Player Skin Designer" target="_blank" rel="external">video.js skin designer</a>.</p>
<p>The designer allows you to watch changes happen to the skin live as you edit the CSS, making it easier to create a custom look.</p>
<p>Check out <a href="http://codepen.io/heff/pen/wtrHL" target="_blank" rel="external">this familiar looking example</a> that was done in just a few minutes.</p>
<p>Try creating your own and let us know what you think. Better yet, create your own, share it on CodePen.io and post a link in the comments. (It&rsquo;s probably easiest if you start by forking <a href="http://codepen.io/heff/pen/EarCt" title="Video.js Default Skin" target="_blank" rel="external">this unedited example</a>.)</p>
<p>One of my favorite things about video.js is that the skins are built in HTML and CSS, while working across both HTML5 <em>and</em> Flash video. I think this designer does a nice job of showing off how easy that makes it to customize a player&rsquo;s skin.</p>
<p><strong>Some notes on how we built it&hellip;</strong></p>
<p>As a starting point we used Brian Frichette&rsquo;s awesome <a href="https://github.com/brian-frichette/less-preview/" target="_blank" rel="external">LESS2CSS</a>, which gave us a huge head start. Brian has offered to help with the skin designer as well, so that&rsquo;s great!</p>
<p>We haven&rsquo;t added a CSS preprocessor to video.js before because we didn&rsquo;t want the extra layer of abstraction, or the extra step in the build process. When looking at the CSS in the new designer however, it became clear how valuable things like variables can be for helping people understand what&rsquo;s happening in the CSS. Still, we&rsquo;re trying to find the balance between using LESS features and keeping the CSS easily readable by anyone who just knows CSS. That means avoiding some of the more advanced LESS features like conditional statements (though we do use one for big play button positioning).</p>
<p>We chose to use <a href="http://lesscss.org" target="_blank" rel="external">LESS</a> because of the ability to parse the LESS markup in javascript in the browser. I&rsquo;m not aware of any up-to-date in-browser <a href="http://sass-lang.com" target="_blank" rel="external">SASS</a> parsers. The completeness of LESS2CSS also influenced that decision. We&rsquo;re using a small enough subset of features that it doesn&rsquo;t really matter which one we use otherwise, though I do like the idea of using $ for variables over @.</p>
<p>It&rsquo;s hosted on <a href="https://www.nodejitsu.com" target="_blank" rel="external">Nodejitsu</a>, and we&rsquo;re taking advantage of their free hosting for open source. I have to say, it was pretty simple to get the app deployed with their command line tool.</p>
<p>Let us know if you have any thoughts. The code for the designer can be found here: <a href="https://github.com/videojs/designer" target="_blank" rel="external">https://github.com/videojs/designer</a></p>
<p>Cheers,<br>-heff<br><img src="http://feeds.feedburner.com/~r/video-js/~4/-k5HhU559kM" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;a href=&quot;http://designer.videojs.com&quot; title=&quot;Video Player Skin Designer&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;&lt;img src=&quot;http://65.media.tumblr.
    
    </summary>
    
    
      <category term="html5 video" scheme="http://blog.videojs.com/tags/html5-video/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 4.1.0 Released</title>
    <link href="http://blog.videojs.com/Video-js-4-1-0-Released/"/>
    <id>http://blog.videojs.com/Video-js-4-1-0-Released/</id>
    <published>2013-06-28T19:34:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>Just in time for the weekend, the next minor version of Video.js is now available. Updates include:</p>
<ul>
<li>Turned on method queuing for unready playback technologies (flash) (<a href="https://github.com/videojs/video.js/pull/553" target="_blank" rel="external">view</a>)</li>
<li>Blocking user text selection on player components (<a href="https://github.com/videojs/video.js/pull/524" target="_blank" rel="external">view</a>)</li>
<li>Exported requestFullScreen() and cancelFullScreen() in the minified version (<a href="https://github.com/videojs/video.js/pull/555" target="_blank" rel="external">view</a>)</li>
<li>Exported the global players reference, videojs.players (<a href="https://github.com/videojs/video.js/pull/560" target="_blank" rel="external">view</a>)</li>
<li>Added google analytics to the CDN version (<a href="https://github.com/videojs/video.js/pull/568" target="_blank" rel="external">view</a>)</li>
<li>Exported fadeIn/fadeOut for the Component API (<a href="https://github.com/videojs/video.js/pull/581" target="_blank" rel="external">view</a>)</li>
<li>Fixed an IE poster error when autoplaying (<a href="https://github.com/videojs/video.js/pull/593" target="_blank" rel="external">view</a>)</li>
<li>Exported bufferedPercent for the API (<a href="https://github.com/videojs/video.js/pull/588" target="_blank" rel="external">view</a>)</li>
<li>Augmented user agent detection, specifically for Android versions (<a href="https://github.com/videojs/video.js/pull/470" target="_blank" rel="external">view</a>)</li>
<li>Fixed IE9 canPlayType error (<a href="https://github.com/videojs/video.js/pull/606" target="_blank" rel="external">view</a>)</li>
<li>Fixed various issues with captions (<a href="https://github.com/videojs/video.js/pull/609" target="_blank" rel="external">view</a>)</li>
</ul>
<p>You can get the latest version on <a href="http://www.videojs.com" target="_blank" rel="external">videojs.com</a>, either as a download or hosted on our CDN.</p>
<p>Have a great weekend!</p>
<p>-heff<br><img src="http://feeds.feedburner.com/~r/video-js/~4/uqMAcXs28uI" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Just in time for the weekend, the next minor version of Video.js is now available. Updates include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Turned on method queuing
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Video.js 4.0 now available!</title>
    <link href="http://blog.videojs.com/Video-js-4-0-now-available/"/>
    <id>http://blog.videojs.com/Video-js-4-0-now-available/</id>
    <published>2013-05-09T13:10:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>Today we&rsquo;re releasing Video.js 4.0, which is the most solid, lightweight, and I dare say prettiest version yet. It&rsquo;s available for download, on Github, and hosted for free on our CDN.</p>
<p>Version 4.0 received the most community collaboration of any previous version, which speaks to the growing strength of the JavaScript community, the growing popularity of HTML5 video, and an increase in Video.js usage. Over the last year the number of sites using Video.js has more than <a href="http://trends.builtwith.com/media/VideoJS" target="_blank" rel="external">doubled</a>, and each month there are over 200 million hits to the CDN-hosted version alone! Thank you to all of the Video.js community members for contributing code and filing bug reports.</p>
<p>This version is also a milestone in that it&rsquo;s the first version released since <a href="http://blog.videojs.com/post/35666994917/brightcove-acquires-zencoder">Brightcove acquired Zencoder</a> last year. For those who missed the announcement, it was a very good thing for Video.js. In the past, Video.js was a side project for Zencoder that I maintained on top of my regular responsibilities (as if startup life isn&rsquo;t exciting enough). Post-acquisition, Brightcove has not only put me full-time on Video.js, but the Brightcove video player team has become contributors to the project. The Brightcove team is probably the most experienced video player team in the world, supporting the most advanced video technology, for the biggest brands, across all the devices. It&rsquo;s been a privilege to work with them and they&rsquo;ve made major contributions to this version.</p>
<h3 id="4-0-Major-Feature-Summary"><a href="/Video-js-4-0-now-available/#4-0-Major-Feature-Summary" class="headerlink" title="4.0 Major Feature Summary:"></a>4.0 Major Feature Summary:</h3><p>Improved performance through an 18% size reduction using Google Closure Compiler in advanced mode</p>
<ul>
<li>Greater stability through an automated cross-browser/device test suite using TravisCI, Bunyip, and Browserstack.</li>
<li>New plugin interface and plugin listing for extending Video.js</li>
<li>New default skin design that uses font icons for greater customization</li>
<li>Responsive design and retina display support</li>
<li>Improved accessibility through better ARIA support</li>
<li>Moved to Apache 2.0 license</li>
<li>100% JavaScript development tool set including Grunt</li>
</ul>
<h4 id="Improved-Performance"><a href="/Video-js-4-0-now-available/#Improved-Performance" class="headerlink" title="Improved Performance"></a>Improved Performance</h4><p>With version 4.0, performance was our top priority, and a major factor of performance is the time it takes to load the library. What would seem to be minor size reductions can have a big impact, especially when a library will be loaded millions of times a month all over the world. We chose to use Google’s <a href="https://developers.google.com/closure/compiler/" target="_blank" rel="external">Closure Compiler</a> because its “advanced mode” currently provides the most aggressive options for code minification, and so far we’ve seen an 18% reduction in code size, with the potential for more.</p>
<p>Closure Compiler also claims to rewrite code for better runtime performance, though we haven’t had a chance to benchmark this yet.</p>
<p>Some preliminary load-time benchmarking* shows:</p>
<ul>
<li>Player load times in under 50 milliseconds</li>
<li>Playback start times in under 150 milliseconds</li>
<li>Actual video playback seen in under 0.5 seconds (using a CDN hosted MP4)</li>
</ul>
<p>*Initial tests used Chrome with an empty cache on a modern MacBook Pro with a Wi-Fi connection. More formal testing to follow.</p>
<h4 id="Greater-Stability"><a href="/Video-js-4-0-now-available/#Greater-Stability" class="headerlink" title="Greater Stability"></a>Greater Stability</h4><p>Automated cross-browser, cross-device testing is the Holy Grail of testing for a JavaScript library. While building version 4.0, we’ve been able to reach that goal through the use of a number of tools, including:</p>
<ul>
<li><a href="https://travis-ci.org" target="_blank" rel="external">TravisCI</a> - Automatically runs unit tests through <a href="http://phantomjs.org" target="_blank" rel="external">PhantomJS</a> on every pull request made to the Video.js source code</li>
<li><a href="http://ryanseddon.github.io/bunyip/" target="_blank" rel="external">Bunyip</a> + <a href="http://www.browserstack.com" target="_blank" rel="external">Browserstack</a> - Allows us to run tests in cloud-hosted instances of any browser from IE6 to the latest Chrome, and also a wide range of iOS and Android devices.</li>
</ul>
<p>This ability to easily run tests across environments before any new release will give us more protection against regressions, and can allow for a faster feature release cycle.</p>
<h4 id="New-Plugin-Interface"><a href="/Video-js-4-0-now-available/#New-Plugin-Interface" class="headerlink" title="New Plugin Interface"></a>New Plugin Interface</h4><p>The new <a href="https://github.com/videojs/video.js/blob/master/docs/plugins.md" target="_blank" rel="external">plugins API</a> allows developers to more easily add custom features to Video.js. The API works similarly to the jQuery plugin interface, giving developers access to add to or overwrite any piece of Video.js. Once a plugin has been created, it can be shared on the <a href="https://github.com/videojs/video.js/wiki/Plugins" target="_blank" rel="external">Video.js plugin list</a> page on the wiki.</p>
<h4 id="New-Default-Skin"><a href="/Video-js-4-0-now-available/#New-Default-Skin" class="headerlink" title="New Default Skin"></a>New Default Skin</h4><p>With help from the Brightcove UX team, we’ve created a new default skin that’s simpler, more polished, and more customizable. One of the most interesting features is that we’ve moved from using images for icons to font icons. The use of font icons allows you to change the color and size of the icons simply by changing a CSS value. You can see an example of this on the <a href="http://videojs.com" target="_blank" rel="external">Video.js homepage</a>.</p>
<h4 id="Improved-Accessibility"><a href="/Video-js-4-0-now-available/#Improved-Accessibility" class="headerlink" title="Improved Accessibility"></a>Improved Accessibility</h4><p>Greg Kraus, a Video.js community member from <a href="http://www.NCSU.edu" target="_blank" rel="external">NCSU.edu</a>, did some great work testing and improving Video.js accessibility through better use of <a href="http://www.w3.org/WAI/intro/aria" target="_blank" rel="external">ARIA</a> roles. The changes make it so keyboard-only users, screen reader users, and voice-interface users will be able to interact with the video player. UPDATE: Read more in <a href="http://accessibility.oit.ncsu.edu/blog/2013/05/09/accessible-video-js-player-available-on-global-accessibility-awareness-day/" target="_blank" rel="external">Greg&rsquo;s blog post</a>.</p>
<h4 id="Moved-to-Apache-2-0-License"><a href="/Video-js-4-0-now-available/#Moved-to-Apache-2-0-License" class="headerlink" title="Moved to Apache 2.0 License"></a>Moved to Apache 2.0 License</h4><p>Earlier versions of Video.js were released under the LGPLv3 license. LGPL often gets confused with its stricter sibling, GPL, which requires that all code the software touches must also be open source. Video.js is meant to be open and free to use in all contexts, and we want that to be clear, so version 4.0 is now released under Apache 2.0, the same license Twitter Bootstrap is released under.</p>
<h4 id="100-JavaScript-Tool-Set"><a href="/Video-js-4-0-now-available/#100-JavaScript-Tool-Set" class="headerlink" title="100% JavaScript Tool Set"></a>100% JavaScript Tool Set</h4><p>Previously Video.js used Ruby for development tools, including Rake for deployment tasks, and zenflow–an internal Zencoder tool that builds on <a href="https://github.com/nvie/gitflow" target="_blank" rel="external">gitflow</a> for development process workflow. With 4.0 we’ve moved to <a href="http://gruntjs.com" target="_blank" rel="external">Grunt</a> for tasks and we’re building out a tool similar to zenflow in Node.js.</p>
<h4 id="Videojs-com-Now-Open-Source"><a href="/Video-js-4-0-now-available/#Videojs-com-Now-Open-Source" class="headerlink" title="Videojs.com Now Open Source"></a>Videojs.com Now Open Source</h4><p>As part of this release we’ve also made the Videojs.com website open source. So if you see something that should be added or fixed, <a href="https://github.com/videojs/videojs.com" target="_blank" rel="external">fork it</a>.</p>
<h3 id="What-now"><a href="/Video-js-4-0-now-available/#What-now" class="headerlink" title="What now?"></a>What now?</h3><p>Even with all of the updates listed above, this is simply a jumping-off point for what will be an exciting year for Video.js. We’re continuing to improve performance, multi-platform stability, and customizability through plugins and skins. Members of the community have already started work on plugins for some of the more requested features, like playlists, analytics, and advertising.</p>
<p>Follow <a href="http://twitter.com/videojs" target="_blank" rel="external">@videojs</a> or sign up for our <a href="http://zencoder.us2.list-manage2.com/subscribe?u=36f130c3d3fadb2a21d2983b7&amp;id=0f35b0535c" target="_blank" rel="external">newsletter</a> to stay up-to-date on new features and roadmap updates.</p>
<p>If you’d like to get involved in the project, check out our <a href="https://github.com/videojs/video.js/blob/master/CONTRIBUTING.md" target="_blank" rel="external">contributing guide</a>.</p>
<p>Cheers,<br>-<a href="http://blog.heff.me" target="_blank" rel="external">heff</a><br><img src="http://feeds.feedburner.com/~r/video-js/~4/2fKZ1Q5wRIE" alt=""></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Today we&amp;rsquo;re releasing Video.js 4.0, which is the most solid, lightweight, and I dare say prettiest version yet. It&amp;rsquo;s availabl
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Repo Moved!</title>
    <link href="http://blog.videojs.com/Repo-Moved/"/>
    <id>http://blog.videojs.com/Repo-Moved/</id>
    <published>2013-05-06T16:56:59.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>In preparation for the next version we&rsquo;ve moved the source code repository from github.com/zencoder/video-js to <a href="http://github.com/videojs/video.js" target="_blank" rel="external">github.com/videojs/video.js</a></p>
<p>If you have a local clone you can update your clone&rsquo;s upstream URL with:</p>
<pre>git remote set-url upstream git://github.com/videojs/video.js.git</pre>

<p>The relationship between your fork (e.g. github.com/you/video-js) should still be intact, including any pull requests.</p>
<p>Cheers,<br>-heff</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;In preparation for the next version we&amp;rsquo;ve moved the source code repository from github.com/zencoder/video-js to &lt;a href=&quot;http://git
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Site and Support Updates</title>
    <link href="http://blog.videojs.com/Site-and-Support-Updates/"/>
    <id>http://blog.videojs.com/Site-and-Support-Updates/</id>
    <published>2012-11-15T14:54:18.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>After a brief hiatus of helping <a href="http://blog.videojs.com/post/35666994917/brightcove-acquires-zencoder" title="Zencoder acquired by Brightcove">Brightcove and Zencoder come together</a>, I&rsquo;m moving full time to developing and supporting Video.js. Thank you to everyone who has continued to commit code and help out in the forums. </p>
<p>As part of this move I&rsquo;m trying to optimize the tools used for video.js project management and support. The first big change is that the forums are being replaced with <a href="http://stackoverflow.com/questions/tagged/video.js" title="Video.js Support on Stack Overflow" target="_blank" rel="external">Stack Overflow</a> (tag with &ldquo;video.js&rdquo;) and <a href="https://github.com/zencoder/video-js/issues" title="Video.js Submit Issues" target="_blank" rel="external">Github Issues</a>.</p>
<p>Over the last few years Video.js has become more popular than I ever expected, and at the same time Stack Overflow has come up as an incredible tool for supporting developer communities. So along with many other projects like <a href="http://blog.stackoverflow.com/2011/08/facebook-stackoverflow/" title="Facebook on Stack Overflow" target="_blank" rel="external">Facebook</a>, <a href="http://android-developers.blogspot.com/2009/12/hello-stack-overflow.html" title="Android on Stack Overflow" target="_blank" rel="external">Android</a>, and <a href="http://html5boilerplate.com" title="HTML5 Boilerplate" target="_blank" rel="external">HTML5 Boilerplate</a>, I&rsquo;m excited to move support to Stack Overflow&rsquo;s awesome tool and community. I&rsquo;ll be leaving the forums up for bit but from here forward please post questions to Stack Overflow and use the &ldquo;video.js&rdquo; tag.</p>
<p>I&rsquo;ve also begun cleaning up and organizing the <a href="https://github.com/zencoder/video-js/issues" title="Video.js Submit Issues" target="_blank" rel="external">Github Issues</a> for Video.js, which previously existed, but issues were split between the forum and Github. If you find specific bugs with video.js please <a href="https://github.com/zencoder/video-js/issues/new" title="Submit Issue" target="_blank" rel="external">submit them there</a>.</p>
<p>On the project management side of things I&rsquo;ll be using <a href="https://trello.com" title="Trello" target="_blank" rel="external">Trello</a>, and exposing boards so others can see the progress of development.</p>
<p>I&rsquo;m also paring down the site and moving more complex sections to other services that can better handle them. I&rsquo;ve already moved the blog to <a href="http://tumblr.com" title="Tumblr" target="_blank" rel="external">Tumblr</a>, and I&rsquo;m moving the docs to the <a href="https://github.com/zencoder/video-js/tree/master/docs/index.md" title="Video.js docs" target="_blank" rel="external">Github repo</a>, which has built-in docs formatting.</p>
<p>For those starting an open source project today, you can look at this as my guide to supporting an open source project. I wish I would have know to do all this when I started on Video.js.</p>
<p>More project updates coming soon.</p>
<p>Cheers,<br>-heff </p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;After a brief hiatus of helping &lt;a href=&quot;http://blog.videojs.com/post/35666994917/brightcove-acquires-zencoder&quot; title=&quot;Zencoder acquired 
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>Brightcove Acquires Zencoder</title>
    <link href="http://blog.videojs.com/Brightcove-Acquires-Zencoder/"/>
    <id>http://blog.videojs.com/Brightcove-Acquires-Zencoder/</id>
    <published>2012-07-26T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.569Z</updated>
    
    <content type="html"><![CDATA[<p><img src="http://66.media.tumblr.com/tumblr_mdgad5rr0S1qzc111.png" alt=""></p>
<p>Today, Zencoder announced that it is being acquired by <a href="http://brightcove.com" target="_blank" rel="external">Brightcove</a>, the leading online video platform (OVP). You can read more on the specifics in the <a href="http://blog.zencoder.com/2012/07/26/brightcove-acquires-zencoder/" target="_blank" rel="external">Zencoder blog post</a> and <a href="http://www.brightcove.com/en/company/press/brightcove-signs-definitive-agreement-acquire-zencoder" target="_blank" rel="external">press release</a>, but I also wanted to be clear on what this means for Video.js. As you may know, Video.js was created by me (Steve Heffernan, Co-founder of Zencoder) and Zencoder continues to be its core contributor and sponsor (like 37signals to Rails or Joyent to Node.js).</p>
<p>This acquisition means only great things for Video.js. To quickly summarize, Video.js will continue to be a free and open source video player &amp; framework, and Brightcove will be investing more in Video.js than Zencoder ever could.</p>
<p>I wrote the first version of Video.js in early 2010 during Zencoder’s time in Y Combinator (while secluded in our rented house deep in the Santa Cruz mountains). Over the past few years I’ve continued to build the library and pull in contributions from other Zencoder team members and the community, but only on the side of my ongoing Founder and VP of Marketing duties at Zencoder. While Video.js has continued to gain popularity among developers and is now being <a href="http://trends.builtwith.com/media/VideoJS" target="_blank" rel="external">used on over 25,000 websites</a>, there’s still work to be done and room to grow. So one of the more significant changes that will be happening is that Brightcove will be putting me on Video.js full time, freeing me up to work on the core of the project and to better support the Video.js community, both users and contributors.</p>
<p>Beyond this, Brightcove has a first-class player development team backing their platform’s video player. While the specifics of how the two teams and players will work together are still being discussed, we have agreement on our philosophies and views about where player technology is going. This combined knowledge and collaboration is sure to have a positive impact for both players.</p>
<p>While the additional resources will have a big impact, the best open source software projects only got to where they are through the contributions of developers in the community. So if you’ve previously been cautious to dig into the source or push back a specific feature or bug fix, I hope this news only helps encourage you to jump in and help make Video.js the best resource for working with video in the browser.</p>
<p>There will be more info to come as things progress, but please feel free to ask any questions in the comments below.</p>
<p>Cheers,</p>
<p>Steve &amp; The Zencoder Team</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;img src=&quot;http://66.media.tumblr.com/tumblr_mdgad5rr0S1qzc111.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Today, Zencoder announced that it is being acquired by 
    
    </summary>
    
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
  </entry>
  
  <entry>
    <title>Version 3.2 Update</title>
    <link href="http://blog.videojs.com/Version-3-2-Update/"/>
    <id>http://blog.videojs.com/Version-3-2-Update/</id>
    <published>2012-03-23T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>First of all, check out the new <a href="/Version-3-2-Update//tag-builder/">video tag builder</a>. The previous version of this site had an embed code builder, and people were <a href="http://help.videojs.com/discussions/problems/873-whered-the-embed-builder-go" target="_blank" rel="external">pretty disappointed</a> that the new site didn&rsquo;t. So I&rsquo;m happy to announce that it&rsquo;s available again, now as an HTML5 video tag builder that could probably be used outside of Video.js, it includes track tags, and even lets you test the settings. Let me know if you have any feedback on it.</p>
<p>The most notable change in this release is probably the completely overhauled &lt;track&gt; tag support.</p>
<p><a href="https://gist.github.com/4092295.js?file=html5-track-tag.html" target="_blank" rel="external">https://gist.github.com/4092295.js?file=html5-track-tag.html</a></p>
<p>The new version supports subtitles, captions, and even chapters. When you include tracks of different kinds, Video.js will automatically create menus in the player where users can select the language to display, or which chapter to jump to. Video.js also now supports the new <a href="http://dev.w3.org/html5/webvtt/" target="_blank" rel="external">WebVTT</a> text format, which is not far off from the previously supported WebSRT format but did take some tweaking in the parser. Not all WebVTT placement features are supported yet, but the basics of displaying text are, and we&rsquo;ll be working to get more WebVTT features built in.</p>
<p>Additionally there was work done to make some API methods accessible earlier. For any method that isn&rsquo;t a getter (returns a specific value from the player), if you call the method before the playback technology (HTML5/Flash) is ready, it will now cache the call until it is ready. So where previously you might have had to wait for the ready callback:</p>
<p><a href="https://gist.github.com/4092295.js?file=wait-for-ready.js" target="_blank" rel="external">https://gist.github.com/4092295.js?file=wait-for-ready.js</a></p>
<p>You could now do:</p>
<p><a href="https://gist.github.com/4092295.js?file=no-wait-for-ready.js" target="_blank" rel="external">https://gist.github.com/4092295.js?file=no-wait-for-ready.js</a></p>
<p>Again, that&rsquo;s just for methods where you are setting a value or triggering an action. If you try to get a value back like <code>myPlayer.duration()</code>, you&rsquo;ll get nothing until the player is ready.</p>
<p>One other feature that was requested in the forums was automatically translating relative video URLs to absolute URLs for the flash fallback. This was an issue with the CDN hosted version which involved loading a remote SWF file which didn&rsquo;t have the same context as the player. Before we would just tell people to use full URLs (http://) but that shouldn&rsquo;t be an issue anymore.</p>
<p>Thanks to everyone that&rsquo;s helped contribute code lately, and apologies for any long response times in the forums as I continue to try to push out code.</p>
<p>Here&rsquo;s the full change log for the release.</p>
<h3 id="3-2-0-2012-03-20-baxter"><a href="/Version-3-2-Update/#3-2-0-2012-03-20-baxter" class="headerlink" title="3.2.0 / 2012-03-20 / baxter"></a>3.2.0 / 2012-03-20 / baxter</h3><ul>
<li>Updated docs with more options.</li>
<li>Overhauled HTML5 Track support.</li>
<li>Fixed Flash always autoplaying when setting source.</li>
<li>Fixed localStorage context</li>
<li>Updated &lsquo;fullscreenchange&rsquo; event to be called even if the user presses escape to exit fullscreen.</li>
<li>Automatically converting source URL to absolute for Flash fallback.</li>
<li>Created new ‘loadedalldata&rsquo; event for when the source is completely downloaded</li>
<li>Improved player.destroy(). Now removes elements and references.</li>
<li>Refactored API to be more immediately available.</li>
</ul>
<p>Cheers,<br> -Heff</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;First of all, check out the new &lt;a href=&quot;/Version-3-2-Update//tag-builder/&quot;&gt;video tag builder&lt;/a&gt;. The previous version of this site had 
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Version 3.1 Update</title>
    <link href="http://blog.videojs.com/Version-3-1-Update/"/>
    <id>http://blog.videojs.com/Version-3-1-Update/</id>
    <published>2012-01-30T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>This is the first release since the initial 3.0 launch, aside from some hotfixes that went out immediately. It includes a number of fixes for things that users in the <a href="http://help.videojs.com" target="_blank" rel="external">forums</a> found right off the bat.</p>
<p>One feature that&rsquo;s optional for testing in this release is iFrame Mode for Flash. One the of the unique things about Video.js is we haven&rsquo;t built any controls into our Flash player, and instead use HTML and CSS to create the controls for the Flash side as well. This keeps the experience consistent and the Flash player very lightweight, however there&rsquo;s a number of issues that you run into with Flash when you take an approach like this. If you&rsquo;ve ever tried to resize the parent of a Flash object, or hide a Flash object and then show it again, you&rsquo;ve probably run into the issue of Flash reloading in Firefox. This is a bug that&rsquo;s been in Firefox for <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=90268" target="_blank" rel="external">quite a long time</a> however it looks like it might be fixed by version 13 (currently 9). To add on top of this, with the new <a href="https://wiki.mozilla.org/Gecko:FullScreenAPI" target="_blank" rel="external">browser fullscreen API</a>, the other browsers now also reload Flash when you go to native fullscreen.</p>
<p>We&rsquo;ve found a bit of a fix where if you embed the Flash object in an iframe first, it can get around the reloading in some of these cases. So in the new version there&rsquo;s an option to turn this on and try it.</p>
<p><a href="https://gist.github.com/4092929.js?file=iframe-mode.js" target="_blank" rel="external">https://gist.github.com/4092929.js?file=iframe-mode.js</a></p>
<p>We&rsquo;ll be doing some more testing to make sure it&rsquo;s stable before we push it out to everyone.</p>
<p>Here&rsquo;s the full change log for the release.</p>
<h4 id="3-1-0-2012-01-30-leonardo"><a href="/Version-3-1-Update/#3-1-0-2012-01-30-leonardo" class="headerlink" title="3.1.0 / 2012-01-30 / leonardo"></a>3.1.0 / 2012-01-30 / leonardo</h4><ul>
<li>Added CSS fix for Firefox 9 fullscreen (in the rare case that it&rsquo;s enabled)</li>
<li>Replaced swfobject with custom embed to save file size.</li>
<li>Added flash iframe-mode, an experimental method for getting around flash reloading issues.</li>
<li>Fixed issue with volume knob position. Improved controls fading.</li>
<li>Fixed ian issue with triggering fullscreen a second time.</li>
<li>Fixed issue with getting attributes in Firefox 3.0</li>
<li>Escaping special characters in source URL for Flash</li>
<li>Added a check for if Firefox is enabled which fixes a Firefox 9 issue</li>
<li>Stopped spinner from showing on &lsquo;stalled&rsquo; events since browsers sometimes don&rsquo;t show that they&rsquo;ve recovered.</li>
<li>Fixed CDN Version which was breaking dev.html</li>
<li>Made full-window mode more independent</li>
<li>Added rakefile for release generation</li>
</ul>
<p>Cheers,<br> -Heff</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;This is the first release since the initial 3.0 launch, aside from some hotfixes that went out immediately. It includes a number of fixes
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Video.js Version 3.0!</title>
    <link href="http://blog.videojs.com/Video-js-Version-3-0/"/>
    <id>http://blog.videojs.com/Video-js-Version-3-0/</id>
    <published>2012-01-10T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>After months and months of work we&rsquo;re happy to announce Video.js version 3.0. Some of the exiting new features include:</p>
<ul>
<li>Same HTML/CSS Skin for both HTML5 and Flash video</li>
<li>Super lightweight Flash fallback player for browsers that don&rsquo;t support HTML5 video</li>
<li>Free CDN hosting by Level3 A lot more releases and developments are on their way!</li>
</ul>
<p>Cheers,<br>-Heff</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;After months and months of work we&amp;rsquo;re happy to announce Video.js version 3.0. Some of the exiting new features include:&lt;/p&gt;
&lt;ul&gt;
&lt;l
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Lynda.com HTML5 Video Tutorial Released</title>
    <link href="http://blog.videojs.com/Lynda-com-HTML5-Video-Tutorial-Released/"/>
    <id>http://blog.videojs.com/Lynda-com-HTML5-Video-Tutorial-Released/</id>
    <published>2011-06-17T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<p><a href="http://goo.gl/y0SZb" target="_blank" rel="external"><img src="http://videojs.com/img/blog/2011/06/lynda_com.jpg" alt="Lynda HTML5 Video Tutorial"></a></p>
<p>I recently filmed a series of <a href="http://goo.gl/y0SZb" target="_blank" rel="external">HTML5 video tutorials</a> for Lynda.com, a really great service for online training. It was a great experience, and the videos are now available for viewing. You can get a <a href="http://www.lynda.com/promo/trial/Default.aspx?lpk35=1833&amp;utm_medium=affiliate&amp;utm_source=ldc_affiliate&amp;utm_content=655&amp;utm_campaign=CD3175&amp;bid=655&amp;aid=CD3175&amp;opt=" target="_blank" rel="external">7-day free trial here</a> and check them out. Let me know if they&rsquo;re helpful at all.</p>
<p>-Heff</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;a href=&quot;http://goo.gl/y0SZb&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;&lt;img src=&quot;http://videojs.com/img/blog/2011/06/lynda_com.jpg&quot; alt=&quot;Lynda HTML
    
    </summary>
    
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
      <category term="code" scheme="http://blog.videojs.com/tags/code/"/>
    
  </entry>
  
  <entry>
    <title>How are you using video.js?</title>
    <link href="http://blog.videojs.com/How-are-you-using-video-js/"/>
    <id>http://blog.videojs.com/How-are-you-using-video-js/</id>
    <published>2011-06-07T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<p>I&rsquo;d love to hear where and how people are using video.js. If you&rsquo;re using it somewhere, leave a note/link in the comments.</p>
<p>Cheers,<br>-Heff</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;I&amp;rsquo;d love to hear where and how people are using video.js. If you&amp;rsquo;re using it somewhere, leave a note/link in the comments.&lt;/p
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>New MPEG LA WebM/VP8 Patent Pool</title>
    <link href="http://blog.videojs.com/New-MPEG-LA-WebM-VP8-Patent-Pool/"/>
    <id>http://blog.videojs.com/New-MPEG-LA-WebM-VP8-Patent-Pool/</id>
    <published>2011-02-11T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>One of the things that browser and device vendors stand behind when deciding to support MP4/h.264 over Google&rsquo;s Webm video format and VP8 codec, is that while VP8 is open source, it may still be encumbered by patents. So far none of these <a href="http://en.wikipedia.org/wiki/Submarine_patent" target="_blank" rel="external">submarine patents</a> have surfaced, but now MPEG LA has <a href="http://www.mpegla.com/main/pid/vp8/default.aspx" target="_blank" rel="external">put out a call</a>, and hopes to form a patent pool that would create a license for VP8, and essentially put a price on it. In <a href="http://www.webmproject.org/license/additional/" target="_blank" rel="external">Google&rsquo;s own license</a>, it says:</p>
<blockquote>
<p>&ldquo;If you or your agent or exclusive licensee institute or order or agree to the institution of patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that this implementation of VP8 or any code incorporated within this implementation of VP8 constitutes direct or contributory patent infringement, or inducement of patent infringement, then any patent rights granted to you under this License for this implementation of VP8 shall terminate as of the date such litigation is filed.&rdquo;</p>
</blockquote>
<p>So if you claim VP8 infringes on a patent and sue, your license to use VP8 is terminated. Not sure exactly how that would affect a patent pool, but an interesting battle could be ahead.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;One of the things that browser and device vendors stand behind when deciding to support MP4/h.264 over Google&amp;rsquo;s Webm video format a
    
    </summary>
    
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
  </entry>
  
  <entry>
    <title>Apple adds AirPlay to Mobile Safari</title>
    <link href="http://blog.videojs.com/Apple-adds-AirPlay-to-Mobile-Safari/"/>
    <id>http://blog.videojs.com/Apple-adds-AirPlay-to-Mobile-Safari/</id>
    <published>2011-01-28T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.568Z</updated>
    
    <content type="html"><![CDATA[<p>AirPlay is a video feature on iOS devices that lets you play video from your device on your TV, by streaming it to an Apple TV on the same wireless network. Before now this was only available in the iPod and YouTube apps, but with iOS 4.3 (now in beta) it will be available through Mobile Safari as well.</p>
<p><img src="http://macosrumors.com/wp-content/uploads/2011/01/IMG_0169.png" alt="AirPlay Feature in Mobile Safari"></p>
<p>In order to allow AirPlay as an option, video publishers have to add an attribute to the HTML5 video tag. &lt;video width=&ldquo;480&rdquo; height=&ldquo;300&rdquo; controls x-webkit-airplay=&ldquo;allow&rdquo;&gt; &hellip; We&rsquo;ll be adding this as a default attribute in the next VideoJS version.</p>
<p><a href="http://macosrumors.com/2011/01/12/first-look-mobile-safari-airplay/" target="_blank" rel="external">Read the whole story on MacRumors</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;AirPlay is a video feature on iOS devices that lets you play video from your device on your TV, by streaming it to an Apple TV on the sam
    
    </summary>
    
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
      <category term="code" scheme="http://blog.videojs.com/tags/code/"/>
    
  </entry>
  
  <entry>
    <title>Google is dropping h.264 from Chrome</title>
    <link href="http://blog.videojs.com/Google-is-dropping-h-264-from-Chrome/"/>
    <id>http://blog.videojs.com/Google-is-dropping-h-264-from-Chrome/</id>
    <published>2011-01-11T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<p>UPDATE: Added a chart that shows what format support will look like without Chrome supporting h.264.</p>
<p><img src="http://videojs.com/img/blog/2011/01/google-chrome-drops-h264.png" alt="Google Chrome Drops h.264 Support"></p>
<p>Google has decided to support the open source community by dropping h.264 support from Chrome. Previously Chrome was the only browser that could play all 3 major HTML5 formats—MP4/h.264, WebM/VP8, and Ogg/Theora. This is probably a strategic move at the same time, since h.264 seems unlikely to be beaten at this point, especially with IE9 supporting h.264 while requiring an extra plugin to use VP8. In my opinion, there&rsquo;s two major events that could end the format war.</p>
<ol>
<li>Apple adopts WebM/VP8 (which would require adequate hardware to include in iOS devices)</li>
<li>MPEG LA removes all royalties from h.264</li>
</ol>
<p><a href="http://blog.chromium.org/2011/01/html-video-codec-support-in-chrome.html" target="_blank" rel="external">Read the original post</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;UPDATE: Added a chart that shows what format support will look like without Chrome supporting h.264.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://videojs.com/
    
    </summary>
    
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
      <category term="stats" scheme="http://blog.videojs.com/tags/stats/"/>
    
  </entry>
  
  <entry>
    <title>Over 50% of web users now support HTML5 Video</title>
    <link href="http://blog.videojs.com/Over-50-of-web-users-now-support-HTML5-Video/"/>
    <id>http://blog.videojs.com/Over-50-of-web-users-now-support-HTML5-Video/</id>
    <published>2011-01-07T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>As we roll into 2011, HTML5 video hits a major milestone. 50.5% of web users now support HTML5 video playback. This number was gathered by comparing browser versions that support HTML5 video with StatCounter&rsquo;s <a href="http://gs.statcounter.com/#browser_version-ww-daily-20101201-20101231" target="_blank" rel="external">world-wide browser version statistics</a>. <img src="http://videojs.com/img/blog/2011/01/html5-video-user-support.png" alt="HTML5 Video Statistics">This is a 66% growth in HTML5 video user support since December of 2009. With the expected release of Internet Explorer 9 in the near future, 2011 could see a major increase in websites adopting HTML5 video as their primary playback method. Of browsers that support HTML5 video, Mozilla&rsquo;s Firefox is the clear leader, with Google&rsquo;s Chrome in second place. Much of the growth in HTML5 video support can be attributed to Chrome&rsquo;s success in stealing market share from Internet Explore over the last year.</p>
<h2 id="Video-Formats"><a href="/Over-50-of-web-users-now-support-HTML5-Video/#Video-Formats" class="headerlink" title="Video Formats"></a>Video Formats</h2><p>The format war continues to be a deterrent of HTML5 video adoption, and there&rsquo;s no clear end in sight. While Apple has helped accelerate HTML5 video by requiring it for video playback on the iPhone, it&rsquo;s also the one vendor that will not support Google&rsquo;s WebM/VP8 format, which has the highest potential for becoming the standard format for HTML5 video. Among other reasons, Apple has invested a lot of money in the mp4/h.264 format, including hardware built into iPads and iPhones to decode/encode it. Meaning even if Apple decided to support WebM, it would take more than a simple software update to get WebM to the many iPhone and iPad users. Microsoft has said they will support WebM/VP8 in Internet Explorer 9, however only &ldquo;when the user has installed a VP8 codec&rdquo;. Which basically means they won&rsquo;t support it. Microsoft&rsquo;s preference for MP4/h.264 was made more obvious with their <a href="http://news.cnet.com/8301-30685_3-20025721-264.html?part=rss&amp;subj=news&amp;tag=2547-1_3-0-20" target="_blank" rel="external">release of a plugin</a> that allows h.264 to be played back in Firefox on Windows. The following graphs show the support and growth of the different video formats. <img src="http://videojs.com/img/blog/2011/01/html5-format-statistics.png" alt="HTML5 Video Format Statistics"> WebM had a sharp rise in August as Google released Chrome 6 and pushed out updates to its users. In the following charts you can see different views of how formats are divided among HTML5 video users. The first chart shows user support by combinations of formats. The second compares support of open vs. closed formats. <img src="http://videojs.com/img/blog/2011/01/html5-video-format-group-stats.png" alt="HTML5 Video Format Group Statistics"> From an HTML5 video perspective, open formats win out significantly over closed formats, with Apple and IE9 hanging on to the last 10%. This may change over the next year with the official release of IE9, unless Microsoft decides to support WebM/VP8 without the need for an additional installation. Finally, if you are interested in the Flash vs. HTML5 debate, Flash is well entrenched and HTML5 video still has a long way to catch up. According to Adobe, Flash is supported by over 99% of web users. Statistics from other sites seem to support this, though according to Omniture (now Adobe), the internet average is 116.8% (sic). <img src="http://videojs.com/img/blog/2011/01/omniture-stat.png" alt="Omniture Flash Support Statistic"> As of Flash 9 update 3 (9.0.115), Flash has supported the MP4/h.264 format for video playback. In the following chart, you can see how considering Flash affects the comparison of video format support. <img src="http://videojs.com/img/blog/2011/01/flash-vs-html5-statistics.png" alt="Flash vs. HTML5 Video Statistics"> However, Adobe has <a href="http://blogs.adobe.com/flashplatform/2010/05/adobe_support_for_vp8.html" target="_blank" rel="external">said they will support WebM/VP8</a> in a later release of Flash. The rate that users upgrade to the latest version of Flash is relatively fast, so this could have a big impact on WebM support when it happens. Overall, Flash will be difficult for HTML5 to dethrone. Beyond user support and format discrepancies there is a long list of features that Flash players have supported for years, which will take time for all browsers to build in. However, many of those features can be built with JavaScript, which allows them to be used across browsers immediately. It&rsquo;s up to the open source community to build the features people need to accept HTML5 as their primary means of video playback. VideoJS is an open source HTML5 video player and framework that makes it easy to support HTML5 video as well as Flash for older browsers. It provides a consistent interface across browsers and solves many browser/mobile device bugs. There are still quite a few rough edges with HTML5 video, but the many contributors to VideoJS are smoothing those over and expanding VideoJS to meet the needs of web users.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;As we roll into 2011, HTML5 video hits a major milestone. 50.5% of web users now support HTML5 video playback. This number was gathered b
    
    </summary>
    
    
      <category term="stats" scheme="http://blog.videojs.com/tags/stats/"/>
    
  </entry>
  
  <entry>
    <title>HTML5 Video + Google Maps Mashup</title>
    <link href="http://blog.videojs.com/HTML5-Video-Google-Maps-Mashup/"/>
    <id>http://blog.videojs.com/HTML5-Video-Google-Maps-Mashup/</id>
    <published>2010-12-16T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<p>Mozilla has a cool demo of playing a video while drawing a line on a Google map similar to what you&rsquo;d see in an Indiana Jones film. Check out the <a href="http://hacks.mozilla.org/2010/12/spirit-of-indiana-jones-syncing-html5-video-with-maps/" target="_blank" rel="external">original post</a> and the <a href="http://isithackday.com/spirit-of-indiana/" target="_blank" rel="external">demo</a>.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Mozilla has a cool demo of playing a video while drawing a line on a Google map similar to what you&amp;rsquo;d see in an Indiana Jones film.
    
    </summary>
    
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
  </entry>
  
  <entry>
    <title>2.0.2 Release - Subtitle Optimization + Safari on Leopard FS Fix</title>
    <link href="http://blog.videojs.com/2-0-2-Release-Subtitle-Optimization-Safari-on-Leopard-FS-Fix/"/>
    <id>http://blog.videojs.com/2-0-2-Release-Subtitle-Optimization-Safari-on-Leopard-FS-Fix/</id>
    <published>2010-12-10T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.568Z</updated>
    
    <content type="html"><![CDATA[<p>Smallish update with some fixes and optimizations. Rewrote the subtitles parser so it&rsquo;s a lot more optimized and fixes a subtitle display bug. Put in a check for Safari running on Mac OSX 10.5 (Leopard), which doesn&rsquo;t like native fullscreen for some reason. Triggering full window mode instead.</p>
<p>Full List</p>
<ul>
<li>Feature: Rewrote and optimized subtitle code.</li>
<li>Feature: Protecting against volume ranges outside of 1 and 0.</li>
<li>Fix: Bug in Safari for Mac OS 10.5 (Leopard) that was breaking fullscreen.</li>
</ul>
<p><a href="http://videojs.com/#download" target="_blank" rel="external">Download version 2.0.2</a></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Smallish update with some fixes and optimizations. Rewrote the subtitles parser so it&amp;rsquo;s a lot more optimized and fixes a subtitle d
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>2.0.0 Release - Behaviors, fallback APIs, and more.</title>
    <link href="http://blog.videojs.com/2-0-0-Release-Behaviors-fallback-APIs-and-more/"/>
    <id>http://blog.videojs.com/2-0-0-Release-Behaviors-fallback-APIs-and-more/</id>
    <published>2010-11-22T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.568Z</updated>
    
    <content type="html"><![CDATA[<p>Big update. The biggest change for current users is a move back to using DIVs for control bar elements instead of unordered lists. There were a lot of conflicting styles issues when using lists, which shouldn&rsquo;t be an issue with divs. So if you upgrade, don&rsquo;t forget to upgrade your stylesheets as well.</p>
<p>Beyond that, a lot of code was reorganized and modularized to create a platform for further expansion, like custom plugins and controls. The concept of &ldquo;behaviors&rdquo; was added, so you can activate any element on the page to act like a video controls. For instance, the following code snippet will make the specified element act like a play button, and play the video when clicked.</p>
<pre>myplayer.activateElement(myElement, "playButton");
</pre>

<p>The next code snippet will make the element act like a play progress bar, meaning it will grow horizontally as the video plays.</p>
<pre>myplayer.activateElement(myElement, "playProgressBar");
</pre>

<p>More documentation on this is coming.</p>
<p>The code is now prepped for APIs to the fallback flash players. So if you call myPlayer.play(), it will trigger a play in both the HTML5 and the Flash version, whichever is currently being used. A flowplayer API is just about done, and other popular Flash players will follow.</p>
<p>Finally, you can change the fallback order by modifying the playerFallbackOrder option, which is an array of player platforms. So if you want Flash to be dominant, you would pass the following option.</p>
<pre>VideoJS.setupAllWhenReady({
  playerFallbackOrder: ["flash", "html5", "links"]
});
</pre>

<p>This also leaves room for other platforms to be added, like Quicktime.</p>
<p>So coming up is Flash player APIs, and another cool feature I don&rsquo;t want to mention just yet.</p>
<p>Full list:</p>
<ul>
<li>Feature: Created &ldquo;behaviors&rdquo; concept for adding behaviors to elements - Feature: Switched back to divs for controls, for more portable styles</li>
<li>Feature: Created playerFallbackOrder array option. [&ldquo;html5&rdquo;, &ldquo;flash&rdquo;, &ldquo;links&rdquo;]</li>
<li>Feature: Created playerType concept, for initializing different platforms</li>
<li>Feature: Added play button for Android</li>
<li>Feature: Added spinner for iPad (non-fullscreen)</li>
<li>Feature: Split into multiple files for easier development</li>
<li>Feature: Combined VideoJS &amp; _V_ into the same variable to reduce confusion</li>
<li>Fix: Checking for m3u8 files (Apple HTTP Streaming)</li>
<li>Fix: Catching error on localStorage full that safari seems to randomly throw</li>
<li>Fix: Scrubbing to end doesn&rsquo;t trigger onEnded</li>
</ul>
<p><a href="http://videojs.com/#download" target="_blank" rel="external">Download version 2.0.0</a></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Big update. The biggest change for current users is a move back to using DIVs for control bar elements instead of unordered lists. There 
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Make sites serve you HTML5 video in Safari</title>
    <link href="http://blog.videojs.com/Make-sites-serve-you-HTML5-video-in-Safari/"/>
    <id>http://blog.videojs.com/Make-sites-serve-you-HTML5-video-in-Safari/</id>
    <published>2010-11-19T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.575Z</updated>
    
    <content type="html"><![CDATA[<p>John Gruber of Daring Fireball has a cool post on <a href="http://daringfireball.net/2010/11/masquerading_as_mobile_safari" target="_blank" rel="external">tricking websites to display HTML5 video</a> when they say they can only play Flash. Many sites will tell you they require Flash, even when they actually support <a href="http://videojs.com/html5-video/" target="_blank" rel="external">HTML5 video</a> for iOS devices.</p>
<p>To add to Gruber&rsquo;s post, there&rsquo;s two reasons a site might do this:</p>
<ol>
<li>They&rsquo;re trying to protect their content from being easily downloaded, which HTML5 video can&rsquo;t do very well yet.</li>
<li>They assume everyone with a browser has Flash, and just serve HTML5 video to iOS devices.</li>
</ol>
<p>So for this first, this is actually a hack to download content some publishers might not want you to. I probably shouldn&rsquo;t be publishing this since security of the content is one of the main reasons HTML5 video will still take time to spread. But for that purpose, it&rsquo;s really not hard to figure out.</p>
<p>For the second, it&rsquo;s kind of lazy implementation of fallbacks. It&rsquo;s pretty easy to check if Flash is supported, and if not, fall back to HTML5, instead of checking for a specific user agent string. So for sites using VideoJS, this method wouldn&rsquo;t work, but there also wouldn&rsquo;t be a need because VideoJS would fallback appropriately to HTML5.</p>
<p>Gruber has disabled Flash in Safari for better performance with video. That says a lot. Most people probably won&rsquo;t go to same effort he has, but I know he&rsquo;s not the only one.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;John Gruber of Daring Fireball has a cool post on &lt;a href=&quot;http://daringfireball.net/2010/11/masquerading_as_mobile_safari&quot; target=&quot;_blan
    
    </summary>
    
    
      <category term="code" scheme="http://blog.videojs.com/tags/code/"/>
    
  </entry>
  
  <entry>
    <title>1.1.5 Release - Subtitles using track, Android fix &amp; more</title>
    <link href="http://blog.videojs.com/1-1-5-Release-Subtitles-using-track-Android-fix-more/"/>
    <id>http://blog.videojs.com/1-1-5-Release-Subtitles-using-track-Android-fix-more/</id>
    <published>2010-11-09T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.568Z</updated>
    
    <content type="html"><![CDATA[<ul>
<li>Feature: Switched to track method for setting subtitles. Now works like spec.</li>
<li>Feature: Created &ldquo;players&rdquo; concept for defining fallbacks and fallback order</li>
<li>Fix: Android playback bug.</li>
<li>Fix: Massive reorganization of code to make easier to navigate</li>
</ul>
<p>I&rsquo;ve switched the subtitles to use the new track element defined in the <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html" target="_blank" rel="external">HTML5 spec</a>. You can now add subtitles by creating a track element pointing to your <a href="http://www.delphiki.com/websrt/" target="_blank" rel="external">WebSRT</a>subtitles source.</p>
<pre>&lt;video ...&gt;
  &lt;track kind="subtitles" src="../demo-subtitles.srt" srclang="en-US" label="English"&gt;&lt;/track&gt;
&lt;/vide&gt;</pre>

<p>The closing track tag is needed, otherwise Safari thinks everything else is a child of the track, even with a self-closing track tag. Not sure why that is, but it&rsquo;s kind of annoying.</p>
<p>Also a fix for Android playback was added. Android HTML5 video is pretty rough. The canPlayType function returns nothing on Android so VideoJS has a check to see if the source is mp4/m4v, and assumes it&rsquo;ll play. Then VideoJS adds a click event to the video so it&rsquo;ll play when you touch it. Also the Android will show the poster image, but no indication that it&rsquo;s a video and not just an image. Hopefully this will be improved in the next Android version.</p>
<p>Beyond that, I did a massive reorganization of the code, so it should be easier to navigate if you&rsquo;re planning to hack at it or contribute.</p>
<p><a href="http://videojs.com/downloads/video-js-1.1.5.zip" target="_blank" rel="external">Download version 1.1.5</a></p>
]]></content>
    
    <summary type="html">
    
      &lt;ul&gt;
&lt;li&gt;Feature: Switched to track method for setting subtitles. Now works like spec.&lt;/li&gt;
&lt;li&gt;Feature: Created &amp;ldquo;players&amp;rdquo; conce
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Version 1.1.4 Release - CSS Loading Spinner &amp; More</title>
    <link href="http://blog.videojs.com/Version-1-1-4-Release-CSS-Loading-Spinner-More/"/>
    <id>http://blog.videojs.com/Version-1-1-4-Release-CSS-Loading-Spinner-More/</id>
    <published>2010-11-06T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>The most notable update in this version is a loading indicator (spinner), for when the video is buffering or seeking. The spinner works pretty well, however it&rsquo;s limited by how accurately each browser tells us what it&rsquo;s currently doing through triggered events. The spinner works best in Firefox so far. Safari/Chrome are less consistent with what events are triggered and when. For this reason I&rsquo;m using a more careful approach that makes sure the spinner gets hidden, as opposed to making sure the spinner always shows when the player is busy. There&rsquo;s a few bugs I had to account for too, like when Safari throws a &ldquo;waiting&rdquo; event, but then no other event to let us know it&rsquo;s not waiting anymore.</p>
<p>The spinner icon is made with CSS3 effects (border-radius and transform). The spinning animation is created with a little javascript for now. In webkit browsers the animation could have been done with CSS3 animation, but I&rsquo;d rather keep it consistent between browsers. The technique comes from <a href="http://kilianvalkhof.com/2010/css-xhtml/css3-loading-spinners-without-images/" target="_blank" rel="external">Kilian Valkhof</a> with initial integration into VideoJS by <a href="http://twitter.com/#!/dz0ny" target="_blank" rel="external">Janez Troha</a> (<a href="https://github.com/dz0ny" target="_blank" rel="external">dz0ny</a>)</p>
<p>Other features and fixes include:</p>
<ul>
<li>Feature: Added loading spinner.</li>
<li>Feature: Improved styles loaded checking.</li>
<li>Feature: Added volume() function to get and set volume through the player. - Fix: Fix issue where FF would loop video in background when ended.</li>
<li>Fix: Bug in Chrome that shows poster &amp; plays audio if you set currentTime too quickly.</li>
<li>Fix: Bug in Safari where waiting is triggered and shows spinner when not needed</li>
<li>Fix: Updated to show links if only unplayable sources and no Flash.</li>
<li>Fix: Issue where if play button was loaded after play, it wouldn&rsquo;t hide.</li>
</ul>
<p><a href="http://videojs.com/downloads/video-js-1.1.4.zip" target="_blank" rel="external">Download version 1.1.4</a></p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;The most notable update in this version is a loading indicator (spinner), for when the video is buffering or seeking. The spinner works p
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Version 1.1.3 Release</title>
    <link href="http://blog.videojs.com/Version-1-1-3-Release/"/>
    <id>http://blog.videojs.com/Version-1-1-3-Release/</id>
    <published>2010-10-19T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>Version 1.1.3 of VideoJS is now available.</p>
<p>Probably the most notable change is a switch to using a big play button before the movie plays for the first time, as opposed to showing the control bar. The main reason for doing this is actually a bug in Safari. If you try to call any functions on the video other than play, before the video has loaded, Safari will error out. Some people mentioned that fullscreen mode did not work in Safari for them, and this is most likely what was happening for them. This would only happen if you were not preloading the video. You can still go back to showing the controls first through the showControlsAtStart option, but it&rsquo;s not recommended.</p>
<p>Other features and fixes include:</p>
<ul>
<li>Feature: Width/Height functions for resizing the player</li>
<li>Feature: Made initial click &amp; hold trigger new value on progress and volume</li>
<li>Feature: Made controls not hide when hovering over them</li>
<li>Fix: Removed trailing comma that was breaking IE7</li>
<li>Fix: Removed some vars from global scope</li>
<li>Fix: Changed a document.onmousemove to an eventListener to prevent conflicts</li>
<li>Fix: Added a unique ID to FlowPlayer demo object to fix a FlowPlayer bug. Thanks @emirpprime.</li>
<li>Fix: Safari error on unloaded video</li>
</ul>
<p>Let me know if you have any questions.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;Version 1.1.3 of VideoJS is now available.&lt;/p&gt;
&lt;p&gt;Probably the most notable change is a switch to using a big play button before the movi
    
    </summary>
    
    
      <category term="version" scheme="http://blog.videojs.com/tags/version/"/>
    
  </entry>
  
  <entry>
    <title>Facebook Adds HTML5 Video</title>
    <link href="http://blog.videojs.com/Facebook-Adds-HTML5-Video/"/>
    <id>http://blog.videojs.com/Facebook-Adds-HTML5-Video/</id>
    <published>2010-10-12T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.569Z</updated>
    
    <content type="html"><![CDATA[<p><a href="http://www.flickr.com/photos/24374884@N08/4603715307/" title="What" target="_blank" rel="external"><img src="http://farm2.static.flickr.com/1199/4603715307_c878c8a77b_m.jpg" alt="What"></a></p>
<p>Among other new HTML5 features, Facebook has an HTML5 video player for playback on the iPhone and iPad. They say that on other mobile browsers, Flash outperformed the HTML5 implementation. That&rsquo;s a little discouraging to hear, but HTML5 video is still young.</p>
<p><a href="http://www.facebook.com/notes/facebook-engineering/using-html5-today/438532093919" target="_blank" rel="external">Read the full post</a></p>
<p>In contrast, check out this video of HTML5 vs. Flash on a Mac. Spoiler: HTML5 wins.</p>
<object height="390" width="640"><param name="movie" value="http://www.youtube.com/v/IP7A09ty1do&amp;hl=en_US&amp;feature=player_embedded&amp;version=3"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"></object>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;a href=&quot;http://www.flickr.com/photos/24374884@N08/4603715307/&quot; title=&quot;What&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;&lt;img src=&quot;http://farm2.static
    
    </summary>
    
    
      <category term="news" scheme="http://blog.videojs.com/tags/news/"/>
    
  </entry>
  
  <entry>
    <title>iPad &amp; iPhone Video Poster Fix (bonus Javascript Placement Fix)</title>
    <link href="http://blog.videojs.com/iPad-iPhone-Video-Poster-Fix-bonus-Javascript-Placement-Fix/"/>
    <id>http://blog.videojs.com/iPad-iPhone-Video-Poster-Fix-bonus-Javascript-Placement-Fix/</id>
    <published>2010-09-20T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<h3 id="Bug-1-Poster-Attribute"><a href="/iPad-iPhone-Video-Poster-Fix-bonus-Javascript-Placement-Fix/#Bug-1-Poster-Attribute" class="headerlink" title="Bug #1 - Poster Attribute"></a>Bug #1 - Poster Attribute</h3><p>If you include the poster attribute on the video tag when you&rsquo;re using &lt;source&gt; tags, the video won&rsquo;t work on iPads &amp; iPhones using iOS 3. You&rsquo;ll see a broken play button, or no play button at all. On the iPad specifically, playback in inconsistent. Sometimes it&rsquo;ll work and sometimes it won&rsquo;t. This is <a href="http://camendesign.com/code/video_for_everybody#notes" target="_blank" rel="external">documented on the Video for Everybody site</a>.</p>
<h3 id="Bug-2-Javascript-in-the-Head"><a href="/iPad-iPhone-Video-Poster-Fix-bonus-Javascript-Placement-Fix/#Bug-2-Javascript-in-the-Head" class="headerlink" title="Bug #2 - Javascript in the Head"></a>Bug #2 - Javascript in the Head</h3><p>This is a fun one&hellip; If you include Javascript in the head of your page, it&rsquo;ll break playback on the iPad (also inconsistent). If you move the Javascript to the bottom of the page, and still include a stylesheet, the iPad will work, but the iPhone 3 won&rsquo;t. I first read about this in a <a href="http://blog.noinc.com/2010/05/13/html5-video-tag-iphone-ipad-ihaveheadache" target="_blank" rel="external">post on the No.inc blog</a>, and then ran into it myself when redesigning the VideoJS site. Their original solution was to put the JS at the bottom of the page for iPads only (fun).</p>
<p>Apple&rsquo;s iOS4 seems to fix both of these problems on the iPhone, but until iOS4 is available on the iPad, and everyone in the world upgrades their devices, we have to deal with this.</p>
<h3 id="Fix-for-iOS-3"><a href="/iPad-iPhone-Video-Poster-Fix-bonus-Javascript-Placement-Fix/#Fix-for-iOS-3" class="headerlink" title="Fix for iOS 3"></a>Fix for iOS 3</h3><p>The problem seems to be some kind of race condition, that trips up the devices. The solution that has fixed both of these for me is to add the playable source directly to the video tag, and tell the video to load (all through Javascript).</p>
<p>I&rsquo;ve added all this to VideoJS 1.1.2, but here&rsquo;s the basics of how it works.</p>
<pre>var video = document.getElementById("your_video");
    var children = video.children;
    for (var i=0,j=children.length; i&lt;j; i++) {
      if (children[i].tagName.toUpperCase() == "SOURCE") {
        var canPlay = video.canPlayType(children[i].type);
        if(canPlay == "probably" || canPlay == "maybe") {
          video.src = children[i].src;
          video.load();
          break; // or return or whatever
        }
      }
    }</pre>

<p>So loop through the source elements, find the one that&rsquo;s compatible, and add that source to the video src. Then trigger the video&rsquo;s load() function.</p>
<p>That seems to fix both issues. <strong>This will not make the poster show up in either device.</strong>It just makes makes the video playable. Sometimes you&rsquo;ll see it flash the controls and then go back to the big play button.</p>
<p>Any feedback is appreciated.</p>
<p>Let&rsquo;s go Apple, get iOS4 out to everybody!</p>
]]></content>
    
    <summary type="html">
    
      &lt;h3 id=&quot;Bug-1-Poster-Attribute&quot;&gt;&lt;a href=&quot;/iPad-iPhone-Video-Poster-Fix-bonus-Javascript-Placement-Fix/#Bug-1-Poster-Attribute&quot; class=&quot;header
    
    </summary>
    
    
      <category term="code" scheme="http://blog.videojs.com/tags/code/"/>
    
  </entry>
  
  <entry>
    <title>VideoJS is IE9 Compatible</title>
    <link href="http://blog.videojs.com/VideoJS-is-IE9-Compatible/"/>
    <id>http://blog.videojs.com/VideoJS-is-IE9-Compatible/</id>
    <published>2010-09-15T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.606Z</updated>
    
    <content type="html"><![CDATA[<p>After an initial test, VideoJS works with the new <a href="http://ie.microsoft.com/testdrive/" target="_blank" rel="external">Internet Explorer 9 preview</a>. Great news, and a little surprising considering the CSS layout of the controls, and the general nature of IE. Other VideoJS site layout stuff seems to break, but for now as long as the player works I&rsquo;m happy.</p>
<p>If you find differently let me know (along with any info that might be helpful).</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;After an initial test, VideoJS works with the new &lt;a href=&quot;http://ie.microsoft.com/testdrive/&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;Internet Ex
    
    </summary>
    
    
  </entry>
  
  <entry>
    <title>New VideoJS Site (Now with more HTML5)!</title>
    <link href="http://blog.videojs.com/New-VideoJS-Site-Now-with-more-HTML5/"/>
    <id>http://blog.videojs.com/New-VideoJS-Site-Now-with-more-HTML5/</id>
    <published>2010-09-15T00:00:00.000Z</published>
    <updated>2019-01-18T19:57:55.576Z</updated>
    
    <content type="html"><![CDATA[<p>I told myself when the site reached 100,000 visits I would redesign it. Well that number&rsquo;s come and gone, so <a href="http://videojs.com" target="_blank" rel="external">here it is</a>.</p>
<p>I also took this as an opportunity to code an HTML5 based site, using tags like <code>header</code>, <code>footer</code>, and <code>section</code>. And I built it on the newly popular <a href="http://html5boilerplate.com/" target="_blank" rel="external">HTML5 Boilerplate</a>. Actually I built a <a href="http://github.com/zencoder/html5-boilerplate-for-wordpress" target="_blank" rel="external">WordPress them for HTML5 Boilerplate</a>first, in case you&rsquo;re interested in doing the same.</p>
<p>I got to use some fun CSS tricks throughout as well. One of them is the thin color bar at the top of the page. Resize the window and watch it go!</p>
<p>I also added this blog and a <a href="http://twitter.com/videojs" target="_blank" rel="external">twitter account</a>, where I&rsquo;ll be posting updates to VideoJS, as well as general HTML5 video news.</p>
]]></content>
    
    <summary type="html">
    
      &lt;p&gt;I told myself when the site reached 100,000 visits I would redesign it. Well that number&amp;rsquo;s come and gone, so &lt;a href=&quot;http://videoj
    
    </summary>
    
    
  </entry>
  
</feed>
