简体   繁体   中英

Safari 9.0 can not play mp4 video on the storage server

The following video link cannot be played with safari 9.0 (latest version). But older versions of safari, chrome and firefox can play.

http://assets00.grou.ps/0F2E3C/wysiwyg_files/Videos/saksuka/20150928104628-lhmkkfbhnkiisbhht.mp4

I can play with safari 9.0 when i download the video from the server to my computer.

That's why I don't think this problem stems video encoding.

I have done these settings;

mime.types
video/mp4   mp4 m4v
video/ogg   ogv
video/webm  webm

httpd.conf
AddType video/mp4 mp4 m4v
AddType video/ogg ogv
AddType video/webm webm

.htaccess
AddType video/mp4 mp4 m4v
AddType video/ogg ogv
AddType video/webm webm

Update 2 - June 2020

The most common root cause of this issue appears to be servers that are not configured to handle range requests properly.

Safari expects to see a '206' response when it sends a request with a byte range. If the server responds with a '200' request it appears Safari cannot handle this. Some other browsers seem to be ok with this - for example Chrome.

The inspection network tab screenshot below shows a successful video playback with range requests and a 206 'Partial Content' response:

在此处输入图片说明

While this example below shows a video which fails to play in Safari but does play in Chrome - and it can be seen that the server is simply responding with a 200 request:

在此处输入图片说明

You can test if the server is properly accepting range requests using a CURL command - see info from apple here:

If you are not sure whether your media server supports byte-range requests, you can open the Terminal application in OS X and use the curl command-line tool to download a short segment from a file on the server:

curl --range 0-99 http://example.com/test.mov -o /dev/null

If the tool reports that it downloaded 100 bytes, the media server correctly handled the byte-range request. If it downloads the entire file, you may need to update the media server. For more information on curl, see OS X Man Pages.

(from: https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP40006514-SW6 )

Using the CURL command in the above reference for the first video which plays correctly, we can see the response is that just the range requested is returned as expected:

在此处输入图片说明

Using the same CURL command with the example above which does not play in Safari (but does in Chrome) shows that the server is responding with the full file, instead of just with the range requested:

在此处输入图片说明

This CURL test is probably the quickest way to check whether your server is correctly try handling the request.

Original Answer

This seems to be recurring problem with some mp4 files on Safari.

I tested your video on a localhost node.js static server and it played fine in Safari, which means the video itself should be fine.

If you look at the web inspector in Safari you will see that the web request is not including some headers. This causes some servers problems and they do not respond the way Safari is expecting, or do not respond at all.

You can see similar problems being discussed (the second one is not your case I think but illustrates that the info included in the request sent to the server can cause the server to 'decide' not to respond as you want):

Update 1 :

Using wireshark to capture the request from Chrome, it can be seen to result in a response from the server with the video to be played while the request from Safari (on the same machine) results in no response from the server.

The requests are generally similar and both do include the referrer header. The Safari browser is only asking for the first 2 bytes to be returned from the server initially - it does this by using the 'range' header, which is used to specify the bytes range that a file returns:

  • Range: bytes=0-1\\r\\n

Chrome on the other hand requests the entire video in its range request:

  • Range: bytes=0-\\r\\n

However, using a HTTP tool (eg Postman) on Chrome and changing the range to 0-1 does not seem to stop the server responding in the Chrome case. In fact using the tool to set, as far as possible, all the same headers as Safari sets seems still seems to return the video ok.

The issue is that safari or iOs expects chunks. Meaning from a streaming server. If your video is from a blob or file server then safari will throw an error. You can relate it to this post Failed to Load Resource, Plugin Handled Load on iOS

To shed some more light on mp4s not playing in the video tag, I'd like to share my experience here. I spent a good while troubleshooting an issue recently that was preventing mp4s from playing in Safari.

As mentioned in one of the previous answers, Safari first sends a byte range request for a Video tag that expects a 206 response. However, if you use a Service worker, the response returns with a 200 and it appears Safari doesn't know how to handle this. Our solution was to exclude using a Service Worker for Safari.

We found this by using the network tab of the Safari debugger on a MacBook to troubleshoot the issue we were seeing on the iPad. Attached is a screenshot for comparison/reference. The left tab shows what the call should look like by default. The right tab shows what you would see if using a Service Worker.

Safari 网络标签服务工作者

In my case Safari 15+ the browser would return the same 206 error but would play the video regardless

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM