淺談iOS的AVPlayerViewController播放視頻

在iOS9以后,MPMoviePlayerViewController被棄用,蘋果推薦我們使用AVPlayerViewControlller,下面我們來了解一下AVPlayerViewController的使用方法。
在我們了解AVPlayerViewController之前,先要了解AVPlayer和AVPlayerItem。

一、AVPlayer

以下為AVPlayer官方文檔對AVPlayer的介紹。

An AVPlayer is a controller object used to manage the playback and timing of a media asset. It provides the interface to control the player’s transport behavior such as its ability to play, pause, change the playback rate, and seek to various points in time within the media’s timeline. You can use an AVPlayer to play local and remote file-based media, such as QuickTime movies and MP3 audio files, as well as audiovisual media served using HTTP Live Streaming.

可以看到,AVPlayer是一個控制器,可以實現(xiàn)音視頻播放的基本需求,???

AVPlayer不僅可以播放本地音視頻,還可以播放HTTP流媒體。

AVPlayer可以實現(xiàn)播放,暫停,改變播放速率,在視頻的時間線上進行跳轉。

AVPlayer的初始化有四種方式:

-initWithURL: 初始化一個player??梢圆シ艈蝹€的視聽資源。傳入一個URL。

+playerWithURL: 返回一個player。可以播放單個的視聽資源。傳入一個URL。

-initWithPlayerItem: 初始化一個player??梢圆シ盘囟ǖ腁VPlayerItem。

+playerWithPlayerItem: 返回一個player。可以播放特定的AVPlayerItem。

如果通過傳入URL的方式,則不能修改視頻播放源。傳入AVplayerItem則可以通過replaceCurrentItemWithPlayerItem:修改currentItem來修改播放源。

下面是使用AVPlayer播放本地視頻的代碼。

//ViewContoller.m
#import <UIKit/UIKit.h>
#import "ViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#import <AVFoundation/AVFoundation.h>   
#import <AVKit/AVKit.h>
#import <time.h>
@interface ViewController ()

@property (strong,nonatomic) AVPlayerViewController *moviePlayer;
@property (strong,nonatomic) AVPlayer *player;
@property (strong,nonatomic) AVPlayerItem *item;


@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

self.view.backgroundColor=[UIColor whiteColor];

//設置本地視頻路徑
NSString *mpath=[[NSBundle mainBundle] pathForResource:@"a" ofType:@"mp4"];

NSURL *url=[NSURL fileURLWithPath:mpath];

AVAsset *asset = [AVAsset assetWithURL:url];

self.item=[AVPlayerItem playerItemWithAsset:asset]; 

//設置流媒體視頻路徑
//self.item=[AVPlayerItem playerItemWithURL:movieURL];

//設置AVPlayer中的AVPlayerItem
self.player=[AVPlayer playerWithPlayerItem:self.item];

//初始化layer 傳入player
AVPlayerLayer *layer=[AVPlayerLayer playerLayerWithPlayer:self.player];

//設置layer的屬性
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;

layer.contentsScale = [UIScreen mainScreen].scale;

layer.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height/2);

layer.backgroundColor=[UIColor greenColor].CGColor;

//將視頻的layer添加到視圖的layer中
[self.view.layer addSublayer:layer];    

//替換AVPlayer中的AVPlayerItem
//[self.player replaceCurrentItemWithPlayerItem:self.item];

//監(jiān)聽status屬性,注意監(jiān)聽的是AVPlayerItem
[self.item addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];

//監(jiān)聽loadedTimeRanges屬性
[self.item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

}

//AVPlayerItem監(jiān)聽的回調函數(shù)
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    AVPlayerItem *playerItem = (AVPlayerItem *)object;

    if ([keyPath isEqualToString:@"loadedTimeRanges"]){

    }else if ([keyPath isEqualToString:@"status"]){
        if (playerItem.status == AVPlayerItemStatusReadyToPlay){
            NSLog(@"playerItem is ready");

            //如果視頻準備好 就開始播放
            [self.player play];

            } else if(playerItem.status==AVPlayerStatusUnknown){
            NSLog(@"playerItem Unknown錯誤");
            }
        else if (playerItem.status==AVPlayerStatusFailed){
            NSLog(@"playerItem 失敗");
        }
    }
}

二、AVPlayerVIewController

以下為AVPlayerViewController官方文檔對AVPlayer的介紹。

Using AVPlayerViewController makes it easy for you to add media playback capabilities to your application matching the styling and features of the native system players. Since AVPlayerViewController is a system framework class, your playback applications automatically adopt the new aesthetics and features of future operating system updates without any additional work from you.

