zhuguang123 发表于 2023-11-4 14:51

使用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秒
应该是时间戳的位置或是最后循环的那段需要修改 但是百度了很久都没找到解决方案
有无大佬接触过的

一闪一闪233 发表于 2023-11-4 15:04

如果你想增加帧率(例如,从30fps增加到60fps),那么你需要在每两帧之间插入一个新的帧。这个新的帧可以通过插值得到,比如,它可以是前一帧和后一帧的平均。

反过来,如果你想降低帧率(例如,从60fps降低到30fps),那么你需要丢弃一些帧。一个简单的方法是每丢弃一帧,保留一帧。

zhuguang123 发表于 2023-11-4 16:17

一闪一闪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]
查看完整版本: 使用javacv调用ffmpeg转码视频修改帧率导致播放时长和速度与原视频不一致的问题