iOS流媒体

MPMoviePlayerController

  • 简介
    MPMoviePlayerController既支持本地音视频播放也支持网络流媒体播放,功能已经十分完善了,流媒体项目常用的需求都可以满足,比如播放、暂停,快进、后退、监听播放器的播放状态、截图等功能,同时MPMoviePlayerController提供了一个简单的全屏播放界面,可以轻松实现简单的流媒体播放需求,如果需要深度自定义一个视频播放器,可以将MPMoviePlayerController的view添加到自定义的控制器中,然后再讲一些自定义的控件添加到相应view即可,代码如下:

      MPMoviePlayerController *player =  [[MPMoviePlayerController alloc] initWithContentURL: myURL];
      [player prepareToPlay];
      [player.view setFrame: myView.bounds];
      [myView addSubview: player.view];
      [player play];
  • 总结
    MPMoviePlayerController为音视频开发提供了简洁易用的接口,小伙伴们自行查阅文档即可,这里就不赘述了。需要注意的是在iOS9 以后MPMoviePlayerController被苹果弃用了,取而代之的是AVPlayerViewController,究其原因,iOS9以后iPad支持了画中画功能,即使用画中画播放后,我们退出APP,视频会在一个小的窗口继续播放,用户可以在使用其他APP的同时观看视频,AVPlayerViewController提供了完整的画中画技术支持,具体后面再讲。画中画如下图:

    画中画.png

    AVPlayer

  • 简介
    如果我们只是开发只有音频的流媒体项目,MPMoviePlayerController足够用了,可以满足几乎任何需求,开发一个简单的视频播放器也足够用。但是要深度自定义一个视频播放器 使用AVPlayer就很方便了, AVPlayer自由度很高,可以自定义视频播放器, AVPlayer本身无法显示视频,需要借助AVPlayerLayer显示,初始化以及播放过程代码如下:
      #import <AVFoundation/AVFoundation.h>
    
      @interface ViewController ()
    
      @property (strong, nonatomic) AVPlayer *avPlayer;
    
      @end
    
      @implementation ViewController
    
      - (void)viewDidLoad {
          [super viewDidLoad];
      //这个链接是M3U8的,你看到此博客的时候此链接可能已经失效,请自行找链接测试
     AVPlayerItem *playItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:@"http://cctv1.vtime.cntv.cloudcdn.net/cache/12_/seg0/index.m3u8?AUTH=KDumCPYYPzSTcmtewPt/u78MdD6mwSpceXl98vdwcN8RIWA7hZqDK8s3RWkdW3PymV7TkVLHQ5UJp1gHXtkWGg=="]];
      //初始化AVPlayer
      self.avPlayer = [[AVPlayer alloc] initWithPlayerItem:playItem];
      //设置AVPlayer关联
      AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];
      //设置视频模式
      playerLayer.videoGravity = AVLayerVideoGravityResize;
      playerLayer.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width * 9.0 / 16.0);
      //创建一个UIView与AVPlayerLayer关联
      UIView *playerView = [[UIView alloc] initWithFrame:CGRectMake(0, 20, CGRectGetWidth(playerLayer.frame), CGRectGetHeight(playerLayer.frame))];
      playerView.backgroundColor = [UIColor blackColor];
      [playerView.layer addSublayer:playerLayer];
      [self.view addSubview:playerView];
      //开始播放(请在真机上运行)
      [self.avPlayer play];
      }

    真机运行图如下:

    AVPlayer播放M3U8效果.png

  • 总结
    上面我们已经可以把展示我们视频的view随意处置了,可以为视频播放增加常用的改变视频比例、手势改变音量、亮度等常用的功能。
    注意
    1、获取AVPlayer的缓冲进度
    通过监听loadedTimeRanges、status可以获取缓冲进度和播放进度
    代码如下:
    首先添加监听
      [playItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
      [playItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

    监听回调

      - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
    
      AVPlayerItem *playerItem = (AVPlayerItem *)object;
      if ([keyPath isEqualToString:@"loadedTimeRanges"]){
      //获取缓冲进度
      NSArray *loadedTimeRanges = [playerItem loadedTimeRanges];
      // 获取缓冲区域
      CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];
      //开始的时间
      NSTimeInterval startSeconds = CMTimeGetSeconds(timeRange.start);
      //表示已经缓冲的时间
      NSTimeInterval durationSeconds = CMTimeGetSeconds(timeRange.duration);
      // 计算缓冲总时间
      NSTimeInterval result = startSeconds + durationSeconds;
      NSLog(@"开始:%f,持续:%f,总时间:%f", startSeconds, durationSeconds, result);
      NSLog(@"视频的加载进度是:%%%f", durationSeconds / self.total * 100);
          }else if ([keyPath isEqualToString:@"status"]){
      //获取播放状态
      if (playerItem.status == AVPlayerItemStatusReadyToPlay){
          NSLog(@"准备播放");
          //获取视频的总播放时长
          [self.avPlayer play];
          self.total = CMTimeGetSeconds(self.avPlayer.currentItem.duration);
              } else{
          NSLog(@"播放失败");
          }
        }
       }

