Question

I'm currently using AVAssetWriter to generate a Quicktime mov. The video track is generated correctly. Now I'd like to add a "garbage" mp4a audio track. The audio can just be white noise. What I'm mainly concerned with is the mov file containing both video and audio tracks.

How do I setup a CMSampleBufferRef that just contains white noise in mp4a format? Here's what I've tried so far:

CMSampleBufferRef garbageAudioSampleBuffer = NULL;

AudioStreamBasicDescription audioFormat;
audioFormat.mSampleRate = 44100;
audioFormat.mFormatID   = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFramesPerPacket = 1;
audioFormat.mChannelsPerFrame = 2;
audioFormat.mBitsPerChannel = 16;
audioFormat.mBytesPerPacket = 4;            
audioFormat.mBytesPerFrame = 4;

CMAudioFormatDescriptionRef audioFormatDescrip = NULL;
CMAudioFormatDescriptionCreate(kCFAllocatorDefault, 
                               &audioFormat, 
                               0, 
                               NULL,
                               0, 
                               NULL, 
                               NULL, 
                               &audioFormatDescrip
                               );

CMSampleBufferCreate(kCFAllocatorDefault, 
                     NULL,
                     YES, 
                     NULL, 
                     NULL, 
                     NULL, // audioFormatDescrip,
                     0,
                     0, 
                     NULL, 
                     0, 
                     NULL, 
                     &garbageAudioSampleBuffer
                     );

if(myAVAssetAudioWriterInput isReadyForMoreMediaData)
    [myAVAssetAudioWriterInput appendSampleBuffer:garbageAudioSampleBuffer];

When NULL is passed for the audioFormatDescrip the mov file is generated successfully but contains only a video track (and no audio track). When I actually pass audioFormatDescrip the mov file seems to be corrupted. I probably have to actually pass some samples but I'm not sure how.

Note: I've verified that appendSampleBuffer returns YES (for brevity I omitted that code).

Was it helpful?

Solution

There are a bunch of problems in your code:

  1. White noise has a statistical definition, you're creating undefined noise.
  2. You're not passing the audioFormatDescription to CMSampleBufferCreate
  3. You're complicating your life by using CMSampleBufferCreate instead of CMAudioSampleBufferCreateWithPacketDescriptions (you don't have packet descriptions, so just past null & 0)
  4. You need to say when your audio buffer is with a Presentation Time Stamp
  5. Your audio buffer is 0 frames long. That's too short.
  6. and finally, you need to keep adding audio buffers, enough for the whole duration of your film

CoreMedia code can be tricky because there are hundreds of arguments that need to be just right. For your purposes it may be a little too general, so why not get a loopable snippet of white noise and assemble it using an AVMutableComposition? This will give you a film & and an audio file which you can then zip together using another AVMutableComposition and an AVAssetExportSession.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top