如何使用QTKit从电影中提取原始音频

时间:2011-02-18 23:28:19

标签: objective-c quicktime qtkit

我正在尝试使用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);
}

1 个答案:

答案 0 :(得分:1)

事实证明,在将numFrames的引用传递给MovieAudioExtractionFillBuffer之前,必须先设置{{1}}。