****AVPlayerViewController繼承自UIViewController,但是如果直接把AVPlayerViewController當做UIViewController添加到UIWindow的話,不會顯示視頻控制欄,正確的代碼如下****

//moviewPlayer就是一個AVPlayerViewController
self.moviePlayer=[[AVPlayerViewController alloc]init];

//設置AVPlayerViewController的player
self.moviePlayer.player=self.player;

//把AVPlayerViewController的view添加到UIViewController的view中
[self.view addSubview:self.moviePlayer.view];

另外,AVPlayerViewController有以下幾個常用屬性?

showsPlaybackControls:BOOL屬性,默認值為YES,設置是否顯示控制欄

videoGravity:設置視頻的縮放格式,默認值為AVLayerVideoGravityResizeAspect,包括以下三種:

AVLayerVideoGravityResizeAspect

AVLayerVideoGravityResizeAspectFill

AVLayerVideoGravityResize

話不多說,下面貼代碼:

//ViewContoller.m
#import <UIKit/UIKit.h>
#import "ViewController.h"
#import <MediaPlayer/MediaPlayer.h>
#import <AVFoundation/AVFoundation.h>   
#import <AVKit/AVKit.h>
#import <time.h>
@interface ViewController ()

@property (strong,nonatomic) AVPlayerViewController *moviePlayer;
@property (strong,nonatomic) AVPlayer *player;
@property (strong,nonatomic) AVPlayerItem *item;


@end

@implementation ViewController

- (void)viewDidLoad {

[super viewDidLoad];

self.view.backgroundColor=[UIColor whiteColor];

//設置本地視頻路徑
NSString *mpath=[[NSBundle mainBundle] pathForResource:@"a" ofType:@"mp4"];

NSURL *url=[NSURL fileURLWithPath:mpath];

AVAsset *asset = [AVAsset assetWithURL:url];

self.item=[AVPlayerItem playerItemWithAsset:asset]; 

//設置流媒體視頻路徑
//self.item=[AVPlayerItem playerItemWithURL:movieURL];

//設置AVPlayer中的AVPlayerItem
self.player=[AVPlayer playerWithPlayerItem:self.item];

//初始化AVPlayerViewController
self.moviePlayer=[[AVPlayerViewController alloc]init];

self.moviePlayer.player=self.player;

[self.view addSubview:self.moviePlayer.view];

//設置AVPlayerViewController的frame
self.moviePlayer.view.frame=self.view.frame;    

//替換AVPlayer中的AVPlayerItem
//[self.player replaceCurrentItemWithPlayerItem:self.item];

//監(jiān)聽status屬性,注意監(jiān)聽的是AVPlayerItem
[self.item addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];

//監(jiān)聽loadedTimeRanges屬性
[self.item addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

//設置監(jiān)聽函數(shù),監(jiān)聽視頻播放進度的變化,每播放一秒,回調此函數(shù)
    __weak __typeof(self) weakSelf = self;
[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
    //當前播放的時間
    NSTimeInterval current = CMTimeGetSeconds(time);
    //視頻的總時間
    NSTimeInterval total = CMTimeGetSeconds(weakSelf.player.currentItem.duration);

    //輸出當前播放的時間
    NSLog(@"now %f",current);
    }];

}

//AVPlayerItem監(jiān)聽的回調函數(shù)
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    AVPlayerItem *playerItem = (AVPlayerItem *)object;

    if ([keyPath isEqualToString:@"loadedTimeRanges"]){
        double t=[self availableDurationWithplayerItem:self.item];
        NSLog(@"loadranges %f",t);

    }else if ([keyPath isEqualToString:@"status"]){
        if (playerItem.status == AVPlayerItemStatusReadyToPlay){
            NSLog(@"playerItem is ready");

            //如果視頻準備好 就開始播放
            [self.player play];

            } else if(playerItem.status==AVPlayerStatusUnknown){
            NSLog(@"playerItem Unknown錯誤");
            }
        else if (playerItem.status==AVPlayerStatusFailed){
            NSLog(@"playerItem 失敗");
        }
    }
}

//計算緩沖進度的函數(shù)
- (NSTimeInterval)availableDurationWithplayerItem:(AVPlayerItem *)playerItem
{
    NSArray *loadedTimeRanges = [playerItem loadedTimeRanges];
    CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 獲取緩沖區(qū)域
    NSTimeInterval startSeconds = CMTimeGetSeconds(timeRange.start);
    NSTimeInterval durationSeconds = CMTimeGetSeconds(timeRange.duration);
    NSTimeInterval result = startSeconds + durationSeconds;// 計算緩沖總進度
    return result;
}

效果如圖


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

相關閱讀更多精彩內容

友情鏈接更多精彩內容