以下代码正常,但输出文件比输入短.
例如,输入文件的持续时间为1:59,但输出1:50且音频内容相同.
- (voID)reverse:(AVAsset *)asset{AVAssetReader* reader = [[AVAssetReader alloc] initWithAsset:asset error:nil];AVAssetTrack* audioTrack = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];NSMutableDictionary* audioReadSettings = [NSMutableDictionary dictionary];[audioReadSettings setValue:[NSNumber numberWithInt:kAudioFormatlinearPCM] forKey:AVFormatIDKey];AVAssetReaderTrackOutput* readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:audioTrack outputSettings:audioReadSettings];[reader addOutput:readerOutput];[reader startReading];NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithInt: kAudioFormatMPEG4AAC],AVFormatIDKey,[NSNumber numberWithfloat:44100.0],AVSampleRateKey,[NSNumber numberWithInt:2],AVNumberOfChannelsKey,[NSNumber numberWithInt:128000],AVEncoderBitRateKey,[NSData data],AVChannelLayoutKey,nil];AVAssetWriterinput *writerinput = [[AVAssetWriterinput alloc] initWithMediaType:AVMediaTypeAudio outputSettings:outputSettings];Nsstring *exportPath = [NstemporaryDirectory() stringByAppendingPathComponent:@"out.m4a"];NSURL *exportURL = [NSURL fileURLWithPath:exportPath];NSError *writerError = nil;AVAssetWriter *writer = [[AVAssetWriter alloc] initWithURL:exportURL fileType:AVfileTypeAppleM4A error:&writerError];[writerinput setExpectsMediaDataInRealTime:NO];[writer addinput:writerinput];[writer startWriting];[writer startSessionAtSourceTime:kCMTimeZero];CMSampleBufferRef sample = [readerOutput copyNextSampleBuffer];NSMutableArray *samples = [[NSMutableArray alloc] init];while (sample != NulL) { sample = [readerOutput copyNextSampleBuffer]; if (sample == NulL) continue; [samples addobject:(__brIDge ID)(sample)]; CFRelease(sample);}NSArray* reversedSamples = [[samples reverSEObjectEnumerator] allObjects];for (ID reversedSample in reversedSamples) { if (writerinput.readyForMoreMediaData) { [writerinput appendSampleBuffer:(__brIDge CMSampleBufferRef)(reversedSample)]; } else { [NSThread sleepForTimeInterval:0.05]; }}[writerinput markAsFinished];dispatch_queue_t queue = dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_HIGH,0);dispatch_async(queue,^{ [writer finishWriting];});}
更新:
如果我在第一个while循环中直接写样本 – 一切正常(即使使用writerinput.readyForMoreMediaData检查).在这种情况下,结果文件与原始文件的持续时间完全相同.但如果我从反向NSArray中写出相同的样本 – 结果会更短.
解决方法 以样本数打印每个缓冲区的大小(通过“读取”readOuput while循环),并在“写入”writerinput for循环中重复.这样您就可以看到所有缓冲区大小,看看它们是否相加.例如,如果(writerinput.readyForMoreMediaData)为false,您是“睡眠”,但是然后进入reverseSamples中的下一个reversedSample(缓冲区有效地从writerinput中删除),您是丢失还是跳过缓冲区?
更新(根据评论):
我在代码中发现,有两个问题:
>输出设置不正确(输入文件为单声道(1声道),但输出设置配置为2声道.应该是:[NSNumber numberWithInt:1],AVNumberOfChannelsKey.查看输出和输入文件的信息:
>第二个问题是您正在反转8192个音频样本的643个缓冲区,而不是反转每个音频样本的索引.为了查看每个缓冲区,我改变了调试,从查看每个样本的大小到查看缓冲区的大小,即8192.因此,第76行现在是:size_t sampleSize = CMSampleBufferGetNumSamples(sample);
输出如下:
2015-03-19 22:26:28.171 audioReverse[25012:4901250] Reading [0]: 81922015-03-19 22:26:28.172 audioReverse[25012:4901250] Reading [1]: 8192...2015-03-19 22:26:28.651 audioReverse[25012:4901250] Reading [640]: 81922015-03-19 22:26:28.651 audioReverse[25012:4901250] Reading [641]: 81922015-03-19 22:26:28.651 audioReverse[25012:4901250] Reading [642]: 50562015-03-19 22:26:28.651 audioReverse[25012:4901250] Writing [0]: 50562015-03-19 22:26:28.652 audioReverse[25012:4901250] Writing [1]: 8192...2015-03-19 22:26:29.134 audioReverse[25012:4901250] Writing [640]: 81922015-03-19 22:26:29.135 audioReverse[25012:4901250] Writing [641]: 81922015-03-19 22:26:29.135 audioReverse[25012:4901250] Writing [642]: 8192
这表明您正在颠倒8192个样本的每个缓冲区的顺序,但在每个缓冲区中,音频仍然“朝前”.我们可以在这个屏幕截图中看到这一点,我采用了正确的反转(逐个样本)与缓冲区逆转:
我认为如果你还反转每个8192缓冲区的每个样本,你的当前方案都可以工作.我个人不建议使用NSArray枚举器进行信号处理,但如果你在样本级别 *** 作它可以工作.
总结以上是内存溢出为你收集整理的iOS反向音频通过AVAssetWriter全部内容,希望文章能够帮你解决iOS反向音频通过AVAssetWriter所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)