2011-02-18 416 views
2

我试图使用QTKit从电影中提取原始音频,以便绘制波形。我正在使用下面的代码,但我所有的输出帧都是零。有关我可能做错什么的想法? (你也可以在这里下载项目:http://richcollins.net/AudioSample.zip如何从使用QTKit的电影中提取原始音频

NSError *error; 

QTMovie *movie = [QTMovie movieWithFile:[[NSBundle mainBundle] pathForResource:@"Sosumi" ofType:@"aiff"] error:&error]; 

if(error) 
{ 
    NSLog(@"movieWithFile Error: %@", [error localizedDescription]); 
    exit(1); 
} 

OSStatus err = noErr; 

MovieAudioExtractionRef extractionSessionRef = nil; 
err = MovieAudioExtractionBegin([movie quickTimeMovie], 0, &extractionSessionRef); 

AudioStreamBasicDescription asbd; 
err = MovieAudioExtractionGetProperty(extractionSessionRef, 
             kQTPropertyClass_MovieAudioExtraction_Audio, 
             kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription, 
             sizeof (asbd), &asbd, nil); 

if (err) 
{ 
    NSLog(@"MovieAudioExtractionGetProperty Error: %i", err); 
    exit(1); 
} 

AudioBufferList *bufferList = calloc(1, sizeof(AudioBufferList) + asbd.mChannelsPerFrame*sizeof(AudioBuffer)); 
bufferList->mNumberBuffers = asbd.mChannelsPerFrame; 

QTTime duration = [[movie attributeForKey:QTMovieDurationAttribute] QTTimeValue]; 
long long estimatedFrameCount = (long long)ceil(((double)duration.timeValue*asbd.mSampleRate)/duration.timeScale); 

int i; 
for (i = 0; i < asbd.mChannelsPerFrame; i ++) 
{ 
    AudioBuffer audioBuffer = bufferList->mBuffers[i]; 
    audioBuffer.mNumberChannels = 1; 
    audioBuffer.mDataByteSize = estimatedFrameCount*sizeof(Float32); 
    audioBuffer.mData = calloc(1, estimatedFrameCount*sizeof(Float32)); 
    bufferList->mBuffers[i] = audioBuffer; 
} 

UInt32 numFrames; 
UInt32 flags; 
UInt32 actualFrameCount = 0; 

while (true) 
{ 
    err = MovieAudioExtractionFillBuffer(extractionSessionRef, &numFrames, bufferList, &flags); 
    if (err) 
    { 
     NSLog(@"MovieAudioExtractionFillBuffer Error: %i", err); 
     exit(1); 
    } 
    actualFrameCount += numFrames; 
    if (flags & kQTMovieAudioExtractionComplete) 
    { 
     NSLog(@"break"); 
     break; 
    } 
} 

for (i = 0; i < asbd.mChannelsPerFrame; i ++) 
{ 
    printf("channel %i\n", i); 
    Float32 *frames = (Float32 *)bufferList->mBuffers[i].mData; 
    int j; 
    for (j = 0; j < actualFrameCount; j ++) 
    { 
     printf("%f,", frames[j]); 
    } 
    printf("\n"); 
} 

err = MovieAudioExtractionEnd(extractionSessionRef); 
if (err) 
{ 
    NSLog(@"MovieAudioExtractionEnd Error: %i", err); 
    exit(1); 
} 

回答

1

事实证明,numFrames具有传递一个引用来MovieAudioExtractionFillBuffer前设置。