我有一个奇怪的问题。我正在捕获.mov / .wav / .aiff文件的一些音频样本来播放它们。 我使用以下代码捕获未更改的PCM样本(如果可用),否则将它们转换为32位浮点数。
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的持续时间从Audacity和音频轨道持续时间mainAudioTrack.timeRange报告为3.75,而打印样本长度和播放偏移量的代码转储为:3.657120
这是转储:
2014-03-06 10:48:15.721 FrameDecoder [665:303]收到带有[TIMESTAMP:0.0ms]的PCM缓冲区 2014-03-06 10:48:15.721 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.721 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]缓冲区包含[样本:8192] 2014-03-06 10:48:15.721 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.722 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:371.5ms] 2014-03-06 10:48:15.722 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.722 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.722 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:557.3ms] 2014-03-06 10:48:15.722 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.722 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.723 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:743.0ms] 2014-03-06 10:48:15.723 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.723 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.723 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:928.8ms] 2014-03-06 10:48:15.726 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.726 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.727 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:1114.6ms] 2014-03-06 10:48:15.727 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.727 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.727 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:1300.3ms] 2014-03-06 10:48:15.727 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.727 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.727 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:1486.1ms] 2014-03-06 10:48:15.728 FrameDecoder [665:303]缓冲区包含[样本: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]缓冲区包含[样本: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:1857.6ms] 2014-03-06 10:48:15.729 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.729 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.729 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:2043.4ms] 2014-03-06 10:48:15.729 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.729 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.729 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:2229.1ms] 2014-03-06 10:48:15.730 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.730 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.730 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:2414.9ms] 2014-03-06 10:48:15.730 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.730 FrameDecoder [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]缓冲区包含[样本:8192] 2014-03-06 10:48:15.731 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.731 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:2786.4ms] 2014-03-06 10:48:15.731 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.731 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.732 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:2972.2ms] 2014-03-06 10:48:15.732 FrameDecoder [665:303]缓冲区包含[样本:8192] 2014-03-06 10:48:15.732 FrameDecoder [665:303]缓冲区包含[DURATION:185.8ms]音频 2014-03-06 10:48:15.732 FrameDecoder [665:303]收到PCM缓冲区[TIMESTAMP:3157.9ms] 2014-03-06 10:48:15.732 FrameDecoder [665: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:3343.7ms] 2014-03-06 10:48:15.733 FrameDecoder [665: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]缓冲区包含[样本:5631] 2014-03-06 10:48:15.734 FrameDecoder [665:303]缓冲区包含[DURATION:127.7ms]音频 2014-03-06 10:48:15.734 FrameDecoder [665:303]总样本持续时间:3.657120 2014-03-06 10:48:15.734 FrameDecoder [665:303]报道的总报道持续时间:3.750000
有人遇到过像这样的奇怪问题吗?我尝试过多个音频文件以及压缩不同的.mov文件。同样的东西!我完全坚持这个!
同样,当我通过AudioUnits播放样本时,它会发现实际上缺少的是从样本开始的那些......
谢谢!
答案 0 :(得分:0)
我的解决方法......
//starting 2 buffers before
[_reader setTimeRange:CMTimeRangeMake(CMTimeMake(-16384, samplerate), kCMTimeNegativeInfinity)];
//and
while ([_reader status] == AVAssetReaderStatusReading) {
CMSampleBufferRef sampleBufferRef = [_ringBufferReaderTrackOutput copyNextSampleBuffer];
if (sampleBufferRef){
CMTime t = CMSampleBufferGetOutputPresentationTimeStamp(sampleBufferRef);
if( t.value < 0 )
release, continue...
}
但我最后遗漏了4096个样本: - (