gpt4 book ai didi

iphone - 提取 iPod 库原始 PCM 样本并播放音效

转载 作者:太空狗 更新时间:2023-10-30 03:31:18 24 4
gpt4 key购买 nike

我正在尝试从 iPod 库中的 MP3 中提取原始 PCM 样本,以便我可以播放歌曲并控制音高、速度和应用声音效果(例如过滤器)。我已经走上了 AVPlayer 和 AVAudioPlayer 的道路,它们根本不允许对播放进行太多控制。

下面的代码是我目前为止得到的。我现在不知道如何处理 while 循环中的 CMSampleBufferRef,因为我不知道要使用哪个框架来播放音频和应用此类效果。

知道实现此目标的最佳方法是什么吗?我已经查看了使用 AVAssetWriter 转换文件的情况,但这对我来说并不适用,因为这个过程太耗时了。当然,我可以直接将 PCM 样本读入内存进行播放,而不必先将它们写入磁盘吗?

注意:我知道下面的代码引用了项目中的 mp3,但我知道这种方法的工作方式与从 MPMediaPropertyAssetURL 中提取 NSURL 的效果相同


-(IBAction)loadTrack:(id)sender {

NSString *songPath = [[NSBundle mainBundle] pathForResource:@"Smooth_Sub Focus_192" ofType:@"mp3"];
NSURL *assetURL = [[NSURL alloc] initFileURLWithPath:songPath];

AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:assetURL options:nil];

NSError *assetError = nil;
AVAssetReader *assetReader = [[AVAssetReader assetReaderWithAsset:songAsset
error:&assetError] retain];
if (assetError) {
NSLog (@"Error: %@", assetError);
return;
}

AVAssetReaderOutput *assetReaderOutput = [[AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks
audioSettings: nil] retain];
if (![assetReader canAddOutput:assetReaderOutput]) {
NSLog (@"Incompatible Asser Reader Output");
return;
}

[assetReader addOutput: assetReaderOutput];
[assetReader startReading];

CMSampleBufferRef nextBuffer;
while (nextBuffer = [assetReaderOutput copyNextSampleBuffer]) {
/* What Do I Do Here? */
}

[assetReader release];
[assetReaderOutput release];

}

最佳答案

我正在自己的代码中做类似的事情。以下方法为 AVURLAsset 返回一些 NSData:

- (NSData *)extractDataForAsset:(AVURLAsset *)songAsset {

NSError * error = nil;
AVAssetReader * reader = [[AVAssetReader alloc] initWithAsset:songAsset error:&error];

AVAssetTrack * songTrack = [songAsset.tracks objectAtIndex:0];
AVAssetReaderTrackOutput * output = [[AVAssetReaderTrackOutput alloc] initWithTrack:songTrack outputSettings:nil];
[reader addOutput:output];
[output release];

NSMutableData * fullSongData = [[NSMutableData alloc] init];
[reader startReading];

while (reader.status == AVAssetReaderStatusReading){

AVAssetReaderTrackOutput * trackOutput = (AVAssetReaderTrackOutput *)[reader.outputs objectAtIndex:0];
CMSampleBufferRef sampleBufferRef = [trackOutput copyNextSampleBuffer];

if (sampleBufferRef){
CMBlockBufferRef blockBufferRef = CMSampleBufferGetDataBuffer(sampleBufferRef);

size_t length = CMBlockBufferGetDataLength(blockBufferRef);
UInt8 buffer[length];
CMBlockBufferCopyDataBytes(blockBufferRef, 0, length, buffer);

NSData * data = [[NSData alloc] initWithBytes:buffer length:length];
[fullSongData appendData:data];
[data release];

CMSampleBufferInvalidate(sampleBufferRef);
CFRelease(sampleBufferRef);
}
}

if (reader.status == AVAssetReaderStatusFailed || reader.status == AVAssetReaderStatusUnknown){
// Something went wrong. Handle it.
}

if (reader.status == AVAssetReaderStatusCompleted){
// You're done. It worked.
}

[reader release];

return [fullSongData autorelease];
}

我建议在后台线程上执行此操作,因为它很耗时。

这种方法的一个缺点是整首歌曲都加载到内存中,这当然是有限的。

关于iphone - 提取 iPod 库原始 PCM 样本并播放音效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4796643/

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