Copy apikey query parameter to DASH & HLS manifest (#5061)

* Copy apikey query parameter to DASH & HLS manifest

When an API key is provided to the DASH and HLS manifest endpoints, this
it will now be copied to the URLs inside the manifest. This allows for
clients that are only able to pass an URL to an (external) video player
to function in case authentication is set up on stash.
This commit is contained in:
Lenny3D
2024-07-16 05:17:18 +02:00
committed by GitHub
parent bfd8e81ffd
commit f79677ba96

View File

@@ -8,6 +8,7 @@ import (
"io" "io"
"math" "math"
"net/http" "net/http"
"net/url"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@@ -45,6 +46,10 @@ const (
// maximum idle time between segment requests before // maximum idle time between segment requests before
// stopping transcode and deleting cache folder // stopping transcode and deleting cache folder
maxIdleTime = 30 * time.Second maxIdleTime = 30 * time.Second
resolutionParamKey = "resolution"
// TODO - setting the apikey in here isn't ideal
apiKeyParamKey = "apikey"
) )
type StreamType struct { type StreamType struct {
@@ -425,9 +430,21 @@ func serveHLSManifest(sm *StreamManager, w http.ResponseWriter, r *http.Request,
baseUrl.RawQuery = "" baseUrl.RawQuery = ""
baseURL := baseUrl.String() baseURL := baseUrl.String()
var urlQuery string urlQuery := url.Values{}
apikey := r.URL.Query().Get(apiKeyParamKey)
if resolution != "" { if resolution != "" {
urlQuery = fmt.Sprintf("?resolution=%s", resolution) urlQuery.Set(resolutionParamKey, resolution)
}
// TODO - this needs to be handled outside of this package
if apikey != "" {
urlQuery.Set(apiKeyParamKey, apikey)
}
urlQueryString := ""
if len(urlQuery) > 0 {
urlQueryString = "?" + urlQuery.Encode()
} }
var buf bytes.Buffer var buf bytes.Buffer
@@ -449,7 +466,7 @@ func serveHLSManifest(sm *StreamManager, w http.ResponseWriter, r *http.Request,
} }
fmt.Fprintf(&buf, "#EXTINF:%f,\n", thisLength) fmt.Fprintf(&buf, "#EXTINF:%f,\n", thisLength)
fmt.Fprintf(&buf, "%s/%d.ts%s\n", baseURL, segment, urlQuery) fmt.Fprintf(&buf, "%s/%d.ts%s\n", baseURL, segment, urlQueryString)
leftover -= thisLength leftover -= thisLength
segment++ segment++
@@ -508,11 +525,18 @@ func serveDASHManifest(sm *StreamManager, w http.ResponseWriter, r *http.Request
videoWidth = vf.Width videoWidth = vf.Width
} }
var urlQuery string urlQuery := url.Values{}
// TODO - this needs to be handled outside of this package
apikey := r.URL.Query().Get(apiKeyParamKey)
if apikey != "" {
urlQuery.Set(apiKeyParamKey, apikey)
}
maxTranscodeSize := sm.config.GetMaxStreamingTranscodeSize().GetMaxResolution() maxTranscodeSize := sm.config.GetMaxStreamingTranscodeSize().GetMaxResolution()
if resolution != "" { if resolution != "" {
maxTranscodeSize = models.StreamingResolutionEnum(resolution).GetMaxResolution() maxTranscodeSize = models.StreamingResolutionEnum(resolution).GetMaxResolution()
urlQuery = fmt.Sprintf("?resolution=%s", resolution) urlQuery.Set(resolutionParamKey, resolution)
} }
if maxTranscodeSize != 0 { if maxTranscodeSize != 0 {
videoSize := videoHeight videoSize := videoHeight
@@ -527,6 +551,11 @@ func serveDASHManifest(sm *StreamManager, w http.ResponseWriter, r *http.Request
} }
} }
urlQueryString := ""
if len(urlQuery) > 0 {
urlQueryString = "?" + urlQuery.Encode()
}
mediaDuration := mpd.Duration(time.Duration(probeResult.FileDuration * float64(time.Second))) mediaDuration := mpd.Duration(time.Duration(probeResult.FileDuration * float64(time.Second)))
m := mpd.NewMPD(mpd.DASH_PROFILE_LIVE, mediaDuration.String(), "PT4.0S") m := mpd.NewMPD(mpd.DASH_PROFILE_LIVE, mediaDuration.String(), "PT4.0S")
@@ -536,12 +565,12 @@ func serveDASHManifest(sm *StreamManager, w http.ResponseWriter, r *http.Request
video, _ := m.AddNewAdaptationSetVideo(MimeWebmVideo, "progressive", true, 1) video, _ := m.AddNewAdaptationSetVideo(MimeWebmVideo, "progressive", true, 1)
_, _ = video.SetNewSegmentTemplate(2, "init_v.webm"+urlQuery, "$Number$_v.webm"+urlQuery, 0, 1) _, _ = video.SetNewSegmentTemplate(2, "init_v.webm"+urlQueryString, "$Number$_v.webm"+urlQueryString, 0, 1)
_, _ = video.AddNewRepresentationVideo(200000, "vp09.00.40.08", "0", framerate, int64(videoWidth), int64(videoHeight)) _, _ = video.AddNewRepresentationVideo(200000, "vp09.00.40.08", "0", framerate, int64(videoWidth), int64(videoHeight))
if ProbeAudioCodec(vf.AudioCodec) != MissingUnsupported { if ProbeAudioCodec(vf.AudioCodec) != MissingUnsupported {
audio, _ := m.AddNewAdaptationSetAudio(MimeWebmAudio, true, 1, "und") audio, _ := m.AddNewAdaptationSetAudio(MimeWebmAudio, true, 1, "und")
_, _ = audio.SetNewSegmentTemplate(2, "init_a.webm"+urlQuery, "$Number$_a.webm"+urlQuery, 0, 1) _, _ = audio.SetNewSegmentTemplate(2, "init_a.webm"+urlQueryString, "$Number$_a.webm"+urlQueryString, 0, 1)
_, _ = audio.AddNewRepresentationAudio(48000, 96000, "opus", "1") _, _ = audio.AddNewRepresentationAudio(48000, 96000, "opus", "1")
} }