具有不同时基的ffmpeg concat视频
ffmpeg concat videos with different timebase
我用
ffmpeg.exe -f concat -i file_path_list_txt -c copy out_out.mp4
连接
for file in 1265_*; do ffmpeg -i $file -crf 30 -b:a 23k -b:v 96k -threads 3 -y 'out_'$file; done
压缩视频。
当我播放生成的视频时,播放器显示的视频长度远远超过压缩视频片段的总和。并且在切片之间的联动处,帧可以播放很长时间,播放器上的时间在进行,但是帧是静止的。
我用ffprobe
来展示原视频片段和压缩视频片段。并找到了相同 tbr,tbn,tbc
的原始视频,而压缩后却没有。
原创视频:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, progressive), 1600x1144, 134 kb/s, 8.17 fps, 600 tbr, 600 tbn, 1200 tbc (default)
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, progressive), 1600x1144, 138 kb/s, 9.73 fps, 600 tbr, 600 tbn, 1200 tbc (default)
压缩视频:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1600x1144, 174 kb/s, 8.17 fps, 8.17 tbr, 245050 tbn, 16.33 tbc (default)
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1600x1144, 127 kb/s, 9.73 fps, 9.73 tbr, 1750800 tbn, 19.45 tbc (default)
当我连接时,在控制台中,ffmpeg 显示以下信息:
[mp4 @ 000001fe0193b700] Application provided duration: 2585263321 / timestamp: 6303355764 is out of range for mov/mp4 format
[mp4 @ 000001fe0193b700] pts has no value
[mp4 @ 000001fe0193b700] Application provided duration: 2585443321 / timestamp: 6303535765 is out of range for mov/mp4 format
[mp4 @ 000001fe0193b700] pts has no value
在我的情况下,视频片段是按时间生成的,我不知道它什么时候停止,所以我不能在压缩前进行连接。每次生成视频片段时,我都会压缩并附加它。
当压缩到 MOV/MP4 时,使用 -video_track_timescale N
设置一个共同的时间尺度 tbn
。对于您的输入,N=600 看起来不错。
在的帮助下,我让它工作了,我需要设置压缩和追加过程tbn
。
详情如下:
每次生成一个新的视频片段,用get_video_attributes
得到tbn
,然后用
压缩
ffmpeg -i $video_path_i -crf 30 -b:a 23k -b:v 96k -video_track_timescale $tbn -threads 3 -y 'out_'$file
然后将压缩后的切片附加到之前的视频中,
ffmpeg.exe -f concat -i file_path_list_txt -video_track_timescale $tbn -c copy out_out.mp4
更新 get_video_attribute
功能根据llogan 的评论
function get_video_attribute(&$video_attribute,$video_path,$ffprobe="ffprobe"){
$command = "$ffprobe -v error -show_entries stream=codec_type,codec_name,width,height,bit_rage,avg_frame_rate,r_frame_rate,".
"channels,channel_layout,sample_rate,bit_rate,time_base,codec_time_base,duration:format=duration,size,bit_rate -of json $video_path";
$video_attribute = [];
exec($command,$output,$return_var);
if ($return_var) {
return false;
}
if(false !== ($attribute=json_decode(join($output),true))){
// TODO video file may have more streams or less streams than one video and one audio stream
foreach($attribute["streams"] as $stream){
if(!isset(${$stream["codec_type"]})){
${$stream["codec_type"]} = $stream;
}
}
$video_attribute = array(
'width' => $video["width"],
'height' => $video["height"],
'duration' => intval($attribute["format"]["duration"]),
'v_codec' => $video["codec_name"],
'a_codec' => $audio["codec_name"],
"tbn" => $video["time_base"] ? explode("/",$video["time_base"])[1] : null,
'bps' => $attribute["format"]["bit_rate"],
'v_bps' => $video["bit_rate"],
'a_bps' => $audio["bit_rate"]
);
return true;
}else{
return false;
}
}
我用
ffmpeg.exe -f concat -i file_path_list_txt -c copy out_out.mp4
连接
for file in 1265_*; do ffmpeg -i $file -crf 30 -b:a 23k -b:v 96k -threads 3 -y 'out_'$file; done
压缩视频。
当我播放生成的视频时,播放器显示的视频长度远远超过压缩视频片段的总和。并且在切片之间的联动处,帧可以播放很长时间,播放器上的时间在进行,但是帧是静止的。
我用ffprobe
来展示原视频片段和压缩视频片段。并找到了相同 tbr,tbn,tbc
的原始视频,而压缩后却没有。
原创视频:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, progressive), 1600x1144, 134 kb/s, 8.17 fps, 600 tbr, 600 tbn, 1200 tbc (default)
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, progressive), 1600x1144, 138 kb/s, 9.73 fps, 600 tbr, 600 tbn, 1200 tbc (default)
压缩视频:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1600x1144, 174 kb/s, 8.17 fps, 8.17 tbr, 245050 tbn, 16.33 tbc (default)
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1600x1144, 127 kb/s, 9.73 fps, 9.73 tbr, 1750800 tbn, 19.45 tbc (default)
当我连接时,在控制台中,ffmpeg 显示以下信息:
[mp4 @ 000001fe0193b700] Application provided duration: 2585263321 / timestamp: 6303355764 is out of range for mov/mp4 format
[mp4 @ 000001fe0193b700] pts has no value
[mp4 @ 000001fe0193b700] Application provided duration: 2585443321 / timestamp: 6303535765 is out of range for mov/mp4 format
[mp4 @ 000001fe0193b700] pts has no value
在我的情况下,视频片段是按时间生成的,我不知道它什么时候停止,所以我不能在压缩前进行连接。每次生成视频片段时,我都会压缩并附加它。
当压缩到 MOV/MP4 时,使用 -video_track_timescale N
设置一个共同的时间尺度 tbn
。对于您的输入,N=600 看起来不错。
在tbn
。
详情如下:
每次生成一个新的视频片段,用get_video_attributes
得到tbn
,然后用
ffmpeg -i $video_path_i -crf 30 -b:a 23k -b:v 96k -video_track_timescale $tbn -threads 3 -y 'out_'$file
然后将压缩后的切片附加到之前的视频中,
ffmpeg.exe -f concat -i file_path_list_txt -video_track_timescale $tbn -c copy out_out.mp4
更新 get_video_attribute
功能根据llogan 的评论
function get_video_attribute(&$video_attribute,$video_path,$ffprobe="ffprobe"){
$command = "$ffprobe -v error -show_entries stream=codec_type,codec_name,width,height,bit_rage,avg_frame_rate,r_frame_rate,".
"channels,channel_layout,sample_rate,bit_rate,time_base,codec_time_base,duration:format=duration,size,bit_rate -of json $video_path";
$video_attribute = [];
exec($command,$output,$return_var);
if ($return_var) {
return false;
}
if(false !== ($attribute=json_decode(join($output),true))){
// TODO video file may have more streams or less streams than one video and one audio stream
foreach($attribute["streams"] as $stream){
if(!isset(${$stream["codec_type"]})){
${$stream["codec_type"]} = $stream;
}
}
$video_attribute = array(
'width' => $video["width"],
'height' => $video["height"],
'duration' => intval($attribute["format"]["duration"]),
'v_codec' => $video["codec_name"],
'a_codec' => $audio["codec_name"],
"tbn" => $video["time_base"] ? explode("/",$video["time_base"])[1] : null,
'bps' => $attribute["format"]["bit_rate"],
'v_bps' => $video["bit_rate"],
'a_bps' => $audio["bit_rate"]
);
return true;
}else{
return false;
}
}