Implented FLAC streaming under Safari
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
2650039581
commit
2803192316
|
@ -17,6 +17,7 @@ Radio streamer ([kawa](https://github.com/Luminarys/kawa) drop-in compatible).
|
|||
* Can read and apply ReplayGain tags, or normalize audio loudness.
|
||||
* Can have audio sources over HTTP(s) URLs on `path` property, and supports seeking.
|
||||
* Precise metadata and timing information packet stream, trigger via `x-audio-packet-stream: 1` HTTP header.
|
||||
* Workaround to allow FLAC streaming under Safari
|
||||
|
||||
## Dependencies
|
||||
### Go >= 1.18
|
||||
|
|
30
queue.go
30
queue.go
|
@ -450,6 +450,36 @@ func (q *Queue) HandleRadioRequest(writer http.ResponseWriter, request *http.Req
|
|||
rangeHeader := request.Header.Get("range")
|
||||
if rangeHeader != "" && rangeHeader != "bytes=0-" {
|
||||
//TODO: maybe should fail in case bytes are requested
|
||||
|
||||
if strings.Index(request.UserAgent(), " Safari/") != -1 && mount.MimeType == "audio/flac" {
|
||||
//Safari special case, fake Range check so it decodes afterwards.
|
||||
//Safari creates a request with Range for 0-1, specifically for FLAC, and expects a result supporting range. Afterwards it requests the whole file.
|
||||
//However the decoder is able to decode FLAC livestreams. If we fake the initial range response, then afterwards serve normal responses, Safari will happily work.
|
||||
//TODO: remove this AS SOON as safari works on its own
|
||||
//safariLargeFileValue arbitrary large value, cannot be that large or iOS Safari fails.
|
||||
safariLargeFileValue := 1024 * 1024 * 1024 * 1024 * 16 // 16 TiB
|
||||
|
||||
if rangeHeader == "bytes=0-1" {
|
||||
//first request
|
||||
writer.Header().Set("Accept-Ranges", "bytes")
|
||||
writer.Header().Set("Content-Range", fmt.Sprintf("bytes 0-1/%d", safariLargeFileValue)) //64 TiB max fake size
|
||||
writer.Header().Set("Content-Length", "2")
|
||||
writer.WriteHeader(http.StatusPartialContent)
|
||||
writer.Write([]byte{'\x00', '\x00'})
|
||||
return
|
||||
} else if rangeHeader == fmt.Sprintf("bytes=0-%d", safariLargeFileValue-1) {
|
||||
//second request, serve status 200 to keep retries to a minimum
|
||||
writer.Header().Set("Content-Length", fmt.Sprintf("%d", safariLargeFileValue))
|
||||
writer.WriteHeader(http.StatusOK)
|
||||
} else if strings.HasPrefix(rangeHeader, "bytes=") && strings.HasSuffix(rangeHeader, fmt.Sprintf("-%d", safariLargeFileValue-1)) {
|
||||
//any other requests, these should fail
|
||||
writer.Header().Set("Content-Range", fmt.Sprintf("bytes %s/%d", strings.TrimPrefix(rangeHeader, "bytes="), safariLargeFileValue))
|
||||
writer.Header().Set("Accept-Ranges", "bytes")
|
||||
writer.WriteHeader(http.StatusRequestedRangeNotSatisfiable)
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bitrate := 0
|
||||
|
|
Loading…
Reference in a new issue