I've been playing around with the HTML5 video tag and I'm puzzled as to how best to degrade when you can't support a codec?
For older browsers (or IE) that don't support the video tag at all this quite is straight forward:
<video width="320" height="240">
<source src="vid.ogv" type='video/ogg'>
<source src="vid.mp4" type='video/mp4'>
<object>
<!-- Embed Flash video here to play mp4 -->
<object>
</video>
They will fall through and will receive the Flash version (or other alternate such as an image!)
How about when the browser does support the tag but not the codec - Like FireFox 3.5 for example - and I can't support OGG (possibly because I already have vast archives of H.264):
<video width="320" height="240">
<source src="vid.mp4" type='video/mp4'>
<object>
<!-- Embed Flash video here to play mp4 -->
<object>
</video>
All I get in FireFox 3.5 is a grey box with an x in it. This isn't exactly a great user experience for FireFox users! I can only think of using JavaScript to check for FF3.5 and change the DOM!! is this really the bad old all over again! ...or is there some part of the spec I'm missing out on like a 'novideo' tag?
An important part of graceful degradation is the querying capabilities... Dive into HTML5 is a great read... specifically, look at the video section. Relevant code here:
function supports_h264_baseline_video() {
if (!supports_video()) { return false; }
var v = document.createElement("video");
return v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
}
Note: this does require DOM checking, but for capabilities and not browser signature. It's the right thing to do :-)
Once you know if the browser can support, you can show your video tag or pull up a lightbox or redirect as you see fit.
One really good way to tackle this problem is to use modernizer js library.Its really easy to use and quick.It can check HTML5 capabilities in the user's browser . Visit the site here : http://www.modernizr.com/
Video for Everybody's test page indicates that Firefox 3.5 can only play OGG. You might want to add a flash version if you really don't want to add OGG. VfE also does not use JavaScript, so it might be worth looking into.
Related
My ranking from Google Page Speed insights is being severely penalised because of:
"Serve Images in Next-Gen Formats" more info on Google's help page here.
However, according to this, this and this those formats are supported very few browsers.
What do you do in this scenario? What
You could use the <picture> element to deliver a WebP image to users with browsers that support it, falling back to a JPEG or PNG for those that don't. The advantage of using the <picture> element rather than other fallback methods is that browsers that don't support the element will fallback to whatever source is defined in the <img> tag.
<picture>
<source srcset="img/yourImage.webp" type="image/webp">
<source srcset="img/yourImage.jpg" type="image/jpeg">
<img src="img/yourImage.jpg" alt="Your image">
</picture>
Here's a method for converting source images to WebP.
If you're using WordPress there are plugins that will automatically generate WebP images from your media library and include fallback functionality. The only one I've used is WebP Express but it served me reasonably well when a client was alarmed that their 100/100 PageSpeed Insight score took a nosedive to 30 overnight with the Lighthouse roll-out.
This does feel like another way for Google to push another propriety technology but then WebP compression is quite impressive compared to other 'next-gen' formats.
WebP is the one that currently has broader support, pretty much all major browser except Safari support it.
As colossalyouth mentioned on one of the answers you can use the picture tag to load webp images and in the case is not supported it will fallback to any other format you choose.
And if you are using background-image you can use something like modernizr to detect feature support by the browser and end up with CSS like the following:
my-selector {
background: url('../images/home-bg.webp') no-repeat scroll center center
}
.no-webp my-selector {
background: url('../images/home-bg.jpg') no-repeat scroll center center
}
I have actually done both things on my website and successfully implemented webp formats, I have created a detailed post on how I did it and the performance gains I had you can check it out here: Improve your website speed performance using next-gen formats
Until major browsers support those next-gen formats, it's probably best to continue using JPG/PNG, as they have wide-spread support. Most websites do indeed use JPG & PNG and it will take some time till browsers are in-line with next-gen tech.
You could always use an image CDN like ImageEngine. Full disclosure I work for the company behind ImageEngine.
It acts as a pull based CDN and will automatically transform your images to WebP or JPEG-2000 if the end users device supports that format. It will also automatically apply compression and resizing to further optimize your image content, but it will definitely help with your page speed.
You can sign up for a free trial and see how that improves your Google Page Speed score.
You can use a tool like https://www.imagecompress.org/ to convert your current image formats, and follow the example to update your old tags https://www.imagecompress.org/examples.
I recommend you to use "Enhanced Media Library" plugin if you're a wordpress user. It will simply allow you to directly upload Webp images without configuring anything manually.
WebP format will load faster and consume less cellular data. Anyone can work with the format and suggest improvements in WebP open source.
In <picture> attribute <source> can be used to load alternative image file formats that might not be supported in all browsers. For example, you can serve an image in WebP format to browsers that support it, while falling back to a JPEG on other browsers:
<picture>
<source type="image/webp" srcset="images/verz.webp">
<img src="images/banner.jpg" alt="Banner Image" width="100" height="100">
</picture>
Note: The element is currently available Chrome 38. Try it out with screen emulation in the Chrome DevTools. As per Google, WebP is supported in Chrome and Opera and provides better lossy and lossless compression for images on the web. WebP does not support all browsers. For other browsers, You'll need to serve a fallback PNG or JPEG image.
If your website is in WordPress. Use plugins that will automatically convert your uploaded images to the optimal formats.
I have VideoJS displaying a video in a modal window in a Wordpress website. I'm NOT using a videoJS plugin, I've loaded the latest VideoJS version to the home directory. The code for the video tag is in a separate non-Wordpress html file all on it's own.
The video IS working fine in Safari on the Mac, it's also working fine in Firefox on Windows. It is NOT working properly in Firefox on the Mac.
I have traced this issue back to it being caused by the 'controls' option in the tag. As soon as I change the options to 'autoplay' and take out 'controls', the video plays perfectly well in Firefox and Safari on the Mac.
More specifically it appears to be the small timer (showing how much video has played) on the skin's slider.
The skin in Firefox is different that the one in Safari. The one in Safari is BLACK and displays the time to the left and right of the slider at the bottom of the player. The one in Firefox is GREY and has the time in a small raised box above the slider at the bottom of the player. It is this raised box that seems to be causing an issue with the video playing in Firefox. The video is only playing slowly on a strip just above the slider and only to the height of the timer box.
I have tried putting:
<script>
_V_.ControlBar.prototype.options.components = {'playToggle':{}}
</script>
right under the call to
<script src="http://vjs.zencdn.net/c/video.js"></script>
in the head of the Wordpress page that has the modal window displaying the separate html page containing the code.
That did NOT work; both Safari and Firefox still show the controls at the bottom of the player.
I also tried adding:
.vjs-default-skin .vjs-time-controls {display: none !important;}
to my WP theme's stylesheet. That did NOT work either.
QUESTION 1: Why is Firefox using a different skin for VideoJS than Safari? If I can get the same controller for Firefox (ie one without the raised time code box) then the video may play normally.
QUESTION 2: How can I limit the controls to show only the large centred play button without showing the controls at the bottom of the player? Again, not having the raised time code box may make the video display normally in Firefox.
QUESTION 3: All this came about because I discovered iPhone and iPad do not play videos with the autoplay setting. I had originally set the option for autoplay in the tag without 'controls', but because it wasn't working in iPad (just getting a black background to the video) I took out 'autoplay' and added the 'controls'. And that's when I noticed the problem in Firefox. So if I can't fix the issue with having controls in Firefox and it not working, is there a way to get round the black screen issue on the iPad and using 'autoplay' for Firefox without controls?
Please let me know if there's any other information you need.
You shouldn't need the code as it's all working; the problem only arises in Firefox on the Mac when I add 'controls' to the tag. And I'm sure this can be fixed by using a different skin or getting rid of the controls at the bottom of the video (well, I'm hoping that will fix it!).
BTW I'm using this in the head of my WP template
<link href="http://vjs.zencdn.net/4.0/video-js.css" rel="stylesheet">
<script src="http://vjs.zencdn.net/4.0/video.js"></script>
Oh, and Firefox is not falling back to the Flash Flowplayer, it's definitely playing the ogg file in the HTML5 video tag.
ctagney, thanks for taking the time to respond.
Question 1
Hmm, strange.
I have this in the header at the moment:
<link href="http://vjs.zencdn.net/4.0/video-js.css" rel="stylesheet">
<script src="http://vjs.zencdn.net/4.0/video.js"></script>
This is the code I have in the html page (I've replaced actual domain with ... as I don't want links to the site --- you can see the video on www. horizonyachtsgrenada .com/ new-yacht-sales-grenada/ at the top of the right-hand side bar:
<div style="margin:0; Padding:0;">
<video id="salesvideo" class="video-js vjs-default-skin" preload="auto" controls width="540" height="320"
poster="http://.../videos/horizon-dream-makers-splash.jpg"
data-setup="{}">
<source src="http://.../video/HORIZON_FINAL_HD.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
<source src="http://.../video/HORIZON_FINAL_HD.ogv" type='video/ogg; codecs="theora, vorbis"' />
<source src="http://.../video/HORIZON_FINAL_HD.webm" type='video/webm; codecs="vp8, vorbis"' />
<!-- Flash Fallback. Use any flash video player here. Make sure to keep the vjs-flash-fallback class. -->
<object id="flash_fallback_1" class="vjs-flash-fallback" width="540" height="320" type="application/x-shockwave-flash" data="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf">
<param name="movie" value="http://releases.flowplayer.org/swf/flowplayer-3.2.1.swf" />
<param name="allowfullscreen" value="true" />
<param name="flashvars" value='config={"playlist":[http://.../videos/horizon-dream-makers-splash.jpg", {"url": "http://.../video/HORIZON_FINAL_HD.mp4","autoPlay":true,"autoBuffering":true}]}' />
<!-- Image Fallback. Typically the same as the poster image. -->
<img src="http://.../videos/horizon-dream-makers-splash.jpg" width="540" height="320" alt="Poster Image" title="No video playback capabilities." />
</object>
</video>
</div>
Any ideas why it's not using the video.js?
Question 2
I've added that code to the page now, so hopefully once it's picking up video.js it will pick this up. I assume I won't need 'controls' in the video tag for this to work, is that correct?
Question 3
So, if I'm understanding your link correctly, I'm right in changing it from autoplay to having controls for it to work on the iPad and iPhone.
New issue:
It's not working in Chrome even though there is a webm version of the video! I'm beginning to go greyer ... just want the video to work now!! :(
Any help much appreciated.
Cheers,
Tracy
EDIT: BTW the video does play on Safari, Firefox, and Chrome on a different site (different server, different video code) so it's not the video itself causing an issue.
The players you're describing in firefox and safari sound like the native video players for each browser. In other words, you're not actually using video.js.
Question 1
Once you get it working, you'll notice that the players should look identical to one another in Safari and Firefox. Without seeing your code it's hard to say why your video.js player isn't getting initialized, but you need to do one of the following:
Include a data-setup='' tag in your video element, which you can use to specify options via a JSON value.
Have a separate script that calls _V_("video id", {}) once the page has loaded.
I recommend you use the second option since you have some additional setup to handle (see: below)
Question 2
The big play button you want is automatically hidden when controls are turned off, so you should just call it's show() method once the video player has been initialized.
<script>
_V_("example", {}, function() { this.bigPlayButton.show(); });
</script>
See the following for a working example.
http://jsbin.com/ijipag/2/edit
Question 3
See Can you autoplay HTML5 videos on the iPad?
The issue was I didn't include the call to the video.js
<link href="http://vjs.zencdn.net/4.0/video-js.css" rel="stylesheet">
<script src="http://vjs.zencdn.net/4.0/video.js"></script>
in the separate (non-WP) html page that's shown in the modal (FancyBox iframe) window. I've now included that and it's successfully calling the video.js and showing the big play button without the bottom controls in Safari and Firefox.
It's still NOT working in Chrome. In Chrome, when you click the play button it's just showing the poster image and the spinning loading gif.
UPDATE: Got it working in Chrome by moving :
<source src="http://www.horizonmotoryachts.com/video/HORIZON_FINAL_HD.webm" type='video/webm; codecs="vp8, vorbis"' />
above the calls to the mpeg4 and ogg files.
Tested on Firefox and Safari on Mac and its still working.
The way YouTube recommends you load a video is like so:
<iframe id="ytplayer" type="text/html" width="640" height="360" src="http://www.youtube.com/embed/Zhawgd0REhA" frameborder="0" allowfullscreen>
This loads the video as an iframe so they can detect iOS or other devices and deliver a swf or HTML5 player depending on what's necessary.
These snippets come from their Player API Demo. https://developers.google.com/youtube/youtube_player_demo
Unfortunately, in IE6-9 this causes serious slowdown - the browser seems to freeze up for as much as 5 seconds, even when the player is the only thing on the page and isn't set to autoplay. In addition, there's a touch of irony to this "demo" in that they aren't at all loading the player the way they recommend, and instead loading it via a custom written Google AppEngine/AppSpot app they put together - and it actually does load more performantly in the demo in IE than when one uses Google's recommended snippet.
Have others run into this? Is there a good solution?
We don't have the .ogv format available from the encoder in our system, but I would like to use the HTML5 Video tag with an MP4 source for those browsers that support it--unfortunately, Firefox does not support MP4.
After some experimentation, it seems that once you put the video tag in Firefox, it will figure out if any of the provided sources are playable, and if none of them are, it will do nothing. It will also ignore the nested fallback object. This is technically the correct behavior per the HTML5 spec, but it seems that if Firefox can't play the MP4 source it should just render the inner object tags.
I know there are JavaScript techniques for testing whether a browser "canPlayType", but I would rather avoid the JavaScript insertion of the video tag.
Am I correct that Firefox ignores the internal fallback markup in a video whether or not the video tag sources are supported?
This is technically the correct behavior per the HTML5 spec
I believe you have your answer. ;)
I know Firefox strives for compliance so I doubt they would go against the grain here. Although, I'll admit, it does seem odd that the spec doesn't allow for a fallback.
Here's my code:
<audio controls preload="auto">
<source src="audio/batcat.mp3" />
Your browser doesn't play MP3s. Download the audio instead.
</audio>
In Chrome & IE9, the browser displays the native audio player.
In Firefox, I would expect it to show the fallback text and the link. Instead, it shows an ugly grey box with an X in the middle and doesn't show the fallback content.
Is this a Firefox bug, or am I doing something wrong?
Are browser makers actually saying include every possible format, or don't use the element at all. That seems a bit harsh.
EDIT
The answer to the above question is "yes" apparently. All I can say to that is :(
Firefox should indeed fallback to the link to the audio file as you've said. It goes through the source list and if it can't find one it is able to play, it should move on.
Perhaps try adding the type aatribute to the source declaration to help the browser decide it won't be able to play it?
<source src="audio/batcat.mp3" type="audio/mp3">
Also if you had a sample page so we could see it in action (or not as the case may be!) that would be helpful.
edit
I've tested it myself and indeed you are correct, it simply doesn't work. How strange, I would have expected it to. The only way to get it to work was by adding a source with an OGG file which it can play.
I suggest you use something like Modernizr to check if it can play MP3s or not.
You're right. This is because each browser supports different "codecs." Originally, HTML5 was going to have a single codec, but the browser vendors could not agree on which one (patent-encumbered vs. open source) so that requirement was dropped.
For example, for video, IE and Safari support H264 (MP4), Chrome, FF, and Opera WebM/Ogg.
To ensure it works in all browsers, you can supply multiple source elements and encode your video three times. Mp4 first, WebM or Ogg second (browsers that support video will try each source element until they find one they can play. Note: currently there is a "bug" on the iPad where it can only play the first source element)
You can even embed a Flash object for your fallback so your video will also work in older versions of IE (<9). You'll end up with something like this:
<!—Multiple videos with alternate Flash content-->
<video controls>
<source src="rocpoc.mp4">
<source src="rocpoc.ogv">
<object data="videoplayer.swf" type="application/x-shockwave-flash">
<param name="movie" value="rocpoc.swf"/>
</object>
A movie by Rocky Lubbers
</video>
If you want to show a link to the file if the browser cannot play the MP3 file, you can use a little bit of JavaScript code to test if the browser can handle the MP3 format and show a link to a file instead of the video instead. The JavaScript method to call is canPlayType.
//Checking for browser support
//canPlayType returns null, maybe, or probably (the best)
//You can check if they are supported in navigator.plugins
var support = videoElement.canPlayType('video/some-format;codecs="some-codec"');
Alternatively, (for video only, I think) you can use services like vid.ly (http://m.vid.ly/user/) that serve up the right files from the cloud.
Same is true for video! If you embed an MP4 file only, Firefox does not jump to the fallback but renders the grey "I cannot play this format" box. You have to use JavaScript to detect which codecs the browser is able to play.
http://praegnanz.de/html5video/firefoxtest