19期_AVFoundation-AVAssetReader

2023-09-27  本文已影响0人  萧修

AVAssetReader用于从AVAsset实例中读取媒体样本

NSError *error;
AVAssetReader *reader = [[AVAssetReader alloc]initWithAsset:asset error:&error]; //创建读取
if (!reader) {
    NSLog(@"%@",[error localizedDescription]);
}

最后向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;
    }
上一篇 下一篇

猜你喜欢

热点阅读