播放器

对于资源的播放,你应使用AVPlayer类。你可以使用AVPlayerItem实例去管理整个资源的显示状态,使用AVPlayerIteamTrack类去管理单独任务的显示状态。你可以使用AVPlayerLayer类进行显示

播放资源

player是你用来管理一个资源播放装置的控制类,比如开始播放、结束播放,特定时间的情况等。你可以使用一个AVPlayer实例去播放一个单独的资源。你可以使用一个AVQueuePlayer(AVPlayer的子类)类去播放一个资源队列。在macOS,你可以选择使用AVKit框架下的AVPlayerView播放视频。
…..

操作不同类型的资源

你配置一个资源播放装置的的方式也许取决于你想要播放资源的种类。总的来说,这有两种类型:文件资源,比如本地文件、摄像资源、媒体库等;流文件,流媒体文件、网络视频等

加载和播放文件资源,这有几个步骤来播放文件资源:
  • 使用AVURLAsset创建资源
  • 创建AVPlayItem实例使用资源
  • 通过AVPlayer与item进行绑定
  • 等待直到item的状态特征指示为准备播放(你可以使用key-value监听状态的改变)
创建和准备流媒体播放装置。

通过使用URL初始化一个AVPlayerItem实例(你不能直接使用AVAsset实例去替代流媒体文件)

let url = NSURL("http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8")
videoItem = AVPlayerItem(URL:url)   self.playerItem.addObserver(self,forKeyPath:"status",options:.New,context:nil) //监听状态
videoplayer = AVPlayer(playerItem:self.playerItem)

当你将playerItem和player绑定时,它就变成了准备播放状态,当它变成了准备播放状态,playerItem就会创建一个AVAsset和AVAssetTrack实例,你可以使用这些检查流媒体的内容。
你可以获取视频时长,通过playItem的duration属性,当视频变成了准备播放状态时,这个属性就会拿到视频的正确时长。
你可以监听状态视频播放状态,例如上面代码。

播放单独资源

videoplayer.play() //播放
播放速度
videoplayer.rate = 2 //速度

值为1表示正常的播放速度,将速度设为0就等同于暂停。它也支持反向播放,通过将速度设为一个负值,你通过设置canPlayReverse属性来设定支持反向播放的状态,它默认的速度是-1,canPlaySlowReverse属性的速度在0到-1之间,canPlayFastReverse属性的速度是小于-1的值。

重新定位播放头

通过使用seekToTime:可以将播放移动到特定的时间:

let fiveSecondsIn = CMTimeMake(30, 1)//当前第20帧,每秒1帧,当前播放时间20/1videoplayer.seekToTime(fiveSecondsIn)//跳到fiveSecondsIn

然而,seekToTime:方法更偏向于性能而非精确。如果你想非常精确地跳转到某个进度,你应该使用seekToTime:toleranceBefore:toleranceAfter:

videoplayer.seekToTime(fiveSecondsIn, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)

当播放完成之后,播放头正好是停留在结束的位置,即使你使用play也没有任何作用,为了让视频播放完之后重新回到开始的位置,我们可以在通知中心注册一个AVPlayerItemDidPlayToEndTimeNotification通知。在通知的回调方法中,你可以通过seekToTime:将参数设为kCMTimeZero。

//监听播放结束NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(FCFAVPlayerController.playItemDidReachEnd(_:)), name: AVPlayerItemDidPlayToEndTimeNotification, object: videoItem)func playItemDidReachEnd(notifacation:NSNotification) {videoplayer.seekToTime(kCMTimeZero)
}

播放多个资源

你可以使用AVQueuePlayer播放一个资源队列,AVQueuePlayer是AVPlayer的子类,初始化一个AVQueuePlayer:

let playItem1 = AVPlayerItem(URL:NSURL(string: "http://tsmusic128.tc.qq.com/37023937.mp3")!)
let playItem2 = AVPlayerItem(URL:NSURL(string:"http://down.treney.com/mov/test.mp4")!)let items = NSArray(array: [playItem1,playItem2])
let queuePlayer = AVQueuePlayer(items: items as! [AVPlayerItem])
let layer = AVPlayerLayer(player: queuePlayer)
layer.frame = CGRectMake(20, 200, CGRectGetWidth(self.view.frame)-40, 200)
layer.backgroundColor = UIColor.blueColor().CGColor
self.view.layer.addSublayer(layer)
queuePlayer.play()

