Allow clientId to be specified in query params

This commit is contained in:
Zoe Roux 2025-10-13 19:10:23 +02:00
parent b7c6ba1e85
commit a7d5f94dfb
No known key found for this signature in database
7 changed files with 25 additions and 21 deletions

View File

@ -646,7 +646,7 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
) )
.get( .get(
":id/master.m3u8", ":id/master.m3u8",
async ({ params: { id }, status, redirect }) => { async ({ params: { id }, request, status, redirect }) => {
const [video] = await db const [video] = await db
.select({ .select({
path: videos.path, path: videos.path,
@ -663,7 +663,8 @@ export const videosH = new Elysia({ prefix: "/videos", tags: ["videos"] })
}); });
} }
const path = Buffer.from(video.path, "utf8").toString("base64url"); const path = Buffer.from(video.path, "utf8").toString("base64url");
return redirect(`/video/${path}/master.m3u8`); const query = request.url.substring(request.url.indexOf("?"))
return redirect(`/video/${path}/master.m3u8${query}`);
}, },
{ {
detail: { description: "Get redirected to the master.m3u8 of the video" }, detail: { description: "Get redirected to the master.m3u8 of the video" },

View File

@ -40,7 +40,7 @@ export const ProgressBar = ({
setProgress={setSeek} setProgress={setSeek}
endSeek={() => { endSeek={() => {
player.seekTo(seek!); player.seekTo(seek!);
setTimeout(player.play, 10); setTimeout(() => player.play(), 10);
setSeek(null); setSeek(null);
}} }}
// onHover={(progress, layout) => { // onHover={(progress, layout) => {

View File

@ -82,7 +82,7 @@ export const TouchControls = ({
// instantly hide the controls when mouse leaves the view // instantly hide the controls when mouse leaves the view
if (e.nativeEvent.pointerType === "mouse") show(false); if (e.nativeEvent.pointerType === "mouse") show(false);
}} }}
{...css({ cursor: "none" as any }, props)} {...css({ cursor: (shouldShow ? "unset" : "none") as any }, props)}
> >
{shouldShow && children} {shouldShow && children}
</DoublePressable> </DoublePressable>

View File

@ -217,9 +217,12 @@ func (h *shandler) GetAudioSegment(c echo.Context) error {
} }
func getClientId(c echo.Context) (string, error) { func getClientId(c echo.Context) (string, error) {
key := c.Request().Header.Get("X-CLIENT-ID") key := c.QueryParam("clientId")
if key == "" { if key == "" {
return "", echo.NewHTTPError(http.StatusBadRequest, "missing client id. Please specify the X-CLIENT-ID header to a guid constant for the lifetime of the player (but unique per instance)") key = c.Request().Header.Get("X-CLIENT-ID")
}
if key == "" {
return "", echo.NewHTTPError(http.StatusBadRequest, "missing client id. Please specify the X-CLIENT-ID header (or the clientId query param) to a guid constant for the lifetime of the player (but unique per instance)")
} }
return key, nil return key, nil
} }

View File

@ -68,7 +68,7 @@ func (fs *FileStream) Destroy() {
_ = os.RemoveAll(fs.Out) _ = os.RemoveAll(fs.Out)
} }
func (fs *FileStream) GetMaster() string { func (fs *FileStream) GetMaster(client string) string {
master := "#EXTM3U\n" master := "#EXTM3U\n"
// TODO: support multiples audio qualities (and original) // TODO: support multiples audio qualities (and original)
@ -89,7 +89,7 @@ func (fs *FileStream) GetMaster() string {
master += "DEFAULT=YES," master += "DEFAULT=YES,"
} }
master += "CHANNELS=\"2\"," master += "CHANNELS=\"2\","
master += fmt.Sprintf("URI=\"audio/%d/index.m3u8\"\n", audio.Index) master += fmt.Sprintf("URI=\"audio/%d/index.m3u8?clientId=%s\"\n", audio.Index, client)
} }
master += "\n" master += "\n"
@ -139,7 +139,7 @@ func (fs *FileStream) GetMaster() string {
if video == *def_video { if video == *def_video {
master += "DEFAULT=YES\n" master += "DEFAULT=YES\n"
} else { } else {
master += fmt.Sprintf("URI=\"%d/%s/index.m3u8\"\n", video.Index, quality) master += fmt.Sprintf("URI=\"%d/%s/index.m3u8?clientId=%s\"\n", video.Index, quality, client)
} }
} }
} }
@ -161,7 +161,7 @@ func (fs *FileStream) GetMaster() string {
} }
master += "AUDIO=\"audio\"," master += "AUDIO=\"audio\","
master += "CLOSED-CAPTIONS=NONE\n" master += "CLOSED-CAPTIONS=NONE\n"
master += fmt.Sprintf("%d/%s/index.m3u8\n", def_video.Index, quality) master += fmt.Sprintf("%d/%s/index.m3u8?clientId=%s\n", def_video.Index, quality, client)
continue continue
} }
@ -172,7 +172,7 @@ func (fs *FileStream) GetMaster() string {
master += fmt.Sprintf("CODECS=\"%s\",", strings.Join([]string{transcode_codec, audio_codec}, ",")) master += fmt.Sprintf("CODECS=\"%s\",", strings.Join([]string{transcode_codec, audio_codec}, ","))
master += "AUDIO=\"audio\"," master += "AUDIO=\"audio\","
master += "CLOSED-CAPTIONS=NONE\n" master += "CLOSED-CAPTIONS=NONE\n"
master += fmt.Sprintf("%d/%s/index.m3u8\n", def_video.Index, quality) master += fmt.Sprintf("%d/%s/index.m3u8?clientId=%s\n", def_video.Index, quality, client)
} }
} }
@ -188,12 +188,12 @@ func (fs *FileStream) getVideoStream(idx uint32, quality Quality) (*VideoStream,
return stream, nil return stream, nil
} }
func (fs *FileStream) GetVideoIndex(idx uint32, quality Quality) (string, error) { func (fs *FileStream) GetVideoIndex(idx uint32, quality Quality, client string) (string, error) {
stream, err := fs.getVideoStream(idx, quality) stream, err := fs.getVideoStream(idx, quality)
if err != nil { if err != nil {
return "", err return "", err
} }
return stream.GetIndex() return stream.GetIndex(client)
} }
func (fs *FileStream) GetVideoSegment(idx uint32, quality Quality, segment int32) (string, error) { func (fs *FileStream) GetVideoSegment(idx uint32, quality Quality, segment int32) (string, error) {
@ -213,12 +213,12 @@ func (fs *FileStream) getAudioStream(audio uint32) (*AudioStream, error) {
return stream, nil return stream, nil
} }
func (fs *FileStream) GetAudioIndex(audio uint32) (string, error) { func (fs *FileStream) GetAudioIndex(audio uint32, client string) (string, error) {
stream, err := fs.getAudioStream(audio) stream, err := fs.getAudioStream(audio)
if err != nil { if err != nil {
return "", nil return "", nil
} }
return stream.GetIndex() return stream.GetIndex(client)
} }
func (fs *FileStream) GetAudioSegment(audio uint32, segment int32) (string, error) { func (fs *FileStream) GetAudioSegment(audio uint32, segment int32) (string, error) {

View File

@ -361,7 +361,7 @@ func (ts *Stream) run(start int32) error {
return nil return nil
} }
func (ts *Stream) GetIndex() (string, error) { func (ts *Stream) GetIndex(client string) (string, error) {
// playlist type is event since we can append to the list if Keyframe.IsDone is false. // playlist type is event since we can append to the list if Keyframe.IsDone is false.
// start time offset makes the stream start at 0s instead of ~3segments from the end (requires version 6 of hls) // start time offset makes the stream start at 0s instead of ~3segments from the end (requires version 6 of hls)
index := `#EXTM3U index := `#EXTM3U
@ -376,13 +376,13 @@ func (ts *Stream) GetIndex() (string, error) {
for segment := int32(0); segment < length-1; segment++ { for segment := int32(0); segment < length-1; segment++ {
index += fmt.Sprintf("#EXTINF:%.6f\n", ts.keyframes.Get(segment+1)-ts.keyframes.Get(segment)) index += fmt.Sprintf("#EXTINF:%.6f\n", ts.keyframes.Get(segment+1)-ts.keyframes.Get(segment))
index += fmt.Sprintf("segment-%d.ts\n", segment) index += fmt.Sprintf("segment-%d.ts?clientId=%s\n", segment, client)
} }
// do not forget to add the last segment between the last keyframe and the end of the file // do not forget to add the last segment between the last keyframe and the end of the file
// if the keyframes extraction is not done, do not bother to add it, it will be retrived on the next index retrival // if the keyframes extraction is not done, do not bother to add it, it will be retrived on the next index retrival
if is_done { if is_done {
index += fmt.Sprintf("#EXTINF:%.6f\n", float64(ts.file.Info.Duration)-ts.keyframes.Get(length-1)) index += fmt.Sprintf("#EXTINF:%.6f\n", float64(ts.file.Info.Duration)-ts.keyframes.Get(length-1))
index += fmt.Sprintf("segment-%d.ts\n", length-1) index += fmt.Sprintf("segment-%d.ts?clientId=%s\n", length-1, client)
index += `#EXT-X-ENDLIST` index += `#EXT-X-ENDLIST`
} }
return index, nil return index, nil

View File

@ -63,7 +63,7 @@ func (t *Transcoder) GetMaster(ctx context.Context, path string, client string,
vhead: -1, vhead: -1,
ahead: -1, ahead: -1,
} }
return stream.GetMaster(), nil return stream.GetMaster(client), nil
} }
func (t *Transcoder) GetVideoIndex( func (t *Transcoder) GetVideoIndex(
@ -87,7 +87,7 @@ func (t *Transcoder) GetVideoIndex(
vhead: -1, vhead: -1,
ahead: -1, ahead: -1,
} }
return stream.GetVideoIndex(video, quality) return stream.GetVideoIndex(video, quality, client)
} }
func (t *Transcoder) GetAudioIndex( func (t *Transcoder) GetAudioIndex(
@ -109,7 +109,7 @@ func (t *Transcoder) GetAudioIndex(
vhead: -1, vhead: -1,
ahead: -1, ahead: -1,
} }
return stream.GetAudioIndex(audio) return stream.GetAudioIndex(audio, client)
} }
func (t *Transcoder) GetVideoSegment( func (t *Transcoder) GetVideoSegment(