bytedeco/javacv

Audio and Video not syncing properly when combining multiple cut videos

Open

#2,164 opened on Jan 3, 2024

View on GitHub
 (1 comment) (0 reactions) (0 assignees)Java (1,583 forks)batch import
help wantedquestion

Repository metrics

Stars
 (6,985 stars)
PR merge metrics
 (No merged PRs in 30d)

Description

Hi, I have this issue where I first take multiple .mp4 videos, cut them and combine them after. The video comes out fine until the audio part... All videos have same frame rate and codecs... but somehow the audio is out of sync.

If i execute this without audio, the video is 41 seconds: `FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFilePath, 1920, 1080); recorder.setFrameRate(30); recorder.setFormat("mp4");

		    recorder.setAudioChannels(2); 
		    recorder.setSampleRate(44100); 
		    recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC); 
		    recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
		    recorder.setVideoBitrate(10_000_000); 

		    recorder.start(); 
		    
		    Frame videoFrame;	  
		    for (FFmpegFrameGrabber videoGrabber : videoGrabbers) {
		        videoGrabber.start();    		           		        
		        while ((videoFrame = videoGrabber.grabFrame(false, true, true, false)) != null) { 
		        	recorder.record(videoFrame);
				}									
			}
			recorder.stop();
		    recorder.release();`

if i change it to while ((videoFrame = videoGrabber.grabFrame(true, true, true, false)) != null) , the video is 53 seconds and the video stops exactly at 41s...

Why is the length of the audio bigger than the video part? Any fix?

In case it might be related this is how I get the cut videos :

`FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(video); grabber.start();

	    int frameRate = 30;

	    // Set output resolution to Full HD (1920x1080)
	    int frameWidth = 1920;
	    int frameHeight = 1080;
	     		    
	    long segmentDurationFrames = frameRate * new Random().nextInt(2, 14);
	    long framesPerSegment = 0;
	    int segmentIndex = 0;

	    FFmpegFrameRecorder recorder = null;

	    int vid = Integer.parseInt(new File(video).getName().toString().substring(3, 4));

	    Frame frame;
	    while ((frame = grabber.grabFrame()) != null) {
	        if (recorder == null) {    		        	
	            recorder = new FFmpegFrameRecorder(outputDirectory + "segment_" + vid + "_" + segmentIndex + ".mp4",
	                    frameWidth, frameHeight);
	            recorder.setFrameRate(frameRate);
	            recorder.setFormat("mp4");
	            
	            recorder.setAudioChannels(2); 
    		    recorder.setSampleRate(44100); 
    		    recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC); 
    		    recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
    		    recorder.setVideoBitrate(10_000_000); 

	            recorder.start();
	            
	            segmentDurationFrames = frameRate * new Random().nextInt(2, 14);
	        }    		            		          		        
	        
	        recorder.record(frame);
	        framesPerSegment++;    		           		        

	        if (framesPerSegment >= segmentDurationFrames || grabber.getTimestamp() >= grabber.getLengthInTime()) {
	            recorder.stop();
	            recorder.release();
	            recorder = null;
	            segmentIndex++;
	            framesPerSegment = 0;
	            		            
	            videoNumber.put(vid, videoNumber.get(vid)+1);
	        }
	    }

	    grabber.stop();
	    grabber.release();`

Contributor guide