javacv将图像和mp3合并在一起,创建的mp4比原来的mp3长

javacv将图像和mp3合并在一起,创建的mp4比原来的mp3长,java,video,mp3,mp4,javacv,Java,Video,Mp3,Mp4,Javacv,我正在使用以下代码合并mp3和图像 IplImage ipl = cvLoadImage(path2ImageFile); int height = ipl.height(); int width = ipl.width(); if(height%2!=0) height = height+1; if(width%2!=0) width = width+1; OpenCVFrameConverter.ToIplImage grabberConverter = new OpenCVFrameCo

我正在使用以下代码合并mp3和图像

IplImage ipl = cvLoadImage(path2ImageFile);
int height = ipl.height();
int width = ipl.width();
if(height%2!=0) height = height+1;
if(width%2!=0) width = width+1;

OpenCVFrameConverter.ToIplImage grabberConverter = new OpenCVFrameConverter.ToIplImage();  
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(path2OutputFile,width,height); 
FrameGrabber audioFileGrabber = new FFmpegFrameGrabber(path2AudioFile);
try 
{  
    audioFileGrabber.start();

    recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264 );//AV_CODEC_ID_VORBIS
    recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);//AV_CODEC_ID_MP3 //AV_CODEC_ID_AAC

    recorder.setFormat("mp4");  
    recorder.setAudioChannels(2);
    recorder.start();  

    Frame frame = null;
    //audioFileGrabber.getFrameNumber()
    while ((frame = audioFileGrabber.grabFrame())!=null) 
    {   recorder.record(grabberConverter.convert(ipl));  
        recorder.record(frame);
    }

    recorder.stop();  
    audioFileGrabber.stop();
 }  
这将产生一个mp4,但它大约长1.5分钟。
为什么会发生这种情况?

有什么办法可以解决这个问题吗?

是一个很好的问题。在国际海事组织看来,这些问题似乎有两个原因

  • 在这种情况下,视频的帧速率需要与音频的帧速率相同,这样就不会增加时间
  • 写入时的音频帧应以相同的时间戳写入
下面是我的最终代码

import org.bytedeco.ffmpeg.global.*;
导入org.bytedeco.javacv.*;
公共课音频示例{
公共静态void main(字符串[]args){
String path2ImageFile=“WhatsApp Image 2018-12-29 at 21.54.58.jpeg”;
字符串path2OutputFile=“test.mp4”;
字符串路径2audiofile=“GMV\u M\u Brice\u English\u Greeting-Menus.mp3”;
FFmpegFrameGrabber imageFileGrabber=新的FFmpegFrameGrabber(路径2图像文件);
FFmpegFrameGrabber audioFileGrabber=新的FFmpegFrameGrabber(路径2音频文件);
试一试{
audioFileGrabber.start();
imageFileGrabber.start();
FFmpegFrameRecorder记录器=新的FFmpegFrameRecorder(路径2输出文件,
imageFileGrabber.getImageWidth(),imageFileGrabber.getImageHeight();
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);//AV_CODEC_ID_VORBIS
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);//AV_CODEC_ID_MP3//AV_CODEC_ID_AAC
setSampleRate(audioFileGrabber.getSampleRate());
setFrameRate(audioFileGrabber.getAudioFrameRate());
录像机。设置视频质量(1);
记录器.setFormat(“mp4”);
录音机。设置音频通道(2);
recorder.start();
Frame=null;
Frame imageFrame=imageFileGrabber.grab();
而((frame=audioFileGrabber.grab())!=null){
记录器。设置时间戳(帧。时间戳);
记录器。记录(图像帧);
记录器。记录(帧);
}
录音机。停止();
audioFileGrabber.stop();
imageFileGrabber.stop();
}捕获(FrameRecorder.Exception | FrameGrabber.Exception e){
e、 printStackTrace();
}
}
}
我删除了opencv for image,因为我们还可以使用另一个framegrabber来获取作为帧的图像。您还可以看到生成的音频与mp3大小相同

尝试#2 由于第一次尝试对视频和音频使用相同的帧速率,这导致了一些问题,因此我考虑固定帧速率,然后在顶部交错音频

import org.bytedeco.ffmpeg.global.*;
导入org.bytedeco.javacv.*;
公共课音频示例{
公共静态void main(字符串[]args){
String path2ImageFile=“/Users/tarunlalwani/Downloads/WhatsApp Image 2018-12-29 at 21.54.58.jpeg”;
字符串path2OutputFile=“/Users/tarunlalwani/Downloads/test.mp4”;
字符串路径2audiofile=“/Users/tarunlalwani/Downloads/GMV_M_Brice_English_Greeting-Menus.mp3”;
FFmpegFrameGrabber imageFileGrabber=新的FFmpegFrameGrabber(路径2图像文件);
FFmpegFrameGrabber audioFileGrabber=新的FFmpegFrameGrabber(路径2音频文件);
试一试{
audioFileGrabber.start();
imageFileGrabber.start();
FFmpegFrameRecorder记录器=新的FFmpegFrameRecorder(路径2输出文件,
imageFileGrabber.getImageWidth(),imageFileGrabber.getImageHeight();
recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);//AV_CODEC_ID_VORBIS
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);//AV_CODEC_ID_MP3//AV_CODEC_ID_AAC
setSampleRate(audioFileGrabber.getSampleRate());
整数帧率=30;
记录器。设置帧速率(帧速率);
记录器.setFormat(“mp4”);
录音机。设置音频通道(2);
recorder.start();
Frame=null;
Frame imageFrame=imageFileGrabber.grab();
int frames=(int)((audioFileGrabber.getLengthInTime()/1000000f)*帧率)+1;
int i=0;
//使用固定图像和帧速率创建视频

而(i++这额外的1.5分钟包含什么(例如:任何图片或声音)?谢谢。它在VLC中工作,但在标准windows media player中可以听到声音,但屏幕是黑色的。我正在使用winows 10。我没有windows进行测试。这可能与选择的视频编解码器有关吗?在javacv论坛上,他们说可能与我录制的帧数少或太多有关。我应该这样做只记录与最大帧速率相同的帧数,显然setFrameRate函数设置了最大帧速率。实际帧速率是在实际使用setTimestamp设置帧时设置的。我仍然很难理解这一切不幸的是:(生成的视频…工作和不工作取决于…我不知道具体是什么…:(很多事情都不清楚,因为没有任何文件表明你最好这样做或那样做。这更多的是通过hit n学习trial@Para,请参阅更新后的答案。我希望新代码能帮助您解决问题。您可以在此代码中使用固定帧速率