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