视频播放-MediaPlayer - (Obj-C)

1.导入<MediaPlayer/MediaPlayer.h>头文件

2.通过MPMoviePlayerViewController为我们提供的两种方式:带视图和不带视图

__带视图(MPMoviePlayerViewController) : __系统已经封装好,可以拿来直接使用

  创建控制器->modal展示

__不带视图(MPMoviePlayerController) : __ 可以满足自定义的需求

MPMoviePlayerController和MPMoviePlayerViewController在iOS 9下目前已经过期

带视图的示例代码:

- (IBAction)clickStartPlayButton:(UIButton *)sender {
    
    // 获取视频路径 (这里使用了本地视频文件,如果使用网络视频,设置网络视频URL即可)
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"minion_01.mp4" ofType:nil];
    // 带视图
    // 创建控制器
    MPMoviePlayerViewController *playerViewController = [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL fileURLWithPath:filePath]];
    
    // 进行modal展示
    [self presentViewController:playerViewController animated:YES completion:nil];
    
}

在界面上添加了一个开始播放按钮,点击时进行视频播放:

视频播放_1.png

而且默认的媒体控制系统已经帮我们处理好,点击Done会自动dismiss

MPMoviePlayerViewController中包含一个moviePlayer属性

@property (nonatomic, readonly) MPMoviePlayerController *moviePlayer;

MPMoviePlayerController继承自NSObject,所以不能直接进行present,通过<MPMediaPlayback>协议实现播放

不带视图的示例代码:

声明一个强引用类型的属性:
方式一中带有视图的控制器是通过当前控制器modal展现,也就是Self强引用了MPMoviePlayerViewController,保证了MPMoviePlayerViewController不会被释放
同理这里为了保证MPMoviePlayerController不被销毁,所以声明了一个强引用的属性

@property(nonatomic,strong) MPMoviePlayerController *playerController;

按钮点击事件中:

- (IBAction)clickStartPlayButton:(UIButton *)sender {
    
    // 不带视图 (可以自定义视图)
    // 获取视频路径 (这里使用了本地视频文件,如果使用网络视频,设置网络视频URL即可)
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"minion_01.mp4" ofType:nil];
    
    // 创建播放器
    self.playerController = [[MPMoviePlayerController alloc]initWithContentURL:[NSURL fileURLWithPath:filePath]];
    // 准备播放
    [self.playerController prepareToPlay];
    // 开始播放
    [self.playerController play];
}

这样虽然能够实现视频播放,但是只能听到声音,因为还未设置视图

// 设置视图
self.playerController.view.frame = [UIScreen mainScreen].bounds;
[self.view addSubview:self.playerController.view];

这样就能显示视图了:

视频播放_2.png

底部的媒体按钮也是可以直接使用的,右下角按钮点击还能进入全屏:

视频播放_3.png

主要区别在于全屏模式上面会多出一个视图:

视频播放_4.png

进入全屏后,媒体按钮系统都已经帮我们实现好了

Done按钮点击后,会退出全屏,并自动暂停视频

这里设置的是屏幕尺寸,如果需要设置窗口模式,手动给视图设置一个尺寸即可

self.playerController.view.frame = CGRectMake(100, 50, 200, 200);
视频播放_5.png

上面提到了,当自定义窗口视图后,进入全屏播放,点击左上角的Done按钮,会恢复窗口模式,暂停视图,做进一步处理,当点击Done按钮时,恢复窗口模式并销毁视图

实现方式:
1.监听视频控制器(从全屏恢复窗口)

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

2监听到状态变化后进一步判断
全屏模式除了点击Done按钮会退出全屏,右上角也有一个退出全屏的按钮
区别在于:点击Done后会自动停止播放,当退出全屏并暂停播放时就是我们需要的状态,接下来就是移除自定义的播放视频视图

