Skip to content

Commit 0436891

Browse files
committed
Preserve media source in transcode URLs
1 parent e9abf56 commit 0436891

2 files changed

Lines changed: 50 additions & 7 deletions

File tree

internal/emby/playback.go

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package emby
33
import (
44
"encoding/json"
55
"fmt"
6+
"net/url"
67
"regexp"
8+
"strconv"
79
"strings"
810
)
911

@@ -70,16 +72,15 @@ func RewritePlaybackInfoWithReport(body []byte, itemID string, publicURL string,
7072
}
7173
sourceID, _ := source["Id"].(string)
7274
sessionID := SessionID(itemID, sourceID, index)
73-
transcodeURL := fmt.Sprintf("/streambridge/transcode/%s/master.m3u8", sessionID)
74-
if len(rawQuery) > 0 && rawQuery[0] != "" {
75-
transcodeURL += "?" + rawQuery[0]
76-
}
77-
7875
beforeDirectPlay, _ := source["SupportsDirectPlay"].(bool)
7976
beforeTranscode, _ := source["SupportsTranscoding"].(bool)
8077
beforeDirectStreamURL, _ := source["DirectStreamUrl"].(string)
8178
beforeTranscodingURL, _ := source["TranscodingUrl"].(string)
8279
sourceReport := sourceReportFromMap(source)
80+
transcodeURL := fmt.Sprintf("/streambridge/transcode/%s/master.m3u8", sessionID)
81+
if enrichedQuery := transcodeQueryForSource(firstRawQuery(rawQuery), sourceID, sourceReport.AudioStreams); enrichedQuery != "" {
82+
transcodeURL += "?" + enrichedQuery
83+
}
8384
sourceReport.Index = index
8485
sourceReport.ID = sourceID
8586
sourceReport.SessionID = sessionID
@@ -132,6 +133,27 @@ func RewritePlaybackInfoWithReport(body []byte, itemID string, publicURL string,
132133
return out, true, report, nil
133134
}
134135

136+
func firstRawQuery(rawQuery []string) string {
137+
if len(rawQuery) == 0 {
138+
return ""
139+
}
140+
return rawQuery[0]
141+
}
142+
143+
func transcodeQueryForSource(rawQuery string, sourceID string, audioStreams []AudioStreamReport) string {
144+
query, err := url.ParseQuery(rawQuery)
145+
if err != nil {
146+
return rawQuery
147+
}
148+
if sourceID != "" && query.Get("MediaSourceId") == "" {
149+
query.Set("MediaSourceId", sourceID)
150+
}
151+
if query.Get("AudioStreamIndex") == "" && len(audioStreams) > 0 {
152+
query.Set("AudioStreamIndex", strconv.Itoa(audioStreams[0].Index))
153+
}
154+
return query.Encode()
155+
}
156+
135157
func sourceReportFromMap(source map[string]any) SourceReport {
136158
report := SourceReport{
137159
Name: stringValue(source, "Name"),

internal/emby/playback_test.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,30 @@ func TestRewritePlaybackInfoPreservesQueryString(t *testing.T) {
5757
if !changed {
5858
t.Fatal("expected rewrite to change response")
5959
}
60-
if !bytes.Contains(out, []byte(`master.m3u8?X-Emby-Token=abc`)) {
60+
if !bytes.Contains(out, []byte(`X-Emby-Token=abc`)) {
6161
t.Fatalf("missing query string: %s", out)
6262
}
63+
if !bytes.Contains(out, []byte(`MediaSourceId=source1`)) {
64+
t.Fatalf("missing media source id: %s", out)
65+
}
66+
}
67+
68+
func TestRewritePlaybackInfoAddsSourceParametersWhenClientOmitsThem(t *testing.T) {
69+
input := []byte(`{"MediaSources":[{"Id":"source1","SupportsDirectPlay":true,"MediaStreams":[{"Type":"Audio","Index":1,"Codec":"dts"}]}]}`)
70+
71+
out, changed, err := emby.RewritePlaybackInfo(input, "item123", "http://proxy.local", "AutoOpenLiveStream=false&IsPlayback=false")
72+
if err != nil {
73+
t.Fatal(err)
74+
}
75+
if !changed {
76+
t.Fatal("expected rewrite to change response")
77+
}
78+
if !bytes.Contains(out, []byte(`MediaSourceId=source1`)) {
79+
t.Fatalf("missing media source id: %s", out)
80+
}
81+
if !bytes.Contains(out, []byte(`AudioStreamIndex=1`)) {
82+
t.Fatalf("missing audio stream index: %s", out)
83+
}
6384
}
6485

6586
func TestRewritePlaybackInfoWithReportDescribesSources(t *testing.T) {
@@ -85,7 +106,7 @@ func TestRewritePlaybackInfoWithReportDescribesSources(t *testing.T) {
85106
if source.BeforeDirectStreamURL != "/Videos/1/stream" {
86107
t.Fatalf("direct stream url = %q", source.BeforeDirectStreamURL)
87108
}
88-
if source.AfterTranscodingURL != "/streambridge/transcode/item123/master.m3u8" {
109+
if source.AfterTranscodingURL != "/streambridge/transcode/item123/master.m3u8?AudioStreamIndex=1&MediaSourceId=source1" {
89110
t.Fatalf("after url = %q", source.AfterTranscodingURL)
90111
}
91112
if source.SessionID != "item123" {

0 commit comments

Comments
 (0)