Alex Rivera | Logout

How to write a movie with video AND audio using AVAssetWriter?

Asked 2011-03-30T02:36:34.630
21

I want to export a movie with AVAssetWriter and can't figure out how to include video and audio tracks in sync. Exporting only video works fine, but when I add audio the resulting movie looks like this:

First I see the video (without audio), then the video freezes (showing the last image frame until the end) and after some seconds I hear the audio.

I tried some things with CMSampleBufferSetOutputPresentationTimeStamp (subtracting the first CMSampleBufferGetPresentationTimeStamp from the current) for the audio, but it all didn't work and I don't think it is the right direction, since video & audio in the source movie should be in sync anyway...

My setup in short: I create an AVAssetReader and 2 AVAssetReaderTrackOutput (one for video, one for audio) and add them to the AVAssetReader, then I create an AVAssetWriter and 2 AVAssetWriterInput (video & audio) and add them to the AVAssetWriter... I start it all up with:

[assetReader startReading];
[assetWriter startWriting];
[assetWriter startSessionAtSourceTime:kCMTimeZero];

Then I run 2 queues for doing the sample buffer stuff:

dispatch_queue_t queueVideo=dispatch_queue_create("assetVideoWriterQueue", NULL);
[assetWriterVideoInput requestMediaDataWhenReadyOnQueue:queueVideo usingBlock:^
{
     while([assetWriterVideoInput isReadyForMoreMediaData])
     {
         CMSampleBufferRef sampleBuffer=[assetReaderVideoOutput copyNextSampleBuffer];
         if(sampleBuffer)
         {
             [assetWriterVideoInput appendSampleBuffer:sampleBuffer];
             CFRelease(sampleBuffer);
         } else
         {
             [assetWriterVideoInput markAsFinished];
             dispatch_release(queueVideo);
             videoFinished=YES;
             break;
         }
     }
}];

dispatch_queue_t queueAudio=dispatch_q
Edit
Report

1 Answer

-3

It seams that assetWriterAudioInput ignores sample buffer time for audio writing. Do this way.

1) Write video track.

2) When done, mark it finished i.e. [videoWriterInput markAsFinished];

3) do [assetWriter startSessionAtSourceTime:timeRangeStart];

3) instantiate audio reader and start writing audio.

answered 2013-06-17T07:57:59.447

Your Answer