AVFoundation Programming GuidePlayback文档格式.docx
- 文档编号:22335533
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:17
- 大小:91.57KB
AVFoundation Programming GuidePlayback文档格式.docx
《AVFoundation Programming GuidePlayback文档格式.docx》由会员分享,可在线阅读,更多相关《AVFoundation Programming GuidePlayback文档格式.docx(17页珍藏版)》请在冰豆网上搜索。
我们能够使用存在的资源(asset)初始化一个playeritem对象,或者直接使用URL初始化playeritem以致于我们能够在特定的位置进行播放资源(resource),这里AVPlayerItem将根据给定点的resource创建并配置一个asset。
就AVAsset来说,简单的初始化playeritem对象,并不一定意味着准备好立马进行播放,我们可以使用观测者来观察playeritem的status属性来确定是否playeritem已经准备好播放。
HandlingDifferentTypesofAsset
配置资源(asset)进行播放的方式取决于我们使用的是哪种类型的资源(asset),一般来说,这里有两种类型:
基于文件的资源(file-basedassets),这些文件我们可以随意访问(比如:
本地文件,照相机,媒体库),另外一种类型是基于流的资源(stream-basedassets)(HTTPLiveStreamingformat).
为了加载并播放file-basedassets,这里有一些步骤:
1:
使用AVURLAsset创建一个asset
2:
使用刚刚创建的asset来创建AVPlayerItem实例
3:
使用AVPlayerItem实例来初始化AVPlayer
4:
等待AVPlayerItem的status属性指示准备播放
该方法的具体实现将在后续PuttingItAllTogether:
PlayingaVideoFileUsingAVPlayerLayer部分解释。
为了创建和准备HTTPlivestream用于播放,通过制定URL来初始化AVPlayerItem类(这里不能够直接创建AVAsset实例来来呈现媒体内容在HTTPLiveStream中)
[objc]viewplaincopy在CODE上查看代码片派生到我的代码片
NSURL*url=[NSURLURLWithString:
@"
<
#LivestreamURL#>
];
//Youmayfindateststreamat<
self.playerItem=[AVPlayerItemplayerItemWithURL:
url];
[playerItemaddObserver:
selfforKeyPath:
status"
options:
0context:
&
ItemStatusContext];
self.player=[AVPlayerplayerWithPlayerItem:
playerItem];
当我们为player关联playeritem的时候,已经开始准备播放了,当准备开始播放的时候,playeritem将创建AVAsset和AVAssetTrack实例,可以使用这些事例检测流媒体(livestream)的内容。
为了获取流媒体对象(streamingitem)时间,我们能够观察playeritem的duration属性。
当playeritem准备播放,该属性将为流媒体更新到正确的值。
注意:
使用playeritem的duration属性要求iOS4.3或之后,可以使用观察者模式,观察属性status,当playeritem的status属性状态变为AVPlayerItemStatusReadyToPlay,duration能够使用下面代码获取:
[[[[[playerItemtracks]objectAtIndex:
0]assetTrack]asset]duration];
如果我们想简单的播放流媒体(livestream),我们能够直接使用URL创建player对象进行播放,如下:
[javascript]viewplaincopy在CODE上查看代码片派生到我的代码片
self.player=[AVPlayerplayerWithURL:
[playeraddObserver:
PlayerStatusContext];
就assets和playeritems来说,初始化player并不意味着准备播放,我们应该观察status属性,当属性变为AVPlayerItemStatusReadyToPlay就说明准备播放了,我们也可以观察currentItem属性来获取为流媒体(stream)创建的playeritem对象。
如果你并不知道你有什么类型的URL,可以使用如下步骤:
尝试着使用URL初始化AVURLAsset,这时候加载AVURLAsset的trackskey值,如果加载tracks成功,这时候能够为asset创建一个playeritem对象。
如果第一步失败,直接使用URL创建AVPlayerItem并观察status属性来确定是否可以播放
以上两种方法任意一种成功,我们将使用playeritem对象创建player。
PlayinganItem
为了开始播放,我们可以调用player的play方法:
-(IBAction)play:
(UIButton*)sender{
[playerplay];
}
除了简单播放之外,我们可以管理播放的各个方面,比如:
播放是速度和播放头的位置。
我们也可以监控player播放的状态情况。
更多可以看:
MonitoringPlayback
ChangingthePlaybackRate
我们能够通过设置player的rate属性来改变播放的速度:
aPlayer.rate=0.5;
aPlayer.rate=2.0;
该值为1.0意味这currentitem是以正常的速度进行播放,设置rate为0.0相当于停止播放,也就是使用AVplayer的pause方法。
AVplayeritem支持倒退播放(reverseplayback),我们能够设置rate属性为负值来设置倒退播放的速度。
我们能够使用playerItem的相关属性确定倒退播放的类型。
如:
canPlayReverse(supportsaratevalueof-1.0),canPlaySlowReverse(supportsratesbetween0.0and1.0)andcanPlayFastReverse(supportsratevalueslessthan-1.0).
Seeking—RepositioningthePlayhead
为了移动播放头到特定的时间,我们经常使用seekToTime:
方法,如下:
CMTimefiveSecondsIn=CMTimeMake(5,1);
[playerseekToTime:
fiveSecondsIn];
seekToTime:
方法用于调整操作而不精确,如果我们想精确进行移动,我们需要使用seekToTime:
toleranceBefore:
toleranceAfter:
方法:
fiveSecondsIntoleranceBefore:
kCMTimeZerotoleranceAfter:
kCMTimeZero];
使用容忍度为0可能要求框架编码大量的数据,我们使用zero的情况:
例如,写复杂的媒体编辑应用并要求精准的控制。
在播放之后,播放头将显示在playeritem的最后并且进一步调用play播放方法无效。
为了使用播放头的位置回到最item的开始,我们能够注册通知接受AVPlayerItemDidPlayToEndTimeNotification通知,在通知的回调中,我们调用seekToTime:
方法并使用kCMTimeZero作为参数。
//Registerwiththenotificationcenteraftercreatingtheplayeritem.
[[NSNotificationCenterdefaultCenter]
addObserver:
self
selector:
@selector(playerItemDidReachEnd:
)
name:
AVPlayerItemDidPlayToEndTimeNotification
object:
#Theplayeritem#>
-(void)playerItemDidReachEnd:
(NSNotification*)notification{
[playerseekToTime:
PlayingMultipleItems
我们能够使用一个AVQueuePlayer对象来播放序列中的多个items。
AVQueuePlayer是AVplayer的子类,我们使用playeritem数组来初始化queueplayer:
NSArray*items=<
#Anarrayofplayeritems#>
;
AVQueuePlayer*queuePlayer=[[AVQueuePlayeralloc]initWithItems:
items];
这时候我们能够使用play方法播放queue,就像一个AVPlayer对象,queueplayer将轮流播放每一个item,如果我们想跳过下一个item,我们可以向列队发送advanceToNextItem信息。
我们还可以使用insertItem:
afterItem:
removeItem:
andremoveAllItems等方法来修改列队(queue),当我们添加一个新的item的时候,首先我们需要确认该item是否能够被插入到列队中,使用canInsertItem:
.方法,我们为第二个参数传入nil来测试新的item是否能够加入列队。
AVPlayerItem*anItem=<
#Getaplayeritem#>
if([queuePlayercanInsertItem:
anItemafterItem:
nil]){
[queuePlayerinsertItem:
nil];
MonitoringPlayback
我们能够监控许多方面,包括播放者(player)呈现的状态和playeritem播放时的状态,状态的改变是非常有用但是这种改变并不是在我们的控制之下。
如果用户使用多任务并在不同的应用之间进行切换,player的rate属性将下降到0.0
如果我们正在播放远程媒体内容,随着越来越多的可用数据,playeritem的loadedTimeRanges和seekableTimeRanges属性将随着更多数据变得可使用而发生改变。
这些属性告诉我们playeritem的时间轴(timeline)是可以使用了。
playeritem创建使用了HTTP流媒体(HTTPlivestream),player的currentItem属性将改变
当正在播放HTTPlivestream的时候,playeritem的tracks属性可能改变。
比如:
当流媒体(stream)为内容提供了不同的编码;
或者player切换到不同的编码,tracks将改变
5:
如果playback由于某些原因失败,player或者playeritem的status属性可能改变。
我们能够使用key-valueobserving来检测属性的改变。
我们应该在主线程注册KVO改变通知和移除KVO改变通知,如果改变是发生在其他线程并发主线程,这可以避免接收部分通知的可能性。
AVFoundation将在主线程调用observeValueForKeyPath:
ofObject:
change:
context:
,即使是在其它线程发生改变。
RespondingtoaChangeinStatus
当player或者playeritem的状态改变,将发送观察改变通知,如果一个对象由于某些原因不能够播放(例如:
媒体服务被重置),播放状态将改变为AVPlayerStatusFailed或AVPlayerItemStatusFailed.在这种情况,对象的error属性的值将描述错误的原因。
AVFoundation并不能够指定通知发送的线程,如果我们想更新用户界面,必须确保任意相关的代码在主线程调用。
可以使用dispatch_async如下:
-(void)observeValueForKeyPath:
(NSString*)keyPathofObject:
(id)object
(NSDictionary*)changecontext:
(void*)context{
if(context==<
#Playerstatuscontext#>
){
AVPlayer*thePlayer=(AVPlayer*)object;
if([thePlayerstatus]==AVPlayerStatusFailed){
NSError*error=[<
#TheAVPlayerobject#>
error];
//Respondtoerror:
forexample,displayanalertsheet.
return;
}
//Dealwithotherstatuschangeifappropriate.
//Dealwithotherchangenotificationsifappropriate.
[superobserveValueForKeyPath:
keyPathofObject:
object
change:
changecontext:
context];
TrackingReadinessforVisualDisplay
我们能够观察AVPlayerLayer对象的readyForDisplay属性接受当layer已经显示用户视觉内容的通知,在特定情景中,我们能够插入playerlayer到layertree中,执行相应的过渡动画到用户所关注的内容。
TrackingTime
为了跟踪AVPlayer对象播放头位置的改变,我们能够使用addPeriodicTimeObserverForInterval:
queue:
usingBlock:
或者addBoundaryTimeObserverForTimes:
方法。
根据时间的消耗和时间的剩余更新用户的界面,或者执行一些其它用户界面同步操作。
addPeriodicTimeObserverForInterval:
方法中的block将在我们所指定的具体时间调用,如果时间跳过,播放开始或停止
addBoundaryTimeObserverForTimes:
方法,我们传递一个数组,数组中的值是包含结构体CMTime的NSValue对象,block将在任意指定值到达时进行。
上面两个方法都将返回一个不透明对象作为观察者。
只要我们想player能够调用时间观察者的block,我们必须保持强引用返回值。
我们也必须在适当的时候调用removeTimeObserver:
方法进行去除。
对于上面两个方法,AVFoundation并不能够保证block在每一次间歇时间或者指定时间到达时调用。
如果前面执行的block并没有完成那么AVFoundation并不会调用block,因此,我们必须确保我们所执行的block并不会对系统造成过大的影响。
//Assumeaproperty:
@property(strong)idplayerObserver;
Float64durationSeconds=CMTimeGetSeconds([<
#Anasset#>
duration]);
CMTimefirstThird=CMTimeMakeWithSeconds(durationSeconds/3.0,1);
CMTimesecondThird=CMTimeMakeWithSeconds(durationSeconds*2.0/3.0,1);
NSArray*times=@[[NSValuevalueWithCMTime:
firstThird],[NSValuevalueWithCMTime:
secondThird]];
self.playerObserver=[<
#Aplayer#>
timesqueue:
NULLusingBlock:
^{
NSString*timeDescription=(NSString*)
CFBridgingRelease(CMTimeCopyDescription(NULL,[self.playercurrentTime]));
NSLog(@"
Passedaboundaryat%@"
timeDescription);
}];
ReachingtheEndofanItem
我们能够注册通知AVPlayerItemDidPlayToEndTimeNotificationnotification,当playeritem完成播放。
[[NSNotificationCenterdefaultCenter]addObserver:
#Theobserver,typicallyself#>
@selector(<
#Theselectorname#>
name:
object:
#Aplayeritem#>
PuttingItAllTogether:
PlayingaVideoFileUsingAVPlayerLayer
简短的代码就能够解释怎样使用AVPlayer对象播放videofile,明白几点:
配置一个view来使用AVPlayerLayerlayer
创建一个AVPlayer对象
创建一个AVPlayerItem对象基于文件的asset并且使用key-valueobserving观察status属性状态变化
根据playeritem的响应准备播放
播放item并在播放完成使播放头回到最开始位置
为了集中于大多数相关代码,该例子将省略完整应用的几个部分,比如:
内存管理和去除观察者。
ThePlayerView
为了播放视觉内容,我们需要一个view来包含
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- AVFoundation Programming Guide Playback