6

Starting from just a CAF audio recording, I need to create a video file where the video track is just empty frames, and the audio track is this audio recording file. I know it's a strange use case, and that's probably why I can't find information on how to do it. I'm trying to use an AVMutableComposition, but I cannot figure out how to get it to work.

Here is what I have right now:

AVMutableComposition *composition = [AVMutableComposition composition];    

/* soundFilePath is the path to the CAF audio file */
AVURLAsset *audioAsset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:soundFilePath] options:nil];
CMTimeRange fullTime = CMTimeRangeMake(kCMTimeZero, [audioAsset duration]);
AVAssetTrack *sourceAudioTrack = [[audioAsset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];

/* Add audio track */
AVMutableCompositionTrack *compositionAudioTrack = [composition addMutableTrackWithMediaType:AVMediaTypeAudio preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionAudioTrack insertTimeRange:fullTime ofTrack:sourceAudioTrack atTime:kCMTimeZero error:nil];

/* docsDir is defined previously as the path to where I want to save the file */
NSString *videoFilePath = [docsDir stringByAppendingPathComponent:@"video.mov"];
NSURL *videoFileURL = [NSURL fileURLWithPath:videoFilePath];

AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset:composition presetName:AVAssetExportPresetHighestQuality];

exporter.outputFileType = AVFileTypeQuickTimeMovie;
exporter.outputURL = videoFileURL;

[exporter exportAsynchronouslyWithCompletionHandler:nil];

What this gets me is a .mov file which does contain the audio, but no video. I need the file to have some sort of video content - just empty video frames. I'm very new to all of these iOS libraries, so all of the code above is basically just cobbled together from various examples and I certainly don't have a complete understanding of how all this is supposed to work.

I also tried adding an AVMutableVideoComposition to my AVMutableComposition in case that is the correct approach. In order to do that, I added a blank video track to the AVMutableComposition in the same way I added the audio track:

/* Add video track */
AVMutableCompositionTrack *compositionVideoTrack = [composition addMutableTrackWithMediaType:AVMediaTypeVideo preferredTrackID:kCMPersistentTrackID_Invalid];
[compositionVideoTrack insertEmptyTimeRange:fullTime];

Then I created and configured an AVMutableVideoComposition like so:

AVMutableVideoComposition *videoComposition = [AVMutableVideoComposition videoComposition];
videoComposition.frameDuration = [audioAsset duration];
videoComposition.renderScale = 1.0;
videoComposition.renderSize = CGSizeMake(320, 240);
AVMutableVideoCompositionInstruction *instruction = [AVMutableVideoCompositionInstruction videoCompositionInstruction];
AVMutableVideoCompositionLayerInstruction *layerInstruction = [AVMutableVideoCompositionLayerInstruction videoCompositionLayerInstructionWithAssetTrack:compositionVideoTrack];
instruction.layerInstructions = [NSArray arrayWithObject:layerInstruction];
instruction.timeRange = compositionVideoTrack.timeRange;

videoComposition.instructions = [NSArray arrayWithObject:instruction];

And finally, added the AVMutableVideoComposition to the AVMutableComposition:

exporter.videoComposition = videoComposition;

However, with this approach, I get nothing. No video file is created. I put a log statement in the completion handler for the export and it does complete, but no video file is created.

Any help on this would be greatly appreciated. Thank you!

andr
  • 15,970
  • 10
  • 45
  • 59
user2041338
  • 211
  • 3
  • 6
  • 2
    I have never had any luck with adding Empty space to a video composition, what I have done is I create a 1 second clip of solid black and add that to the video track instead of using the empty time range thing. give that a shot, I have done extensive work with AVFoundation for a recent project, and its a pain! – box86rowh Feb 05 '13 at 20:14
  • also, when creating your instructions, they cannot overlap or have even 1 frame of gap in the timeline or it will break. – box86rowh Feb 05 '13 at 20:15
  • 1
    For a start frameDuration is the duration of one frame, (eg 1/25s or 1/29.97s) not the entire clip duration. I'm suspecting that since you haven't set a duration for the VideoComposition (I assume default is 0), it doesn't have anything to insert. PS I'm looking for how to add some black frames to the end of my AVMutableComposition. – silicontrip Jun 22 '20 at 08:31

0 Answers0