From 83ec412e055868180c5fd5db4427c27cba3a4c2b Mon Sep 17 00:00:00 2001 From: Ingo Oppermann Date: Mon, 4 Nov 2024 12:06:59 +0100 Subject: [PATCH] Allow segments to be mp4 additional to ts --- http/middleware/session/HLS.go | 8 +-- http/middleware/session/HLS_test.go | 63 ++++++++++++++++--- .../{segments.txt => segments_v6.txt} | 0 ...ssion.txt => segments_v6_with_session.txt} | 0 .../session/fixtures/segments_v7.txt | 24 +++++++ .../fixtures/segments_v7_with_session.txt | 24 +++++++ 6 files changed, 108 insertions(+), 11 deletions(-) rename http/middleware/session/fixtures/{segments.txt => segments_v6.txt} (100%) rename http/middleware/session/fixtures/{segments_with_session.txt => segments_v6_with_session.txt} (100%) create mode 100644 http/middleware/session/fixtures/segments_v7.txt create mode 100644 http/middleware/session/fixtures/segments_v7_with_session.txt diff --git a/http/middleware/session/HLS.go b/http/middleware/session/HLS.go index fa03d4e2..f7939f31 100644 --- a/http/middleware/session/HLS.go +++ b/http/middleware/session/HLS.go @@ -81,7 +81,7 @@ func (h *handler) handleHLSIngress(c echo.Context, _ string, data map[string]int mem.Put(r.buffer) }() - } else if strings.HasSuffix(path, ".ts") { + } else if strings.HasSuffix(path, ".ts") || strings.HasSuffix(path, ".mp4") { // Get the size of the .ts file and store it in the ts-map for later use. reader := req.Body r := &bodysizeReader{ @@ -117,7 +117,7 @@ func (h *handler) handleHLSEgress(c echo.Context, _ string, data map[string]inte sessionID := c.QueryParam("session") isM3U8 := strings.HasSuffix(path, ".m3u8") - isTS := strings.HasSuffix(path, ".ts") + isTS := strings.HasSuffix(path, ".ts") || strings.HasSuffix(path, ".mp4") rewrite := false @@ -281,7 +281,7 @@ func (r *segmentReader) getSegments(dir string) []string { } // Ignore anything that doesn't end in .ts - if !strings.HasSuffix(u.Path, ".ts") { + if !strings.HasSuffix(u.Path, ".ts") && !strings.HasSuffix(u.Path, ".mp4") { continue } @@ -337,7 +337,7 @@ func (g *sessionRewriter) rewriteHLS(sessionID string, requestURL *url.URL, buff } // Write anything that doesn't end in .m3u8 or .ts unmodified - if !strings.HasSuffix(u.Path, ".m3u8") && !strings.HasSuffix(u.Path, ".ts") { + if !strings.HasSuffix(u.Path, ".m3u8") && !strings.HasSuffix(u.Path, ".ts") && !strings.HasSuffix(u.Path, ".mp4") { buffer.Write(byteline) buffer.WriteByte('\n') continue diff --git a/http/middleware/session/HLS_test.go b/http/middleware/session/HLS_test.go index 5d27103b..b5e7a958 100644 --- a/http/middleware/session/HLS_test.go +++ b/http/middleware/session/HLS_test.go @@ -11,8 +11,8 @@ import ( "github.com/stretchr/testify/require" ) -func TestHLSSegmentReader(t *testing.T) { - data, err := os.ReadFile("./fixtures/segments.txt") +func TestHLSSegmentReaderTS(t *testing.T) { + data, err := os.ReadFile("./fixtures/segments_v6.txt") require.NoError(t, err) r := bytes.NewReader(data) @@ -38,8 +38,33 @@ func TestHLSSegmentReader(t *testing.T) { }, segments) } +func TestHLSSegmentReaderMP4(t *testing.T) { + data, err := os.ReadFile("./fixtures/segments_v7.txt") + require.NoError(t, err) + + r := bytes.NewReader(data) + + br := &segmentReader{ + reader: io.NopCloser(r), + buffer: &mem.Buffer{}, + } + + _, err = io.ReadAll(br) + require.NoError(t, err) + + segments := br.getSegments("/foobar") + require.Equal(t, []string{ + "/foobar/test_output_0_0067.mp4", + "/foobar/test_output_0_0068.mp4", + "/foobar/test_output_0_0069.mp4", + "/foobar/test_output_0_0070.mp4", + "/foobar/test_output_0_0071.mp4", + "/foobar/test_output_0_0072.mp4", + }, segments) +} + func BenchmarkHLSSegmentReader(b *testing.B) { - data, err := os.ReadFile("./fixtures/segments.txt") + data, err := os.ReadFile("./fixtures/segments_v6.txt") require.NoError(b, err) rd := bytes.NewReader(data) @@ -59,8 +84,8 @@ func BenchmarkHLSSegmentReader(b *testing.B) { } } -func TestHLSRewrite(t *testing.T) { - data, err := os.ReadFile("./fixtures/segments.txt") +func TestHLSRewriteTS(t *testing.T) { + data, err := os.ReadFile("./fixtures/segments_v6.txt") require.NoError(t, err) br := &sessionRewriter{ @@ -77,14 +102,38 @@ func TestHLSRewrite(t *testing.T) { br.rewriteHLS("oT5GV8eWBbRAh4aib5egoK", u, buffer) - data, err = os.ReadFile("./fixtures/segments_with_session.txt") + data, err = os.ReadFile("./fixtures/segments_v6_with_session.txt") + require.NoError(t, err) + + require.Equal(t, data, buffer.Bytes()) +} + +func TestHLSRewriteMP4(t *testing.T) { + data, err := os.ReadFile("./fixtures/segments_v7.txt") + require.NoError(t, err) + + br := &sessionRewriter{ + buffer: &mem.Buffer{}, + } + + _, err = br.Write(data) + require.NoError(t, err) + + u, err := url.Parse("http://example.com/test.m3u8") + require.NoError(t, err) + + buffer := &mem.Buffer{} + + br.rewriteHLS("oT5GV8eWBbRAh4aib5egoK", u, buffer) + + data, err = os.ReadFile("./fixtures/segments_v7_with_session.txt") require.NoError(t, err) require.Equal(t, data, buffer.Bytes()) } func BenchmarkHLSRewrite(b *testing.B) { - data, err := os.ReadFile("./fixtures/segments.txt") + data, err := os.ReadFile("./fixtures/segments_v6.txt") require.NoError(b, err) u, err := url.Parse("http://example.com/test.m3u8") diff --git a/http/middleware/session/fixtures/segments.txt b/http/middleware/session/fixtures/segments_v6.txt similarity index 100% rename from http/middleware/session/fixtures/segments.txt rename to http/middleware/session/fixtures/segments_v6.txt diff --git a/http/middleware/session/fixtures/segments_with_session.txt b/http/middleware/session/fixtures/segments_v6_with_session.txt similarity index 100% rename from http/middleware/session/fixtures/segments_with_session.txt rename to http/middleware/session/fixtures/segments_v6_with_session.txt diff --git a/http/middleware/session/fixtures/segments_v7.txt b/http/middleware/session/fixtures/segments_v7.txt new file mode 100644 index 00000000..2192459b --- /dev/null +++ b/http/middleware/session/fixtures/segments_v7.txt @@ -0,0 +1,24 @@ +#EXTM3U +#EXT-X-VERSION:7 +#EXT-X-TARGETDURATION:2 +#EXT-X-MEDIA-SEQUENCE:67 +#EXT-X-INDEPENDENT-SEGMENTS +#EXT-X-MAP:URI="test.mp4" +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:14:54.317+0000 +test_output_0_0067.mp4 +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:14:56.317+0000 +test_output_0_0068.mp4 +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:14:58.317+0000 +test_output_0_0069.mp4 +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:15:00.317+0000 +test_output_0_0070.mp4 +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:15:02.317+0000 +test_output_0_0071.mp4 +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:15:04.317+0000 +test_output_0_0072.mp4 diff --git a/http/middleware/session/fixtures/segments_v7_with_session.txt b/http/middleware/session/fixtures/segments_v7_with_session.txt new file mode 100644 index 00000000..a9c82058 --- /dev/null +++ b/http/middleware/session/fixtures/segments_v7_with_session.txt @@ -0,0 +1,24 @@ +#EXTM3U +#EXT-X-VERSION:7 +#EXT-X-TARGETDURATION:2 +#EXT-X-MEDIA-SEQUENCE:67 +#EXT-X-INDEPENDENT-SEGMENTS +#EXT-X-MAP:URI="test.mp4" +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:14:54.317+0000 +test_output_0_0067.mp4?session=oT5GV8eWBbRAh4aib5egoK +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:14:56.317+0000 +test_output_0_0068.mp4?session=oT5GV8eWBbRAh4aib5egoK +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:14:58.317+0000 +test_output_0_0069.mp4?session=oT5GV8eWBbRAh4aib5egoK +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:15:00.317+0000 +test_output_0_0070.mp4?session=oT5GV8eWBbRAh4aib5egoK +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:15:02.317+0000 +test_output_0_0071.mp4?session=oT5GV8eWBbRAh4aib5egoK +#EXTINF:2.000000, +#EXT-X-PROGRAM-DATE-TIME:2024-11-04T10:15:04.317+0000 +test_output_0_0072.mp4?session=oT5GV8eWBbRAh4aib5egoK