iOS AVPlayer(視頻播放)

AVPlayer

在iOS開發(fā)中,播放視頻通常有兩種方式,一種是使用MPMoviePlayerController(需要導(dǎo)入MediaPlayer.Framework),還有一種是使用AVPlayer。AVPlay既可以用來播放音頻也可以用來播放視頻,AVPlay在播放音頻方面可以直接用來播放網(wǎng)絡(luò)上的音頻。在使用AVPlay的時(shí)候我們需要導(dǎo)入AVFoundation.framework框架,再引入頭文件#import<AVFound
ation/AVFoundation.h>。

AVPlayer視頻播放

在開發(fā)中,單純的使用AVPlayer類是無法現(xiàn)實(shí)視頻的,要將視頻添加到AVPlayerLayer中,這樣才能將視頻現(xiàn)實(shí)出來,所以我們先在@interface中添加一下屬性

@property (strong, nonatomic)AVPlayer *myPlayer;//播放器
@property (strong, nonatomic)AVPlayerItem *item;//播放單元
@property (strong, nonatomic)AVPlayerLayer *playerLayer;//播放界面(layer)

我們簡(jiǎn)單介紹一下這三個(gè)屬性之間的關(guān)系吧
首先我們之所以能夠看到視頻是因?yàn)锳VPlayerLayer幫我們把視頻呈現(xiàn)出來了,可以說是AVPlayerLayer就是一個(gè)視頻播放器的載體,它負(fù)責(zé)需要播放的畫面。用MVC比喻,就是AVPlayerLayer屬于V層,負(fù)責(zé)對(duì)用戶的呈現(xiàn)。從AVPlayerLayer的便利構(gòu)造器方法中可以看出我們?cè)趧?chuàng)建一個(gè)AVPlayerLayer的時(shí)候需要一個(gè)AVPlayer類型的參數(shù)。所以在創(chuàng)建AVPlayerLayer的時(shí)候,我們需要先有一個(gè)AVPlayer,它用MVC來分類的話就相當(dāng)于MVC中的C層,負(fù)責(zé)播放單元和播放界面的協(xié)調(diào)工作,我們?cè)谒谋憷麡?gòu)造器方法中可以看到他需要我們傳入一個(gè)AVPlayerItem也就是播放單元,所謂的播放單元就是給播放器提供了一個(gè)數(shù)據(jù)的來源,用MVC來類比的話,它就屬于M層,在創(chuàng)建一個(gè)播放單元的時(shí)候,我們首先得需要一個(gè)網(wǎng)址。
綜上所述,將一個(gè)視頻播放出來可分為如下幾個(gè)步驟。
第一步:首先我們需要一個(gè)播放的網(wǎng)址

    NSURL *mediaURL = [NSURL URLWithString:@"http://baobab.wdjcdn.com”]

第二步:初始化一個(gè)播放單元

 self.item = [AVPlayerItem playerItemWithURL:mediaURL];

第三步:初始化一個(gè)播放器對(duì)象

self.myPlayer = [AVPlayer playerWithPlayerItem:self.item];

第四步:初始化一個(gè)播放器的Layer

self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.myPlayer];
self.playerLayer.frame = CGRectMake(0, 0, self.view.bounds.size.width, 500);
[self.view.layer addSublayer:self.playerLayer];

第五步:開始播放

[self.myPlayer play];

只要順序執(zhí)行上面的五個(gè)步驟,就可以將一個(gè)視頻播放到界面上。當(dāng)然現(xiàn)在還只是能夠播放了而已,要具體實(shí)現(xiàn)視頻的快進(jìn)快退功能,請(qǐng)繼續(xù)往下看。

AVPlayer視頻快進(jìn)快退

播放進(jìn)度 CMTime類型一般是用來表示視頻或者動(dòng)畫的時(shí)間類型。CMTime對(duì)象的Value屬性是用來得到當(dāng)前視頻或者動(dòng)畫一共有多少幀,timescale指的是每秒多少幀;timescale指的是每秒多少幀,value/timescale = 視頻的總時(shí)長(zhǎng)(秒)
視頻的快進(jìn)快退,首先我們聲明了兩個(gè)屬性

