使用javacv调用ffmpeg转码视频修改帧率导致播放时长和速度与原视频不一致的问题
FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(inputFilePath);grabber.start();
int audioChannels = grabber.getAudioChannels();
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFilePath, width, height, audioChannels);
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H265); // 设置视频编码为H.265
recorder.setFormat("mpegts");
recorder.setFrameRate(targetFrameRate);
recorder.setVideoBitrate(15000000); // 设置视频比特率,根据需要调整
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P); // 设置像素格式
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
recorder.setSampleRate(grabber.getSampleRate());
recorder.setAudioBitrate(grabber.getAudioBitrate());
recorder.setTimestamp(grabber.getTimestamp());
recorder.start();
Frame frame;
// 转码并记录每一帧
while (Objects.nonNull((frame = grabber.grabFrame()))) {
recorder.record(frame);
}
recorder.stop();
grabber.stop();
转码前后的视频如果帧率一致就没有问题
如果修改帧率的话就会导致视频播放速度变快,从而导致视频时长也会缩小10秒
应该是时间戳的位置或是最后循环的那段需要修改 但是百度了很久都没找到解决方案
有无大佬接触过的 如果你想增加帧率(例如,从30fps增加到60fps),那么你需要在每两帧之间插入一个新的帧。这个新的帧可以通过插值得到,比如,它可以是前一帧和后一帧的平均。
反过来,如果你想降低帧率(例如,从60fps降低到30fps),那么你需要丢弃一些帧。一个简单的方法是每丢弃一帧,保留一帧。 一闪一闪233 发表于 2023-11-4 15:04
如果你想增加帧率(例如,从30fps增加到60fps),那么你需要在每两帧之间插入一个新的帧。这个新的帧可以通 ...
while ((frame = grabber.grabFrame()) != null) {
if (previousTimestamp != -1) {
// 计算时间基准调整因子
double timeBaseAdjustment = (double) targetFrameRate / originalFrameRate;
// 调整时间戳
frame.timestamp = (long) (previousTimestamp + (frame.timestamp - previousTimestamp) * timeBaseAdjustment);
}
previousTimestamp = frame.timestamp;
recorder.record(frame);
// 插入额外帧以匹配目标帧率
double frameInterval = 1.0 / targetFrameRate;
double currentTime = frame.timestamp / 1000000.0;
double nextFrameTime = currentTime + frameInterval;
while (nextFrameTime < currentTime) {
Frame interpolatedFrame = interpolateFrames(frame, previousFrame, nextFrameTime);
recorder.record(interpolatedFrame);
nextFrameTime += frameInterval;
}
previousFrame = frame.clone();
}
改成这样还是没用 不知道怎么修改了
页:
[1]