你可以使用play()播放资源队列,就像AVPlayer一样,队列按顺序播放每一个资源,如果你想播放在一个资源,你可以使用advanceToNextItem。
你同样可以使用insertItem:afterItem:,removeItem:,removeAllItem:修改资源队列。当你要增加一个新的资源的时候,你最好使用canInsertItem:afterItem:先判断队列是否可以插入新的资源,第二个参数里传入nil则是测试新资源追加到队列末尾。

let playNewItem = AVPlayerItem(URL:NSURL(string:"http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8")!)if queuePlayer.canInsertItem(playNewItem, afterItem: nil) {queuePlayer.insertItem(playNewItem, afterItem: nil)}

监听播放

你可以监听当前正在播放的资源的呈现状态及播放项目的各个方面,这对于那些无法直接控制下的状态变化非常有用,比如说:
* 如果用户使用多线程切换不同的app时,播放器的速度将有可能降至0
* 如果正在播放的是一个远程媒体,随着越来越多的数据可用item的loadedTimeRange和seekableTimeRange属性将会改变。这些属性将会告诉你资源的哪些时间段是可用的。
* 播放器的currentItem属性会随着新的item创建而改变
* 播放的过程中item的tracks属性可能会随着播放改变,一般是当内容有多种转码方式的时候,当编码方式切换的时候tracks会改变
* 播放器、item的status可能会改变如果播放失败或者其他一些原因
你可以使用key-value监听这些属性的改变。

监听状态的改变

当播放器或者item的状态改变时,它会发出一个通知。如果一个资源出于某些原因无法播放,那么status就会改变成AVPlayerStatusFailed或者AVPlayerItemStatusFailed,这种状态时,属性error将会有关于为什么不能播放的描述。
AV Foundation没有说明返回的通知是在什么线程,如果你想要更新UI,你必须确保任何相关的ui代码是在主线程中,例如:

//监控状态属性,videoItem.addObserver(self, forKeyPath: "status", options: .New, context:nil)//监控网络加载情况的属性videoItem.addObserver(self, forKeyPath: "loadedTimeRanges", options: .New, context: nil)override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {let playItem:AVPlayerItem = object as! AVPlayerItemif keyPath == "status" {if playItem.status == AVPlayerItemStatus.Failed {let error = playItem.errorprint(error)return}print("正在播放...,视频总长\(CMTimeGetSeconds(playItem.duration))")}else if keyPath == "loadedTimeRanges" {let array = playItem.loadedTimeRangeslet timeRange = array.first?.CMTimeRangeValue //本次缓冲时间范围let startSecondes = CMTimeGetSeconds((timeRange?.start)!);let durationSeconds = CMTimeGetSeconds((timeRange?.duration)!)let totalBuffer = startSecondes + durationSeconds //缓冲总长度print("缓冲总长度 \(totalBuffer)")}}

追踪显示状态

当资源有显示内容的话,你可以获取一个AVPlayerLayer的readyForDisplay属性通知

追踪时间

你可以使用addPeriodicTimeObserverForInterval:queue:usingBlock:或者addBoundaryTimeObserverForTimes:queue:usingBlock:去追踪播放进度。这样你就知道已经完成的时间和剩余时间,并且同步操作更新UI。

  • addPeriodicTimeObserverForInterval:queue:usingBlock:这个方法传入的是一个CMTime结构时间,每隔这个时间段,block会回调一次,开始和结束的时候,也会回调一次。
  • addBoundaryTimeObserverForTimes:queue:usingBlock:这个是传入了一个CMTime结构的数组,当播放到数组里的时间时,block会回调一次。
    你同样可以使用removeTimeObserver:取消这个观察者。

对于这两个方法,AVFoundation不会保证每次时间点到了都会回调block,如果前面的block没有执行完的时候,下一次就不会回调。所以应该保证block不会太耗时。

//追踪时间let durations = CMTimeGetSeconds(asset.duration)let firstTrack = CMTimeMakeWithSeconds(durations/3.0, 1)let secondTrack = CMTimeMakeWithSeconds(durations*2.0/3.0, 1)let times = [NSValue(CMTime: firstTrack),NSValue(CMTime:secondTrack)]self.videoplayer.addBoundaryTimeObserverForTimes(times, queue: nil) { print("xxxxx")}

