iOS实现一个简单的视频播放器

摘自:http://blog.csdn.net/u011334685/article/details/42675179

说明:用系统自带的AVPlayer类实现一个简单的视频播放器。它既能播放本地视频,也能较流畅地播放网络视频。

首先要引入AVFoundation.framework框架;

播放器类.h文件代码如下:

[objc]  view plain  copy
  1. #import <UIKit/UIKit.h>  
  2. #import <AVFoundation/AVFoundation.h>  
  3.   
  4. @interface PlayView : UIView  
  5. -(void)setPlayer:(AVPlayer *)myPlayer;  
  6. -(void)playWith:(NSURL *)url;  
  7. -(void)releasePlayer;  
  8. @end  

播放器类.m文件代码如下:

[objc]  view plain  copy
  1. #import "PlayView.h"  
  2.   
  3. @interface PlayView()  
  4. {  
  5.     UIView   *_bgView;  
  6.     //播放器  
  7.     AVPlayer *_player;  
  8.     //用于显示(控制)视频的播放进度  
  9.     UISlider *_progressSlider;  
  10. }  
  11. -(void)uiConfigWith:(CGRect)bframe;  
  12. @end  
  13.   
  14. @implementation PlayView  
  15.   
  16. - (id)initWithFrame:(CGRect)frame  
  17. {  
  18.     self = [super initWithFrame:frame];  
  19.     if (self) {  
  20.         [self uiConfigWith:frame];  
  21.         [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(moviePlayDidEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:_player.currentItem];  
  22.     }  
  23.     return self;  
  24. }  
  25.   
  26. -(void)uiConfigWith:(CGRect)bframe  
  27. {  
  28.     self.backgroundColor=[UIColor blackColor];  
  29.       
  30.     _bgView=[[UIView alloc]initWithFrame:CGRectMake(0, bframe.size.height-50, bframe.size.width50)];  
  31.     _bgView.backgroundColor=[UIColor lightGrayColor];  
  32.     [self addSubview:_bgView];  
  33.       
  34.     //播放暂停按钮  
  35.     UIButton *playBtn = [UIButton buttonWithType:UIButtonTypeCustom];  
  36.     [playBtn setFrame:CGRectMake(0,0,100,50)];  
  37.     playBtn.backgroundColor=[UIColor whiteColor];  
  38.     playBtn.selected=YES;  
  39.     [playBtn setTitle:@"play" forState:UIControlStateNormal];  
  40.     [playBtn setTitle:@"pause" forState:UIControlStateSelected];  
  41.     [playBtn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];  
  42.     [playBtn addTarget:self action:@selector(playBtnClick:) forControlEvents:UIControlEventTouchUpInside];  
  43.     [_bgView addSubview:playBtn];  
  44.       
  45.     _progressSlider= [[UISlider alloc] initWithFrame:CGRectMake(100,0,bframe.size.width-100,50)];  
  46.     _progressSlider.minimumValue = 0.0;  
  47.     _progressSlider.maximumValue = 1.0;  
  48.     [_progressSlider addTarget:self action:@selector(progressChange:) forControlEvents:UIControlEventValueChanged];  
  49.     [_bgView addSubview:_progressSlider];  
  50. }  
  51.   
  52. //每个视图都对应一个层,改变视图的形状、动画效果\与播放器的关联等,都可以在层上操作  
  53. //播放器支持的播放格式:mp4、mov(iPhone手机录制视频的默认格式) avi  
  54. -(void)setPlayer:(AVPlayer *)myPlayer  
  55. {  
  56.     AVPlayerLayer *playerLayer=(AVPlayerLayer *)self.layer;  
  57.     [playerLayer setPlayer:myPlayer];  
  58. }  
  59. //在调用视图的layer时,会自动触发layerClass方法,重写它,保证返回的类型是AVPlayerLayer  
  60. +(Class)layerClass  
  61. {  
  62.     return [AVPlayerLayer class];  
  63. }  
  64. -(void)playWith:(NSURL *)url  
  65. {  
  66.     //加载视频资源的类  
  67.     AVURLAsset *asset = [AVURLAsset assetWithURL:url];  
  68.     //AVURLAsset 通过tracks关键字会将资源异步加载在程序的一个临时内存缓冲区中  
  69.     [asset loadValuesAsynchronouslyForKeys:[NSArray arrayWithObject:@"tracks"] completionHandler:^{  
  70.         //能够得到资源被加载的状态  
  71.         AVKeyValueStatus status = [asset statusOfValueForKey:@"tracks" error:nil];  
  72.         //如果资源加载完成,开始进行播放  
  73.         if (status == AVKeyValueStatusLoaded) {  
  74.             //将加载好的资源放入AVPlayerItem 中,item中包含视频资源数据,视频资源时长、当前播放的时间点等信息  
  75.             AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];  
  76.             _player = [[AVPlayer alloc] initWithPlayerItem:item];  
  77.             //将播放器与播放视图关联  
  78.             [self setPlayer:_player];  
  79.             [_player play];  
  80.             //需要时时显示播放的进度  
  81.             //根据播放的帧数、速率,进行时间的异步(在子线程中完成)获取  
  82.             [_player addPeriodicTimeObserverForInterval:CMTimeMake(1.01.0) queue:dispatch_get_global_queue(00) usingBlock:^(CMTime time) {  
  83.                 //获取时间  
  84.                 //获取当前播放时间(根据帧数和播放速率,视频资源的总长度得到的CMTime)  
  85.                 CMTime current = _player.currentItem.currentTime;  
  86.                 //总时间  
  87.                 CMTime dur =_player.currentItem.duration;  
  88.                 //CMTimeGetSeconds 将描述视频时间的结构体转化为float(秒)  
  89.                 float pro = CMTimeGetSeconds(current)/CMTimeGetSeconds(dur);  
  90.                 //回到主线程刷新UI  
  91.                 dispatch_async(dispatch_get_main_queue(), ^{  
  92.                     //要考虑到代码的健壮性  
  93.                     /*1、在向对象发送消息前,要判断对象是否为空 
  94.                      *2、一些值(数组、控制中的属性值)是否越界的判断 
  95.                      *3、是否对各种异常情况进行了处理(照片、定位 用户允许、不允许) 
  96.                      *4、数据存储,对nil的判断或处理 
  97.                      *5、对硬件功能支持情况的判断等 
  98.                      */  
  99.                     if (pro >=0 && pro <=1) {  
  100.                         _progressSlider.value = pro;  
  101.                     }  
  102.                 });  
  103.                   
  104.             }];  
  105.         }  
  106.     }];  
  107.   
  108. }  
  109. #pragma mark -------BtnClick---------  
  110. -(void)playBtnClick:(UIButton *)btn  
  111. {  
  112.     if (btn.selected==YES) { //暂停按钮被点击  
  113.           
  114.         if (_player) {  
  115.             [_player pause];  
  116.         }  
  117.         btn.selected=NO;  
  118.         return;  
  119.     }  
  120.       
  121.     //播放按钮被点击  
  122.     if (_player) {  
  123.         [_player play];  
  124.     }  
  125.     btn.selected=YES;  
  126.     return;  
  127. }  
  128. -(void)progressChange:(UISlider *)sl  
  129. {  
  130.     //通过进度条控制播放进度  
  131.     if (!_player) {  
  132.         return;  
  133.     }  
  134.     CMTime dur = _player.currentItem.duration;  
  135.     float current = _progressSlider.value;  
  136.     //CMTimeMultiplyByFloat64 将总时长,当前进度,转化成为CMTime  
  137.     //seekToTime 跳转到指定的时间  
  138.     [_player seekToTime:CMTimeMultiplyByFloat64(dur, current)];  
  139. }  
  140.   
  141. //销毁player  
  142. -(void)releasePlayer  
  143. {  
  144.     if (_player) {  
  145.         [_player pause];  
  146.         _player=nil;  
  147.     }  
  148.     [[NSNotificationCenter defaultCenter] removeObserver:self];  
  149.     for(int i=0;i<[_bgView.subviews count];i++)  
  150.     {  
  151.         UIView *view=[_bgView.subviews objectAtIndex:i];  
  152.         [view removeFromSuperview];  
  153.         view=nil;  
  154.         i--;  
  155.     }  
  156.     [_bgView removeFromSuperview];  
  157.     _bgView=nil;  
  158. }  
  159.   
  160. #pragma mark ------Notification-------  
  161. -(void)moviePlayDidEnd:(NSNotification*)notification  
  162. {  
  163.     NSLog(@"视频播放完毕!");  
  164. }  
  165.   
  166. @end  

这个简单的视频播放器类就做好了。

在ViewController类中创建一个简单的按钮,点击按钮,调用PlayView类播放视频。

如果是网络视频,

[objc]  view plain  copy
  1. NSURL *url = [NSURL URLWithString:@"http://123.com/123.mp4"];  
如果是本地视频,

[objc]  view plain  copy
  1. NSString *path=[[NSBundle mainBundle]pathForResource:@"123.mp4" ofType:nil];  
  2. NSURL *url=[NSURL fileURLWithPath:path];  
调用:

[objc]  view plain  copy
  1. PlayView *playView=[[PlayView alloc] initWithFrame:CGRectMake(00320300)];  
  2. [playView playWith:url];  
  3. [self.view addSubview:playView];  
这样,视频就可以播放了!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值