我编写了一个程序,它以编程的方式连接视频输入列表。问题是这些视频是录制流的一部分,它们的分辨率可能会在同一个文件中改变几次。目前,如果发生这种情况,ffmpeg就会失败,表示无法连接具有不同分辨率的文件。有没有办法让ffmpeg自动处理这个问题?一个好的解决方案是选择缩放具有意外分辨率的帧。
下面是一个清单:
ffmpeg -y -i 1.mkv -i 1.mka
-max_muxing_queue_size 10000
-preset veryfast -r 30 -crf 20 -b:a 96000 -vbr on
-strict experimental
-filter_complex '
color=black:s=320x240:d=7ms[black0];
aevalsrc=0:d=15ms[silence1];
[black0][0]concat=n=2:v=1:a=0[video];
[1][silence1]concat=n=2:v=0:a=1[audio]'
-map [video] -map [audio] -c:v libvpx -c:a libopus output.webm
ffmpeg version 4.3.1 Copyright (c) 2000-2020 the FFmpeg developers
built with Apple clang version 11.0.0 (clang-1100.0.33.17)
configuration: --prefix=/usr/local/Cellar/ffmpeg/4.3.1_9 --enable-shared --enable-pthreads --enable-version3 --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librtmp --enable-libspeex --enable-libsoxr --enable-videotoolbox --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack
libavutil 56. 51.100 / 56. 51.100
libavcodec 58. 91.100 / 58. 91.100
libavformat 58. 45.100 / 58. 45.100
libavdevice 58. 10.100 / 58. 10.100
libavfilter 7. 85.100 / 7. 85.100
libavresample 4. 0. 0 / 4. 0. 0
libswscale 5. 7.100 / 5. 7.100
libswresample 3. 7.100 / 3. 7.100
libpostproc 55. 7.100 / 55. 7.100
Input #0, matroska,webm, from '1.mkv':
Metadata:
encoder : GStreamer matroskamux version 1.8.1.1
creation_time : 2021-03-02T13:44:03.000000Z
Duration: 00:01:48.41, start: 0.710000, bitrate: 757 kb/s
Stream #0:0(eng): Video: vp8, yuv420p(progressive), 320x240, SAR 1:1 DAR 4:3, 120 tbr, 1k tbn, 1k tbc (default)
Metadata:
title : Video
Input #1, matroska,webm, from '1.mka':
Metadata:
encoder : GStreamer matroskamux version 1.8.1.1
creation_time : 2021-03-02T13:44:03.000000Z
Duration: 00:01:48.40, start: 0.703000, bitrate: 38 kb/s
Stream #1:0(eng): Audio: opus, 48000 Hz, stereo, fltp (default)
Metadata:
title : Audio
Codec AVOption preset (Configuration preset) specified for output file #0 (output.webm) has not been used for any stream. The most likely reason is either wrong type (e.g. a video option with no video streams) or that it is a private option of some encoder which was not actually used for any stream.
Stream mapping:
Stream #0:0 (vp8) -> concat:in1:v0
Stream #1:0 (opus) -> concat:in0:a0
concat -> Stream #0:0 (libvpx)
concat -> Stream #0:1 (libopus)
Press [q] to stop, [?] for help
[libvpx @ 0x7fe08a80bc00] v1.9.0
[libvpx @ 0x7fe08a80bc00] Bitrate not specified for constrained quality mode, using default of 256kbit/sec
Output #0, webm, to 'output.webm':
Metadata:
encoder : Lavf58.45.100
Stream #0:0: Video: vp8 (libvpx), yuv420p, 320x240 [SAR 1:1 DAR 4:3], q=-1--1, 256 kb/s, 30 fps, 1k tbn, 30 tbc (default)
Metadata:
encoder : Lavc58.91.100 libvpx
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
Stream #0:1: Audio: opus (libopus), 48000 Hz, stereo, flt, 96 kb/s (default)
Metadata:
encoder : Lavc58.91.100 libopus
[Parsed_color_0 @ 0x7fe089815940] EOF timestamp not reliable
[Parsed_concat_2 @ 0x7fe088501980] Input link in0:v0 parameters (size 640x480, SAR 1:1) do not match the corresponding output link in0:v0 parameters (320x240, SAR 1:1)
[Parsed_concat_2 @ 0x7fe088501980] Failed to configure output pad on Parsed_concat_2
Error reinitializing filters!
Failed to inject frame into filter network: Invalid argument
Error while processing the decoded data for stream #0:0
[libopus @ 0x7fe08a810c00] 1 frames left in the queue on closing
Conversion failed!
这是唯一一个带有"floating"分辨率,无法与320x240彩色滤镜连接。
如果我没有错,你只是想合并视频,可以是不同的分辨率,那么这将为你工作,看看给定的代码:
解释:在这里,我已经创建了pad
(一种类型的容器),我安装视频,每个视频会自动适应给定垫大小,加一件事如果你的视频是哑巴比命令将失败,所以我添加了新方法isVideoHaveAudioTrack()
检查视频音频或没有,如果视频没有任何音频我们必须添加沉默的音频,然后命令可以工作成功。
private boolean isVideoHaveAudioTrack(String path) {
boolean isAudioTrackAvailable;
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
try {
retriever.setDataSource(path);
String hasAudioStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO);
isAudioTrackAvailable = hasAudioStr != null && hasAudioStr.equals("yes");
} catch (Exception e) {
isAudioTrackAvailable = false;
}
return isAudioTrackAvailable;
}
public static LinkedList<String> mergeVideo(ArrayList<Video> selectedVideos, String silencedAudio, String filepath) {
String str3 = "";
StringBuilder str4 = new StringBuilder(str3);
StringBuilder str5 = new StringBuilder(str4.toString());
boolean isAnyMuteVideo = false;
LinkedList<String> commandList = new LinkedList<>();
for (int i = 0; i < selectedVideos.size(); i++) {
commandList.add("-i");
commandList.add(selectedVideos.get(i).getLocation());
if (!isVideoHaveAudioTrack(selectedVideos.get(i).getPath())) {
isAnyMuteVideo = true;
}
if (i == selectedVideos.size() - 1) {
if (isAnyMuteVideo) {
commandList.add("-i");
commandList.add(silencedAudio);
}
}
String str6 = str3 + "[" + i + ":v]fps=25,scale=w=min(iw*" + "1280" + "/ih\," + "720" + "):h=min(" +
"1280" + "\,ih*" + "720" + "/iw), pad=w=" + "720" +
":h=" + "1280" + ":x=( " + "720" + "-iw)/2:y=(" + "1280" + "-ih)/2,format=yuv420p,setsar=1,setpts=PTS-STARTPTS[v" + i + "];";
if (isVideoHaveAudioTrack(selectedVideos.get(i).getPath())) {
str4.append("[").append(i).append(":a]aformat=channel_layouts=stereo:sample_rates=44100,asetpts=PTS-STARTPTS[a").append(i).append("];");
str5.append("[v").append(i).append("][a").append(i).append("]");
} else {
str4.append("[").append(selectedVideos.size()).append(":a]aformat=channel_layouts=stereo:sample_rates=44100,asetpts=PTS-STARTPTS[a").append(selectedVideos.size()).append("];");
str5.append("[v").append(i).append("][a").append(selectedVideos.size()).append("]");
}
str3 = str6;
}
commandList.add("-filter_complex");
commandList.add(str3 + str4 + str5 + "concat=n=" + selectedVideos.size() + ":v=1:a=1[v][a]");
commandList.add("-map");
commandList.add("[v]");
commandList.add("-map");
commandList.add("[a]");
commandList.add("-c:v");
commandList.add("libx264");
commandList.add("-c:a");
commandList.add("aac");
commandList.add("-preset");
commandList.add("ultrafast");
commandList.add(filepath);
return commandList;
}
试试这个,告诉我们这是否适用于您的ffmpeg日志,以便我们可以通过改进上面的答案来帮助您。