Making HTML5 Video work on Android phones

Warning This article was written over six months ago, and may contain outdated information.

I recently became the owner of an Android phone* and found that, despite it being listed as a feature of the browser, the HTML5 video element didn’t work for almost all of the examples I tried. I’ve just done some experimentation with this and think I’ve found a solution, so this post is offered in the hope that it helps anyone who may be tearing their hair out over the same problem.

From what I can tell, there are three requirements for video to work in Android browsers:

  1. You must not use the type attribute when calling the video
  2. You must manually call the play() method using JavaScript
  3. The video must be encoded as .m4v, not .mp4 Update: This is not correct (see below)

Update: This may be a specific encoding issue rather than all .mp4s; some .mp4 videos seem to play with no problems, others do not. Further update: The video type was a red herring; see my follow-up post, Encoding Video for Android, for more about this.

You can see this working in the demo attached to an older post of mine: Demo: HTML5 Video Controls With JavaScript. This works, AFAIK, in Android, iPhone and all video-enabled desktop browsers. The markup I’ve used is:

<video id="video" autobuffer height="240" width="360">
<source src="BigBuck.m4v">
<source src="BigBuck.webm" type="video/webm">
<source src="BigBuck.theora.ogv" type="video/ogg">
</video>

The first source element calls the video in .m4v format, without specifying the MIME type in the type attribute; I’ve tried both video/mp4 and video/x-m4v, and neither works. Omitting the type attribute altogether lets the video play, and seems to have no ill-effect on other browsers which play the .m4v file.

In order to play the video in Android, I also have an event listener in the JavaScript which plays the video when the element is clicked on, somewhat like this:

var video = document.getElementById('video');
video.addEventListener('click',function(){
  video.play();
},false);

I tested this on my own phone and an HTC Desire, and it works just fine on both. Hope this is of help to someone.

* It’s a Samsung Galaxy S, and I’m delighted by it.

