我正在对一个视频做一些重构技术,而不是立即在整个视频上使用这些技术,我想分别在视频的图片组(GOPs)上使用这些技术,所以我想知道的是,有什么方法可以提取由编解码器生成的视频的图片组。
发布于 2022-07-21 21:26:30
图片组(GOP)应用从关键帧开始的所有视频帧,并在下一个关键帧之前结束一个帧。
(上述定义假定为"关闭共和党人")。
以下职位有将视频分割成GOP的示例,但是没有Python代码示例,我不确定这个剧本是否真的工作。
对于将视频文件分割成多个文件时,每个文件是一个GOP,我们可以使用段穆克塞与-segment_times参数。
-segment_times需要一个时间戳列表。我们shell提供输入文件中所有关键帧的时间戳列表。
让我们首先构建一个用于测试的输入视频文件(使用FFmpeg CLI):
ffmpeg -y -f lavfi -i testsrc=size=192x108:rate=1:duration=100 -vcodec libx264 -g 10 in.mp4
上面的命令构建一个固定GOP大小为10帧的合成视频文件(用于测试)。
框架是有编号的,所以很容易跟踪.
使用FFprobe CLI获取所有关键帧的时间戳(用于演示概念):
ffprobe -skip_frame nokey -select_streams v:0 -show_frames -show_entries frame=pkt_pts_time -of json in.mp4 > tmp.txt
(将从Python执行类似的命令)。
上面的命令以JSON格式创建一个带有所有关键帧时间戳的文本文件:
{
"frames": [
...
{
"pkt_pts_time": "10.000000"
},
{
"pkt_pts_time": "20.000000"
},
...
}segment_times列表将是:"10.000000,20.000000,30.000000..."。
使用Python脚本以编程方式将视频文件拆分为GOP:
out0000.mp4、out0001.mp4、out0002.mp4):
sp.run('ffmpeg','-i',in_file_name,'-codec','copy','-f',‘段’,‘-重置_时间戳’,'1',‘-段_time’,segment_times,'out%04d.mp4')上面的代码使用子流程模块在Python中执行FFmpeg和FFprobe。
确保ffmpeg和ff探头处于退出路径。
Python代码:
import subprocess as sp
import json
# Preparation: build synthetic video file for testing
# ffmpeg -y -f lavfi -i testsrc=size=192x108:rate=1:duration=100 -vcodec libx264 -g 10 in.mp4
in_file_name = 'in.mp4' # Input file name
# Use FFprobe for getting the PTS timestamps of all key frames (get it in JSON format).
data = sp.run(['ffprobe', '-skip_frame', 'nokey', '-select_streams', 'v:0', '-show_frames', '-show_entries', 'frame=pkt_pts_time', '-of', 'json', in_file_name], stdout=sp.PIPE).stdout
dict = json.loads(data) # Convert from JSON (string) to dictionary
frames_dict = dict['frames'] # Get 'frames' out of the dictionary
pts_list = [item['pkt_pts_time'] for item in frames_dict] # Convert to list: ['0.000000', '10.000000', '20.000000', ...]
segment_times = ",".join(pts_list) # Convert list to comma separated string: '0.000000,10.000000,20.000000,...'
# Use FFmpeg for splitting the input video by timestamps (files: out0000.mp4, out0001.mp4, out0002.mp4)
# Each segment file is going to be a GOP - start from key-frame, and end one frame before the next key-frame.
sp.run(['ffmpeg', '-i', in_file_name, '-codec', 'copy', '-f', 'segment', '-reset_timestamps', '1', '-segment_times', segment_times, 'out%04d.mp4'])注意:
https://stackoverflow.com/questions/73064958
复制相似问题