我有一个奇怪的问题。我正在捕获一些.mov/.wav/.aiff文件的音频样本以播放它们。 我使用以下代码捕获未更改的PCM样本(如果可用),否则将它们转换为32位浮点型。AVAssetReader音频捕获,样本丢失
NSError *error = nil;
AVAssetReader *assetReader= [[[AVAssetReader alloc] initWithAsset:self.movieAsset error:&error] autorelease];
NSArray *audioTracks=[movieAsset tracksWithMediaType:AVMediaTypeAudio];
AVAssetReaderTrackOutput* audioReaderOutput=nil;
AVAssetTrack *mainAudioTrack = nil;
CMTimeRange audioRange;
if ([audioTracks count]) {
mainAudioTrack=[audioTracks objectAtIndex:0];
audioRange = mainAudioTrack.timeRange;
CMTimeRange readingRange = CMTimeRangeMake(kCMTimeZero,audioRange.duration);
assetReader.timeRange = readingRange;
NSArray* formatDesc = mainAudioTrack.formatDescriptions;
if ([formatDesc count]) {
CMAudioFormatDescriptionRef item = (CMAudioFormatDescriptionRef)[formatDesc objectAtIndex:0];
const AudioStreamBasicDescription* pcmAudioDescription = CMAudioFormatDescriptionGetStreamBasicDescription (item);
NSDictionary * outputSettings;
memcpy(&audioDescription,pcmAudioDescription,sizeof(AudioStreamBasicDescription));
if (pcmAudioDescription->mFormatID != kAudioFormatLinearPCM) {
// Resample
outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
[NSNumber numberWithFloat:pcmAudioDescription->mSampleRate], AVSampleRateKey,
[NSNumber numberWithInt:pcmAudioDescription->mChannelsPerFrame], AVNumberOfChannelsKey,
[NSNumber numberWithInt:32], AVLinearPCMBitDepthKey,
[NSNumber numberWithBool:YES], AVLinearPCMIsFloatKey,
nil];
audioDescription.mFormatID = kAudioFormatLinearPCM;
audioDescription.mBitsPerChannel = 32;
audioDescription.mFramesPerPacket = 1;
audioDescription.mChannelsPerFrame = pcmAudioDescription->mChannelsPerFrame;
audioDescription.mBytesPerFrame = audioDescription.mBitsPerChannel/8 * audioDescription.mChannelsPerFrame;
audioDescription.mBytesPerPacket = audioDescription.mFramesPerPacket * audioDescription.mBytesPerFrame;
audioDescription.mFormatFlags = kAudioFormatFlagIsFloat;
} else {
outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,
nil];
audioDescription.mFormatID = kAudioFormatLinearPCM;
}
audioReaderOutput=[[[AVAssetReaderTrackOutput alloc]
initWithTrack:mainAudioTrack
outputSettings:outputSettings] autorelease];
if([assetReader canAddOutput:audioReaderOutput]) [assetReader addOutput:audioReaderOutput];
else audioReaderOutput = nil;
}
}
if (audioReaderOutput) {
if([assetReader startReading]==YES){
CMSampleBufferRef buffer = 0;
NSTimeInterval duration = 0.0;
while([assetReader status]==AVAssetReaderStatusReading){
if (audioReaderOutput != nil) {
buffer=[audioReaderOutput copyNextSampleBuffer];
if (buffer) {
CMTime sampleDuration = CMSampleBufferGetDuration (buffer);
CMTime currentSampleTime = CMSampleBufferGetOutputPresentationTimeStamp (buffer);
MovieSample* sample = [[[MovieSample alloc] init] autorelease];
sample.sampleTime = currentSampleTime;
sample.sampleBuffer = buffer;
sample.sampleDuration = sampleDuration;
[self.audioStore addObject:sample];
//NSLog(@"Adding sample %lld %lld %f %f",currentSampleTime.value,sampleDuration.value,currentOutputSampleTime.value/(NSTimeInterval)currentOutputSampleTime.timescale,
// (currentOutputSampleTime.value+sampleDuration.value)/(NSTimeInterval)currentOutputSampleTime.timescale);
NSLog(@"Received PCM buffer with [TIMESTAMP:%.1fms]", CMTimeGetSeconds(currentSampleTime) * 1000);
NSLog(@"Buffer contains [SAMPLES:%ld]", CMSampleBufferGetNumSamples(buffer));
NSLog(@"Buffer contains [DURATION:%.1fms] worth of audio", CMTimeGetSeconds(sampleDuration) * 1000);
duration += CMTimeGetSeconds(CMSampleBufferGetDuration(buffer));
}
}
}
NSLog(@"Total samples duration: %f", duration);
NSLog(@"Total track reported duration: %f", audioRange.duration.value/(NSTimeInterval)audioRange.duration.timescale);
}
else {
DLog(@"could not start Audio reading asset.");
DLog(@"reader status: %ld", [assetReader status]);
}
}
现在奇怪的是,无论我开什么文件时,它总是在文件中错过了一些样品。 下面的循环http://www.vvertex.com/loop.wav有无论是从无畏和音频轨道持续时间,mainAudioTrack.timeRange报告为3.75的持续时间,而我的代码打印样品长度和播放抵消转储:3.657120
这是转储FrameDecoder [665:303] FrameDecoder [665:303] FrameDecoder [665:303]缓冲区包含:[TIMESTAMP:0.0ms]接收到的PCM缓冲区:
2014-03-06 10:48:15.721 FrameDecoder [665:303] FrameDecoder [665:303]缓冲包含[DURATION:185.8ms]的音频 2014-03-06 10:48:15.721 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:185.8ms] 2014-03-06 10:48:15.721 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]缓冲区包含[样本:8192] 2014-03-06 10:48:15.721 FrameDecoder [665:303]的音频信号 2014-03-06 10:48:15.722 FrameDecoder [665:303] FrameDecoder [665:303]缓冲区包含[SAMPLES :8192] 2014-03-06 10:48:15.722 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]的音频帧解码器[665:303]接收到的PCM缓冲区包含[TIMESTAMP:557.3ms]缓冲区包含[SAMPLES:8192] BufferDecoder [665:303] BufferDecoder [665:303]缓冲区包含[包含[DURATION:185.8ms]的音频 2014-03-06 10:4 8:15.723 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10收到的带有[TIMESTAMP:743.0ms]的PCM缓冲区 2014-03-06 10:48:15.723 FrameDecoder [665:303] :48:15.723 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]的音频 2014-03-06 10:48:15.723 FrameDecoder [665:303]收到的带有[TIMESTAMP:928.8ms]的PCM缓冲区 2014 -03-06 10:48:15.726 FrameDecoder [665:303]缓冲液含有[样品:8192] 2014年3月6日 10:48:15.726 FrameDecoder [665:303]缓冲液含有[DURATION:185.8ms]音频的值得帧解码器[665:303]缓冲器包含[样本:8192] ] 2014-03-06 10:48:15.727 FrameDecoder [665:303] Buffer contains [TIMERAMP:1300.3ms]收到的PCM缓冲器[TIMER:185.8ms] 2014-03-06 10:48:15.727 FrameDecoder [665:303] FrameDecoder [665 :303]缓冲器包含[时间:185.8ms]缓冲器包含[样品:8192] 2014-03-06 10:48:15.727 FrameDecoder [665:303] FrameDecoder [665:303]收到的PCM缓冲区[TIMESTAMP:1486.1ms] 2014-03-06 10:48:15.728 FrameDecoder [665:303]缓冲区包含[SAMPLES:8192] 2014-03-06 10:48:15.728 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]的音频 2014-03-06 10:48:15.728 FrameDecoder [665:303]收到的PCM缓冲区为[TIMESTAMP:1671.8ms] 2014-03-06 10:48:15.728 FrameDecoder [665:303]缓冲区包含[SAMPLES:8192] 2014年3月6日10:48:15.728 FrameDecoder [665:303]缓冲液含有[DURATION:185.8ms]值得音频 2014年3月6日10:48:15.728 FrameDecoder [665:303]所获PCM缓冲液[ TIMESTAMP:1857.6ms] 2014-03-06 10:48:15。729 FrameDecoder [665:303] BufferDecoder [665:303]缓冲器包含[DURATION:185.8ms]的音频 2014-03-06 10:48:15.729 FrameDecoder [665:303] 48:15.729 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10收到的带有[TIMESTAMP:2043.4ms]的PCM缓冲区 2014-03-06 10:48:15.729 FrameDecoder [665:303] :48:15.729帧解码器[665:303]缓冲器包含[时长:185.8ms]的音频 2014-03-06 10:48:15.729帧解码器[665:303]收到的PCM缓冲器与[TIMESTAMP:2229.1ms] 2014 -03-06 10:48:15.730 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]的音频缓冲区包含[样本:8192] 2014-03-06 10:48:15.730 FrameDecoder [665:303] 2014-03-06 10:48:15.730 FrameDecoder [665:303]收到的PCM bu帧解码器[665:303]缓冲器包含[样本:8192] 2014-03-06 10:48:15.730帧解码器[665:303]缓冲器包含[DURATION:185.8ms]的音频 2014-03-06 10:48:15.731 FrameDecoder [665:303]收到的PCM缓冲区[TIMESTAMP:2600.6ms] 2014-03-06 10:48:15.731 FrameDecoder [ 665:303]缓冲区包含[DATE:185.8ms]缓冲区包含[DATE:185.8ms] 2014-03-06 10:48:15 FrameDecoder [665:303]收到的PCM缓冲区[TIMESTAMP:2786.4ms] 2014-03-06 10:48:15.731 FrameDecoder [665:303]缓冲区包含[SAMPLES:8192] 2014-03-06 10:48: 15.731 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]的音频 2014-03-06 10:48:15.732 FrameDecoder [665:303] FrameDecoder [665:303]缓冲区包含[SAMPLES:8192 ] 2014-03-06 10:48:15.732 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]的音频数据FrameDecoder [665:303]帧解码器[665:303]缓冲器包含[样本:8192] 2014-03-06 10:48:15.733帧解码器[665:303]帧频解码器[665:303]收到的PCM缓冲器与[TIMESTAMP:3343.7ms] 2014-03-06 10:48:15.733帧解码器[665:303.7ms]价值的音频 2014-03-06 10:48:15.733 FrameDecoder [ 303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.733 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]的音频 2014-03-06 10:48:15.733 FrameDecoder [665:303]收到的PCM缓冲区[TIMESTAMP:3529.4ms] 2014-03-06 10:48:15.734 FrameDecoder [665:303]缓冲区包含[DURATION:127.7ms]的音频 2014-03缓冲区包含[样本:5631] 2014-03-06 10:48:15.734 FrameDecoder [665:303] -06 10:48:15.734 FrameDecoder [665:303]总样本持续时间:3.657120 2014-03-06 10:48:15.734 FrameDecoder [665:303]总的曲目报告的持续时间:3.750000
任何人都会遇到一个奇怪的像这样的问题?我已经尝试了几个音频文件以及具有不同压缩的.mov文件。相同的东西!我完全沉迷于此!
此外,当我通过AudioUnits打样品,它的接缝什么有效缺少的是从样品的开始....
谢谢!
附加说明,AVReaderWriterOSX样品有同样的问题,它轧液音频采样的初始部分!这是否意味着AVAssetReader不好翻录音频样本? –