Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Video ffmpeg使用H265 vcopy查找关键帧_Video_Ffmpeg_Mp4_Seek_Hevc - Fatal编程技术网

Video ffmpeg使用H265 vcopy查找关键帧

Video ffmpeg使用H265 vcopy查找关键帧,video,ffmpeg,mp4,seek,hevc,Video,Ffmpeg,Mp4,Seek,Hevc,我有一个H265 4K MP4 29.97fps的视频,GOP大小正好是30帧。 当我尝试从一开始就使用以下命令进行剪切时: ffmpeg -ss 1 -i INPUT.MP4 -vcodec copy OUTPUT_1SEC.MP4 ffmpeg -ss 2 -i INPUT.MP4 -vcodec copy OUTPUT_2SEC.MP4 ffmpeg -ss 3 -i INPUT.MP4 -vcodec copy OUTPUT_3SEC.MP4 ffmpeg -ss 4 -i INPUT.

我有一个H265 4K MP4 29.97fps的视频,GOP大小正好是30帧。 当我尝试从一开始就使用以下命令进行剪切时:

ffmpeg -ss 1 -i INPUT.MP4 -vcodec copy OUTPUT_1SEC.MP4
ffmpeg -ss 2 -i INPUT.MP4 -vcodec copy OUTPUT_2SEC.MP4
ffmpeg -ss 3 -i INPUT.MP4 -vcodec copy OUTPUT_3SEC.MP4
ffmpeg -ss 4 -i INPUT.MP4 -vcodec copy OUTPUT_4SEC.MP4
ffmpeg -ss 5 -i INPUT.MP4 -vcodec copy OUTPUT_5SEC.MP4
ffmpeg -ss 6 -i INPUT.MP4 -vcodec copy OUTPUT_6SEC.MP4
ffmpeg -ss 7 -i INPUT.MP4 -vcodec copy OUTPUT_7SEC.MP4
ffmpeg -ss 8 -i INPUT.MP4 -vcodec copy OUTPUT_8SEC.MP4
ffmpeg -ss 9 -i INPUT.MP4 -vcodec copy OUTPUT_9SEC.MP4
输出视频从0(-SS1~4)、4(-SS5~8)或8秒(-SS9)开始,如下所示:

因此,ffmpeg似乎以某种方式检测到了4秒而不是1秒的GOP。这正常吗

另外,如何在输出视频中刻录正确的时间码? 例如,我尝试了许多组合,例如:

ffmpeg -ss 5 -i INPUT.MP4 -vcodec copy -timecode 00:00:05:00 OUTPUT_5SEC.MP4
ffmpeg -ss 5 -i INPUT.MP4 -vcodec copy -copyts OUTPUT_5SEC.MP4
ffmpeg -start_at_zero -ss 5 -i INPUT.MP4 -vcodec copy -copyts OUTPUT_5SEC.MP4
但它要么给我确切的时间码(第一行),要么从零开始(最后两行)

最初,我想在精确的第二秒(或几帧之后)寻找,所以我知道我会得到一个关键帧,这样我就可以猜出输出将开始的确切时间码,但是ffmpeg-ss似乎并不完全基于关键帧?也许我遗漏了什么?谢谢你的帮助

附加信息

我想为剪切过程编写脚本,这就是为什么我想知道这4秒“关键帧间隔”的来源

以下是我输入的ffprobe输出:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'INPUT.MP4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2mp41
    encoder         : Lavf57.72.101
    comment         : DE=None, Mode=M, DSW=0001
    location-{    : +XX.4914-0XX.5164+XX.000000/
    location        : +XX.4914-0XX.5164+XX.000000/
  Duration: 00:01:45.31, start: 0.000000, bitrate: 100065 kb/s
    Stream #0:0(eng): Video: hevc (Main) (hev1 / 0x31766568), yuv420p(tv, bt709), 4096x2160 [SAR 1:1 DAR 256:135], 100062 kb/s, 29.97 fps, 29.97 tbr, 30k tbn, 29.97 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(eng): Subtitle: mov_text (tx3g / 0x67337874), 2 kb/s (default)
    Metadata:
      handler_name    : SubtitleHandler
下面是我用来检查gop大小的命令(“I”类型为1,31,61,…中间为“p”):

ffmpeg版本N-86330-gbd1179e和ffmpeg版本N-86330-gbd1179e


编辑:

尽管每秒都有一个关键帧,但在MOOV框中,只有三帧被设置为同步采样

/moov/trak/mdia/minf/stbl/stss                              @ 0x77e8515
  Box size: 0x1c    version: 0x0    flags: 0x0
  entry_count:              0x3
    sample_number:
    0x1    0x79    0xf1
(这些是第1帧、第121帧和第241帧。)

FFmpeg在搜索时依赖此信息


解决方法是多路复用到TS,然后再复用到MP4

ffmpeg -i input.mp4 -c copy input.ts
然后

ffmpeg -i input.ts -c copy newinput.mp4
或者在一个命令中

ffmpeg -i input.mp4 -c copy -f mpegts - | ffmpeg -f mpegts -i - -c copy newinput.mp4
MPEG-TS文件没有索引,因此如果要使用该文件进行提取,请在要剪切的关键帧之前指定一个搜索点


至于为什么同步表是这样的,我不知道。这取决于原始编写应用程序和其中使用的设置/参数

第1,31,61行,。。。和
frame,P
在所有其他行上,帧值不是pict类型。不是所有的I帧都是IDR帧。哦,对了,对不起。相同的模式,但在第1,31,61行有
帧,1
。。。和所有其他行上的
帧,0
。好的,仅在映射视频曲目的情况下尝试复制(
-map 0:v
)。时间码是单个编码字符串,而不是计时元数据。感谢这些有用的信息。现在我可以每秒拆分newinput.mp4,但生成的剪辑包含跳跃、黑色和绿色帧+压缩块。我最终将我所有的h265转换为DnxHR,并保留完整的未编辑h265以供存档。我真的很感谢你花了这么多时间来研究这个问题,现在我对关键帧的东西有了更多的了解。
ffmpeg -i input.mp4 -c copy -f mpegts - | ffmpeg -f mpegts -i - -c copy newinput.mp4