HOWTO: HTML5 Video that works (almost) everywhere
So I got this video from a friend, and I wanted to post it on my site, but I wanted to do it without using any Flash, or any plugins, and I wanted it to work on the iPhone, and Chrome, and Firefox, and IE…
Step 1: Convert the file.
First I took the file and used Miro Video Converter to make two versions of the file. The first version I made was using the “Theora” format. This is an Ogg format, and you basically only need to make it for the video to show up in Firefox. Future versions of Firefox will support the WebM format instead (Chrome supports it now), so when Firefox 4 comes out, use that format. Next, use Miro again and this time make a version using the iPhone preset. This basically creates an MP4 version of the file, but at the right resolution to have it show up on the iPhone. Annoyingly, the original file was from an iPhone, so it should have played, but it wouldn’t on mine. I suspect that the resolution difference between the iPhone 4 (used to make the photo) and the iPhone 3GS (which I have) is the problem. Regardless, I just used the preset to downscale the video resolution.
Step 2: Adjust WordPress’ settings
WordPress didn’t like me uploading these files. Turned out that it was because I’m on multisite. In the Network Admin screen, find the Network Settings menu option, go to the bottom of the page, and add the mp4 and ogv extensions to the list of allowed files. Also add webm while you’re there, for the future. Note: If you’re not on multisite but still have problems uploading the files, then add this line of code to your wp-config.php file, to turn on the unfiltered_upload capabilities for administrators:
Step 3: Check .htaccess settings
One of the things WordPress relies on to know if it’s a video or not is the MIME Type. Some servers have these properly configured, some don’t. Doesn’t hurt to help the process along by explicitly defining some of them in the .htaccess file. For good measure, I added a bunch of common ones, just to be sure:
AddType text/xml .xml AddType video/mp4 .mp4 .m4v AddType video/mpeg .mpeg .mpg AddType video/quicktime .mov AddType video/ogg .ogv AddType video/webm .webm AddType audio/mp4 .m4a .m4b .m4r AddType audio/mpeg .mp3 AddType audio/playlist .m3u AddType audio/x-scpls .pls AddType audio/ogg .ogg AddType audio/wav .wav
Step 4: Upload the videos
Easy one. Go into the Media->Library and upload your two videos. After doing that, get the URLs of both of them.
Step 5: Make the post
Make a new post and type in everything you want to type in. Then make sure you’re in the HTML editing mode, and add this code to the post:
<video width="640" height="360" controls> <source src="http://example.com/wp-content/uploads/video.mp4" type='video/mp4'></source> <source src="http://example.com/wp-content/uploads/video.ogv" type='video/ogg'></source> </video>
There’s a few things there you’ll need to manually edit. Obviously the URLs need to point to your files. Also, it’s important that the MP4 one is first, some older iPad software doesn’t like it otherwise. The second one is the width and height. Now, like with posting images, these don’t have to exactly match the actual width and height of the video. The browser will use these sizes and scale the video accordingly. However, you’ll want to get the aspect ratio correct, so you don’t stretch or squish the video into the wrong sized box. And you can leave the height and width out entirely to not scale it, if you got your sizes correct in the video itself. But it’s a good idea to have them there regardless, to clue the browser into the size beforehand and speed up page rendering. Also note that the iPhone doesn’t care about those width and height tags, since it will just show the video full screen when you tap on it. Sidenote: Do NOT switch into Visual mode. TinyMCE will muck up this code, badly, and try to add a SWF player to it and Flash and a bunch of other stuff. This is probably by design, but I wanted to do this without Flash at all and see how that worked. Turns out to work fine in the browsers I tested. Finally, preview and publish as normal.
One thing I haven’t figured out is how to target the iPhone specifically with a separate file. With this setup, Chrome and IE are now showing the iPhone file, which is lower resolution than the OGV file (which is at original resolution). In this specific case, the video was poor and so it doesn’t make much difference, but I’d prefer to have a separate file specified that only iPhones used without having to resort to user agent targeting. EDIT: Turns out you can do this with a media query on the source that targets the iPhone. So here’s my new code:
<video width="640" height="360" controls> <source src="http://example.com/wp-content/uploads/video.iphone.mp4" type='video/mp4' media='only screen and (max-device-width: 480px)'></source> <source src="http://example.com/wp-content/uploads/video.mp4" type='video/mp4'></source> <source src="http://example.com/wp-content/uploads/video.ogv" type='video/ogg'></source> </video>
The media attribute lets you specify a CSS3 Media Query. The max-device-width of 480px = iPhone. So desktop browsers will use the video.mp4 while the iPhone uses the video.iphone.mp4. I’ve confirmed that this works properly with Chrome. It’s interesting to see that browsers can do this reasonably well, even if you do have to make a few different versions of the video.
At the suggestion of ipstenu in the comments below, I made this into a shortcode plugin. You can download it here: HTML5 Video Shortcode. This plugin has the advantage of being ignored by TinyMCE.