控制台输出结果
开始:0.000000,持续:0.325000,总时间:0.325000
视频的加载进度是:%inf
准备播放
开始:0.000000,持续:18.203000,总时间:18.203000
视频的加载进度是:%12.227365
开始:0.000000,持续:35.108000,总时间:35.108000
视频的加载进度是:%23.582833
开始:0.000000,持续:43.119000,总时间:43.119000
视频的加载进度是:%28.964002
开始:0.000000,持续:46.068000,总时间:46.068000
视频的加载进度是:%30.944912
开始:0.000000,持续:62.160000,总时间:62.160000
视频的加载进度是:%41.754270
开始:0.000000,持续:73.283000,总时间:73.283000
视频的加载进度是:%49.225840
开始:0.000000,持续:80.064000,总时间:80.064000
视频的加载进度是:%53.780790
开始:0.000000,持续:94.298000,总时间:94.298000
视频的加载进度是:%63.342088
开始:0.000000,持续:101.682000,总时间:101.682000
视频的加载进度是:%68.302087
开始:0.000000,持续:106.977000,总时间:106.977000
视频的加载进度是:%71.858858
开始:0.000000,持续:117.775000,总时间:117.775000
视频的加载进度是:%79.112117
开始:0.000000,持续:132.172000,总时间:132.172000
视频的加载进度是:%88.782906
开始:0.000000,持续:148.871000,总时间:148.871000
视频的加载进度是:%100.000000

从控制台输出的结果可以很清楚的看到视频加载的进度,这里有几点需要注意
1、只有播放状态变成AVPlayerItemStatusReadyToPlay时才可以获取视频播放的总时间,提前获取无效;
2、我们判断缓冲进度是靠比较视频总时长self.total和已经缓冲的总时间durationSeconds作比较,如果二者相等即达到100%视频则加载完成,这里需要注意,有时这2个值在浮点数下不一定相同,有可能出现99.990836%这样的情况,但是视频实际上已经加载完成,如果我们硬性的凭借100%判断会出现有的视频永远加载不完的假象,因此在判断的时候应该设置一个误差值,比如缓冲进度>99.95%就认为是加载完成了,具体数值可以根据项目自行设定一个合理的误差;
3、这里显示的所有数据,比如视频的总时长、进度都是点播类播放源,非M3U8,M3U8是直播无法获取总时长数据,开始时间和缓冲时间等数据也没有参考价值,项目中的直播视频也不会涉及到这些。

2、获取AVPlayer当前的播放进度

    CMTime ctime = self.avPlayer.currentTime;
    CGFloat currentTimeSec = ctime.value / ctime.timescale;

有了当前的播放进度,视频的进度条功能就可以完成,很简单,这里就不赘述了。

