AVAssetReader用于从AVAsset实例中读取媒体样本
NSError *error;
AVAssetReader *reader = [[AVAssetReader alloc]initWithAsset:asset error:&error]; //创建读取
if (!reader) {
NSLog(@"%@",[error localizedDescription]);
}
- 设置Asset Reader的Outputs
AVAssetReaderTrackOutput:在创建asset reader之后,至少设置一个output来接受读取的媒体数据,
最后向AssetReader添加输出
AVAssetTrack *track = [[asset tracksWithMediaType:AVMediaTypeAudio] firstObject];//从媒体中得到声音轨道
//读取配置
NSDictionary *dic = @{AVFormatIDKey :@(kAudioFormatLinearPCM),
AVLinearPCMIsBigEndianKey:@NO,
AVLinearPCMIsFloatKey :@NO,
AVLinearPCMBitDepthKey :@(16)
};
//读取输出,在相应的轨道和输出对应格式的数
AVAssetReaderTrackOutput *output = [[AVAssetReaderTrackOutput alloc]initWithTrack:track outputSettings:dic];
[reader addOutput:output];
[reader startReading];
- 读取资产媒体数据
使用copyNextSampleBuffer
方法,从每个出口分别获取媒体数据,读取是一个持续的过程,每次只读取后面对应的大小的数据。
当读取的状态发生改变时,其status属性会发生对应的改变,我们可以凭此判断是否完成文件读取
while (reader.status == AVAssetReaderStatusReading) {
CMSampleBufferRef sampleBuffer = [output copyNextSampleBuffer]; //读取到数据
// recorder?.averagePower(forChannel: 0) ?? 0
if (sampleBuffer) {
CMBlockBufferRef blockBUfferRef = CMSampleBufferGetDataBuffer(sampleBuffer);//取出数据
size_t length = CMBlockBufferGetDataLength(blockBUfferRef); //返回一个大小,size_t针对不同的品台有不同的实现,扩展性更好
SInt16 sampleBytes[length];
CMBlockBufferCopyDataBytes(blockBUfferRef, 0, length, sampleBytes); //将数据放入数组
[data appendBytes:sampleBytes length:length]; //将数据附加到data中
CMSampleBufferInvalidate(sampleBuffer); //销毁
CFRelease(sampleBuffer); //释放
}
}
//状态完成,最终数据存在data中
if (reader.status == AVAssetReaderStatusCompleted) {
}else{
return nil;
}
网友评论