Live video on the AT Protocol
at eli/node-22 167 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 i := 0; i < streamplaceTestCount; i++ { 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 70 // Convert MP4 to MPEG-TS 71 _, err = MP4ToMPEGTS(context.Background(), bytes.NewReader(bs), &buf) 72 require.ErrorContains(t, err, "This file is invalid and cannot be played") 73} 74 75// func TestNoRealtime(t *testing.T) { 76// gst.Init(nil) 77 78// // Open input file 79// inputFile, err := os.Open(getFixture("5sec.mp4")) 80// require.NoError(t, err) 81// defer inputFile.Close() 82 83// // Create a buffer for output 84// tsBuf := bytes.Buffer{} 85 86// // Convert MP4 to MPEG-TS 87// start := time.Now() 88// dur, err := MP4ToMPEGTS(context.Background(), inputFile, &tsBuf) 89// require.NoError(t, err) 90// require.Greater(t, dur, int64(0), "Duration should be greater than 0") 91// elapsed := time.Since(start) 92// require.Less(t, elapsed, 4*time.Second, "MP4 to MPEG-TS conversion should take less than 4 seconds") 93// require.Greater(t, tsBuf.Len(), 0, "MPEG-TS buffer should not be empty") 94 95// // Convert back to MP4 96// mp4Buf := bytes.Buffer{} 97// start = time.Now() 98// err = MPEGTSToMP4(context.Background(), bytes.NewReader(tsBuf.Bytes()), &mp4Buf) 99// require.NoError(t, err) 100// elapsed = time.Since(start) 101// require.Less(t, elapsed, 4*time.Second, "MPEG-TS to MP4 conversion should take less than 4 seconds") 102// require.Greater(t, mp4Buf.Len(), 0, "MP4 buffer should not be empty") 103// } 104 105func TestMPEGTSToMP4(t *testing.T) { 106 ignore := goleak.IgnoreCurrent() 107 defer goleak.VerifyNone(t, ignore) 108 before := getLeakCount(t) 109 defer checkGStreamerLeaks(t, before) 110 111 // Open input file 112 inputFile, err := os.Open(getFixture("sample-segment.mpegts")) 113 require.NoError(t, err) 114 defer inputFile.Close() 115 bs, err := io.ReadAll(inputFile) 116 require.NoError(t, err) 117 // Create temporary output file 118 buf := bytes.Buffer{} 119 120 g, _ := errgroup.WithContext(context.Background()) 121 for i := 0; i < streamplaceTestCount; i++ { 122 g.Go(func() error { 123 return MPEGTSToMP4(context.Background(), bytes.NewReader(bs), &buf) 124 }) 125 } 126 err = g.Wait() 127 // Convert MPEG-TS to MP4 128 129 require.NoError(t, err) 130 require.Greater(t, buf.Len(), 0, "Output file should not be empty") 131} 132 133func TestMP4ToMPEGTSVideoMP4Audio(t *testing.T) { 134 ignore := goleak.IgnoreCurrent() 135 defer goleak.VerifyNone(t, ignore) 136 before := getLeakCount(t) 137 defer checkGStreamerLeaks(t, before) 138 139 // Open input file 140 inputFile, err := os.Open(getFixture("5sec.mp4")) 141 require.NoError(t, err) 142 defer inputFile.Close() 143 144 // Create buffers for output 145 videoBuf := bytes.Buffer{} 146 audioBuf := bytes.Buffer{} 147 148 // Split MP4 into MPEG-TS video and MP4 audio 149 start := time.Now() 150 err = MP4ToMPEGTSVideoMP4Audio(context.Background(), inputFile, &videoBuf, &audioBuf) 151 require.NoError(t, err) 152 elapsed := time.Since(start) 153 require.Less(t, elapsed, 4*time.Second, "MP4 to MPEG-TS/MP4 conversion should take less than 4 seconds") 154 155 // Verify outputs 156 require.Greater(t, videoBuf.Len(), 0, "Video buffer should not be empty") 157 require.Greater(t, audioBuf.Len(), 0, "Audio buffer should not be empty") 158 159 // Join video and audio back together 160 buf := bytes.Buffer{} 161 start = time.Now() 162 err = MPEGTSVideoMP4AudioToMP4(context.Background(), &videoBuf, &audioBuf, &buf) 163 require.NoError(t, err) 164 require.Greater(t, buf.Len(), 0, "Output buffer should not be empty") 165 elapsed = time.Since(start) 166 require.Less(t, elapsed, 4*time.Second, "MPEG-TS/MP4 to MP4 conversion should take less than 4 seconds") 167}