AVAsset 是一个播放音频和视频的抽象类。
比较常用到的是它的子类 AVURLAsset ,通过 URL 实例化它。AVComposition 是用于时间编辑的。
要播放一个AVAsset实例,需要先初始化一个 AVPlayerItem 实例,使用 AVPlayerItem 去设置一些初始化状态(例如:timeRange),然后将 player item 提供给 AVPlayer 去播放。
AVAssetReader 望名知义,作用就是从 AVAsset 获取音频/视频数据。
AVAssetReader 能够让你:
- initWithAsset:error:
+ assetReaderWithAsset:error:
AVAssetReaderOutput 是一个抽象类,作用是从 AVAssetReader 里读取读取单一集合里多媒体的采样率。
可以使用 AVAssetReader 的addOutput:方法向 AVAssetReader里添加 AVAssetReaderOutput 的具体实现类来读取多媒体(音频/视频)数据。
AVAssetReaderAudioMixOutput 是 AVAssetReaderOutput 的子类,作用是读取 AVAssetReader 里的一个或者多个 Asset 混合后的音频采样率。采样率能够以默认的格式读取或者转化成其他的格式。
初始化方式有两种:
- initWithAudioTracks:audioSettings:
+ assetReaderAudioMixOutputWithAudioTracks:audioSettings:
CMFormatDescriptions 是 Core Foundation 的一个不可变对象,描述了各种各样的多媒体数据,包括音频、视频和混合多媒体数据。它有两种类型的API:media-type-agnostic 和 media-type-agnostic 。具体查看这里。
最后,放上一段播放 iPod 音频初始化的代码,仅供参考:
NSURL *asset_url = [NSURL URLWithString:ipodPath]; NSError *reader_error=nil; _asset = [AVURLAsset URLAssetWithURL:asset_url options:nil]; if (_asset == nil || [_asset URL] == nil ) { _errorCode = DECODE_ERROR_CODE_IPOD_PATH_ERROR; [self callBackOnPreDecode:PRE_DECODE_STATUS_FAIL]; return ; } _duration = _asset.duration; _assetReader =[AVAssetReader assetReaderWithAsset:_asset error:&reader_error]; if (reader_error) { NSLog(@"failed to creat asset reader,reason:%@",[reader_error description]); _errorCode = DECODE_ERROR_CODE_IPOD_DECODE_ERROR; [self callBackOnPreDecode:PRE_DECODE_STATUS_FAIL]; return ; } NSArray *asset_tracks=_asset.tracks; NSMutableArray *audio_asset_tracks = [[NSMutableArray alloc] initWithCapacity:asset_tracks.count]; for (int i=0; i< asset_tracks.count; i++) { AVAssetTrack *track = [asset_tracks objectAtIndex:0]; if ([track.mediaType isEqualToString:AVMediaTypeAudio]) { [audio_asset_tracks addObject:track]; } } if ([audio_asset_tracks count] < 1) { NSLog(@"no tracks"); _errorCode = DECODE_ERROR_CODE_IPOD_DECODE_ERROR; [self callBackOnPreDecode:PRE_DECODE_STATUS_FAIL]; return ; } _assetOutput = [AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:audio_asset_tracks audioSettings:nil]; if ([_assetReader canAddOutput:_assetOutput]) { [_assetReader addOutput:_assetOutput]; }else { NSLog(@"the reader can not add the output"); _errorCode = DECODE_ERROR_CODE_IPOD_DECODE_ERROR; [self callBackOnPreDecode:PRE_DECODE_STATUS_FAIL]; return ; } NSArray *formatDesc = ((AVAssetTrack*)[[_assetOutput audioTracks] objectAtIndex:0]).formatDescriptions; for (unsigned int i = 0; i < [formatDesc count]; ++i) { CMAudioFormatDescriptionRef item = (__bridge CMAudioFormatDescriptionRef)[formatDesc objectAtIndex:i]; const AudioStreamBasicDescription *asDesc = (AudioStreamBasicDescription*)CMAudioFormatDescriptionGetStreamBasicDescription(item); if (asDesc) { // get data streamDesc = *asDesc; break; } } [self callBackOnPreDecode:PRE_DECODE_STATUS_SUCCESS]; _seekTime = 0; _assetReader.timeRange = CMTimeRangeMake(CMTimeMakeWithSeconds(_seekTime, _asset.duration.timescale), kCMTimePositiveInfinity); [_assetReader startReading];