如何从FFmpeg的HLS输出中提取.ts分片原始数据(不写入磁盘)
问题
我试图获取通常写入.ts文件的原始数据,但不想生成播放列表或将这些数据写入磁盘,而是希望缓冲FFmpeg的输出并通过解析获取相同内容。我当前的方向是否有误?是否应该寻找MP4相关的头信息?
当前代码
package main import ( "bytes" "io" "log" "os/exec" "strings" "testing" ) func TestExtractor(t *testing.T) { args := "-i https://www.w3schools.com/html/mov_bbb.mp4 -c:v libx264 -crf 21 -preset veryfast -g 25 -sc_threshold 0 -c:a aac -b:a 128k -ac 2 -f hls -sc_threshold 0 -hls_segment_type mpegts -hls_time 2 -" cmd := exec.Command("ffmpeg", strings.Split(args, " ")...) // Create a pipe to read the FFmpeg output. stdout, err := cmd.StdoutPipe() if err != nil { log.Fatal(err) } if err := cmd.Start(); err != nil { log.Fatal(err) } s := []byte{ // Offset 0x0004A543 to 0x0004A5D9 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} buffer := make([]byte, len(s)) for { n, err := stdout.Read(buffer) if err == io.EOF { break } if err != nil { log.Fatal(err) } if bytes.Equal(buffer[:n], s) { log.Printf("\nFOUND BUFFER \n %v \n ============= \b", buffer[:n]) } else { //log.Printf("\nNOT FOUND BUFFER \n %v \n ============= \b", buffer[:n]) } } if err := cmd.Wait(); err != nil { log.Fatal(err) } }
解决方案
当前命令的核心问题
你使用了-f hls参数,FFmpeg会优先输出HLS播放列表(m3u8格式文本),之后才会输出TS片段数据。这导致你从标准输出读到的内容并非纯TS流,包含了播放列表的冗余信息,方向确实有误。修正FFmpeg命令
直接指定输出格式为mpegts而非hls,FFmpeg会直接输出原始TS流到标准输出,不会生成播放列表。修改后的参数如下:
args := "-i https://www.w3schools.com/html/mov_bbb.mp4 -c:v libx264 -crf 21 -preset veryfast -g 25 -sc_threshold 0 -c:a aac -b:a 128k -ac 2 -f mpegts -"
关于MP4头的疑问
不需要寻找MP4相关头信息。你已经通过FFmpeg将MP4转码为TS流,输出的是TS格式的原始数据,需要解析的是TS流的结构(比如每个TS包开头的同步字节0x47),而非MP4的容器结构。代码逻辑优化建议
当前用固定长度buffer匹配全0xff数组的逻辑不合理,TS流中不会存在大量连续的0xff。建议调整为:
- 使用TS包的标准长度188字节作为buffer大小(或更大的缓冲块)
- 查找流中的
0x47字节定位TS包起始位置,以此解析TS流内容
内容的提问来源于stack exchange,提问作者n0body7331
相关产品推荐
相关产品推荐

