視頻播放-MediaPlayer - (Obj-C)

1.導(dǎo)入<MediaPlayer/MediaPlayer.h>頭文件

2.通過(guò)MPMoviePlayerViewController為我們提供的兩種方式:帶視圖和不帶視圖

__帶視圖(MPMoviePlayerViewController) : __系統(tǒng)已經(jīng)封裝好,可以拿來(lái)直接使用

  創(chuàng)建控制器->modal展示

__不帶視圖(MPMoviePlayerController) : __ 可以滿足自定義的需求

MPMoviePlayerController和MPMoviePlayerViewController在iOS 9下目前已經(jīng)過(guò)期

帶視圖的示例代碼:

- (IBAction)clickStartPlayButton:(UIButton *)sender {
    
    // 獲取視頻路徑 (這里使用了本地視頻文件,如果使用網(wǎng)絡(luò)視頻,設(shè)置網(wǎng)絡(luò)視頻URL即可)
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"minion_01.mp4" ofType:nil];
    // 帶視圖
    // 創(chuàng)建控制器
    MPMoviePlayerViewController *playerViewController = [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL fileURLWithPath:filePath]];
    
    // 進(jìn)行modal展示
    [self presentViewController:playerViewController animated:YES completion:nil];
    
}

在界面上添加了一個(gè)開(kāi)始播放按鈕,點(diǎn)擊時(shí)進(jìn)行視頻播放:

視頻播放_(tái)1.png

而且默認(rèn)的媒體控制系統(tǒng)已經(jīng)幫我們處理好,點(diǎn)擊Done會(huì)自動(dòng)dismiss

MPMoviePlayerViewController中包含一個(gè)moviePlayer屬性

@property (nonatomic, readonly) MPMoviePlayerController *moviePlayer;

MPMoviePlayerController繼承自NSObject,所以不能直接進(jìn)行present,通過(guò)<MPMediaPlayback>協(xié)議實(shí)現(xiàn)播放

不帶視圖的示例代碼:

聲明一個(gè)強(qiáng)引用類型的屬性:
方式一中帶有視圖的控制器是通過(guò)當(dāng)前控制器modal展現(xiàn),也就是Self強(qiáng)引用了MPMoviePlayerViewController,保證了MPMoviePlayerViewController不會(huì)被釋放
同理這里為了保證MPMoviePlayerController不被銷毀,所以聲明了一個(gè)強(qiáng)引用的屬性

@property(nonatomic,strong) MPMoviePlayerController *playerController;

按鈕點(diǎn)擊事件中:

- (IBAction)clickStartPlayButton:(UIButton *)sender {
    
    // 不帶視圖 (可以自定義視圖)
    // 獲取視頻路徑 (這里使用了本地視頻文件,如果使用網(wǎng)絡(luò)視頻,設(shè)置網(wǎng)絡(luò)視頻URL即可)
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"minion_01.mp4" ofType:nil];
    
    // 創(chuàng)建播放器
    self.playerController = [[MPMoviePlayerController alloc]initWithContentURL:[NSURL fileURLWithPath:filePath]];
    // 準(zhǔn)備播放
    [self.playerController prepareToPlay];
    // 開(kāi)始播放
    [self.playerController play];
}

這樣雖然能夠?qū)崿F(xiàn)視頻播放,但是只能聽(tīng)到聲音,因?yàn)檫€未設(shè)置視圖

// 設(shè)置視圖
self.playerController.view.frame = [UIScreen mainScreen].bounds;
[self.view addSubview:self.playerController.view];

這樣就能顯示視圖了:

視頻播放_(tái)2.png

底部的媒體按鈕也是可以直接使用的,右下角按鈕點(diǎn)擊還能進(jìn)入全屏:

視頻播放_(tái)3.png

主要區(qū)別在于全屏模式上面會(huì)多出一個(gè)視圖:

視頻播放_(tái)4.png

進(jìn)入全屏后,媒體按鈕系統(tǒng)都已經(jīng)幫我們實(shí)現(xiàn)好了

Done按鈕點(diǎn)擊后,會(huì)退出全屏,并自動(dòng)暫停視頻

這里設(shè)置的是屏幕尺寸,如果需要設(shè)置窗口模式,手動(dòng)給視圖設(shè)置一個(gè)尺寸即可

self.playerController.view.frame = CGRectMake(100, 50, 200, 200);
視頻播放_(tái)5.png

上面提到了,當(dāng)自定義窗口視圖后,進(jìn)入全屏播放,點(diǎn)擊左上角的Done按鈕,會(huì)恢復(fù)窗口模式,暫停視圖,做進(jìn)一步處理,當(dāng)點(diǎn)擊Done按鈕時(shí),恢復(fù)窗口模式并銷毀視圖

實(shí)現(xiàn)方式:
1.監(jiān)聽(tīng)視頻控制器(從全屏恢復(fù)窗口)

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stop) name:MPMoviePlayerWillExitFullscreenNotification object:nil];

