To Top

HTML 5, Theora and more

I’ve read quite a few articles on HTML 5, Theora, and video tags, but most of them discussed theoretical rather than practical issues. On my site MJV-ART.ORG, I recently added an anime section, JV-Video, which is a small video hosting (similar to YouTube) based on HTML5/Theora. In this article, I’m going to tell you about the real problems that I encountered.

Web browsers

Although all major web browsers seemingly support HTML 5 and Theora, glitches do occur here and there. Even Firefox, still the finest browser, does have lots of quirks and oddities in that regard, which we’ll discuss for starters.

  • The early builds of Firefox 3.5 failed to recognize the aspect ratio setting in Ogg containers, so picture proportions tended to go haywire, especially when MPG files were re-encoded. The bug was fixed in the latest builds.
  • Firefox 3.5.* builds ignore the instruction to show the controls menu: controls=”controls” (thus being non-compliant with the standard), which makes it necessary to use the non-standard instruction: controls=”true”. Firefox 3.6 doesn’t have this issue.
  • Firefox 3.5.* builds refuse to play some slightly “wrong” files, producing the following error: [theora @ 0xac90c0]Missing extradata! The problem was fixed in Firefox 3.6.
  • When certain videos are played back in Firefox 3.5 or 3.6, the sound is missing for some unknown reasons.
  • Audio often lags behind video, sometimes by as much as 20 seconds. In some cases, such out-of-sync starts immediately; in others, somewhere in the middle of the track.
  • Fullscreen playback mode became available in Firefox 3.6 only. It really works — all you need is a very simple hack written in JavaScript:
  • document.getElementById('video_post').style.position='absolute';
    return false;

I must say that Chrome 3 for Windows handles video just fine! (At least, I didn’t find any problems, though I didn’t test it thoroughly.) Most of our complaints are about Chromium 4, which is now available for all major operating systems.

  • The main problem with Chromium 4 and 5 (running under Linux) is that the controls menu doesn’t work properly — try to use it, and somewhere in the middle of the track, video playback will hang up and go into an infinite loop. Read more about this bug here: It’s quite possible that the glitch isn’t present in Google’s browser versions for Windows or Mac OS X. To solve the issue, when my website detects that a visitor is using Chrome 4, it automatically turns off the playback controls and pastes in the following pieces of code:
  • document.getElementById('video_post').play();return false; // For "Play".
    document.getElementById('video_post').pause();return false; // For "Pause".
    document.getElementById('video_post').controls='true';return false; // To turn on the controls menu.

    You can use these pieces with the “onclick” attribute of such HTML tags as “a”, “img”, and so on, so that site visitors can watch a video and have basic playback controls. (Controls are verified upon each synchronization with SVN.)
  • Sometimes video playback doesn’t work at all, or only the audio is played.
  • There is no built-in fullscreen playback mode, but you can enable it using the same JavaScript code (see above).
  • As neither bilinear nor analog filtering are available, picture resizing results in heavy pixelation.

Although Safari lacks native Theora support, you only need to install a QuickTime plugin for enabling Theora-based video playback; after that, everything works perfectly! As with other web browsers, you have to use the JavaScript tweak to enable fullscreen playback mode.


All stable versions simply ignore the “video” tag, but the pre-alpha version 0.50_pre6177 (for Linux) can already play back video, although with some issues:

  • The slider in the controls menu doesn’t work. (Play and Pause work just fine.)
  • From time to time, the picture twitches (as it usually happens when a CPU cannot handle the load) while the CPU load actually isn’t high at all. Probably, that’s because double buffering isn’t used (or is it?), but I’m not sure.

QtWebkit-based browsers can at least play audio (but not video) if Gstreamer is enabled in Phonone (running under Linux). In case of Xine, the situation is even worse.


I didn’t test GtkWebkit-based browsers, but it would be very interesting to read about such tests.


I’ve decided to go the simple way, so I just used the ffmpeg2theora converter. After experimenting for quite a long time, I settled on the following parameters for encoding video:
ffmpeg2theora --speedlevel 0 --optimize -S 0 -v 6 -a 3 -x 480 -H 44100
(The resulting video quality was as good as that of YouTube, or maybe even better.)
I could also use Gstreamer for encoding video, and I’m going to experiment with that in future.
Here are the problems that I encountered:

  • In versions earlier than 0.25, aspect ratio was recognized incorrectly (or should I say, ignored), and this issue exists in addition to Firefox’s own problems with detecting aspect ratio.
  • Either the MP4 container itself is pretty bad, or the applications that make .mp4 video should go to hell! While one FPS is clearly specified in an .mp4 file (and ffmpeg2theora does its best and uses that setting), the video stream’s actual FPS is quite different — surely, video and audio go out of sync! Sometimes (but not always!) it helps if you disassemble a glitchy .mp4 file into its components and then reassemble them, using the standard utilities available in Linux. Some players can handle even quirky .mp4 files: mplayer, for example, first reads the “hardwired” FPS and uses it in the first few seconds of playback, but then re-syncs audio and video by using information from the video stream.
  • It seemed like a bad idea to overload my server with Theora encoding, so I used a very simple, distributed encoding system: I created a folder on the server with a few subfolders (“pre_buf”, “pre”, “proc”, “err”, and “out”), which are NFS-mounted by the computers assigned to encode video. When video files are uploaded to the server, first they go to the “pre_buf” folder; when uploading is complete, the files are moved at once to the “pre” folder. On the video-encoding computers, the cron process runs a special script that finds the first subfolder in the “pre” folder and moves it (of course, sometimes the moving fails or it may be too late) to the “proc” folder, and then the video conversion begins. The result is stored either to the “out” folder or (if some error occurs) to the “err” folder. On the server, a script run by cron checks the “out” and “err” folders and updates the database accordingly, and the finished files are moved from the “out” folder to a location where site visitors can access them. As you can see, such an approach is great for reducing the main server’s load.
Web server

As I’ve found out, not every configuration is good enough for making video accessible for playback. Initially I used lighttpd-scgi-python/Pylons, and the playback was awful (the picture twitched, artefacts were present, etc.), so I moved all static files to a separate domain and implemented direct access to them via lighttpd (which, by the way, is used by YouTube too), and now everything works just fine! Please note that ogv, oga, and ogg may be missing in Lighttpd’s mime types; in such case, add them yourself.

Hopefully, in this article I’ve told you everything I wanted and helped you learn more about current issues with HTML5-video/Theora.

More inSplashnology

Privacy Preference Center