71 comments on
“Making HTML5 Video work on Android phones”

  1. It’s hard to believe that HTML5 video is still so badly broken in Android, even in the latest version. This should have been working since version 1 and they have no excuses—the markup has been out there and in use by the iPhone for *THREE YEARS*. I’m irate at Google for their incompetence with HTML5 video on Android. Where does one file a bug?

  2. Hi Kroc, I’ve added this blog post to an open bug, number 8272 – I encourage you to do the same.

  3. @KROC_CAMEN – HTML5 video support isn’t perfect, but the example doesn’t work on iPhone. Maybe you should check next time before going on a rant and spouting bullshit.

  4. Wait; my example doesn’t work on iPhone? It certainly did when I checked it. Are you using iOS3? There’s a well-known bug with that, where the poster attribute causes problems.

    Also, please try to be civil.

  5. are there any special settings to encode the video with? The Javascript works fine, but as soon as I click the icon I get a message telling me “Video can not be displayed. This video is not a valid streaming media format”. Any ideas what might be wrong with the video (it’s a .m4v Format). Thanks!

  6. Hi Kirsten,

    Thanks for the comment. Your result is interesting, because I don’t get that message at all; I get the same message on some .mp4 files. What phone and version of Android are you using? I’m going to look into this further.

    Peter

  7. Hi Peter,

    thanks for the quick reply. I am using the HTC Desire with the current standard version Android 2.1 update1. I tried various encoding settings. There was no chance with the mp4 encoding, as you have written. I use ISkySoft as converting software and the encoding settings were: M4V -MPEG – 4Video(*.m4v), Codec: H.264
    Any idea? The alternative .ogv File is available as download only.
    Thanks in advance! Kirsten

  8. Kirsten,

    I’m going to put together a test page, and we’ll see if we can get to the bottom of this.

    Peter

  9. Kirsten, could you take a look at this test page:

    http://broken-links.com/tests/video/comparison.html

    And let me know which of the videos (A,B,C,D) works for you? I’ve got a fairly good idea of what the problem is now, but want confirmation.

    Peter

  10. Hi Peter, Video A and B worked perfeictly. With C and D I got the same error message as with my movie. I am looking forwarnd to your answer. Kirsten

  11. Hi all,
    This is a good article.
    Thank you very much.
    But i have an issue (not small).

    We can watch video on Android but it can be autobuffer (or preload).
    On iPhone, you can press PAUSE and wait the player buffer the video. Then you can watch whole video without delay.

    On Android, even you press PAUSE, but it just buffer 1/20 of video and stop buffer.
    THen you watch video, if your internet is slow, the video will be delay to load… many times.

    Please help me to solve this problem.
    I am trying to find the solution for this whole week, but i still can not find out…

    Please…
    Thank you very much.
    Regards,
    Cuonga

  12. @Kirsten: OK, so all four test videos were encoded using http://handbrake.fr; the only difference is that A & B used the ‘web optimized’ setting, C & D didn’t. I don’t know exactly what that does (rearranges the MP4 files so they stream better, from what I can tell) or how to make this happen in other encoding applications, but in the short term this will help you encode video. In the longer term, I’m going to look into this some more.

    @MiniHD.mobi: I don’t get that problem on my Samsung Galaxy; may be a phone issue rather than an Android issue? What version of Android are you on? (Also I prefer if you use a name or nickname rather than a company name; it makes it harder to tell spam from genuine comments if you use your company name as your user name).

  13. Hi Peter
    Thanks for the great info. Can I ask you a question please.
    I’ve made a simple html5 video page. Please see the code below

    #script#
    var video = document.getElementById(‘video’);
    video.addEventListener(‘click’,function(){
    document.play();
    },false);
    #/script#

    #video width=”320″ height=”240″ poster=”poster.png” autobuffer controls#
    #source src=”TV_intro.m4v”#
    #source src=”TV_intro.mp4″ type=”video/mp4″#
    #source src=”TV_intro.ogv” type=”video/ogg” /#
    Download the #a href=video.ogg#video#/a#
    #/video#

    But it doesn’t work on my htc desire though.. Can you kindly have a look at my code if I’ve done anything wrong? It works on iPhone.

    Thanks in advance

    ps. I just changed the mp4 extension to m4v to make m4v file as I read it works this way. No?

    Jun

  14. @Jun: As mentioned, it also depends on the way the video is encoded; see my comment to Kirsten, above.

  15. Hi Peter

    Thanks for the rapid reply. So do you think that the html itself is fine?

    Thanks

    Jun

  16. Yes, the HTML seems fine; you just need to encode the video correctly. Try using Handbrake, and set the ‘web optimized’ option.

  17. hmmmm….Yes I used Bandbrake with ‘web optimized’ checked. but no luck yet.. maybe need more googling.. haha
    it must be simple just don’t know what it is.

    Thanks

  18. Hi Peter

    The reason was javascript. Once changed js it works. but only sound. screen is just black. one solved but another came out. Any idea? Anyway will post if there’re any outcomes for other people who have the same issue.

  19. Hi Peter,

    I changed the encoding as you said and now it does work perfectly. Thank you very much for your quick replies!

  20. does not work on htc magic w. A V:1.6

  21. The JS code fixed my Android issues but it has “broken” the pause/play button on all other browsers once the video has started to play. I imagine this is due to conflicts between the EventListener and the ‘click’ function of the play button i.e. you’re essentially hitting play twice and this causes the video to immediately pause after the play. The example on http://diveintohtml5.org/video.html also exhibits this problem – just try and Play -> Pause -> Replay and you’ll see what I mean. My workaround at the moment is to sniff for UserAgent and only add the EventListener if it’s an “android” – but has anyone got a better solution?
    var uagent = navigator.userAgent.toLowerCase();

    if (uagent.search("android") > -1) {

    var video = document.getElementById('video');
    video.addEventListener('click',function(){
    video.play();
    },false);
    }

  22. @Jun I’m getting the same thing as you. It “plays” the video, but it only has audio with a black screen. I just have a link straight to the mp4 file with no javascript.

    I’m trying to figure out how to output once from Camtasia Studio (with web format) to mp4 and have it play on all browsers, iPhone/Touch/Pad, and Android. It’s all working right now except for this problem with Android :S

    Micah Peterson [November 23rd, 2010, 20:09]

  23. I know this is way late, but it’s worth mentioning that you can keep the type=”video/mp4″ on the first source, and then move it to the video element’s .src attribute for Android. Something like:

    var video = document.getElementById(‘video’);
    video.src = video.childNodes[0].src;
    video.addEventListener(‘click’,function(){
    video.play();
    },false);

  24. I know this is arcane, but it may be the real reason for most problems playing video on Android:

    ***Make sure the “moov” atom comes before the “mdat” atom in the file.***

    In Handbrake, for instance, you would check “web optimized” then make sure that “2 pass encoding” is enabled – this second pass is required to re-order the elements in the file such that Android will recognize it, since the natural order these elements are calculated in during single-pass encoding is the reverse.

  25. @Matt: I won’t pretend to know what that means, but that does sound right; I read something similar to that on a forum somewhere.

  26. Hi Peter,

    Are these code applied for Android’s browser only not for Android native application?
    I just created an Android application that run .m4v video file using your code. I used PhoneGap framework for this application so I can use html and Javascript to create an app. But the code didn’t work well. It couldn’t run the media file.
    Could you pls give me any advices?
    Thanks,
    Thom

  27. @Thom Sorry for the slow reply. I don’t know anything about Android app development, and haven’t used PhoneGap, so I can’t give you any advice on this. Sorry.

  28. Hi Peter, am a newbie to android… am trying to run a video in html5(). i’ve read all the comments posted and came to know abt the procedure to run vids on phones. But i want to run thm on emulator. Cld u pls hlp me out of this of avd 2.2 or 2.3.

    Thank you.

  29. @Vinay I’ve never been able to get video working on the emulator, and a lot of people seem to have the same problem. Most of the time I just get the audio. Try searching the Android developers forums and see if you can get a decent response from there.

  30. Peter,

    I don’t know if this is helpful info or not, but I’ve just checked and all of those videos (A-F) on the video comparison page work on Android 2.3 (Nexus S)

    Thanks

  31. @Tom – Very useful, thanks.

  32. […] Displaying HTML5 Video for Android Tutorial at Broken Links […]

  33. […] Making HTML5 Video work on Android phones Related: iPad is the new IE6 […]

  34. Worked fine with HTC Desire[Android 2.1] and iPhone4[iOS 4.2.1]

  35. Hey Peter … This may be late to the game but I read today on Video for Everyone that Android has to be tested using real phones when it comes to video; the emulator won’t play them. Reference: http://camendesign.com/code/video_for_everybody/test.html
    Blurb: “HTML5 video on Android is badly broken. Resolution support varies from one handset to the next (often just 480×360), the fallback image usually doesn’t show and the code requires special adjustments. The Android emulator is completely useless as it doesn’t represent any real hardware and does not play HTML5 video. THERE IS NO WAY TO TEST ON ANDROID WITHOUT A PHYSICAL PHONE. BLAME GOOGLE.”

    Rynne Cowham [May 5th, 2011, 20:46]

  36. Thanks Rynne. My experience is that the screen will go black and play audio, but there’s no video playback. While that’s not great, it does mean that there’s enough feedback for you to tell if a video would play or not. But yes, testing on a physical device is better; the Android emulators are *slow*.

  37. I am trying to get a movie (mp4) to work on both ios and android. I am writing on a mac and using mainly BBEDIT or Dashcode, and editing the *.js file.

    I was wondering if you know what I can write to enable android to work?

    the js file is:

    function writeMovie1()
    {detectBrowser();if(windowsInternetExplorer)
    {document.write(”);}
    else if(isiPhone)
    {document.write(”);}
    else
    {document.write(”);}}
    setTransparentGifURL(‘Media/transparent.gif’);function hostedOnDM()
    {return false;}
    function onPageLoad()
    {loadMozillaCSS(‘Gallery_files/GalleryMoz.css’)
    Widget.onload();fixupAllIEPNGBGs();fixAllIEPNGs(‘Media/transparent.gif’);fixupIECSS3Opacity(‘id2’);performPostEffectsFixups()}
    function onPageUnload()
    {Widget.onunload();}

  38. So what’s the deal with Android 2.2 then? None of these solutions seem to work for that one, and I’ve tried them all — the js play call trick, removing the codecs, removing the type attributes, all of the above…. I even went to your Demo here: http://broken-links.com/tests/video/ with the 2.2 droid and sure enough, it would not play the video. Gave me a spinner for “forever” and then on refresh popped up that “video cannot be played” message.

  39. Really? I have Android 2.2 and it works fine for me. When you have a chance, take a look at this page and see if any work for you:

    http://broken-links.com/tests/video/comparison.html

  40. I tested these on an Android 2.1 device and all played except “C” and “F”. I haven’t had a chance to use again the Android 2.2 phone I was using previously, though. At this point I’m pretty convinced the problem is with how the video is encoded, so I’m gathering info in that regard to see if we can’t get to the bottom of this (including your Encoding article — thank you! Did you ever resolve the iProducts issues on some of those examples, by the way?)

  41. worked on my optimus v except c and f running android 2.2

  42. I’m having the same problem as Stupidian mentioned before. If I apply the play or pause control to the video tag itself, I lose the play or pause control from the default controls. (Actually, it acts like I’ve double-clicked the control. When I click on play on the controls, it advances one frame then stops. If I click on the video, play continues.)
    I noticed that the video works in http://diveintohtml5.org/video.html now, but from Chrome (for example), there is no control by clicking on the video itself. Any idea of how they are getting around this (like a sniffer, because they aren’t claiming to use one), or how do I get around this in general, preferably without sniffing?

    Is there a DOM access to the default play controls? I’d like to have the option of playing by clicking on the play control or by having a giant play button overlay on the poster, because most video players use the standard of clicking either one.

  43. does both android and iphone only play embedded video via it’s native player only? I want it to play on the page…not a popup…. is it possible?

  44. […] Javascriptでトリガーを設置してあげないとフルスクリーン再生してくれなかったりするようです。 […]

  45. […] Addressing challenges playing audio and video in the Android browser. […]

  46. less lines with this.play();

  47. […] read this post Making html5 video work on android phones. But I believe I’ve got that covered in my code above. Anyone see what I can do to get this […]

  48. Hello everybody. First thnx a lot for this code for video for android it works perfectly. Now I wanted to combine with a code for redirecting to another url and it doesn’t work on android. While it’s working in mozzila and safari. Any help? you can see my page

    here

    and here is code I used:

    var video = document.getElementById(‘myvideo’);
    video.addEventListener(‘click’,function(){
    video.play();
    },false);

    var video = document.getElementById(“video”);
    video.addEventListener(“ended”,doSomething,true);

    function doSomething() {

    window.location = “http://www.reyescaballerorey.com/voodoo_page/news.html”
    }

  49. This really saved the day for me in terms of raw functionality to play the video. I was frustrated that I could get the video to play on all HTML5 devices and browsers (including other android phones) except my Ginger-bread based Rezound. It was not an encoding issue, just a click-to-play issue. The video would play if I tapped in the lower left corner of the video area, so it seems as if for some reason the browser or the device makes the controls for video invisible. Instead of making the entire video area hot (clickable), is there a solution to make those video controls visible for browsers/devices that might be hiding them?

  50. Rather than adding an event listener, I simply take advantage of the play() method:
    <video onclick=”this.play();” preload=”auto” controls=”controls”>
    <source src=”movie.mp4″ />
    </video>

  51. I own a Samsung Galaxy S2 and i dont have a problem about videos. Maybe its about the version of the android ????

  52. @FredMC Using inline JavaScript is bad practice, which is why I’ve used an event listener.

  53. I am developing android app using phone gap in which I am using HTML5.Can you please tell me in which folder I should keep my video to make it work..
    Thanks a lot.

  54. Thank you for all the info which i had pulled my hair over.
    I am running php site displaying html-5 video and embed others
    like youtube.

    I tried above javascripts but does not work well. Especially my version of android stock safari browser running on Samsung G. S2
    does not detect anything on the UA while if i switched to Chrome on the same device it does (strange!).

    So i come out with a modified method that work well for me.

    Tested on: Windows XP chrome, Samsung Galaxy S2, iPad2.

    1. Let the php script which displays my html-5 videos detect browser UA.

    a. get this simple php class to detect ua type (or any one available).
    http://code.google.com/p/php-mobile-detect/wiki/Mobile_Detect

    b. Give different video tag treatments if found to be android IOS and safari. (note chrome on android is working perfectly, so above methods memtioned by a few, which test only for android will fail chrome on android, that’s why i use this approach together with onclick=’this.play(); suggested by FREDMC above, Thanks).

    Codes:
    if ( $detect_mobile->isSafari() AND $detect_mobile->isAndroidOS() )
    {
    echo “”; }
    else
    {
    echo “”;
    }
    and follows by the usual video stuff.

    This works perfectly for me on different devices and PC using different browsers.

    hope it helps.

  55. Soemthing was missing in my post above.

    if detech to be safari and androd, i will insert this to video tag:

    onclick=’this.play()’

  56. […] If you experience problems with MP4 video playing on earlier version of Android you may wish to explore removing the type attribute for the MP4 source – as suggested in Peter Gasston’s post. […]

  57. Your demo runs on Ipad 2, I’d to run a single mp4 video file and perfoms OK when I touch the Ipad screen

  58. install vplayer version 3.1.3

    Click on Video download Link, Android system,open with VPlayer

    it will stream it :)

  59. The movies works great on originale browser on phone. My question is, how can I modified a webview, so it play that movies.

  60. An additional consideration is that MP4 video that resides on a server requiring authentication or in a password protected folder will not work in Android Chrome (4.2). It will however work using Firefox for android (diff format as WebM but also not locked down as the MP4 evidently is).

    You can however have an HTML page containing the video tag reside in a secure location as long as the folder where the video is doesn’t require authentication.

    It’s a messed up issue that I hope is resolved in later versions of Android Chrome . . .

  61. For the life of me I cannot get this to play on my android 4.0.4 tablet.

    I downloaded the video, put the code on my page and tried playing it in a a phonegap webview, it just wont happen! Any ideas? Can you make this play inside the webview?

  62. Im trying to start the video with a simple video.play() once the page has loaded but this does not work. Any idea why? I mean whats the diference? It works in my dektop browser. Can you not do .play() without an event listener?

  63. As Stupidian already pointed this out a few years ago: the example code somewhat breaks the HTML5 player of devices other than the one targeted by the fix. So to do it correctly, you’ve to check the User-Agent and apply the fix only for Android versions 2.0.* – 2.2.*. The problem got fixed in Android 2.3.

    A better example code could be like this:

    function myOnload() {
    var ua = navigator.userAgent;
    if (typeof ua != “undefined” && ua.match(/Android.* 2\.[0-2](\.[0-9]+)*[^.0-9]/i) !== null) {
    var vid = document.getElementById(“video”);
    vid.addEventListener(“click”, function() {
    vid.play();
    }, false);
    }
    }
    window.onload = myOnload;

    Another issue many complained about is that (for them) the example doesn’t work at all on 2.2.* Android versions, the playback doesn’t start when you click the video. I had this issue on phones where JavaScript was disabled. Obviously your code won’t run in this case. To cover for this, you can add some warning about the necessity of JavaScript for playback in a NOSCRIPT tag below the JavaScript code.

  64. Thanks so much for your posts. I am having the same problem playing HTML5 video on Android. My videos play on all browsers and iPod, but not Android (I have a Galaxy Tab 2 with Honeycomb).

    I followed your advice on this post and your other post about encoding video for Android but I haven’t gotten it to work yet. My video encoder is called Magix Photostory. I set the the resolution to 480×272, the codec to MPEG-4 H.264, the AVC preset to “Apple iPod” (which set the profile to baseline and the bit rate to 970kb/s). I set the output format as MP4 for iPod and I even checked the box for mobile devices. The resulting video still plays fine on all browsers (once converted as appropriate to WebM or flash), but the darn thing still won’t play on Android.

    I followed the steps above for the HTML 5 code – not using the type attribute when calling the MP4 video and manually calling play(). Manually calling play() seemed to make matters worse, since the controls attribute works OK on the Android (starts and stops play) and the play() command seems to conflict with that some. When I hit play on the video, it looks like it is just buffering with the wheel going around and no picture. I let it run a long time and it never started playing. I also made sure the meta data is in the front of the file (that was needed to get Safari to work properly).

    So, I am out of ideas. Do you have any other suggestions? Would it be possible for you to post a complete HTML file that works so I can check my code against it?

    Thanks again.

  65. Never mind my last post. David Miller’s post below solved my problem. My videos are on a password protected page and they won’t play with Chrome or the Android default browser. As suggested, I tried firefox and it worked like a charm. Thank you, David!!!!!

  66. […] Making HTML5 video work on Android phones. Le sigh. […]

  67. Hi Peter. I’m hoping the community on this thread can help me. I’m trying to play a url to an .mp4 file within a Chrome browser on Android 4.1.2.

    When I click the link I get the playback progress bar and when I click play I get audio but no video within the browser. When I click play fullscreen however the video plays fine filling the screen.

    Here is an example link which gives the issues above – http://download.wavetlan.com/SVV/Media/HTTP/H264/Talkinghead_Media/H264_test1_Talkinghead_mp4_480x360.mp4

    I have tried your test comparison page (www.broken-links.com/tests/video/comparison.html) and all videos playback fine in fullscreen but just show a black screen within the browser.

    Any help with this issue would be greatly appreciated.

  68. Chris, if you are not wed to Chrome, try Firefox. My video is stored on a password protected web page; Firefox is the only browser I’ve found that can play it properly on Android. If your video is not on a password protected page, then this solution may not work. But you might try it anyway to see if Firefox works.

  69. i m also trying to play local video files alerady added in my project assets/www/video/abc.mp4
    here is my post
    http://stackoverflow.com/questions/18997200/html5-video-tag-failed-to-play-mp4-videos-in-phonegap-android-with-cordova-2-9

    but i did not get any answer can anyone help me how to encode video as i want to play videos for phonegap Android api level 8 or AndroidVersion 2.2 but i m unable to play even code is working in browser but no video in device

  70. live RTSP video stream is still playing on the background although browser is closed (i can hear the audio), only task manager->ram manager-> clear memory stops it. any attempt to invoke pause,stop on video element fails. reoccurring on all Galaxy Samsung devices i have tested.
    any idea how to fix it ?

  71. I have a Samsung Galaxy Tab 2 and I’m trying to automatically play a video on an Android Application, but I tried many codes but still, video does not Autoplaying. Would you please help me how.

    Thank you.