问题描述
我有一个 AVI movie file(h264 编码),我想使用 JavaCV 将其导出为一个碎片化的 MP4 文件。从 ffprobe 命令的输出可以看出,此电影文件的显示纵横比与样本纵横比不同:
ffprobe -show_streams Bureau.avi
导致(为简洁起见显示部分结果)
.
.
Duration: 00:00:31.00,start: 0.000000,bitrate: 1014 kb/s
Stream #0:0: Video: h264 (High) (H264 / 0x34363248),yuv420p(progressive),720x576 [SAR 4320:3037 DAR 5400:3037],1010 kb/s,25 fps,25 tbr,25 tbn,50 tbc
.
.
sample_aspect_ratio=4320:3037
display_aspect_ratio=5400:3037
.
.
使用 ffmpeg 命令转换此视频文件时
ffmpeg -i Bureau.avi -vf scale='trunc(ih*dar):ih',setsar=1/1 -frag_duration 1 -movflags empty_moov+default_base_moof+frag_keyframe Bureau_scaled_fragmented.mp4
mp4 文件的 ffprobe 结果是(为简洁起见,部分输出)
.
.
Duration: 00:00:31.00,bitrate: 416 kb/s
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661),yuv420p,1024x576 [SAR 1:1 DAR 16:9],414 kb/s,12800 tbn,50 tbc (default)
.
.
sample_aspect_ratio=1:1
display_aspect_ratio=16:9
.
.
使用 VLC 播放此视频文件时,视频的纵横比正确。
我希望能够通过使用 JavaCV 库(当前使用版本 1.5.5,但使用以下小型 Java 程序未成功,在该程序中我尝试使用 FfmpegFrameFilter 按原样缩放每个帧)被抓取。该程序确实导致生成一个mp4文件,但使用例如VLC播放时视频的纵横比不正确。ffprobe命令的结果还显示缺少SAR和DAR:
Duration: 00:00:31.00,bitrate: 383 kb/s
Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661),720x576,357 kb/s,25600 tbc (default)
.
.
sample_aspect_ratio=N/A
display_aspect_ratio=N/A
.
.
是否可以使用这样的帧过滤器(或通过任何其他方式)来缩放视频,以便产生的 sample_aspect_ratio 和 display_aspect_ratio 与使用 ffmpeg 命令时相同?
正在使用的 Java 程序。
import org.bytedeco.ffmpeg.global.avcodec;
import org.bytedeco.javacv.FFmpegFrameFilter;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.Frame;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class App {
public static void main(String[] args) throws IOException {
File file = new File("/Users/werk/projects/video/bureau.avi");
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(file.getAbsolutePath());
String fileName = null;
Frame captured_frame = null;
FFmpegFrameRecorder recorder = null;
try {
frameGrabber.start();
fileName = file.getAbsolutePath().replace(".avi","_edited.mp4");
recorder = new FFmpegFrameRecorder(fileName,frameGrabber.getimageWidth(),frameGrabber.getimageHeight(),frameGrabber.getAudioChannels());
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setVideoCodecName("avc");
recorder.setFormat("mp4");
// enable fragmented mp4 generation
Map<String,String> options = new HashMap<>();
options.put("frag_duration","1");
options.put("movflags","empty_moov+default_base_moof+frag_keyframe");
recorder.setoptions(options);
recorder.setFrameRate(frameGrabber.getFrameRate());
FFmpegFrameFilter filter = new FFmpegFrameFilter("scale='trunc(ih*dar):ih',setsar=1/1",frameGrabber.getimageHeight());
filter.start();
recorder.start();
while (true) {
try {
captured_frame = frameGrabber.grabFrame();
if (captured_frame == null) {
break;
}
filter.push(captured_frame);
Frame scaledFrame = filter.pull();
recorder.record(scaledFrame);
} catch (Exception e) {
e.printstacktrace();
}
}
recorder.stop();
recorder.release();
frameGrabber.stop();
filter.stop();
} catch (Exception e) {
e.printstacktrace();
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)