如何使用 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);
}
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实证明,在将对它的引用传递给
MovieAudioExtractionFillBuffer
之前,必须先设置numFrames
。It turns out that
numFrames
has to be set before passing a reference to it toMovieAudioExtractionFillBuffer
.