mirror of
https://github.com/navidrome/navidrome.git
synced 2026-05-03 06:51:16 +00:00
feat(subsonic): handle ErrTranscodingBusy in Stream and Download endpoints
This commit is contained in:
parent
4d14ad812c
commit
87e02a3c2d
@ -1,12 +1,14 @@
|
|||||||
package subsonic
|
package subsonic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/navidrome/navidrome/conf"
|
"github.com/navidrome/navidrome/conf"
|
||||||
|
"github.com/navidrome/navidrome/core/stream"
|
||||||
"github.com/navidrome/navidrome/log"
|
"github.com/navidrome/navidrome/log"
|
||||||
"github.com/navidrome/navidrome/model"
|
"github.com/navidrome/navidrome/model"
|
||||||
"github.com/navidrome/navidrome/model/request"
|
"github.com/navidrome/navidrome/model/request"
|
||||||
@ -31,22 +33,25 @@ func (api *Router) Stream(w http.ResponseWriter, r *http.Request) (*responses.Su
|
|||||||
}
|
}
|
||||||
|
|
||||||
streamReq := api.transcodeDecision.ResolveRequest(ctx, mf, format, maxBitRate, timeOffset)
|
streamReq := api.transcodeDecision.ResolveRequest(ctx, mf, format, maxBitRate, timeOffset)
|
||||||
stream, err := api.streamer.NewStream(ctx, mf, streamReq)
|
s, err := api.streamer.NewStream(ctx, mf, streamReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, stream.ErrTranscodingBusy) {
|
||||||
|
return nil, newError(responses.ErrorGeneric, "too many concurrent transcodes, try again later")
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the stream will be closed at the end, to avoid leakage
|
// Make sure the stream will be closed at the end, to avoid leakage
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := stream.Close(); err != nil && log.IsGreaterOrEqualTo(log.LevelDebug) {
|
if err := s.Close(); err != nil && log.IsGreaterOrEqualTo(log.LevelDebug) {
|
||||||
log.Error("Error closing stream", "id", id, "file", stream.Name(), err)
|
log.Error("Error closing stream", "id", id, "file", s.Name(), err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
w.Header().Set("X-Content-Type-Options", "nosniff")
|
w.Header().Set("X-Content-Type-Options", "nosniff")
|
||||||
w.Header().Set("X-Content-Duration", strconv.FormatFloat(float64(stream.Duration()), 'G', -1, 32))
|
w.Header().Set("X-Content-Duration", strconv.FormatFloat(float64(s.Duration()), 'G', -1, 32))
|
||||||
|
|
||||||
_, err = stream.Serve(ctx, w, r)
|
_, err = s.Serve(ctx, w, r)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,22 +105,25 @@ func (api *Router) Download(w http.ResponseWriter, r *http.Request) (*responses.
|
|||||||
switch v := entity.(type) {
|
switch v := entity.(type) {
|
||||||
case *model.MediaFile:
|
case *model.MediaFile:
|
||||||
streamReq := api.transcodeDecision.ResolveRequest(ctx, v, format, maxBitRate, 0)
|
streamReq := api.transcodeDecision.ResolveRequest(ctx, v, format, maxBitRate, 0)
|
||||||
stream, err := api.streamer.NewStream(ctx, v, streamReq)
|
s, err := api.streamer.NewStream(ctx, v, streamReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, stream.ErrTranscodingBusy) {
|
||||||
|
return nil, newError(responses.ErrorGeneric, "too many concurrent transcodes, try again later")
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the stream will be closed at the end, to avoid leakage
|
// Make sure the stream will be closed at the end, to avoid leakage
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := stream.Close(); err != nil && log.IsGreaterOrEqualTo(log.LevelDebug) {
|
if err := s.Close(); err != nil && log.IsGreaterOrEqualTo(log.LevelDebug) {
|
||||||
log.Error("Error closing stream", "id", id, "file", stream.Name(), err)
|
log.Error("Error closing stream", "id", id, "file", s.Name(), err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
disposition := fmt.Sprintf("attachment; filename=\"%s\"", stream.Name())
|
disposition := fmt.Sprintf("attachment; filename=\"%s\"", s.Name())
|
||||||
w.Header().Set("Content-Disposition", disposition)
|
w.Header().Set("Content-Disposition", disposition)
|
||||||
|
|
||||||
_, err = stream.Serve(ctx, w, r)
|
_, err = s.Serve(ctx, w, r)
|
||||||
return nil, err
|
return nil, err
|
||||||
case *model.Album:
|
case *model.Album:
|
||||||
setHeaders(v.Name)
|
setHeaders(v.Name)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user