HTML5 Video tag not working in Safari , iPhone and iPad
Asked Answered
M

32

178

I am trying to create an html5 web page in which there is a small video like 13s , I converted the flash version of this video into 3 format : .ogv using fireFogg , .webm using firefogg also and .mp4 using HandBrake application the html script I used in my page :

<video  width="800" height="640" loop preload="false" autoplay  controls tabindex="0">
  <source src="xmasvideo/video.mp4" type="video/mp4" />
  <source src="xmasvideo/M&P-Xmas 2.ogv" type="video/ogv" />
  <source type="video/webm" src="xmasvideo/M&P-Xmas.webm" />
</video>

The video is working fine in Chrome and FireFox but not working at all neither in Safari on Desktop nor on iPhone or iPad , the output is simply a blank page that shows the controls of the the video tag but nothing is loaded

Note that the Safari version that I have supports HTML5 video

Mecke answered 3/12, 2013 at 9:30 Comment(5)
Apparently its a MimeType issue Check this link for more information I found it here Have a nice day :)Incommodious
good to note, video on ios never does autoplay: developer.apple.com/library/safari/documentation/AudioVideo/… ..Honniball
Did you try the attribute playsinline in video tag?Champac
My issue was due to animation frame in parent element, the solution was adding video tag after the animation and removing video tag before animation.Kisner
Can you check this tutorial: Video tag not working on iPhone Safari or ChromeGraham
B
242

I had same issue with apple devices like iPhone and iPad, I turned off the low power mode and it worked and you should also include playsinline attribute in video tag like this:

<video class="video-background" autoplay loop muted playsinline>

It only worked when including playsinline.

Bedchamber answered 19/7, 2018 at 22:41 Comment(7)
We didn't want to show the video controls even though that got it working on iphones for us, but adding "playsinline" worked perfectly and got it working on iphones as well as all other devices without showing controls. Perfect answer!Leuko
Note for anyone using React: you'll need to use playsInline, in camelCase.Exonerate
this works 100%.. I noticed the issue is not just the browser itself rather than iPhones in general because my video wasn't playing in other browsers on iPhones as wellDownstate
It's sad but for me, playsinline does not work.Elbow
Didn't work for me, am using AndroidElegist
it did not work me unfortunatelyEste
when I added width and height and preload= "auto" it worked for meEste
C
54

Another possible solution for you future searchers: (If your problem is not a mimetype issue.)

For some reason videos would not play on iPad unless i set the controls="true" flag.

Example: This worked for me on iPhone but not iPad.

<video loop autoplay width='100%' height='100%' src='//some_video.mp4' type='video/mp4'></video>

And this now works on both iPad and iPhone:

<video loop autoplay controls="true" width='100%' height='100%' src='//some_video.mp4' type='video/mp4'></video>
Cadelle answered 4/9, 2014 at 16:37 Comment(5)
This was the problem for me as well... nothing worked until adding the controls attribute to the video tag.Kelle
This worked perfectly for me. For future readers, I am embedding an mp4 using the video tag that @Cadelle posted above. Thanks!Dolt
For me, adding the autoplay option worked. I have controls="false" in my code.Bisk
@Bisk controls="false" is redundant; controls itself is a boolean that when present turns on the controls, and when not present there are no controls. See W3C specSandeesandeep
Also, since controls is a Boolean attribute, the only valid values are none, an empty string, or its own name. True and false values are incorrect.Stockbreeder
S
38

Your web server might not support HTTP byte-range requests. This is the case with the web server I'm using, and the result is that the video widget loads and a play button appears, but clicking the button has no effect. — The video works in FF and Chrome, but not iPhone or iPad.

Read more here on mobiforge.com about byte-range requests, in Appendix A: Streaming for Apple iPhone:

First, the Safari Web Browser requests the content, and if it's an audio or video file it opens it's media player. The media player then requests the first 2 bytes of the content, to ensure that the Webserver supports byte-range requests. Then, if it supports them, the iPhone's media player requests the rest of the content by byte-ranges and plays it.

You might want to search the web for "iphone mp4 byte-range".

