From f4d2c801f094d98189b694f20738e3a99f302b57 Mon Sep 17 00:00:00 2001 From: Alexey Khit Date: Mon, 30 Jan 2023 22:00:07 +0300 Subject: [PATCH] Add redirect for Safari from MP4 to HLS --- cmd/mp4/mp4.go | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/cmd/mp4/mp4.go b/cmd/mp4/mp4.go index de9006d8..d98cae80 100644 --- a/cmd/mp4/mp4.go +++ b/cmd/mp4/mp4.go @@ -26,8 +26,14 @@ func Init() { var log zerolog.Logger func handlerKeyframe(w http.ResponseWriter, r *http.Request) { - if isChromeFirst(w, r) { - return + // Chrome 105 does two requests: without Range and with `Range: bytes=0-` + ua := r.UserAgent() + if strings.Contains(ua, " Chrome/") { + if r.Header.Values("Range") == nil { + w.Header().Set("Content-Type", "video/mp4") + w.WriteHeader(http.StatusOK) + return + } } src := r.URL.Query().Get("src") @@ -68,7 +74,22 @@ func handlerKeyframe(w http.ResponseWriter, r *http.Request) { func handlerMP4(w http.ResponseWriter, r *http.Request) { log.Trace().Msgf("[mp4] %s %+v", r.Method, r.Header) - if isChromeFirst(w, r) || isSafari(w, r) { + // Chrome has Safari in UA, so check first Chrome and later Safari + ua := r.UserAgent() + if strings.Contains(ua, " Chrome/") { + if r.Header.Values("Range") == nil { + w.Header().Set("Content-Type", "video/mp4") + w.WriteHeader(http.StatusOK) + return + } + } else if strings.Contains(ua, " Safari/") { + // auto redirect to HLS/fMP4 format, because Safari not support MP4 stream + url := "stream.m3u8?" + r.URL.RawQuery + if !r.URL.Query().Has("mp4") { + url += "&mp4" + } + + http.Redirect(w, r, url, http.StatusMovedPermanently) return } @@ -138,23 +159,3 @@ func handlerMP4(w http.ResponseWriter, r *http.Request) { duration.Stop() } } - -func isChromeFirst(w http.ResponseWriter, r *http.Request) bool { - // Chrome 105 does two requests: without Range and with `Range: bytes=0-` - if strings.Contains(r.UserAgent(), " Chrome/") { - if r.Header.Values("Range") == nil { - w.Header().Set("Content-Type", "video/mp4") - w.WriteHeader(http.StatusOK) - return true - } - } - return false -} - -func isSafari(w http.ResponseWriter, r *http.Request) bool { - if r.Header.Get("Range") == "bytes=0-1" { - handlerKeyframe(w, r) - return true - } - return false -}