2監(jiān)聽(tīng)到狀態(tài)變化后進(jìn)一步判斷
全屏模式除了點(diǎn)擊Done按鈕會(huì)退出全屏,右上角也有一個(gè)退出全屏的按鈕
區(qū)別在于:點(diǎn)擊Done后會(huì)自動(dòng)停止播放,當(dāng)退出全屏并暫停播放時(shí)就是我們需要的狀態(tài),接下來(lái)就是移除自定義的播放視頻視圖

- (void)stop{
    
    switch (self.playerController.playbackState) {
            
    /*
     MPMoviePlaybackStateStopped,           停止
     MPMoviePlaybackStatePlaying,           正在播放
     MPMoviePlaybackStatePaused,            暫停
     MPMoviePlaybackStateInterrupted,       中斷
     MPMoviePlaybackStateSeekingForward,    快進(jìn)
     MPMoviePlaybackStateSeekingBackward    快退
     */
            
        case MPMoviePlaybackStatePaused: //退出全屏&狀態(tài)為暫停時(shí),才是點(diǎn)擊Done按鈕
            [self.playerController.view removeFromSuperview];
            break;
            
        default:
            break;
    }
}

完整實(shí)例代碼:

#import "ViewController.h"
#import <MediaPlayer/MediaPlayer.h> //對(duì)<AVFoundation/AVFoundation.h>的封裝

@interface ViewController ()

@property(nonatomic,strong) MPMoviePlayerController *playerController;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 監(jiān)聽(tīng)窗口狀態(tài)  監(jiān)聽(tīng)通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stop) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
    
}

- (void)stop{
    
    switch (self.playerController.playbackState) {
            
    /*
     MPMoviePlaybackStateStopped,           停止
     MPMoviePlaybackStatePlaying,           正在播放
     MPMoviePlaybackStatePaused,            暫停
     MPMoviePlaybackStateInterrupted,       中斷
     MPMoviePlaybackStateSeekingForward,    快進(jìn)
     MPMoviePlaybackStateSeekingBackward    快退
     */
            
        case MPMoviePlaybackStatePaused: //退出全屏&狀態(tài)為暫停時(shí),才是點(diǎn)擊Done按鈕
            [self.playerController.view removeFromSuperview];
            break;
            
        default:
            break;
    }
}

// 開(kāi)始播放
- (IBAction)clickStartPlayButton:(UIButton *)sender {
    
    // 不帶視圖 (可以自定義視圖)
    // 獲取視頻路徑 (這里使用了本地視頻文件,如果使用網(wǎng)絡(luò)視頻,設(shè)置網(wǎng)絡(luò)視頻URL即可)
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"minion_01.mp4" ofType:nil];
    
    // 創(chuàng)建播放器
    self.playerController = [[MPMoviePlayerController alloc]initWithContentURL:[NSURL fileURLWithPath:filePath]];
    
    // 設(shè)置視圖
    //    self.playerController.view.frame = [UIScreen mainScreen].bounds;
    self.playerController.view.frame = CGRectMake(100, 50, 200, 200);
    [self.view addSubview:self.playerController.view];
    
    // 準(zhǔn)備播放
    [self.playerController prepareToPlay];
    // 開(kāi)始播放
    [self.playerController play];
}

@end



  • MPMoviePlayerController中的關(guān)鍵屬性說(shuō)明:
@interface MPMoviePlayerController : NSObject <MPMediaPlayback>
// 視頻文件URL 
@property (nonatomic, copy) NSURL *contentURL;

// 顯示視頻的視圖
@property (nonatomic, readonly) UIView *view;

// 播放視頻的背景視圖
@property (nonatomic, readonly) UIView *backgroundView;

// 播放狀態(tài)
@property (nonatomic, readonly) MPMoviePlaybackState playbackState;

// 加載狀態(tài)(加載是否成功)
@property (nonatomic, readonly) MPMovieLoadState loadState;

// 控制樣式(默認(rèn)顯示)
    MPMovieControlStyleNone,       // No controls (不顯示控制條)
    MPMovieControlStyleEmbedded,   // Controls for an embedded view(默認(rèn))
    MPMovieControlStyleFullscreen, // Controls for fullscreen playback
@property (nonatomic) MPMovieControlStyle controlStyle;

// 重復(fù)
@property (nonatomic) MPMovieRepeatMode repeatMode;

// 是否自動(dòng)播放
@property (nonatomic) BOOL shouldAutoplay;

// 縮放 Defaults to MPMovieScalingModeAspectFit.
@property (nonatomic) MPMovieScalingMode scalingMode;
@end




@interface MPMoviePlayerController (MPMovieProperties)

// The types of media in the movie, or MPMovieMediaTypeNone if not known.
@property (nonatomic, readonly) MPMovieMediaTypeMask movieMediaTypes NS_DEPRECATED_IOS(2_0, 9_0, "Use AVPlayerViewController in AVKit.");