@property (strong, nonatomic)UISlider *avSlider;//用來現(xiàn)實(shí)視頻的播放進(jìn)度,并且通過它來控制視頻的快進(jìn)快退。
@property (assign, nonatomic)BOOL isReadToPlay;//用來判斷當(dāng)前視頻是否準(zhǔn)備好播放。

在這里我們將上面前四個(gè)步驟封裝到一個(gè)方法中,并且在這個(gè)方法中給播放單元也就是AVPlayerItem添加一個(gè)監(jiān)聽,來監(jiān)聽它的狀態(tài)。

-(void)avPlayerMethod{
//構(gòu)建播放網(wǎng)址
    NSURL *mediaURL = [NSURL URLWithString:@"http://baobab.wdjcdn.com/1455782903700jy.mp4"];
//構(gòu)建播放單元
    self.item = [AVPlayerItem playerItemWithURL:mediaURL];
//構(gòu)建播放器對(duì)象
    self.myPlayer = [AVPlayer playerWithPlayerItem:self.item];
//構(gòu)建播放器的layer
    self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.myPlayer];
    self.playerLayer.frame = CGRectMake(0, 66, self.view.bounds.size.width, 300);
    [self.view.layer addSublayer:self.playerLayer];
    //通過KVO來觀察status屬性的變化,來獲得播放之前的錯(cuò)誤信息
    [self.item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}

KVO的回調(diào)方法

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:
(NSDictionary<NSString *,id> *)change context:(void *)context{
    if ([keyPath isEqualToString:@"status"]) {
        //取出status的新值
        AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey]intValue];
        switch (status) {
            case AVPlayerItemStatusFailed:
                NSLog(@"item 有誤");
                self.isReadToPlay = NO;
                break;
            case AVPlayerItemStatusReadyToPlay:
                NSLog(@"準(zhǔn)好播放了");
                self.isReadToPlay = YES;
                self.avSlider.maximumValue = self.item.duration.value / self.item.duration.timescale;
                break;
            case AVPlayerItemStatusUnknown:
                NSLog(@"視頻資源出現(xiàn)未知錯(cuò)誤");
                self.isReadToPlay = NO;
                break;
            default:
                break;
        }
    }
    //移除監(jiān)聽(觀察者)
    [object removeObserver:self forKeyPath:@"status"];
}

視頻的播放按鈕

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(250, 600, 100, 100);
    button.backgroundColor = [UIColor redColor];
    [button setTitle:@"按鈕" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(playAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];

button的回調(diào)方法

- (void)playAction{
    if ( self.isReadToPlay) {
        [self.myPlayer play];
    }else{
        NSLog(@"視頻正在加載中");
    }
}

創(chuàng)建一個(gè)進(jìn)度條來控制視頻的進(jìn)度
使用懶加載的方式,將進(jìn)度條添加到View上面

- (UISlider *)avSlider{
    if (!_avSlider) {
        _avSlider = [[UISlider alloc]initWithFrame:CGRectMake(0, 55, self.view.bounds.size.width, 30)];
        [self.view addSubview:_avSlider];
    }return _avSlider;
}

在viewDidLoad中個(gè)slider(進(jìn)度條)添加一個(gè)回調(diào)。

[self.avSlider addTarget:self action:@selector(avSliderAction) forControlEvents:
UIControlEventTouchUpInside|UIControlEventTouchCancel|UIControlEventTouchUpOutside];

回調(diào)方法

- (void)avSliderAction{
    //slider的value值為視頻的時(shí)間
    float seconds = self.avSlider.value;
    //讓視頻從指定的CMTime對(duì)象處播放。
    CMTime startTime = CMTimeMakeWithSeconds(seconds, self.item.currentTime.timescale);
    //讓視頻從指定處播放
    [self.myPlayer seekToTime:startTime completionHandler:^(BOOL finished) {
        if (finished) {
            [self playAction];
        }
    }];
}

以上就是實(shí)現(xiàn)一個(gè)視頻的播放和快進(jìn)快退的方法與步驟。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容