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 read and apply ReplayGain tags, or normalize audio loudness.
|
||||||
* Can have audio sources over HTTP(s) URLs on `path` property, and supports seeking.
|
* 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.
|
* Precise metadata and timing information packet stream, trigger via `x-audio-packet-stream: 1` HTTP header.
|
||||||
|
* Workaround to allow FLAC streaming under Safari
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
### Go >= 1.18
|
### 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")
|
rangeHeader := request.Header.Get("range")
|
||||||
if rangeHeader != "" && rangeHeader != "bytes=0-" {
|
if rangeHeader != "" && rangeHeader != "bytes=0-" {
|
||||||
//TODO: maybe should fail in case bytes are requested
|
//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
|
bitrate := 0
|
||||||
|
|
Loading…
Reference in a new issue