// The playback type of the movie. Defaults to MPMovieSourceTypeUnknown.
// Specifying a playback type before playing the movie can result in faster load times.
@property (nonatomic) MPMovieSourceType movieSourceType NS_DEPRECATED_IOS(2_0, 9_0, "Use AVPlayerViewController in AVKit.")
;

// The duration of the movie, or 0.0 if not known.
@property (nonatomic, readonly) NSTimeInterval duration NS_DEPRECATED_IOS(2_0, 9_0, "Use AVPlayerViewController in AVKit.")
;

// The currently playable duration of the movie, for progressively downloaded network content.
@property (nonatomic, readonly) NSTimeInterval playableDuration NS_DEPRECATED_IOS(2_0, 9_0, "Use AVPlayerViewController in AVKit.")
;

// The natural size of the movie, or CGSizeZero if not known/applicable.
@property (nonatomic, readonly) CGSize naturalSize NS_DEPRECATED_IOS(2_0, 9_0, "Use AVPlayerViewController in AVKit.")
;

// The start time of movie playback. Defaults to NaN, indicating the natural start time of the movie.
@property (nonatomic) NSTimeInterval initialPlaybackTime NS_DEPRECATED_IOS(2_0, 9_0, "Use AVPlayerViewController in AVKit.")
;

// The end time of movie playback. Defaults to NaN, which indicates natural end time of the movie.
@property (nonatomic) NSTimeInterval endPlaybackTime NS_DEPRECATED_IOS(2_0, 9_0, "Use AVPlayerViewController in AVKit.")
;

// Indicates whether the movie player allows AirPlay video playback. Defaults to YES on iOS 5.0 and later.
@property (nonatomic) BOOL allowsAirPlay NS_DEPRECATED_IOS(4_3, 9_0, "Use AVPlayerViewController in AVKit.")
;

// 
@property (nonatomic, readonly, getter=isAirPlayVideoActive) BOOL airPlayVideoActive ;

@end


如果想要使用自定義的控制條樣式
可以設(shè)置controlStyle為MPMovieControlStyleNone,然后添加自定義的媒體控制視圖

需要注意的是:需要把事件添加到view視圖上, backgroundView下是不能監(jiān)聽(tīng)事件
在view屬性中已經(jīng)給了說(shuō)明

// The view in which the media and playback controls are displayed.
@property (nonatomic, readonly) UIView *view;

如果想要修改背景視圖,可以設(shè)置backgroundView

如果需要播放時(shí)默認(rèn)進(jìn)入全屏,在播放按鈕事件中,還可以重新設(shè)置播放視頻視圖的Frame為屏幕的bounds,并讓其旋轉(zhuǎn)90°,示例代碼:

    [UIView animateWithDuration:0.1 animations:^{
        
        // 播放視圖全屏橫向顯示
        self.playerController.view.transform = CGAffineTransformRotate(self.playerController.view.transform, M_PI_2);
        // 設(shè)置全屏
        self.playerController.view.frame = [UIScreen mainScreen].bounds;
    }];

MPMediaPlayback協(xié)議內(nèi)容:

@protocol MPMediaPlayback

// Prepares the current queue for playback, interrupting any active (non-mixible) audio sessions.
// Automatically invoked when -play is called if the player is not already prepared.
- (void)prepareToPlay;

// Returns YES if prepared for playback.
@property(nonatomic, readonly) BOOL isPreparedToPlay;

// Plays items from the current queue, resuming paused playback if possible.
- (void)play;

// Pauses playback if playing.
- (void)pause;

// Ends playback. Calling -play again will start from the beginnning of the queue.
- (void)stop;

// The current playback time of the now playing item in seconds.
@property(nonatomic) NSTimeInterval currentPlaybackTime;

// The current playback rate of the now playing item. Default is 1.0 (normal speed).
// Pausing will set the rate to 0.0. Setting the rate to non-zero implies playing.
@property(nonatomic) float currentPlaybackRate;

// The seeking rate will increase the longer scanning is active.
- (void)beginSeekingForward;
- (void)beginSeekingBackward;
- (void)endSeeking;

@end

// Posted when the prepared state changes of an object conforming to the MPMediaPlayback protocol changes.
// This supersedes MPMoviePlayerContentPreloadDidFinishNotification.
MP_EXTERN __TVOS_PROHIBITED NSString *const MPMediaPlaybackIsPreparedToPlayDidChangeNotification NS_DEPRECATED_IOS(3_2, 9_0);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評(píng)論 6 541
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,324評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事。” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 178,018評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 63,675評(píng)論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,417評(píng)論 6 412
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 55,783評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評(píng)論 3 446
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 42,960評(píng)論 0 290
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,522評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,267評(píng)論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,471評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,698評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 35,099評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 36,386評(píng)論 1 294
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,204評(píng)論 3 398
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,436評(píng)論 2 378

推薦閱讀更多精彩內(nèi)容