Video 人工编码成MPEG-TS

Video 人工编码成MPEG-TS,video,ffmpeg,h.264,http-live-streaming,mpeg2-ts,Video,Ffmpeg,H.264,Http Live Streaming,Mpeg2 Ts,所以 我正在尝试获取一个H264附件B字节流视频,并用纯Java将其编码为MPEG-TS。我的目标是创建一个最小的MPEG-TS、单节目、有效流,并且不包括任何定时信息(PCR、PTS、DTS) 我目前正处于生成的文件可以传递到ffmpeg(ffmpeg-I myVideo.ts)和ffmpeg报告的位置 [NULL @ 0x7f8103022600] start time is not set in estimate_timings_from_pts Input #0, mpegts, fr

所以

我正在尝试获取一个H264附件B字节流视频,并用纯Java将其编码为MPEG-TS。我的目标是创建一个最小的MPEG-TS、单节目、有效流,并且不包括任何定时信息(PCR、PTS、DTS)

我目前正处于生成的文件可以传递到ffmpeg(ffmpeg-I myVideo.ts)和ffmpeg报告的位置

[NULL @ 0x7f8103022600] start time is not set in estimate_timings_from_pts

Input #0, mpegts, from 'video.ts':
Duration: N/A, bitrate: N/A
Program 1 
  Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
…看来这条关于开始时间的警告不是什么大不了的。。。ffmpeg无法确定视频的长度。如果我从我的视频文件(ffmpeg-I myVideo.ts-vcodec copy validVideo.ts)创建另一个mpeg ts文件并运行ffmpeg-I validVideo.ts,我会得到

Input #0, mpegts, from 'video2.ts':
Duration: 00:00:11.61, start: 1.400000, bitrate: 3325 kb/s
Program 1 
  Metadata:
    service_name    : Service01
    service_provider: FFmpeg
  Stream #0:0[0x100]: Video: h264 (Main) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709), 1280x720 [SAR 1:1 DAR 16:9], 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
…因此,您可以看到计时信息和比特率以及元数据