Sibeal answered 28/2, 2015 at 8:53 Comment(5)
Here's another good resource for configuring your server to support byte range requests.Grate
This was my issue. I'm using Flask with 'send_file' and 'send_from_directory' calls. I had to add 'conditional=True' argument to those calls.Astrophotography
This answer applies to me and worked in my Play Framework implementation (2.7) Use RangeResult.ofPath(finalPath, range, Some(mime)) and should work 2.7 and upwards.Divot
P.S.: Forgot to add how to get the range. That's this call. It comes in as "Range" ` val range = request.headers.get("Range")`Divot
Cheers, this was failing for me as well (using Python's built in http server did not work -- Mobile Safari refused to play the video because the web server didn't support byte-range requests). npmjs.com/package/http-server can be used for this purpose -- it does support byte-range!Simile
L
23

If your videos are protected by a session-based login system, Safari will fail to load them. This is because Safari makes an initial request for the video, then hands the task over to QuickTime, which makes another request. Since Safari holds the session info, it will pass the authentication, but QuickTime will not.

You can see this if you view your server access log ... first the request from Safari, then the request from QuickTime. Other browsers just make a single request from the browser itself.

If this is your problem, you might have to rework the video access to use temporary tokens or a limited time access from the original request. I'll update this answer if I find a more direct solution.

