Live video on the AT Protocol
at eli/fix-gitlab 168 lines 5.0 kB view raw
1package media 2 3import ( 4 "bytes" 5 "context" 6 "io" 7 "os" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/require" 12 "go.uber.org/goleak" 13 "golang.org/x/sync/errgroup" 14) 15 16func TestMP4ToMPEGTS(t *testing.T) { 17 ignore := goleak.IgnoreCurrent() 18 defer goleak.VerifyNone(t, ignore) 19 before := getLeakCount(t) 20 defer checkGStreamerLeaks(t, before) 21 22 for _, file := range []string{"sample-segment.mp4", "short-video.mp4"} { 23 // Open input file 24 inputFile, err := os.Open(getFixture(file)) 25 require.NoError(t, err) 26 defer inputFile.Close() 27 28 // Create a buffer for output 29 buf := bytes.Buffer{} 30 31 bs, err := io.ReadAll(inputFile) 32 require.NoError(t, err) 33 // Create temporary output file 34 35 g, _ := errgroup.WithContext(context.Background()) 36 for range streamplaceTestCount { 37 g.Go(func() error { 38 _, err := MP4ToMPEGTS(context.Background(), bytes.NewReader(bs), &buf) 39 return err 40 }) 41 } 42 err = g.Wait() 43 require.NoError(t, err) 44 // Convert MPEG-TS to MP4 45 46 // Convert MP4 to MPEG-TS 47 dur, err := MP4ToMPEGTS(context.Background(), bytes.NewReader(bs), &buf) 48 require.NoError(t, err) 49 require.Greater(t, dur, int64(0), "Duration should be greater than 0") 50 51 // Verify buffer has content 52 require.Greater(t, buf.Len(), 0, "Output buffer should not be empty") 53 } 54} 55 56func TestMP4ToMPEGTSInvalid(t *testing.T) { 57 ignore := goleak.IgnoreCurrent() 58 defer goleak.VerifyNone(t, ignore) 59 before := getLeakCount(t) 60 defer checkGStreamerLeaks(t, before) 61 62 inputFile, err := os.Open(getFixture("sample-segment.mpegts")) 63 require.NoError(t, err) 64 defer inputFile.Close() 65 66 buf := bytes.Buffer{} 67 68 bs, err := io.ReadAll(inputFile) 69 require.NoError(t, err) 70 71 // Convert MP4 to MPEG-TS 72 _, err = MP4ToMPEGTS(context.Background(), bytes.NewReader(bs), &buf) 73 require.ErrorContains(t, err, "This file is invalid and cannot be played") 74} 75 76// func TestNoRealtime(t *testing.T) { 77// gst.Init(nil) 78 79// // Open input file 80// inputFile, err := os.Open(getFixture("5sec.mp4")) 81// require.NoError(t, err) 82// defer inputFile.Close() 83 84// // Create a buffer for output 85// tsBuf := bytes.Buffer{} 86 87// // Convert MP4 to MPEG-TS 88// start := time.Now() 89// dur, err := MP4ToMPEGTS(context.Background(), inputFile, &tsBuf) 90// require.NoError(t, err) 91// require.Greater(t, dur, int64(0), "Duration should be greater than 0") 92// elapsed := time.Since(start) 93// require.Less(t, elapsed, 4*time.Second, "MP4 to MPEG-TS conversion should take less than 4 seconds") 94// require.Greater(t, tsBuf.Len(), 0, "MPEG-TS buffer should not be empty") 95 96// // Convert back to MP4 97// mp4Buf := bytes.Buffer{} 98// start = time.Now() 99// err = MPEGTSToMP4(context.Background(), bytes.NewReader(tsBuf.Bytes()), &mp4Buf) 100// require.NoError(t, err) 101// elapsed = time.Since(start) 102// require.Less(t, elapsed, 4*time.Second, "MPEG-TS to MP4 conversion should take less than 4 seconds") 103// require.Greater(t, mp4Buf.Len(), 0, "MP4 buffer should not be empty") 104// } 105 106func TestMPEGTSToMP4(t *testing.T) { 107 ignore := goleak.IgnoreCurrent() 108 defer goleak.VerifyNone(t, ignore) 109 before := getLeakCount(t) 110 defer checkGStreamerLeaks(t, before) 111 112 // Open input file 113 inputFile, err := os.Open(getFixture("sample-segment.mpegts")) 114 require.NoError(t, err) 115 defer inputFile.Close() 116 bs, err := io.ReadAll(inputFile) 117 require.NoError(t, err) 118 // Create temporary output file 119 buf := bytes.Buffer{} 120 121 g, _ := errgroup.WithContext(context.Background()) 122 for i := 0; i < streamplaceTestCount; i++ { 123 g.Go(func() error { 124 return MPEGTSToMP4(context.Background(), bytes.NewReader(bs), &buf) 125 }) 126 } 127 err = g.Wait() 128 // Convert MPEG-TS to MP4 129 130 require.NoError(t, err) 131 require.Greater(t, buf.Len(), 0, "Output file should not be empty") 132} 133 134func TestMP4ToMPEGTSVideoMP4Audio(t *testing.T) { 135 ignore := goleak.IgnoreCurrent() 136 defer goleak.VerifyNone(t, ignore) 137 before := getLeakCount(t) 138 defer checkGStreamerLeaks(t, before) 139 140 // Open input file 141 inputFile, err := os.Open(getFixture("5sec.mp4")) 142 require.NoError(t, err) 143 defer inputFile.Close() 144 145 // Create buffers for output 146 videoBuf := bytes.Buffer{} 147 audioBuf := bytes.Buffer{} 148 149 // Split MP4 into MPEG-TS video and MP4 audio 150 start := time.Now() 151 err = MP4ToMPEGTSVideoMP4Audio(context.Background(), inputFile, &videoBuf, &audioBuf) 152 require.NoError(t, err) 153 elapsed := time.Since(start) 154 require.Less(t, elapsed, 4*time.Second, "MP4 to MPEG-TS/MP4 conversion should take less than 4 seconds") 155 156 // Verify outputs 157 require.Greater(t, videoBuf.Len(), 0, "Video buffer should not be empty") 158 require.Greater(t, audioBuf.Len(), 0, "Audio buffer should not be empty") 159 160 // Join video and audio back together 161 buf := bytes.Buffer{} 162 start = time.Now() 163 err = MPEGTSVideoMP4AudioToMP4(context.Background(), &videoBuf, &audioBuf, &buf) 164 require.NoError(t, err) 165 require.Greater(t, buf.Len(), 0, "Output buffer should not be empty") 166 elapsed = time.Since(start) 167 require.Less(t, elapsed, 4*time.Second, "MPEG-TS/MP4 to MP4 conversion should take less than 4 seconds") 168}