gpt4 book ai didi

ios - AVAssetWriter 如何写入降采样/压缩的 m4a/mp3 文件

转载 作者:可可西里 更新时间:2023-11-01 03:13:38 28 4
gpt4 key购买 nike

我正在尝试获取本地 m4a 或 mp3 文件并压缩/下采样该文件(为了制作更小的文件)。

最初,我使用 AVAssetExportSession 将 AVAsset 导出到临时目录,但我无法控制压缩/下采样(您只能使用预设,其中只有 .wav 文件格式支持质量下降)。

然后,按照此处关于 SO 的几个示例,我尝试使用 AVAssetReader/AVAssetWriter 来执行此“导出”。

我这样创建我的读者/作者:

NSString *exportPath = [NSHomeDirectory() stringByAppendingPathComponent:@"out.m4a"];

NSURL *exportURL = [NSURL fileURLWithPath:outPath];

// reader
NSError *readerError = nil;
AVAssetReader *reader = [[AVAssetReader alloc] initWithAsset:asset
error:&readerError];

AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
AVAssetReaderTrackOutput *readerOutput = [[AVAssetReaderTrackOutput alloc] initWithTrack:track
outputSettings:nil];
[reader addOutput:readerOutput];

// writer
NSError *writerError = nil;
AVAssetWriter *writer = [[AVAssetWriter alloc] initWithURL:exportURL
fileType:AVFileTypeAppleM4A
error:&writerError];

AudioChannelLayout channelLayout;
memset(&channelLayout, 0, sizeof(AudioChannelLayout));
channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;

// use different values to affect the downsampling/compression
NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt: kAudioFormatMPEG4AAC], AVFormatIDKey,
[NSNumber numberWithFloat:44100.0], AVSampleRateKey,
[NSNumber numberWithInt:2], AVNumberOfChannelsKey,
[NSNumber numberWithInt:128000], AVEncoderBitRateKey,
[NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey,
nil];

AVAssetWriterInput *writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeAudio
outputSettings:outputSettings];
[writerInput setExpectsMediaDataInRealTime:NO];
[writer addInput:writerInput];

然后我开始写...

[writer startWriting];
[writer startSessionAtSourceTime:kCMTimeZero];

[reader startReading];
dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);
[writerInput requestMediaDataWhenReadyOnQueue:mediaInputQueue usingBlock:^{

NSLog(@"Asset Writer ready : %d", writerInput.readyForMoreMediaData);
while (writerInput.readyForMoreMediaData) {
CMSampleBufferRef nextBuffer;
if ([reader status] == AVAssetReaderStatusReading && (nextBuffer = [readerOutput copyNextSampleBuffer])) {
if (nextBuffer) {
NSLog(@"Adding buffer");
[writerInput appendSampleBuffer:nextBuffer];
}
} else {
[writerInput markAsFinished];

switch ([reader status]) {
case AVAssetReaderStatusReading:
break;
case AVAssetReaderStatusFailed:
[writer cancelWriting];
break;
case AVAssetReaderStatusCompleted:
NSLog(@"Writer completed");
[writer endSessionAtSourceTime:asset.duration];
[writer finishWriting];

NSData *data = [NSData dataWithContentsOfFile:exportPath];
NSLog(@"Data: %@", data);
break;
}
break;
}
}
}];

当我写完后,我应该写入 exportURL 的数据为空,并且作者报告成功完成。有什么想法可能会出错吗?

Update 调用appendSampleBuffer:后writer的状态是AVAssetWriterStatusFailed,而readers的状态是successful,似乎读完了整个文件。

最佳答案

我遇到了解决方案:

NSString *exportPath = [NSHomeDirectory() stringByAppendingPathComponent:@"out.m4a"] 中使用 NSHomeDirectory() 导致作者无法创建文件。不确定为什么,或者我需要做什么才能让它工作,但是将 NSHomeDirectiory() 更改为 NSTemporaryDirectory() 同时解决了我的问题。

关于ios - AVAssetWriter 如何写入降采样/压缩的 m4a/mp3 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13056978/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com