我的H264视频仅由I帧和p帧组成(当然,SP和PPS在I帧之前),我创建MPEG-TS流的方式是

  • 在文件的开头写一个拍子
  • 在文件开头写入一个PMT
  • 从SPS、PPS和I帧创建TS和PES数据包(如果需要,也创建AUD NAL?)
  • 从P帧创建TS和PES数据包(如果需要,也可以创建AUD NAL)
  • 对于I帧或P帧的最后一个有效负载,向自适应字段添加填充字节,以确保它适合完整的TS数据包
  • 对整个文件重复3-5次
  • …我的帕特看起来像这样

    4740 0010 0000 b00d 0001 c100 0000 01f0
    002a b104 b2ff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff
    
    4750 0010
    0002 b012 0001 c100 00ff fff0 001b e100
    f000 c15b 41e0 ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff
    
    …我的PMT看起来像这样

    4740 0010 0000 b00d 0001 c100 0000 01f0
    002a b104 b2ff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff
    
    4750 0010
    0002 b012 0001 c100 00ff fff0 001b e100
    f000 c15b 41e0 ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff
    
    …注意c100之后的“ff ff”,f0。。。说我们没有使用PCR。。。还请注意,我已经更新了我的CRC,以将此更改反映到PMT中。我的第一个帧包看起来像

    4741 0010 0000 01e0
    0000 8000 0000 0000 0109 f000 0000 0127
    4d40 288d 8d60 2802 dd80 b501 0101 4000
    00fa 4000 3a98 3a18 00b7 2000 3380 2ef2
    e343 0016 e400 0670 05de 5c16 345d c000
    0000 0128 ee3c 8000 0000 0165 8880 0020
    0000 4fe5 63b5 4e90 b11c 9f8f f891 10f3
    13b1 666b 9fc6 03e9 e321 36bf 1788 347b
    eb23 fc89 5772 6e2e 1714 96df ed16 9b30
    252d ceb7 07e9 a0c7 c6e7 9515 be87 2df1
    81f3 b9d2 ba5f 243e 2d5c cba2 8ca5 b798
    6bec 8c43 0b5d bbda bc5b 6e7c e15c 84e8
    2f13 be84 
    
    4741 001d
    0000 01e0 0000 8000 0000 0000 0109 f000
    0000 0141 9a00 0200 0593 ff45 a7ae 1acd
    f2d7 f9ec 557f cdb6 ba38 60d6 a626 5edb
    4bb9 9783 89e2 d7e1 102e 4625 2fbf ce16
    f952 d8c9 f027 e55a 6b2a 81c3 48d4 6a45
    050a f355 fbec db01 6562 6405 04aa e011
    50ec 0b45 45e5 0df7 2fed a3f8 ac13 2e69
    6739 6d81 f13d 2455 e6ca 1c6b dc96 65d5
    3bad f250 7dab 42e4 7ba9 f564 ee61 29fb
    1b2c 974c 6924 1a1f 99ef 063c b99a c507
    8c22 b0f8 b14c 3e4d 01d0 6120 4e19 8725
    2fda 6550 f907 3f87
    
    …您会注意到,在01E00000之后,8000 00是PES标头扩展,其中我没有指定PTS/DTS,剩余长度为零。我的第一个P帧包看起来像

    4741 0010 0000 01e0
    0000 8000 0000 0000 0109 f000 0000 0127
    4d40 288d 8d60 2802 dd80 b501 0101 4000
    00fa 4000 3a98 3a18 00b7 2000 3380 2ef2
    e343 0016 e400 0670 05de 5c16 345d c000
    0000 0128 ee3c 8000 0000 0165 8880 0020
    0000 4fe5 63b5 4e90 b11c 9f8f f891 10f3
    13b1 666b 9fc6 03e9 e321 36bf 1788 347b
    eb23 fc89 5772 6e2e 1714 96df ed16 9b30
    252d ceb7 07e9 a0c7 c6e7 9515 be87 2df1
    81f3 b9d2 ba5f 243e 2d5c cba2 8ca5 b798
    6bec 8c43 0b5d bbda bc5b 6e7c e15c 84e8
    2f13 be84 
    
    4741 001d
    0000 01e0 0000 8000 0000 0000 0109 f000
    0000 0141 9a00 0200 0593 ff45 a7ae 1acd
    f2d7 f9ec 557f cdb6 ba38 60d6 a626 5edb
    4bb9 9783 89e2 d7e1 102e 4625 2fbf ce16
    f952 d8c9 f027 e55a 6b2a 81c3 48d4 6a45
    050a f355 fbec db01 6562 6405 04aa e011
    50ec 0b45 45e5 0df7 2fed a3f8 ac13 2e69
    6739 6d81 f13d 2455 e6ca 1c6b dc96 65d5
    3bad f250 7dab 42e4 7ba9 f564 ee61 29fb
    1b2c 974c 6924 1a1f 99ef 063c b99a c507
    8c22 b0f8 b14c 3e4d 01d0 6120 4e19 8725
    2fda 6550 f907 3f87
    
    …每当一个I帧或p帧结束时,我有一个TS数据包,其中有一个自适应字段,如

    4701 003c b000 ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff ffff ffff
    ffff ffff ffff ffff ffff ffff
    

    …其中,第一个b0字节是自适应字段填充字节,其余的是I或p帧的最终字节。因此,正如您所知,我可以使用ffmpeg并将其传递给我的文件,以创建任何格式的有效电影。然而,我需要我创建的文件是正确的格式,我不能完全弄清楚我缺少的最后一块是什么。有什么想法吗

    您有相互冲突的需求。“有效流”和“不包括任何定时信息”不兼容。TS要求至少每100毫秒进行一次PCR。虽然特定于玩家,但大多数玩家不会“呈现”没有“呈现时间戳”的帧。您可以从VUI数据派生时间戳,但它必须存在于容器中。

    谢谢!我看到了PCR要求,但自适应字段和PES标题是“可选”的,这似乎是矛盾的。不管怎么说,我似乎至少需要添加PCR和PTS(对于大多数玩家来说,有些玩家可能没有PTS,对吧?),但我有几个问题。。。时间戳是否来自SPS/PPS?I帧每秒出现一次,那么如何计算P帧时间戳呢?如果我想创建自己的时间戳(从0开始),那么数据包之间预期的时间戳间隔(1会起作用)是多少?我是否可以将这个“假时间”用于PCR和PTS,或者它们是否需要关联?因此我将PCR和PTS添加到我的流中。我将PTS添加到每个PES数据包头中,并将PCR添加到每个TS数据包的PPS/SPS/I帧有效载荷的自适应字段中,并交替添加到P帧有效载荷中。这导致我的视频现在可以在VLC中播放,但开始、持续时间和比特率仍然不正确。每次我都要单步执行PCR和PTS6006(这是ffmpeg创建有效TS文件时所做的)。我缺少一些有关正确的PCR/PTS计算的信息,该计算将输出高质量的视频。TS使用90kHz时钟,因此每帧6006个“滴答声”为每秒15帧
    15~1000/(6006/90)
    。你的视频是每秒15帧吗?不,我的视频是每秒30帧(虽然是29.97帧,因为它是彩色的)。虽然我认为我的代码需要处理每秒15帧和30帧的视频,但我可能需要首先查看VUI数据以获取该信息,以及我想象的初始时间戳……请注意,VUI是SPS中的一个可选字段,因此可能不存在。您能做到这一点吗?我真的很感兴趣的是如何包装h264采取HLS太。。。