3、关于AVPlayer播放卡顿时如何获取此时的状态也是我遇到的难题,因为AVPlayer并没有给出这种状态,有人说根据AVPlayer的rate是1还是0判断,经测试这个方法不靠谱,即使卡顿时rate有时还是1,文章开头连接的博文给出了一种解决办法,可以参考下,这里大家有什么好的方法欢迎留言,感激不尽。

    self.link = [CADisplayLink displayLinkWithTarget:self selector:@selector(upadte)];
    [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

实现update方法

- (void)upadte
{
NSTimeInterval current = CMTimeGetSeconds(self.avPlayer.currentTime);

if (current!=self.lastTime) {
    //没有卡顿
    NSLog(@"没有卡顿");
}else{
    //卡顿了
    NSLog(@"卡顿了");
}
self.lastTime = current;
}

AVPlayerViewController

  • 简介
    AVPlayerViewController是iOS9以后推出的新接口,这个接口在我看来主要就是为了iPad的画中画,通过AVPlayerViewControllerDelegate实现,没有太多可以讲的,AVPlayerViewController的使用与AVPlayer基本一样,这里给简单的使用实例看下就可以了,其余的用法参考AVPlayer。
    AVPlayerViewController示例

尾巴

这里只总结了MPMoviePlayerController、AVPlayer、AVPlayerViewController3个开发流媒体常用的接口,在开发中如何选择呢,我总结了一些经验,仅供参考。
1、如果是纯音频的流媒体项目,并且最低支持的版本在iOS9以下,使用MPMoviePlayerController最合适,音频不需要考虑MPMoviePlayerController本身自定义的界面,只需要播放声音,界面我们自己布局就可以了,并且获取播放的各种状态也要比其余两种方便。
2、有视频需求的流媒体项目,如果只是简单的视频需求可以使用MPMoviePlayerController,如果要深度自定义视频播放器,建议使用AVPlayerViewController,用法和AVPlayer基本是一样的,但是AVPlayerViewController的好处是可以在后续方便的实现画中画功能,后续苹果在更新时接口时也会为AVPlayerViewController提供更多有用方便的方法和属性,方便开发者使用。

原文链接:http://www.jianshu.com/p/6c6b59a875c1

时间: 2024-12-26 06:08:55

iOS流媒体的相关文章

android和ios流媒体库推荐

1基本信息编辑 Vitamio是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染.从2011年8月上线到2014年1月,Vitamio 凭借其简洁易用的 API 接口赢得了全球众多开发者的青睐,全球已经有超过3000 种应用在使用Vitamio,覆盖用户超过5亿. 2功能特性编辑 Vitamio能够流畅播放720P甚至1080P高清MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频,还可以在Android 与 iOS 上跨平台支持 MMS

ios流媒体--播放,下载

进式下载(伪流媒体) 介于下载本地播放与实时流媒体之间的一种播放形式,下载本地播放必须全部将文件下载完成后才能播放,而渐进式下载不必等到全部下载完成后再播放,它可以一边下载一边播放,在完成播放内容之后,整个文件会保存在手机上. 实时流媒体 实时流媒体是一边接收数据包一边播放,本地不保留文件副本,实时流式传输总是实时传送,可以实时实况转播,支持随机访问,用户可以快进或者快退以观看前面或后面的内容.实时流媒体传输必须保证数据包的传输速度大于文件的播放速度,否则用户看到的视频会出现暂停.当网络堵塞情况

ios 流媒体 资料

(1)“Real-Time Streaming Protocol (RTSP)”比较官方的资料(链接). (2)“ffmpeg”在百度百科的简介(链接). (3)“ffmpeg”的官网:http://ffmpeg.org/,使用ffmpeg开发流媒体播放器的实例在这儿. (4)“http://stackoverflow.com/”上有两篇不错的帖子,其中给出了实例,帖子一(这儿)和帖子二(这儿). (5)“RTSP streaming on iphone works great!”也是国外的一篇

浅谈iOS视频开发

这段时间对视频开发进行了一些了解,在这里和大家分享一下我自己觉得学习步骤和资料,希望对那些对视频感兴趣的朋友有些帮助. 一.iOS系统自带播放器 要了解iOS视频开发,首先我们从系统自带的播放器说起,一.我们可以直接播放视频,看到效果,不然搞了半天还播放不了视频,会让大家失去兴趣.二.其实对于很多需求来说,系统的播放器就能够胜任.简单介绍下 1.MPMoviePlayerController 在iOS中播放视频可以使用MPMoviePlayerController类来完成,具备一般的播放器控制功

iOS 视频开发学习

原文:浅谈iOS视频开发 这段时间对视频开发进行了一些了解,在这里和大家分享一下我自己觉得学习步骤和资料,希望对那些对视频感兴趣的朋友有些帮助. 一.iOS系统自带播放器 要了解iOS视频开发,首先我们从系统自带的播放器说起,一.我们可以直接播放视频,看到效果,不然搞了半天还播放不了视频,会让大家失去兴趣.二.其实对于很多需求来说,系统的播放器就能够胜任.简单介绍下 1.MPMoviePlayerController 在iOS中播放视频可以使用MPMoviePlayerController类来完

IOS架构师之路:我对IOS架构的点点认识(大纲)

1.今天我鼓起了勇气,想纪录自己对IOS架构学习成长的点点滴滴. 从事IOS开发也有几年的时间,从刚開始最主要的语言.界面.逻辑,再到后面复杂点的线程.数据处理.网络请求.动画,最后到最复杂的底层音视频.图像算法.自己定义各种效果.网络底层处理.甚至是最后的性能:neon.asm优化. 感觉自己在IOS的开发中,每次都是雾里看花,明明非常接近真理却总是触摸不到.对IOS缺乏一种全局把控的感觉.所以我下定决定想看看IOS的一些官方文档,看看IOS的各个模块的层次结构究竟是怎么回事. 大约从一年前開

iOS基于B站的IJKPlayer框架的流媒体探究

学习交流及技术讨论可新浪微博关注:极客James 一.流媒体 流媒体技术从传输形式上可以分为:渐进式下载和实施流媒体. 1.渐进式下载 它是介于实时播放和本地播放之间的一种播放方式,渐进式下载不必等到全部下载完成后在播放,可以边下载边播放,播放完成后,整个文件会保存下来.从用户的体验上合播放方的效果来看,渐进式下载和实时流媒体没有什么区别,不过是渐进式下载保留有文件在本地.下面来介绍下渐进式下载的开发 渐进式下载的API和本地播放的API没有什么太大的区别,可以使用MediaPlayer框架中得

iOS 关于流媒体 的初级认识与使用

1.流媒体指在Internet/Intranet中使用流式传输技术的连续时基媒体,如:音频.视频或多媒体文件.流式媒体在播放前并不下载整个文件,只将开始部分内容存入内存,流式媒体的数据流随时传送随时播放,只是在开始时有一些延迟.流媒体实现的关键技术就是流式传输. 2.这里的流媒体地址是指服务端那边已经调好格式的可以在ios上播放的视频流. 举例:http://www.jxvdy.com/file/upload/201309/18/18-10-03-19-3.mp4 3.iOS的影片播放 Medi

关于ios对rtsp格式的流媒体支持的一些官方说明

ios明确不支持rtsp格式的流媒体,基于rtsp/rtp对通用性和防炎墙以及需要开新端口等额外影响稳定性和通用性的原因. 而对http流的视频支持是最好的.虽然有第三方的方式配合ffmpeg库,实现了rtsp的流内容播放,但效果很一般. 如果架构的条件不是那么苛刻,不如直接选择http流提供给app去播放呈现. 具体官方说明: Frequently Asked Questions What kinds of encoders are supported? The protocol specif