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

发布于 2024-10-18 06:38:40 字数 2616 浏览 5 评论 0原文

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

I'm trying to extract the raw audio from a movie using QTKit so I can draw a waveform. I'm using the following code but all of my output frames are zero. Any ideas about what I might be doing wrong? (you can also download the project here: 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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神经大条 2024-10-25 06:38:40

事实证明,在将对它的引用传递给 MovieAudioExtractionFillBuffer 之前,必须先设置 numFrames

It turns out that numFrames has to be set before passing a reference to it to MovieAudioExtractionFillBuffer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文