Question

I have a class written using QTKit that reads and creates QuickTime movie files. My function to add an audio track to a movie, which works just fine on Snow Leopard, does not work on Lion or Mountain Lion. The audio information does appear in "Show Movie Inspector" in the QuickTime Player, and the movie is the correct duration. However, the audio is inaudible upon movie playback. Here is my code that works great in 10.6, but not 10.7 or 10.8:

// here's the code that creates the exported movie
NSString *filePath = [NSString stringWithUTF8String:"Foo.mov"];
NSError *errorPtr;
qtMovie = [[QTMovie alloc] initToWritableFile:filePath error:&errorPtr];

// and now here is my function to add an audio track
bool PLQTMovie::addSoundTrack(const std::string &fileName, const long long srcStartTime, const long long srcEndTime, const long long dstStartTime)
{
  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

  NSString *file = [NSString stringWithUTF8String:fileName.c_str()];
  NSError *errorPtr = nil;
  QTMovie *audioMovie = [QTMovie movieWithFile:file error:&errorPtr];

  NSArray *tracks = [audioMovie tracksOfMediaType:QTMediaTypeSound];
  if([tracks count] == 0)
    return false;

  QTTrack *soundTrack = [tracks objectAtIndex:0];
  QTMedia *media = [soundTrack media];
  NSValue *durationValue = [media attributeForKey:QTMediaDurationAttribute];
  QTTime soundTrackTime;
  [durationValue getValue:&soundTrackTime];
  long audioScale = soundTrackTime.timeScale;

  long long srcDuration = 0;
  if(srcEndTime < 0) // use entire source track duration
  {
    srcDuration = soundTrackTime.timeValue;
  }
  else
  {
    srcDuration = srcEndTime - srcStartTime;
  }

  QTTime startTime = QTMakeTime(srcStartTime, audioScale);
  QTTime srcDurationTime = QTMakeTime(srcDuration, audioScale);
  QTTimeRange srcTimeRange = QTMakeTimeRange(startTime, srcDurationTime);
  QTTime dstTime = QTMakeTime(dstStartTime, audioScale);

  QTTrack *audioTrack = [(QTMovie*)qtMovie insertSegmentOfTrack:soundTrack timeRange:srcTimeRange atTime:dstTime];

  [pool drain];

  return true;
}

I know that Apple encourages transitioning from QTKit to AV Foundation, but the old QTKit code should still work. I'm at a loss as to what I should be doing differently here. Any ideas?

Was it helpful?

Solution

Don't know if this will help, but we had a similar problem and the answer turned out to be that you need to flatten the movie after adding the audio.

Basically, we had to write the movie to a tmp file, then export that with [QTMovie writeToFile:withAttributes:error] with an attribute of QTMovieFlatten set to YES.

Hope this helps, so I can start to pay back some of the great tips/answers I've gotten here.

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