- (void)stop{
    
    switch (self.playerController.playbackState) {
            
    /*
     MPMoviePlaybackStateStopped,           停止
     MPMoviePlaybackStatePlaying,           正在播放
     MPMoviePlaybackStatePaused,            暂停
     MPMoviePlaybackStateInterrupted,       中断
     MPMoviePlaybackStateSeekingForward,    快进
     MPMoviePlaybackStateSeekingBackward    快退
     */
            
        case MPMoviePlaybackStatePaused: //退出全屏&状态为暂停时,才是点击Done按钮
            [self.playerController.view removeFromSuperview];
            break;
            
        default:
            break;
    }
}

完整实例代码:

#import "ViewController.h"
#import <MediaPlayer/MediaPlayer.h> //对<AVFoundation/AVFoundation.h>的封装

@interface ViewController ()

@property(nonatomic,strong) MPMoviePlayerController *playerController;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 监听窗口状态  监听通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stop) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
    
}

- (void)stop{
    
    switch (self.playerController.playbackState) {
            
    /*
     MPMoviePlaybackStateStopped,           停止
     MPMoviePlaybackStatePlaying,           正在播放
     MPMoviePlaybackStatePaused,            暂停
     MPMoviePlaybackStateInterrupted,       中断
     MPMoviePlaybackStateSeekingForward,    快进
     MPMoviePlaybackStateSeekingBackward    快退
     */
            
        case MPMoviePlaybackStatePaused: //退出全屏&状态为暂停时,才是点击Done按钮
            [self.playerController.view removeFromSuperview];
            break;
            
        default:
            break;
    }
}

// 开始播放
- (IBAction)clickStartPlayButton:(UIButton *)sender {
    
    // 不带视图 (可以自定义视图)
    // 获取视频路径 (这里使用了本地视频文件,如果使用网络视频,设置网络视频URL即可)
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"minion_01.mp4" ofType:nil];
    
    // 创建播放器
    self.playerController = [[MPMoviePlayerController alloc]initWithContentURL:[NSURL fileURLWithPath:filePath]];
    
    // 设置视图
    //    self.playerController.view.frame = [UIScreen mainScreen].bounds;
    self.playerController.view.frame = CGRectMake(100, 50, 200, 200);
    [self.view addSubview:self.playerController.view];
    
    // 准备播放
    [self.playerController prepareToPlay];
    // 开始播放
    [self.playerController play];
}

@end



  • MPMoviePlayerController中的关键属性说明:
@interface MPMoviePlayerController : NSObject <MPMediaPlayback>
// 视频文件URL 
@property (nonatomic, copy) NSURL *contentURL;

// 显示视频的视图
@property (nonatomic, readonly) UIView *view;

// 播放视频的背景视图
@property (nonatomic, readonly) UIView *backgroundView;

// 播放状态
@property (nonatomic, readonly) MPMoviePlaybackState playbackState;

// 加载状态(加载是否成功)
@property (nonatomic, readonly) MPMovieLoadState loadState;

// 控制样式(默认显示)
    MPMovieControlStyleNone,       // No controls (不显示控制条)
    MPMovieControlStyleEmbedded,   // Controls for an embedded view(默认)
    MPMovieControlStyleFullscreen, // Controls for fullscreen playback
@property (nonatomic) MPMovieControlStyle controlStyle;

// 重复
@property (nonatomic) MPMovieRepeatMode repeatMode;

// 是否自动播放
@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


如果想要使用自定义的控制条样式
可以设置controlStyle为MPMovieControlStyleNone,然后添加自定义的媒体控制视图

需要注意的是:需要把事件添加到view视图上, backgroundView下是不能监听事件
在view属性中已经给了说明

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

如果想要修改背景视图,可以设置backgroundView

如果需要播放时默认进入全屏,在播放按钮事件中,还可以重新设置播放视频视图的Frame为屏幕的bounds,并让其旋转90°,示例代码:

    [UIView animateWithDuration:0.1 animations:^{
        
        // 播放视图全屏横向显示
        self.playerController.view.transform = CGAffineTransformRotate(self.playerController.view.transform, M_PI_2);
        // 设置全屏
        self.playerController.view.frame = [UIScreen mainScreen].bounds;
    }];

MPMediaPlayback协议内容:

@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);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容