Laxity answered 10/7, 2015 at 0:16 Comment(4)
I have the same issue (I'm a web developer but getting this issue in iphone), did you get any solution for this? if then please post it hereMuhammad
Sorry, I don't remember what project I was working on when I wrote this. My current projects use a CDN (Rackspace Cloud Files) that includes a tempURL function, which avoids the problem with session-based authentication.Laxity
Having the same problem here... Somebody any ideas on how to solve this?Puduns
You are a lifesaver! I spent several hours banging my head over this. Development site was locked with basic authentication.Peltry
S
16

Working around for few days into the same problem (and after check "playsinline" and "autoplay" and "muted" ok, "mime-types" and "range" in server ok, etc). The solution for all browsers was:

<video controls autoplay loop muted playsinline>
    <source src="https://example.com/my_video.mov" type="video/mp4">
</video>

Yes: convert video to .MOV and type="video/mp4" in the same tag. Working!

Spur answered 24/2, 2021 at 3:22 Comment(1)
I'm not satisfied with this answer but i also tried all the other suggestions and this is the only thing that gets videos to work on iOS for me. I am also able to do it with no controlsDecent
Y
15

For future searches as well, I had an mp4 file that I downscaled with Handbrake using handbrake-gtk from apt-get, e.g. sudo apt-get install handbrake-gtk. In Ubuntu 14.04, the handbrake repository doesn't include support for MP4 out of the box. I left the default settings, stripped the audio track out, and it generates an *.M4V file. For those wondering, they are the same container but M4V is primarily used on iOS to open in iTunes.

This worked in all browsers except Safari:

<video preload="yes" autoplay loop width="100%" height="auto" poster="http://cdn.foo.com/bar.png">
            <source src="//cdn.foo.com/bar-video.m4v" type="video/mp4">
            <source src="//cdn.foo.com/bar-video.webm" type="video/webm">
</video>

I changed the mime-type between video/mp4 and video/m4v with no effect. I also tested adding the control attribute and again, no effect.

This worked in all browsers tested including Safari 7 on Mavericks and Safari 8 on Yosemite. I simply renamed the same m4v file (the actual file, not just the HTML) to mp4 and reuploaded to our CDN:

<video preload="yes" autoplay loop width="100%" height="auto" poster="http://cdn.foo.com/bar.png">
            <source src="//cdn.foo.com/bar-video.mp4" type="video/mp4">
            <source src="//cdn.foo.com/bar-video.webm" type="video/webm">
</video>

Safari I think is fully expecting an actually-named MP4. No other combinations of file and mime-type worked for me. I think the other browsers opt for the WEBM file first, especially Chrome, even though I'm pretty sure the source list should select the first source that's technically supported.

This has not, however, fixed the video issue in iOS devices (iPad 3 "the new iPad" and iPhone 6 tested).

Yearwood answered 22/1, 2015 at 15:50 Comment(1)
I cannot believe I spent hours debugging my issue and it was because I had my webm above my mp4. this post had given me that idea!Hookworm
M
13

Just add a muted attribute and everything will work fine.

The source of this answer is here: https://webkit.org/blog/6784/new-video-policies-for-ios/

By default, WebKit will have the following policies:

<video autoplay> elements will now honor the autoplay attribute, for elements which meet the following conditions:

  • <video> elements will be allowed to autoplay without a user gesture if their source media contains no audio tracks.
  • <video muted> elements will also be allowed to autoplay without a user gesture.
  • If a <video> element gains an audio track or becomes un-muted without a user gesture, playback will pause.
  • <video autoplay> elements will only begin playing when visible on-screen such as when they are scrolled into the viewport, made visible through CSS, and inserted into the DOM.
  • <video autoplay> elements will pause if they become non-visible, such as by being scrolled out of the viewport.

<video> elements will now honor the play() method, for elements which meet the following conditions:

  • <video> elements will be allowed to play() without a user gesture if their source media contains no audio tracks, or if their muted property is set to true.
  • If a <video> element gains an audio track or becomes un-muted without a user gesture, playback will pause.
  • <video> elements will be allowed to play() when not visible on-screen or when out of the viewport.
  • video.play() will return a Promise, which will be rejected if any of these conditions are not met.

On iPhone, <video playsinline> elements will now be allowed to play inline, and will not automatically enter fullscreen mode when playback begins. <video> elements without playsinline attributes will continue to require fullscreen mode for playback on iPhone. When exiting fullscreen with a pinch gesture, <video> elements without playsinline will continue to play inline.

Magdaleno answered 14/1, 2018 at 12:7 Comment(0)
X
6

By using this code video will play in all browser in safari as well with ios devices... Go for it everyone (I have used this and working fine)

<video autoplay loop muted playsinline poster="video_thumbnail/thumbanil.jpg" src="video/video.mp4">
        <source src="video/video.mp4" type="video/mp4"></source>
        <source src="video/video.webm" type="video/webm"></source>
        <source src="video/video.mov" type="video/mov"></source>
</video>
Xyloid answered 30/11, 2018 at 14:16 Comment(3)
This was the only thing that worked for me trying to get a background video to loop, autoplay and without controls. Thanks Arvinda!Guanabana
have you actually uploaded 3 versions of your video, or is this just syntax trickery?Mcalpine
@Mcalpine thats 3 versions in various formatsAdore
D
6

Add these 4 param autoplay loop muted playsinline, like:

<video autoplay loop muted playsinline
    style="width:100%;height:auto;max-width:100%;">

in video tag to make it autoplay in iOS devices.

Drowse answered 26/1, 2022 at 13:58 Comment(1)
I always remember "muted," but I always forget about "playsinline." That fixes it for me. 👍Infatuation
R
4

I've seen weird issues with a non trusted 'development' SSL certificates where mobile Safari will quite happily serve your page but refuses to serve a video to a 'fake' SSL certificate even if you've accepted the certificate.

To test you can deploy the video elsewhere - or switch to http (for the whole page) and it should play.

Recursion answered 31/8, 2015 at 21:28 Comment(0)
F
4

Adding 'playsinline' works for me on Iphone and Ipa if you don't mind your video being muted.

<video muted playsinline>
  <source src="..." type="video/mp4">
</video>

If you don't want your video being muted, but still want autoplay, maybe try to remove muted attribute with js: How to unmute html5 video with a muted prop

Fourfold answered 2/11, 2018 at 14:33 Comment(0)
M
4

I had a similar issue where videos inside a <video> tag only played on Chrome and Firefox but not Safari. Here is what I did to fix it...

A weird trick I found was to have two different references to your video, one in a <video> tag for Chrome and Firefox, and the other in an <img> tag for Safari. Fun fact, videos do actually play in an <img> tag on Safari. After this, write a simple script to hide one or the other when a certain browser is in use. So for example:

<video id="video-tag" autoplay muted loop playsinline> 
    <source src="video.mp4" type="video/mp4" />  
</video>
<img id="img-tag" src="video.mp4">

<script type="text/javascript">
    function BrowserDetection() {

    //Check if browser is Safari, if it is, hide the <video> tag, otherwise hide the <img> tag
    if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0) {
        document.getElementById('video-tag').style.display= "none";
    } else {
        document.getElementById('img-tag').style.display= "none";
    }               

    //And run the script. Note that the script tag needs to be run after HTML so where you place it is important. 
    BrowserDetection();
</script>

This also helps solve the problem of a thin black frame/border on some videos on certain browsers where they are rendered incorrectly.

Margeret answered 26/9, 2019 at 14:27 Comment(0)
E
4

If your using in REACT use playsInline this is working in all IOS devices

Elane answered 5/10, 2020 at 10:32 Comment(0)
F
3

I have found that although Safari does support HTML5 Video, the Quicktime Player has to be installed in order for this to work. On a site that I built that uses HTML5 Video, the user is alerted when using Safari, telling them they must have Quicktime installed, otherwise they will only be able to see video transcripts. Hope this helps.

Festatus answered 21/1, 2014 at 10:31 Comment(1)
This answer is no longer up-to-date.Heaney
E
3

I had same problem - make sure the url for video asset is coming from secure domain. Our dev environment is http while production is secure. Due to the video being referenced via relative path, it wasn't working on development. Seems to be an issue that apple requires video to be secure...

Egon answered 10/5, 2019 at 20:39 Comment(0)
F
3

My complete solution yesterday includes several good answers from this question plus another blog articles. I`ll try to compile it.

The frontend

video tag

  • playsInline attribute makes difference
<video id='my-video' class='video-js' controls preload='auto' autoplay height="270" poster='img/logo_cathedra.png' playsInline type="video/mp4">
  • withCredentials makes difference to send cookies (in my case, JWT token)
var player = videojs('my-video');
...
window.addEventListener("load", () => {
    player.src({
        src: 'path-to-video',
        type: 'video/mp4',
        withCredentials: true
    });
});

The backend

  • write to the response the status 206 and the headers necessary to byte range and video streaming
Accept-Ranges: bytes
Connection: Keep-Alive
Content-Length: 1289232
Content-Range: bytes 0-1289231/1289232
Content-Type: video/mp4
Last-Modified: Sun, 06 Nov 2022 14:08:57 GMT

In my case, I expect a request Header WITH or WITHOUT limit (right side of range). When the right side is not suplied, I used a fixed chunk size and calculate the Content-Length and Content-Range

  • Ex. using Chrome
# REQUEST
Range: bytes=0-
...
# RESPONSE
Content-Length: 4096
Content-Range: bytes 0-4096/1289232
  • Ex. using Safari
# REQUEST
Range: bytes=0-1
...
# RESPONSE
Content-Length: 1
Content-Range: bytes 0-1/1289232
  • add back do the response headers safari sends playing HTML5 video
X-Playback-Session-Id: someRandom.chars.like.uuid
Federalism answered 10/11, 2022 at 19:21 Comment(0)
O
2

As of iOS 6.1, it is no longer possible to auto-play videos on the iPad. According to Apple documentation Autoplay feature is not working on Safari in all ios devices including iPad:

"Apple has made the decision to disable the automatic playing of video on iOS devices, through both script and attribute implementations.

In Safari, on iOS (for all devices, including iPad), where the user may be on a cellular network and be charged per data unit, preload and auto-play are disabled. No data is loaded until the user initiates it."

You can read more abut it in this Apple documentation

Osgood answered 24/7, 2016 at 6:47 Comment(1)
This doesn't attempt to answer the question in any way and might be useful as a comment. The question was about videos not playing at all, and has nothing to do with the autoplay feature.Bittersweet
W
2

For a .mp4 this works ( safari mobile & desktop ) :

<video height="250" width="250" controls>
    <source src="video.mp4" type="video/mp4" />
    Your browser does not support the video tag.
</video>

The controls=”true” mentioned in an above post make no sence to me as Apple says just use controls on its own.

Reference : “To use HTML5 audio or video, start by creating an  or  element, specifying a source URL for the media, and including the controls attribute. <video src="http://example.com/path/mymovie.mp4" controls></video>

Source : https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Introduction/Introduction.html

In my dealings ( a small digression ) : I have found that uploading video from iPhone sends it to server as .quicktime. Ironically, this is the problem when trying to play back the video from the server on safari. ( mobile & desktop ).

So if ( like me ) you are experiencing a .quicktime ( or anything other than .mp4 ) problem in safari, here is a work around provided by apple. Note, I'm yet to test it myself and I'm not all that happy with it at a glance, just providing more info.

Reference : “Fall Back to the QuickTime Plug-in There is a simple way to fall back to the QuickTime plug-in that works for nearly all browsers—download the prebuilt JavaScript file provided by Apple, ac_quicktime.js, from HTML Video Example and include it in your webpage by inserting the following line of code into your HTML head: <script src="ac_quicktime.js" type="text/javascript"></script>

Source : https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/AudioandVideoTagBasics/AudioandVideoTagBasics.html#//apple_ref/doc/uid/TP40009523-CH2-SW6

Update: For .quicktime rename to .mov prior upload to server ( in base64 filetype "data:video/mov;" ), skip ac_quicktime.js . . . will then work in html video tag; Hackerdy Hack.

Windbag answered 6/3, 2017 at 7:10 Comment(0)
S
2

For someone comes here, using the MediaSource Extension to operate video source.
And had tried other solutions but still not work.

I checked at Can I use MSE, and found the reason is the iOS of iPhone does not support MSE(Media Source Extension). So the MSE didn't work on iPhone.

an image from Can I use MSE
enter image description here

The iPhone's iOS support HLS originally (apple's dev docs), so you need to convert the MP4 to HLS format. (can use bento4 HLS)
📌 MP4 format must be fMP4 format

After converted, the HLS format output directory will look like this
enter image description here

The filename extension should be .m3u8, and the master.m3u8 is a doument that describe the video's all information.

Then let the video tag's src attribute point to the HLS resource's URL(master.m3u8).
like this sample code

<video src="https://XXX/master.m3u8">
</video>

For more information

Look this link

Sphygmic answered 12/10, 2022 at 3:19 Comment(0)
S
1

I had this problem where .mp4 playback in Safari didn't work, but in other browsers it was fine. The error that I was seeing in the console was: error media src not supported. In my case this turned out to be a MIME type issue, but not because it wasn't declared as MIME type in IIS, rather that it was declared twice (once in IIS and also in a web.config file). I found this out by trying to download the .mp4 file locally on the server. I removed the config file from the location of the content I was trying to play and it fixed the issue. I could have just deleted the MIME type from the web.config file, but in this case the web.config file wasn't needed.

Sepulcher answered 27/2, 2017 at 10:44 Comment(0)
D
1

For IOS, please use only mp4 source file. I have observed one issue in latest safari browser that safari browser cant able to detect source file correctly and because of this, video autoplay doesn't work.

Lets check below example -

     <video autoplay loop muted playsinline poster="video_thumbnail/thumbanil.jpg" src="video/video.mp4">
        <source src="video/video.mp4" type="video/mp4"></source>
        <source src="video/video.webm" type="video/webm"></source>
     </video>

As I have used mp4, webm in source files. Safari deosnt support webm but still in latest safari version, it would select webm and it fails video autoplay.

So to work autoplay across supported browser, I would suggest to check browser first and based on that you should generate your html.

So for safari, use below html.

     <video autoplay loop muted playsinline poster="video_thumbnail/thumbanil.jpg" src="video/video.mp4">
        <source src="video/video.mp4" type="video/mp4"></source>
     </video>

For other than safari,

     <video autoplay loop muted playsinline poster="video_thumbnail/thumbanil.jpg" src="video/video.mp4">
        <source src="video/video.webm" type="video/webm"></source>
        <source src="video/video.mp4" type="video/mp4"></source>
     </video>
Dispraise answered 23/1, 2019 at 4:46 Comment(0)
A
1

is working but MacOs recently has autoplay policy for user: https://webkit.org/blog/7734/auto-play-policy-changes-for-macos/, I resolved the same issue using a button to enable sound:

ejm:

<video autoplay loop muted id="myVideo">
  <source src="amazon.mp4" type="video/mp4">
  Sorry, your browser doesn't support embedded videos...
</video>

<button class="pausee" onclick="disableMute()" type="button">Enable sound</button>

<script>
var vid = document.getElementById("myVideo");
function disableMute() { 
  vid.muted = false;
}
</script>
Amersham answered 13/8, 2019 at 21:34 Comment(0)
M
1

I had exactly the same problem, my HTML video tag played well on Chrome & Mozilla, on Safari - controls appeared but video was blank. I tried to play with all the above attributes, remove/add muted, playsInline, etc. and nothing worked. Problem was with servers as described here as well. I had this - DID NOT WORK:

<video 
  muted
  playsInline
  controls
  style={{ width: `100%` }}>
  <source src={MfMfVideo} type="video/mp4" />
  <source src={MfMfVideoWebM} type="video/webm" />
</video>

and I just moved my video out to external library and I am fine on Safari now, it WORKS well:

<video 
  muted
  playsInline
  controls 
  style={{ width: `100%` }}>
  <source src={"https://blabla.com/video/dixneuf-video_r8xuvc.mp4"} type="video/mp4" />
  <source src={"https://blabla.com/videodixneuf-video_gyquuu.webm"} type="video/webm" />
  Sorry, your browser doesn't support embedded videos.
</video>
Measure answered 21/1, 2020 at 14:38 Comment(0)
S
1

I know this is an old post, but the issue still seems to surface under different server environments. None of the above were the solution for me. In my case it came down to web optimization and making use gzip, or rather needing to disable it for videos.

I added this to my htaccess file and it took care it. SetEnvIfNoCase Request_URI .(?:ogv|ogg|oga|m4v|mp4|m4a|mov|mp3|wav|webma?|webmv)$ no-gzip dont-vary

I was already using these attributes on my tag: controls playsinline

Splayfoot answered 9/2, 2021 at 18:44 Comment(0)
S
1

Experienced it too. Video not showing on my iphone... What I did was add the muted and preload attribute to the video element.. and it worked.

 <video width="250" muted preload="metadata">
      <source  src="vid_3.mp4" type="video/mp4" />
 </video>
Schuss answered 12/8, 2021 at 2:34 Comment(0)
S
1

My problem was the video encoding. I changed it by using ffmpeg:

ffmpeg \
  -i input.mp4 \
  -vcodec libx264 \
  -acodec aac output.mp4

Related:

For static video files, use H.264-encoded MP4 files.

Apple.com: "Delivering Video Content for Safari"

Soubrette answered 22/10, 2021 at 22:39 Comment(0)
M
0

I have faced same issue. Because my video frame size was too big. ie.2248 px apple support H.264 Baseline Profile Level 3.0 video, up to 640 x 480 at 30 fps. Note that B frames are not supported in the Baseline profile. check this for more info

Moreover answered 6/7, 2015 at 13:39 Comment(0)
W
0

What helped in my case was dropping the audio track. It was silent before, but it had to be gone completely.

On ubuntu:

ffmpeg -i input.mp4 -vcodec copy -an output.mp4

And safari/desktop start to play the video

Willin answered 30/1, 2018 at 14:54 Comment(0)
M
0

For my use case there were two things:

  1. I wasn't using the new attribute / webkit's policy playsinline;
  2. My video / mime-type or whathathell wasn't properly encoded, so I used this site to convert it to all formats I needed: https://pt.converterpoint.com/

o/

Miscellany answered 2/10, 2019 at 14:38 Comment(1)
This website was the only thing that worked for me on iOS! Thanks a lot :)Torrlow
M
0

Nothing worked for me except for compressing the video to be under 30mb. That did the trick but with very bad compression.

Millan answered 6/5, 2020 at 20:30 Comment(0)
B
0

If someone having same problem i solved it by enabling Byte-Range support on my server. It appears that Safari requires Byte range requests. In my case i use NGINX and i had to add proxy_force_ranges on; to my config file. Thanks to this answer!

Bernardina answered 21/7, 2020 at 9:54 Comment(0)
R
0

On my iPhone 10, I turned off the low power mode & it autoplayed on Chrome.

Include playsinline attribute on video tag.

Rutilant answered 13/9, 2021 at 20:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.