美文网首页iOS进阶知识程序员iOS Developer
Swift 封装一个视频播放器 VGPlayer

Swift 封装一个视频播放器 VGPlayer

作者: Vein_ | 来源:发表于2017-06-13 11:18 被阅读1317次
Banners.png

# 前言

之前学习了 Swift 一直想做一个项目,这次下定决心花了近1个月的空闲时间基于 AVPlayer 封装了一个视频播放器。

# 源代码

  • GitHub地址:VGPlayer
  • 有什么意见建议可以提 issues,在博文下留言,如果觉得不错,欢迎点star。

# 更新列表

  • 2017-6-13 v0.0.1
  • 2017-6-17 v0.0.2 支持外挂字幕 格式 srt & ass 两种都支持
  • 2017-7-1 边播边缓存 v0.1.0
  • 2017-7-11 修复所有编译⚠️. v0.1.2
  • 2017-7-16 修复缓存视频时URL解析错误导致的crash. v0.1.3
  • 2017-8-10 修复退出全屏后的播放视图frame error问题,修复iOS9播放卡住问题,增加example 嵌入在cell中的播放模式. v0.1.4
  • 2017-9-6 v0.1.5 修复URL 解析问题 修复暂停播放问题
  • 2017-9-21 v0.2.0 整理代码、转换成Swift 4

# 演示

demo1.gif demo2.gif vgplayer_embed_in_cell.gif

# 功能

  • 集成了视频播放器常有的手势,包括单击显示控制视图,双击暂停,水平滑动快进、后退,竖直滑动亮度和音量调节。
  • 全屏播放,自适应手机屏幕旋转方向。
  • 自定义控制视图

# 实现思路

流程图.png

VGPlayer

VGPlayer是一个对AVPlayer封装提供播放功能,displayView为播放器画面绘制。
主要是使用了以下几个类:

  • AVURLAsset是 AVAsset的子类,用来本地或者网络视频地址的初始化网络请求,也可以用来获取视频每一帧的画面来实现滑动提前预览图的功能(后续应该会版本迭代加上此功能)
  • AVPlayerItem 是对AVPlayer播放的视频数据管理,对播放的Asset资源进行记录,提供或者视频的时间,播放状态等。
  • AVPlayer 调控数据和视图
  • AVPlayerLayer 进行视频视图绘制

VGPlayer封装AVPlayer提供给调用者可选代理方法

// player delegate
    // play state
    func vgPlayer(_ player: VGPlayer, stateDidChange state: VGPlayerState)
    // playe Duration
    func vgPlayer(_ player: VGPlayer, playerDurationDidChange currentDuration: TimeInterval, totalDuration: TimeInterval)
    // buffer state
    func vgPlayer(_ player: VGPlayer, bufferStateDidChange state: VGPlayerBufferstate)
    // buffered Duration
    func vgPlayer(_ player: VGPlayer, bufferedDidChange bufferedDuration: TimeInterval, totalDuration: TimeInterval)
    // play error
    func vgPlayer(_ player: VGPlayer, playerFailed error: VGPlayerError)

VGPlayerView

  • VGPlayerView负责画面的展示,,只作为展示,而绘制层则是AVPlayerLayer提供,可继承此类进行控制视图的自定义
  • VGPlayerView封装AVPlayerLayer提供可选代理方法
// player view delegate
    /// fullscreen
    func vgPlayerView(_ playerView: VGPlayerView, willFullscreen fullscreen: Bool)
    /// close play view
    func vgPlayerView(didTappedClose playerView: VGPlayerView)
    /// displaye control
    func vgPlayerView(didDisplayControl playerView: VGPlayerView)

VGPlayerError

  • VGPlayerError一个 struct 用来播放出现Error时返回

# 细节调整

  • 后台播放的实现
    设置工程
backgroundModes.png
// AppDelegate settings
 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        do
        {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        }
        catch let error as NSError
        {
            print(error)
        }
        return true
    }

设置VGPlayer的Background mode

self.player.backgroundMode = .proceed
  • VGPlayerUtils 提供判断视频类型方法和一些通用的方法
  • UIButton+VGPlayer 扩展按钮点击范围
  • Timer+VGPlayer 解决Timer的 retain cycle问题

边播边缓存 (参考: VIMediaCache)

  • 使用AVAssetResourceLoader 来控制视频缓存

  • 使用Range请求数据,可取消下载,分段缓存

  • 在 Simulator debugging, 可以看到缓存的文件


    test
  • 使用:

// Settings maxCacheSize
VGPlayerCacheManager.shared.cacheConfig.maxCacheSize = 160000000

// Setting maxCacheAge   default one weak
VGPlayerCacheManager.shared.cacheConfig.maxCacheAge = 60 * 60 * 24 * 7

// clean all cache
VGPlayerCacheManager.shared.cleanAllCache()

// clean old disk cache. 
// This is an async operation.
VGPlayerCacheManager.shared.cleanOldFiles { }

# 参考

# 总结

  • 了解了AVPlayer的整体结构,对播放过程完整的思路和一些遇到的问题。
  • 踩了屏幕旋转细节、按钮点击范围调整的一些交互细节的坑

相关文章

网友评论

  • eecac22d66cf:只希望视频页面能横屏,其他都是竖屏(所以不能全局设置打开landscope Right)。请问这种情况怎么处理呢
  • Tate_code:最近刚好想学下swift视频这一块,感谢分享O(∩_∩)O哈!
  • e8943869101b:想请问下外挂字幕怎么实现
    Vein_:解析srt 、ass两种格式的字幕文件 ,解析成包括index标记、 star字幕开始时间、 end字幕结束时间 content字幕内容的结构体 , 然后剩下就是写label 展示上去 解析实现具体可以看看VGSubtitles
  • 45f2a6500aeb:谢谢分享
  • withJessicaZ:为什么pod找不到VGPlayer呢
    withJessicaZ:@Vein_ 竟然又可以了:flushed:
    withJessicaZ:@Vein_ 有没有其它联系方式:pensive: 我这里确实不行 想截图给你看看:pensive:
    Vein_:platform :ios, '8.0'
    use_frameworks!

    target ‘test’ do
    pod 'VGPlayer'
    end

    我测试了一下没有问题的
  • 小天枢丶:你好,我想问下缓存功能是怎么用的?
    Vein_:@null_b703 pod 'VGPlayer', '~>0.1.0'
    0.1.0以后版本才加入cache功能
    小天枢丶:@Vein_ pod安装下来的话是没有MediaCache文件夹的..VGPlayer.swift文件里面也没有缓存的那两行代码,直接下载下来拖进项目里面才有..
    Vein_:已经直接集成进去了。本地的视频不会缓存,网络的会缓存。
    fileprivate var resourceLoaderManager = VGPlayerResourceLoaderManager()
    self.playerItem = resourceLoaderManager.playerItem(URL)
    上面这两行就直接能缓存了 你可以在VGPlayer.swift 这个源文件看到
    然后
    VGPlayerCacheManager.shared.cacheConfig.maxCacheSize = 160000000

    // Setting maxCacheAge default one weak
    VGPlayerCacheManager.shared.cacheConfig.maxCacheAge = 60 * 60 * 24 * 7
    // clean all cache
    VGPlayerCacheManager.shared.cleanAllCache()

    // clean old disk cache.
    // This is an async operation.
    VGPlayerCacheManager.shared.cleanOldFiles { }
    可以对缓存做限制和清除

本文标题:Swift 封装一个视频播放器 VGPlayer

本文链接:https://www.haomeiwen.com/subject/aildqxtx.html