如何解决使用javacv将AVI文件导出到碎片mp4时如何获得正确的sample_aspect_ratio和display_aspect_ratio
我有一个 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 举报,一经查实,本站将立刻删除。