swift AVFoundation AVPlayer 视频播放器——swift学习(十)相关推荐

  1. iOS AVPlayer视频播放器

    代码地址如下: http://www.demodashi.com/demo/11168.html 一.运行效果 二.实现过程 ①.创建播放器avPlayer //创建播放器url = [url str ...

  2. iOS自带AVPlayer视频播放器

    前言 iOS8之后系统自带使用AVPlayerViewController播放视频 AVPlayerViewController AVPlayerViewController和导航控制器差不多,需要将 ...

  3. java 安卓视频播放器_java - 学习做一个安卓视频播放器,有一些小问题!忘大家请教...

    小葫芦2017-04-18 10:51:293楼 首先解决你的一点疑惑,如何获取本地所有视频路径.Android系统在存储视频,音频,图片等资源的时候,会自动把其相关信息存储在数据库中,信息包括名字, ...

  4. 视频教程-FFmpeg+OpenGL ES+OpenSL ES打造Android视频播放器-Android

    FFmpeg+OpenGL ES+OpenSL ES打造Android视频播放器 从事Android移动端开发多年.主导开发过直播.电商.聊天等各种类型APP和游戏SDK:熟悉Android音视频开发 ...

  5. NDK学习笔记(十二) 原生图形api,使用AVILib创建一个AVI视频播放器

    文章目录 1.练练手,使用AVILib创建一个AVI视频播放器 (1)首先下载transcode,并配置avilib. (2)创建AbstractPlayerActivity并实现native方法 ( ...

  6. iOS 教你使用MP、AVPlayer、AVPlayerVC构建一个完整的视频播放器

    1.前言 标题必须要浮夸!要感觉像是一个大新闻.长者如是说. 其实是前几天去面试的时候,被要求说必须做过视频播放相关项目.有点闹心之余,就花了点时间在家写了一个简单播放器,基本实现了主流播放器的大致功 ...

  7. 视频播放器(AVPlayer)

    1.首先得创建AVPlayer,一个播放对象. 2.但是AVPlayer不能直接添加到self.view上,所以我们得创建一个 AVPlayerLayer的对象,是播放器所在的图层,设置视频填充的模式 ...

  8. 用Swift写服务端 — Perfect框架学习(一)

    用Swift写服务端 - Perfect框架学习(一) 一.Perfect简介 Perfect是一组完整.强大的工具箱.软件框架体系和Web应用服务器,可以在Linux.iOS和macOS (OS X ...

  9. AVPlayer自定制视频播放器(1)——视频播放器基本实现

    在iOS多媒体开发的过程中,经常会用到视频播放器,简单是视频播放器,直接使用苹果封装好的MPMoviePlayerController和MPMoviePlayerViewController就可以实现 ...

最新文章

  1. 摘录cocos2d-x 从环境搭建到win32项目移植android平台
  2. 客户端与服务端的TCP通信实现(Qt)
  3. java 面相,java学习17-面相对象(多态)
  4. eclipes快捷键
  5. 【iCore1S 双核心板_FPGA】例程十六:基于SPI的ARM与FPGA通信实验
  6. python-词云wordcloud-0223
  7. python socket server accpet 时间_Python socket.accept非阻塞?
  8. CheckBox控件和数据库的关联
  9. python字典合并_Python中如何实现两个字典合并
  10. 基于mysql的分析型数据库_数据仓库_数据分析_分析型数据库_MySQL查询
  11. 【CarMaker学习笔记】行人穿过人行道、横穿马路观察自动驾驶车辆避让实验
  12. java坦克大战 素材_坦克大战 游戏源码+ 素材+文档(了解面向对象的具体编程)
  13. Python工程目录结构
  14. 在VC++中的MFC利用一个dialoge对话框中按钮调用另一个dialoge对话框
  15. js 对象的解构赋值
  16. python程序写诗_万能的 LSTM:可以写代码可以写诗还能做文本情感分析
  17. 连接oralce远程服务器,修改表字段长度
  18. ThinkPHP框架的.env读取原理
  19. 困在“规矩”里的太二酸菜鱼,如何撑起百亿估值?
  20. STM32G070RBT6基于STM32CubeMX创建串口中断接收数据

热门文章

  1. 仓促的为ic配置了一下编辑器cke和ckf
  2. macbert4csc纠错
  3. MBA联考-20101213
  4. 2023年MCM/ICM美国大学生数学建模竞赛报名通知
  5. 有关SSL证书的一些事
  6. 如何去掉Windows7开机那个烦人的360安全卫士提示窗口
  7. 卡硬工具箱说系统服务器,卡硬工具箱|卡硬工具箱 v2.95官方版 - 系统天堂
  8. 【计算机组成原理】指令系统(二)—— 扩展操作码
  9. 鱼c论坛 python课后题pdf,我与python的第一次亲密接触_课后测试题及答案.pdf
  10. . NET6 Core 日志组件Log4net和Nlog