BYU-ODH / y-video-back-end

GNU General Public License v3.0
3 stars 2 forks source link

Safari desktop and all browsers on iOS will not play resource videos #120

Open reynoldsnlp opened 2 years ago

reynoldsnlp commented 2 years ago

Also see this companion issue on the front end.

The issue appears to be a problem with any browser using the WebKit engine (Safari on all devices, and all browsers on iOS). Allowing students to watch on their iOS devices would be very helpful. There are very many descriptions of the Safari video problem online:

https://blog.logrocket.com/streaming-video-in-safari/ https://stackoverflow.com/questions/27712778/video-plays-in-other-browsers-but-not-safari

These browsers require Partial-Content (status code 206), rather than simple file transfer. We have implemented Partial Content, and it works great on Chrome, so it is puzzling why this is not working in Safari.

One major obstacle for local development for Safari is that it requires an SSL connection over https. We have not been able to get the configurations right for this to work, so development has consisted of making changes, merging them into develop to deploy to the dev server (!!!), and then accessing yvideodev.byu.edu using Safari. Very slow and muddies the git flow. The mechanics of developing for Safari have really gotten in the way.

FWIW, it is possible to put a macOS VM on Linux: https://github.com/myspaghetti/macos-virtualbox.

reynoldsnlp commented 2 years ago

Apple's website mentions that video should be "H.264-encoded MP4 files". We should ensure that this is the case for all our videos.

reynoldsnlp commented 2 years ago

A relevant issue for react-player was recently closed: https://github.com/cookpete/react-player/issues/1305

reynoldsnlp commented 2 years ago

One thing listed in the Safari Web Content Guide is that MIME types should be in the header.

The solution may be as simple as making sure that the server declares the MIME content type video/mp4 (or otherwise for audio, etc.) in the header for the partial-media/stream-media endpoint.

reynoldsnlp commented 2 years ago

It looks like this is trivial with ring: https://ring-clojure.github.io/ring/ring.middleware.content-type.html

Probably just need to wrap the handler part of stream-partial-media in src/clj/y-video-back/routes/service-handlers/handlers/media-handlers.clj with ring.middleware.wrap-content-type.

reynoldsnlp commented 2 years ago

In case @WorldsEndless doesn't have time for this anytime soon: https://stackoverflow.com/q/73807005/2903532

WorldsEndless commented 2 years ago

Very helpful. Thanks for posting that question!

WorldsEndless commented 1 year ago

Given a running local server, what is a URL at which I can see the absence of those headers?

WorldsEndless commented 12 months ago

visiting this again. What is a way that I can test this -- is there a dummy video already in the codebase?

reynoldsnlp commented 12 months ago

I don't think there is, but it would be great to have that. Maybe you can find something short in the public domain that we could put in the repo?

R


From: Tory S. Anderson @.> Sent: Wednesday, October 11, 2023 11:41 AM To: BYU-ODH/y-video-back-end @.> Cc: Rob Reynolds @.>; State change @.> Subject: Re: [BYU-ODH/y-video-back-end] Safari desktop and all browsers on iOS will not play videos (Issue #120)

visiting this again. What is a way that I can test this -- is there a dummy video already in the codebase?

— Reply to this email directly, view it on GitHubhttps://github.com/BYU-ODH/y-video-back-end/issues/120#issuecomment-1758174773, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ADGCNF75ZN2LZXZVRFRBY3LX63K3ZANCNFSM6AAAAAAQOSESDQ. You are receiving this because you modified the open/close state.Message ID: @.***>

WorldsEndless commented 12 months ago

I see there is a "small video" in the repo. I guess that is too small to try with streaming?

I guess there will need to be a solution developed, since storing large files in git is not desirable.

WorldsEndless commented 11 months ago

There already exists a test which claims to be about streaming. This test can be used to check if we get the right headers in here. https://github.com/BYU-ODH/y-video-back-end/blob/e2648852d983728d41a5140fb9b3422037aa447d/test/clj/usecase/legacy/routes/media.clj#L45

reynoldsnlp commented 11 months ago

@WorldsEndless that looks perfect. I'm glad you found that.

reynoldsnlp commented 11 months ago

@WorldsEndless I just learned that Safari now allows local overrides to HTTP headers, and when I tried overriding Content-Type with video/mp4, it still didn't work in Safari.

Please still add the MIME type to our response headers, but I won't be surprised if that doesn't fix the problem.

reynoldsnlp commented 11 months ago

Also, when re-reading the discussion in this issue, I remembered that Safari is finicky about SSL, so regardless of your local setup, it will probably be necessary to push to the development server to check if it works on Safari (unless I can figure out an easy way to do SSL with a docker-compose setup).

reynoldsnlp commented 6 months ago

@WorldsEndless As expected, #165 did not fix it. However, I think I might have found another possible solution here: https://github.com/cookpete/react-player/issues/1305#issuecomment-1606094291. Looks like Chrome and Safari behave differently with Partial Content requests.

WorldsEndless commented 6 months ago

Safari is not even available on Windows; the last windows version that came out was Safari 5, which one source rightly calls "paleologic, by tech standards."

Safari and much of Mac apparently use webkit https://github.com/WebKit/WebKit On Linux, so I have acquired the latest Epiphany as a webkit browser.

I am referring also to #121 in the hopes of getting access to an actual video in my browser. I have been working blind thusfar,only able to investigate output headers in our server and unable to simulate even working users, to see even if my work applies.

reynoldsnlp commented 6 months ago

The following files are the headers for Chrome and Safari requests to stream. Safari has 3 requests for some reason.

safari_response3_headers.txt safari_response2_headers.txt safari_response1_headers.txt safari_request3_headers.txt safari_request2_headers.txt safari_request1_headers.txt chrome_response_headers.txt chrome_request_headers.txt

WorldsEndless commented 6 months ago

I just heard that browsers on MacOS use whatever engine the browser uses, so Chrome or Firefox are using their respective Blink or Gecko, but on iOS they all use the same proprietary thing. Do you know whether the unexplained inability to play videos is affecting only one or the other mac device, or are they both suffering? @reynoldsnlp

reynoldsnlp commented 6 months ago

@WorldsEndless The issue title and description both include iOS, too. I assume that fixing one will fix the other, but we'll see.

WorldsEndless commented 6 months ago

okay. It appears that you can use other browsers (eg Chrome or Firefox) on desktop, and they will use their own (Blink or Gecko) engines. However, my understanding is that is impossible on iOS, where Safari is singularly mandated. So I am curious if "use a different browser" actually works for desktop users. Also, do you have any feel for how many users are using iOS vs MacOS?

Related: to read: https://developer.apple.com/documentation/webkit/delivering_video_content_for_safari/

reynoldsnlp commented 6 months ago

@WorldsEndless Different browser does work for MacOS, but lots of users are on iOS.

That's the link I pasted above.

I just found a blog post that has another suggestion that we haven't tried: make sure the endpoint has the relevant file extension (e.g. .mp4).

Also, I'm still not getting Content-Type headers on yvideodev.byu.edu after your patch. It occurs to me that if we add the file extension to the URL, the ring middleware content-type wrapper will probably work now, since it is based on the extension in the URL.

reynoldsnlp commented 6 months ago

Also just found this, which could be inspiration: https://github.com/bootstrapping-microservices/video-streaming-example