2

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

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);
}
4

1 回答 1

1

事实证明,numFrames必须在将引用传递给MovieAudioExtractionFillBuffer.

于 2011-02-19T20:22:03.833 回答