{"id":1,"date":"2012-10-15T10:10:50","date_gmt":"2012-10-15T09:10:50","guid":{"rendered":"http:\/\/powered-by-haiku.co.uk\/?p=1"},"modified":"2013-04-09T09:23:33","modified_gmt":"2013-04-09T08:23:33","slug":"hello-world","status":"publish","type":"post","link":"http:\/\/powered-by-haiku.co.uk\/?p=1","title":{"rendered":"Video, Video, Vide&#8230;DOH!"},"content":{"rendered":"<h2>JW Player and HTML5 Video<\/h2>\n<p><strong>When it comes to embedded media on the web, the <a href=\"http:\/\/www.longtailvideo.com\/players\/\">JW Player from LongTail Video<\/a> is widely regarded as one of the best solutions in terms of producing consistent results across a wide range of browsers and devices.<\/strong><\/p>\n<p>\nSince release 5.3, JW Player has included a specific embedding method that caters for the creation of a video player with seamless failover between Flash and HTML5 modes (and vice versa). It also introduced the ability to use the parameters defined in HTML5 <code>video<\/code> and <code>source<\/code> tag attributes as the default configuration options for setting up the player. This means that once the JW Player JavaScript library has been loaded in the page, a JW Player instance can be generated using a simple <code>video<\/code> tag and zero extra JavaScript &#8211; an excellent enhancement to ensure the widest availability of video regardless of a user\u2019s individual browser configuration.\n<\/p>\n<h3>JW HTML CONFIG<\/h3>\n<p>In my role as Web Developer for a large UK organisation, I recently tasked myself with writing an extension to the JW Player solution with the primary aim of simplifying the configuration process (particularly in relation to playlists) whilst additionally producing an output that reacts responsively. The aim was to provide a solution which doesn&#8217;t require additional, separate JavaScript configuration &#8211; all settings are to be driven from simple inline HTML.\n<\/p>\n<p>\nIn much the same way the JW Embedder uses the principle of progressive enhancement by interrogating the HTML5 <code>video<\/code> tag and attributes and then dynamically producing a configuration object, which is used as the basis for the player setup, the solution makes use of additional structured settings blocks (tags with <code>data-<\/code> attributes) to extend this concept further.\n<\/p>\n<p>\nDuring the development of this extension (<em>which takes the form of a small JavaScript library, and <a href=\"http:\/\/powered-by-haiku.co.uk\/?p=189\">details can be found here<\/a><\/em>) I encountered a number of &#8220;setup and playback inconsistencies&#8221; which, when checking in the JW Player forums, became clear I was not alone in experiencing. These &#8220;unexplained hiccups&#8221; appear to be increasingly common and a worrying source of frustration for users who are implementing (or more likely updating) JW Player to make use of the more elegant and accessible HTML5 first approach.\n<\/p>\n<h3>UNEXPLAINED HICCUPS<\/h3>\n<p>To understand more about how these frustrations manifest themselves &#8211; let\u2019s explore a likely route to JW Player\/HTML5  implementation :<\/p>\n<p>\nOk. Let&#8217;s say for arguments sake I have some experience in implementing JW Player, going back to before 5.3, when I happily managed to get MP4 videos playing on my website using the Flash embed method. Life is sweet! A single video format played through a 3rd party plugin. If you don&#8217;t have the plugin, you don&#8217;t get the video &#8211; that&#8217;s just the way it is I&#8217;m afraid!\n<\/p>\n<p>[Time passes by]<\/p>\n<p>\nNow I&#8217;ve been thinking, maybe my website should make more of an effort to cater for a wider audience and start supporting HTML5 video &#8211; specifically to serve those Flash intolerant devices! No problem. As I understand it these devices support MP4 video natively, so all I need to do is upgrade to the latest version of JW Player (let\u2019s say 5.7) and let it handle the Flash to HTML5 failover as required. Perfect.\n<\/p>\n<p>\nErm&#8230; or maybe not! It seems that my MP4 video files don&#8217;t actually play on the latest iDevices. After a mild panic, and a little bit of research, I am able to figure out that while it seems Flash is quite forgiving about the encoding of video, the iDevice is not. Resolving the problem involves re-encoding the videos specifically for the iDevice, which although a bit of a headache, is perfectly manageable and the result is worth it.\n<\/p>\n<p>[More time passes]<\/p>\n<p>\nAs my understanding of my website audience evolves further, and my desire to reach as many different users &#8211; on a broad range of devices &#8211; becomes a key objective, I decide to switch my video strategy to serve HTML5 first with a Flash fall-back.\n<\/p>\n<p>\nAfter a bit of research, I decide that the best approach (involving the least effort) involves simply switching my JW Embed method to make use of the native <code>video<\/code> and <code>source<\/code> tags and providing a WebM version of the video &#8211; to cater for native playback in Firefox &amp; Opera. I also update JW Player to version 5.10 and specifically include the <code>modes<\/code> block in my setup object &#8211;  telling it to use <code>html5<\/code> mode first. This is as described in the JW Player documentation:\n<\/p>\n<p><code class=\"code-block\">&lt;script src=\"\/jwplayer\/jwplayer.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;<br \/>\n&lt;video height=\"270\" width=\"480\" id=\"myVideo\"&gt;<br \/>\n&lt;source src=\"\/static\/bunny.mp4\" type=\"video\/mp4\"&gt;<br \/>\n&lt;source src=\"\/static\/bunny.webm\" type=\"video\/webm\"&gt;<br \/>\n&lt;\/video&gt;<br \/>\n&lt;script type=\"text\/javascript\"&gt;<br \/>\n\/\/ &lt;![CDATA[<br \/>\n jwplayer(\"myVideo\").setup(<br \/>\n{  modes:<br \/>\n[<br \/>\n{ type: 'html5' },<br \/>\n{ type: 'flash', src: '\/jwplayer\/player.swf' }<br \/>\n]<br \/>\n});<br \/>\n\/\/ ]]&gt;<br \/>\n&lt;\/script&gt;<\/code><\/p>\n<p>\nOne change I make to this code is to place the <code>script<\/code> tags at the bottom of the <code>body<\/code> \u2013 as this is commonly best practice right?! My code now looks like this:\n<\/p>\n<p><code class=\"code-block\">&lt;html&gt;<br \/>\n&lt;head&gt;<br \/>\n\u2026<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body&gt;<br \/>\n&lt;!-- Navigation stuff  --&gt;<br \/>\n\u2026<br \/>\n&lt;!-- Content Area  --&gt;<br \/>\n&lt;h2&gt;Check this HTML5 video out!&lt;\/h2&gt;<br \/>\n&lt;video height=\"270\" width=\"480\" id=\"myVideo\"&gt;<br \/>\n&lt;source src=\"\/static\/bunny.mp4\" type=\"video\/mp4\"&gt;<br \/>\n&lt;source src=\"\/static\/bunny.webm\" type=\"video\/webm\"&gt;<br \/>\n&lt;\/video&gt;<br \/>\n&lt;!-- More content  --&gt;<br \/>\n\u2026<br \/>\n&lt;!-- Right hand column  --&gt;<br \/>\n\u2026<br \/>\n&lt;!-- Footer stuff  --&gt;<br \/>\n&lt;script src=\"\/jwplayer\/jwplayer.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;<br \/>\n&lt;script type=\"text\/javascript\"&gt;<br \/>\n\/\/ &lt;![CDATA[<br \/>\n jwplayer(\"myVideo\").setup(<br \/>\n{  modes:<br \/>\n[<br \/>\n{ type: 'html5' },<br \/>\n{ type: 'flash', src: '\/jwplayer\/player.swf' }<br \/>\n]<br \/>\n});<br \/>\n\/\/ ]]&gt;<br \/>\n&lt;\/script&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<br \/>\n<\/code><\/p>\n<p>\nThis in theory caters for the base position of native playback in all the mainstream browsers (Firefox &amp; Opera \u2013 playing WebM; IE9, iOS, Safari &amp; Android \u2013 playing MP4; Chrome &#8211; playing MP4 or WebM).\n<\/p>\n<p>\nIt also has the benefit that if JavaScript is enabled, JW Player will progressively enhance the player to ensure a consistent look-and-feel across all these browsers, plus provide a Flash fall-back for earlier versions of IE \u2013 playing the MP4.\n<\/p>\n<p>\nWell that wasn\u2019t too hard to implement\u2026 Except\u2026 What the\u2026?!\n<\/p>\n<p>\nAfter testing thoroughly and ensuring the videos play in all the browsers as expected I push my site live and I am greeted with\u2026 issues. Not only that, the worse kind of issues \u2013 inconsistent issues.\n<\/p>\n<p>\nA selection of problems encountered include:\n<\/p>\n<ul>\n<li>Chrome not playing the MP4, but playing the WebM. Safari plays the MP4<\/li>\n<li>Firefox not playing WebM. Chrome plays the WebM<\/li>\n<li>Safari not playing natively \u2013 rendering the Flash player<\/li>\n<li>Safari not showing the player at all<\/li>\n<li>IE7 &amp; IE8 not showing the player at all<\/li>\n<li>IE9 not showing controls<\/li>\n<li>IE9 not showing anything<\/li>\n<\/ul>\n<p>\nGiven the specific nature of these issues, they <em>should<\/em> be reasonably easy to debug and determine a solution to.\n<\/p>\n<p>\nHowever the following \u201cgeneric\u201d issues have also been experienced. These are much less obvious in terms of cause and can end up being responsible for hours of debugging frustration:\n<\/p>\n<ul>\n<li>Previously \u201cplayable\u201d video suddenly not loading &#8211; an error is presented<\/li>\n<li>Video appearing to endlessly buffer &#8211; pressing pause and then resume presents a black screen<\/li>\n<li>Video buffering for a long time before finally playing<\/li>\n<li>Video plays on the first visit to a page, then fails on subsequent visits<\/li>\n<li>Video doesn\u2019t play on initial page load, but plays on refresh<\/li>\n<li>Video playing with no audio<\/li>\n<li>Audio playing with no video<\/li>\n<li>Video playing and then stalling or playing out of sync with audio<\/li>\n<li>Video format being played is not the expected one<\/li>\n<\/ul>\n<p>\nNow, there are a number of phrases that might be used to describe this situation &#8211; the most likely in a business context being \u201cshow-stopper\u201d. This may quickly be followed by the dreaded question \u201cIs this the right solution for us?\u201d.\n<\/p>\n<p>\nIn my opinion JW Player is indeed a very good solution &#8211; the support forums are a great means for getting issues resolved, and there is usually willing assistance with helping you understand the complexities of producing video for the web. However, as with many situations, knowing what question to ask in this context can sometimes make the difference between getting a speedy resolution versus a gradual increase in grey hairs and heightened blood pressure!\n<\/p>\n<h3>TIME FOR SOME FOR ANSWERS<\/h3>\n<p>\nHaving experienced a number of these issues first-hand, and worked through them, I thought it would be useful to share my findings. The following pointers should cover off the specific issues detailed above and will also cater for some of the \u201cgeneric\u201d issues:\n<\/p>\n<h4>ENCODING<\/h4>\n<p>\nOne of the most common stumbling blocks (and therefore most likely to resolve issues) is ensuring the encoding used is correct. It has been said many times before and I\u2019m sure it will be said again &#8211; encoding is key. This is particularly relevant when it comes to producing an MP4 which is intended for playback on multiple devices \u2013 desktop browsers, iDevices, Android phones\/tablets and recent Blackberry phones.\n<\/p>\n<p>\nAccording to the JW Player documentation, the following specification should be adhered to:\n<\/p>\n<blockquote><p>\n&gt; Container format: MP4, headers at the beginning of the file (for seeking)<br \/>\n&gt; Video format: H.264, Baseline profile, 480&#215;270 pixels, around 400\/600 kbps (kilobits per second)<br \/>\n&gt; Audio format: AAC, Low Complexity profile, 44.1 kHz stereo, 96 kbps\n<\/p><\/blockquote>\n<p>\nAlso, within the support forums you will regularly see advice to \u201cencode video to H.264 using Handbrake\u201d and the JW documentation continues to say:\n<\/p>\n<blockquote><p>Handbrake has a built-in present called iPhone &amp; iPod Touch, which has exactly the right settings.<\/p><\/blockquote>\n<p>Whilst good advice, this actually falls short of ensuring you get the correct results. <strong>One important option that is unchecked by default<\/strong> in all Handbrake profiles is the \u201cWeb optimized\u201d option. Selecting this option reorders some of the metadata within the encoded video to the start of the container. This ensures the video can stream and allows the user to jump to specific points while the rest is downloading in the background.\n<\/p>\n<p>\nIf the metadata appears at the end of the video, the whole file needs to be downloaded before the video will start playing. I therefore highly recommend checking the \u201cWeb optimised\u201d option when you encode. If you have files that are already encoded and are concerned that the metadata is not at the start, you can use another tool such as <a href=\"http:\/\/multimedia.cx\/eggs\/improving-qt-faststart\/\">qt-faststart<\/a> to move the metadata retrospectively.\n<\/p>\n<p>\nMore recent versions of Handbrake include the \u201ciPhone 4\u201d,  \u201ciPad\u201d &amp; \u201cAppleTV\u201d profiles which have the \u201cLarge file size\u201d option checked by default. They also include the \u201cMaximum B-Frames\u201d set to \u201c3\u201d along with a host of other default settings. I would advise considering these settings further when deciding which profile to use.\n<\/p>\n<p>\nFor further detail regarding HTML5 video support, encoding options and much more useful information check out the excellent <a href=\"http:\/\/diveintohtml5.info\/video.html\">\u201cVideo on the Web\u201d<\/a> resource by Mark Pilgrim\n<\/p>\n<h4>SERVER SETTINGS &#8211; MIME-TYPES &amp; GZIP<\/h4>\n<h5>MIME-TYPES<\/h5>\n<p>\nFor video to be correctly rendered in WebKit based browsers, the MIME-type provided by the server must correctly correspond to the encoding used.<\/p>\n<p>Specifically:<\/p>\n<ul>\n<li>Firefox requires \u201cvideo\/webm\u201d to be set for the \u201c.webm\u201d filetype<\/li>\n<li>IE9 requires \u201cvideo\/mp4\u201d to be set for the \u201c.mp4\u201d filetype<\/li>\n<\/ul>\n<p>\nIn terms of what to include in the <code>type<\/code> attribute of the HTML <code>source<\/code> tag, I would suggest only including the MIME-type string \u2013 don\u2019t bother with the \u201ccodecs\u201d element as this is largely ignored anyway. <strong>Note: Including the MIME-type here DOES NOT negate the need to have the server configured correctly \u2013 they are not related.<\/strong>\n<\/p>\n<p>\nIf you experience problems with MP4 video playing on earlier version of Android you may wish to explore removing the <code>type<\/code> attribute for the MP4 source \u2013 as suggested in <a href=\"http:\/\/www.broken-links.com\/2010\/07\/08\/making-html5-video-work-on-android-phones\/\">Peter Gasston\u2019s post.<\/a>\n<\/p>\n<h5>GZIP<\/h5>\n<p>\nIn a bid to try and save bandwidth, some web hosts will gzip everything by default &#8211; including video files. In Firefox and Opera, seeking will not be possible or the video may not play at all if a video file is gzipped. If this is occurring it would be prudent to check your server \/ hosts and disable the gzipping of media files.\n<\/p>\n<h4>QUICKTIME &amp; FLASH<\/h4>\n<p>\nIt goes without saying that in order to play video via the Flash player, the browser needs to have the Flash plugin installed. Don\u2019t assume this is the case for all browsers and try to provide a positive fall-back option \u2013 this also helps to debug issues.\n<\/p>\n<p>Flash v9+ is required to playback H.264 encoded MP4\u2019s.<\/p>\n<p>\nA less obvious gotcha is the dependency of Quicktime for Safari when playing native video on Windows. Again support for this comes via a plugin, which is commonly not installed. Failure to have this available, plus the lack of the Flash plugin can actually lead to no player being rendered in Safari.\n<\/p>\n<h4>IE SPECIFICS<\/h4>\n<p>\nIE7 &amp; IE8 don&#8217;t understand the native <code>video<\/code> &amp; <code>source<\/code> tags and so will fall-back to Flash mode. However there are two factors that need to be in place in order for this to happen:\n<\/p>\n<p>\nFirstly the Flash plugin needs to be available.<\/p>\n<p>\nSecondly the use of a HTML5 Shim in order to \u201cregister\u201d the availability of the <code>video<\/code> tag. JW Player cannot interrogate and build a configuration object if the <code>video<\/code> tag has not been \u201cmodernised\u201d. This can be done by including a 3rd party HTML5 Shim library <strong>or more sensibly by loading the JW Player library in the head<\/strong> \u2013 JW Player will modernise the <code>video<\/code> tag if needed.\n<\/p>\n<h4>ADDITIONAL VIDEO PARAMETERS<\/h4>\n<p>\nThe following parameters and their impact can often be overlooked when it comes to implementing a native <code>video<\/code> tag in conjunction with JW Player:\n<\/p>\n<blockquote><p>\nautoplay () : include this attribute (no value) to let the video start as the page gets loaded. Use sparsely, since this may frustrate your viewers. Note that it does not work on iOS.<br \/>\ncontrols () : include this attribute (no value) to display a simple controlbar, provided by the browser. The design of this controlbar varies per browser (which is a common issue JW Player resolves gracefully).<br \/>\nheight (number) : height of the video on the page in pixels &#8211; is required.<br \/>\nloop (): Include this attribute to let the browser continuously repeat playback of the video.<br \/>\nposter (string): the url of a poster frame that is shown before the video starts. Can be any PNG, JPG or GIF image. By default, it is not set (i.e. no preview).<br \/>\npreload (&#8216;auto&#8217;, &#8216;metadata&#8217;, &#8216;none&#8217;) : This attribute defines whether the entire video is loaded upon webpage load, or whether only the metadata is initially loaded. Or, you can choose to not load the video at all upon webpage load. The default (on most browsers) is metadata.<br \/>\nsrc (string) : The URL of the video to play. This is not required, since source files can also be listed using  tags.<br \/>\nwidth (number) : width of the video on the page, in pixels. Is required.\n<\/p><\/blockquote>\n<p>\nThe JW Documentation also states:\n<\/p>\n<blockquote><p>\n\u2026 Plus there&#8217;s the inevitable browser bugs (especially on devices) and different looking controls that cannot be styled.<\/p>\n<p>The JW Player helps to fix all these issues. It sniffs out the contents of the video tag &#8211; the sources, as well as the poster, loop, autoplay, etc.). It also detects the browser capabilities and then uses JavaScript to, for example, work around bugs, add new features or embed a Flash version of the player in place of the  tag.\n<\/p><\/blockquote>\n<p>\nGiven these statements you might expect the <code>controls<\/code>, <code>autoplay<\/code>, <code>loop<\/code> and <code>preload<\/code> attributes to be directly controllable via the <code>video<\/code> tag and for the results to be consistent across browsers\/devices.\n<\/p>\n<p>\nSadly this is not the case. Furthermore, these seemingly supplementary attributes are the reason behind most of the unexplainable \u201cgeneric\u201d issues detailed above.\n<\/p>\n<p>\nFirstly it\u2019s important to note that, contrary to what is stated, JW Player does not directly make use of these parameters.\n<\/p>\n<p>\nIt does have similar acting parameters which can only be included as part of the JavaScript setup configuration (<code>controlbar<\/code>, <code>autostart<\/code>, <code>repeat<\/code> and <code>bufferlength<\/code>) but these are not derived from the original parameters and are also not directly included as part of the newly generated JW <code>video<\/code> tag &#8211; they are implemented through pseudo JavaScript methods.\n<\/p>\n<p>\nThe second part of this is understandable as the JW Player needs to override the browsers built in functionality with it&#8217;s own implementation in order to provide consistency.\n<\/p>\n<p>\nIf JW Player determines that it should render in HTML5 mode, then it simply creates an <em>empty video tag stub<\/em> with none of these attributes included. This is because it also doesn&#8217;t set the <code>source<\/code> of the video (or <code>src<\/code> in the case of a single playable video or playlist file) until the user clicks the play button (or the file link in the playlist).\n<\/p>\n<p>\nComing back to the first part, why not allow the attributes to act as the configuration settings for the JW Player &#8211; even if they ultimately translate to JW&#8217;s own implementation? Surely this is a bug&#8230; Actually I believe it&#8217;s an oversight that LongTail Video are happy to brush under the carpet.\n<\/p>\n<h5>DIGGING A BIT DEEPER<\/h5>\n<p>\nLets update my original code with these parameters and work through what happens:\n<\/p>\n<p><code class=\"code-block\">&lt;html&gt;<br \/>\n&lt;head&gt;<br \/>\n\u2026<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body&gt;<br \/>\n&lt;!-- Navigation stuff  --&gt;<br \/>\n\u2026<br \/>\n&lt;!-- Content Area  --&gt;<br \/>\n\t&lt;h2&gt;Check this HTML5 video out!&lt;\/h2&gt;<br \/>\n\t&lt;video height=\"270\" width=\"480\" id=\"myVideo\" preload=\"auto\" controls autoplay&gt;<br \/>\n\t\t&lt;source src=\"\/static\/bunny.mp4\" type=\"video\/mp4\"&gt;<br \/>\n\t\t&lt;source src=\"\/static\/bunny.webm\" type=\"video\/webm\"&gt;<br \/>\n\t&lt;\/video&gt;<br \/>\n&lt;!-- More content  --&gt;<br \/>\n\u2026<br \/>\n&lt;!-- Right hand column  --&gt;<br \/>\n\u2026<br \/>\n&lt;!-- Footer stuff  --&gt;<br \/>\n&lt;script src=\"\/jwplayer\/jwplayer.js\" type=\"text\/javascript\"&gt;&lt;\/script&gt;<br \/>\n&lt;script type=\"text\/javascript\"&gt;<br \/>\n\/\/ &lt;![CDATA[<br \/>\n\tjwplayer(\"myVideo\").setup(<br \/>\n\t{<br \/>\n\t\tmodes:<br \/>\n\t\t[<br \/>\n\t\t\t{ type: 'html5' },<br \/>\n\t\t\t{ type: 'flash', src: '\/jwplayer\/player.swf' }<br \/>\n\t\t]<br \/>\n\t});<br \/>\n\/\/ ]]&gt;<br \/>\n&lt;\/script&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<br \/>\n<\/code><\/p>\n<p>\nThe most obvious thing to note given this configuration is that the native <code>video<\/code> tag will be interpreted and rendered well before the JW Player library is loaded and the <code>setup<\/code> call is made. This will result in the following:\n<\/p>\n<ol>\n<li>The native video placeholder being rendered according to the <code>width<\/code> &amp; <code>height<\/code> specified<\/li>\n<li>Native video <code>controls<\/code> being displayed over the video<\/li>\n<li>The video will be buffered in accordance with the <code>preload<\/code> setting<\/li>\n<li>The video will start to play as soon as enough data is available to do so<\/li>\n<\/ol>\n<p>\nThen when the JW Player library is loaded and the <code>setup<\/code> call is made<strong>[*]<\/strong> the following will happen:\n<\/p>\n<ol>\n<li>JW will &#8220;overwrite&#8221; the existing (already playing) <code>video<\/code> tag with it&#8217;s own player furniture comprising a number of nested <code>div<\/code> tags and a new, empty <code>video<\/code> tag<\/li>\n<li>The <code>poster<\/code> image will be displayed<\/li>\n<li>The JW controls will be displayed over the <code>poster<\/code> image<\/li>\n<li>The <code>video<\/code> will not automatically start to play<\/li>\n<\/ol>\n<p>\n<strong>[*]<\/strong> Depending on what follows the <code>video<\/code> tag in the rest of the page &#8211; how long it takes to be rendered, and in the case of external scripts, how much they block &#8211; this could potentially be a number of seconds later.\n<\/p>\n<p>\nClearly this doesn&#8217;t result in a great user experience and depending on your requirements\/flexibility there are things that can be done to make it better, however it does raise an interesting question &#8211; what <strong>*actually*<\/strong> happens to the video that is already playing when JW overwrites it?\n<\/p>\n<p>\nYou may rightly expect either the browser, or the JW embed process, to handle the clean up of the existing video &#8211; removing it from the DOM and wiping clean any future demands the resource may have on the browser, network or memory&#8230; <strong>You might therefore be surprised to learn that this is not the case!<\/strong>\n<\/p>\n<p>\nThrough my testing (<em>yes &#8211; I ended up building a video testbed<\/em>) I was able to determine the following:\n<\/p>\n<p class=\"jw6-update\">\nIf the native video is given enough time<strong>[1]<\/strong> to start doing &#8220;stuff&#8221;<strong>[2]<\/strong> before it is wiped out by the JW Embed process, the video will continue to exist in memory, can continue to make demands on the network and amazingly may even continue to play.\n<\/p>\n<p>\n<strong>[1]<\/strong> Typically I found this to be anything over 0.5 sec.<br \/>\n<strong>[2]<\/strong> Either buffering data as a result of the <code>preload<\/code> attribute being set (or more likely not being set <em>&#8211; see below<\/em>) or downloading and playing as a result of the <code>autoplay<\/code> attribute.\n<\/p>\n<p>\nThe result of this situation leads to all manner of problems. I have actually seen, and more importantly can reproduce, the &#8220;phantom video&#8221; causing the following:\n<\/p>\n<ul>\n<li>The newly JW embedded video delays playing until the &#8220;phantom&#8221; has finished downloading &#8211; misleadingly this can make you think the video encoding is wrong as it resembles the experience of having the metadata at the end of the file<\/li>\n<li>The newly JW embedded video won&#8217;t play until the &#8220;phantom&#8221; has finished playing &#8211; resulting in a black screen and audio only<\/li>\n<li>The newly JW embedded video buffers infinitely &#8211; this is as a result of the JW video believing it has buffered enough data to be able to play but actually it&#8217;s buffer being empty. It gets confused with the &#8220;phantom&#8221; video&#8217;s buffer which is ready to play &#8211; but never does<\/li>\n<li>In the case of Firefox where it would natively play the WebM version, coupled with the default JW playback mode being &#8220;Flash-first&#8221; (supporting MP4), both videos are played simultaneously resulting in what appears to be echoey audio<\/li>\n<\/ul>\n<p>\nBecause the manifestation of these issues is closely related to the time taken between rendering a native <code>video<\/code> tag on the page and the JW Embedder overwriting it, you can now start to see how a page that one day has a working video, might suddenly start to exhibit inconsistent behaviour &#8211; maybe an external script library is blocking just a bit longer than normal (<em>jQuery on a CDN for example<\/em>) or you&#8217;ve upgraded to a new version of JW Player and the files are not cached the first time you revisit the page.\n<\/p>\n<p>\nWhen you consider the negative impact <code>preload<\/code> and <code>autoplay<\/code> can have depending on your embedding approach, coupled with the fact these two attributes are not respected on the majority of mobile devices it becomes &#8220;understandable&#8221; why LongTail Video might prefer you not to use them &#8211; it just would be nice if the documentation were to accurately reflect this.\n<\/p>\n<h4>AND THE SOLUTION?<\/h4>\n<p>\nYou may deduce that it&#8217;s as simple as to <strong>not include<\/strong> the <code>preload<\/code> or <code>autoplay<\/code> attributes in the native <code>video<\/code> tag. However when checking the current default values for <code>preload<\/code> (in the case that you don&#8217;t specify the attribute) I found the following:<\/p>\n<table>\n<tbody>\n<tr>\n<th>Chrome<\/th>\n<th>Firefox<\/th>\n<th>Safari<\/th>\n<th>Opera<\/th>\n<th>&lt;IE9<\/th>\n<th>IE9<\/th>\n<th>iOS 5<\/th>\n<th>Android<\/th>\n<\/tr>\n<tr>\n<td><code>auto<\/code><\/td>\n<td><code>\"\"<\/code><\/td>\n<td><code>auto<\/code><\/td>\n<td><code>metadata<\/code><\/td>\n<td>n\/a<\/td>\n<td><code>metadata<\/code><\/td>\n<td><code>auto<\/code><\/td>\n<td><code>auto<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\nWhich suggests that <em>most browsers will attempt to load the entire video upon webpage load<\/em> &#8211; or more accurately, when the browser has enough information about the <code>video<\/code> tag to be able to render it &#8211; again this is not in line with what the JW documentation states.\n<\/p>\n<h3>THE RECOMMENDATION<\/h3>\n<p>\nPhew&#8230; that&#8217;s a lot to take on-board.\n<\/p>\n<p>\nHere&#8217;s a quick summary of the approach I recommend in order to minimise the likelihood of problems when using JW Player to progressively enhance an HTML5 video tag.\n<\/p>\n<ul>\n<li>Ensure your videos are encoded correctly<\/li>\n<li>Ensure the MIME-types are set correctly on your server<\/li>\n<li>Ensure GZIP is not enabled for media files<\/li>\n<li>Load JW Library in the head of your web page &#8211; although the JW Documentation actually recommends this (in places) the supporting examples and suggestions in forums often overlook the importance of this<\/li>\n<li>Don&#8217;t include the <code>autoplay<\/code> attribute in the native video tag<\/li>\n<li>Include <code>preload=\"none\"<\/code> in the native video tag<\/li>\n<li>Include the <code>setup<\/code> script as close as possible inline after the <code>video<\/code> tag &#8211; in order to minimise the time it has to do &#8220;stuff&#8221; before it is overwritten<\/li>\n<li>Include the JW equivalent versions of <code>preload<\/code> and <code>autoplay<\/code> in the setup configuration if really needed<\/li>\n<\/ul>\n<h3>HOLD ON, WHAT IF I ACTUALLY WANT TO preload OR autoplay&#8230;<\/h3>\n<p>\nIndeed&#8230; there is a use case scenario where the JW Player is not actually initiated (JavaScript is disabled) and so the native <code>video<\/code> tag (and it&#8217;s attributes) will be the mechanism used to render and play the video.\n<\/p>\n<p>\nFollowing my recommendation unfortunately means that the native video will not preload or autoplay in this scenario.\n<\/p>\n<p>\nOn the one hand, maybe this is a small compromise to pay in order to overcome the wider issues of inconsistent video playback.\n<\/p>\n<p>\nOn the other hand, surely there is a way to clean up the &#8220;phantom video&#8221; issue and have the native video attributes <strong>*actually*<\/strong> drive the configuration of the JW player.\n<\/p>\n<p>\nOh, and while we&#8217;re at it, wouldn&#8217;t it be great if:\n<\/p>\n<ul>\n<li>JW Player was fully configurable through HTML tags &#8211; including playlists &#8211; with no JavaScript knowledge required<\/li>\n<li>Hybrid playlists could be built which were capable of merging YouTube playlists with individual videos &#8211; in Flash and HTML5 mode<\/li>\n<li>And JW Player acted responsively within the body of the page or viewport of a mobile device whilst maintaining the correct aspect ratio<\/li>\n<\/ul>\n<p>\nWell I thought it would be great. Which is why I&#8217;ve enhanced my extension to JW Player so that is does exactly that. <strong><a href=\"http:\/\/powered-by-haiku.co.uk\/?p=189\">You can find more details about this here.<\/a><\/strong>\n<\/p>\n<div class=\"jw6-update\">\n<h3>WAIT NOW&#8230; WHAT&#8217;S THIS&#8230; JW6 IS COMING&#8230;<\/h3>\n<p>\nAnd unbelievably LongTail Video are removing support for embedding over a <code>video<\/code> tag!\n<\/p>\n<p>\nTaken from the beta documentation:\n<\/p>\n<blockquote><p>\nJW6 supports many functionalities not supported by a video tag (e.g. Flash, RSS, YouTube, RTMP, VAST). Additionally, longer term promises of an inline video element (progressive enhancement, video SEO, accessibility) are not there yet. Therefore, JW6 does not support the enhancing of a video element yet.\n<\/p><\/blockquote>\n<p>\nWow&#8230; After being leading advocates of the approach to progressively enhance HTML5 video tags and all the logical reasoning that goes with it, I find it amazing that LongTail Video can drop support for it in such a way.\n<\/p>\n<p>\n<em>JW6 supports many functionalities not supported by a video tag<\/em> &#8211; yeah right, but a <code>video<\/code> tag supports more of these in a fall-back position than a <code>div<\/code> ever will!\n<\/p>\n<p>\nA cynical person might think that by dropping support for this embed method, LongTail Video are looking to reduce the number of support issues that potentially fall under their remit. I imagine that what will actually happen when developers come to implement JW6 is they will simply wrap <code>div<\/code>&#8216;s around their native <code>video<\/code> tags and target these <code>div<\/code>&#8216;s instead &#8211; potentially creating more issues than solving. Only time will tell.\n<\/p>\n<p>\n<strong>In the mean time, I&#8217;ve just added a new requirement to the <a href=\"http:\/\/powered-by-haiku.co.uk\/?p=189\">JW HTML CONFIG<\/a> JavaScript extension I&#8217;ve been developing &#8211; to support JW6!<\/strong>\n<\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<h3><em>Updated &#8211; 18th October 2012<\/em><\/h3>\n<p>Received an interesting response to this article from Jeroen @ LongTail Video today:<\/p>\n<blockquote>\n<p>As James says at the bottom, all embed issues will be solved with JW6. It&#8217;s a full rewrite of our HTML5 mode. The MP4 encoding issues (MOOV atom, baseline, etc) remain though. Luckily, WebM seems about to leave the stage soon.<\/p>\n<p>We specifically chose to not support the <code>video<\/code> element, because of all the issues we ran into with JW5. We do evangelize HTML5 video, for its longer-term promises. We do not support decorating the <code>video<\/code> element in JW6, because those promises have not yet been fulfilled. There&#8217;s no search\/accessibility\/fallback advantages for using a <code>video<\/code> element today. There&#8217;s also many reasons for preferring Flash in HTML5 browsers (codecs, streaming, security, performance, consistency, advertising, etc). <\/p>\n<p>\nOver time, we WILL  support decoration of video tags as an embed method. It&#8217;s just not yet feasible. We have two blog posts lined up for this, in which we&#8217;ll elaborate.\n<\/p>\n<\/blockquote>\n<p>Firstly I&#8217;m guessing Jeroen actually means <em>&#8220;&#8230;<strong>Ogg<\/strong> seems about to leave the stage soon&#8230;&#8221;<\/em> not WebM.<\/p>\n<p>Secondly, it&#8217;s interesting to note that JW6 has switched the default playback mode from Flash first in JW5 to HTML5 first &#8211; which conflicts with the idea that there are <em>&#8220;&#8230; many reasons for preferring Flash in HTML5 browsers&#8230;&#8221;<\/em>. HTML5 mode is all about presenting and decorating the native <code>video<\/code> tag.<\/p>\n<p>For me, it still makes more sense to start with a native <code>video<\/code> tag, whilst providing good documentation (and even a code fix?!) to highlight and overcome the &#8220;Phantom Video&#8221; issue. This will at least ensure some accessibility and SEO benefits over and above an empty <code>div<\/code> tag &#8211; which relies on JavaScript enhancements to function at all.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>JW Player and HTML5 Video When it comes to embedded media on the web, the JW Player from LongTail Video is widely regarded as one of the best solutions in terms of producing consistent results across a wide range of browsers and devices. Since release 5.3, JW Player has included a specific embedding method that&hellip; <a href=\"http:\/\/powered-by-haiku.co.uk\/?p=1\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-1","post","type-post","status-publish","format-standard","hentry","category-jw-player"],"_links":{"self":[{"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/1","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1"}],"version-history":[{"count":78,"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions"}],"predecessor-version":[{"id":465,"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/1\/revisions\/465"}],"wp:attachment":[{"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/powered-by-haiku.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}