Implented FLAC streaming under Safari
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
DataHoarder 2022-04-20 19:08:45 +02:00
parent 2650039581
commit 2803192316
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
2 changed files with 31 additions and 0 deletions

View file

@ -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

View file

@ -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