Skip to content

Alanko5/KSPlayer

Repository files navigation

KSPlayer

一、介绍

KSPlayer是一款基于 AVPlayer, FFmpeg 纯Swift的音视频播放器,支持所有视频格式和全景视频,支持苹果全平台。实现高可用,高性能的音视频播放能力。它包含UI控件模块、字幕模块、播放器内核模块。这些模块都是解耦的,可以通过pod按需接入。

原理详解

二、功能

  • 首屏秒开
  • 无缝循环播放
  • 精确seek
  • 支持外挂字幕、内挂字幕
  • 倍速播放
  • 支持iOS、macOS、tvOS
  • 支持360°全景视频
  • 使用Metal进行渲染
  • 支持所有媒体格式(自动切换KSAVPlayer和KSMEPlayer)
  • 支持横竖屏切换,支持自动旋转屏幕
  • 右侧 1/2 位置上下滑动调节屏幕亮度(模拟器调不了亮度,请在真机调试)
  • 左侧 1/2 位置上下滑动调节音量(模拟器调不了音量,请在真机调试)
  • 左右滑动调节播放进度
  • 清晰度切换
  • H.264 H.265 硬件解码(VideoToolBox)
  • 首屏耗时,缓冲次数,缓冲时长监控
  • AirPlay
  • Bitcode

三、要求

  • iOS 9 +, macOS 10.11 +, tvOS 10.2 +
  • Xcode 10.2
  • Swift 5.0

四、安装

CocoaPods

确保使用最新版本 cocoapods 1.6, 可以使用命令 brew install cocoapods 来安装

target 'ProjectName' do
    use_frameworks!
    pod 'KSPlayer',:git => 'https://github.com/kingslay/KSPlayer.git', :branch => 'master'
    pod 'Openssl',:git => 'https://github.com/kingslay/KSPlayer.git', :branch => 'master'
end

Carthage

git "https://github.com/kingslay/KSPlayer.git" "master"

Demo

进Demo目录打开Demo.xcworkspace。

五、使用

初始化

KSPlayerManager.secondPlayerType = KSMEPlayer.self
playerView = IOSVideoPlayerView()
view.addSubview(playerView)
playerView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
    playerView.topAnchor.constraint(equalTo: view.readableContentGuide.topAnchor),
    playerView.leftAnchor.constraint(equalTo: view.leftAnchor),
    playerView.rightAnchor.constraint(equalTo: view.rightAnchor),
    playerView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
playerView.backBlock = { [unowned self] in
    if UIApplication.shared.statusBarOrientation.isLandscape {
        self.playerView.updateUI(isLandscape: false)
    } else {
        self.navigationController?.popViewController(animated: true)
    }
}

设置普通视频

playerView.set(url:URL(string: "http://baobab.wdjcdn.com/14525705791193.mp4")!)
playerView.set(resource: KSPlayerResource(url: url, name: name!, cover: URL(string: "http://img.wdjimg.com/image/video/447f973848167ee5e44b67c8d4df9839_0_0.jpeg"), subtitle: nil))

多清晰度,带封面视频

let res0 = KSPlayerResourceDefinition(url: URL(string: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")!,
                                      definition: "高清")
let res1 = KSPlayerResourceDefinition(url: URL(string: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")!,
                                      definition: "标清")
   
let asset = KSPlayerResource(name: "Big Buck Bunny",
                             definitions: [res0, res1],
                             cover: URL(string: "https://upload.wikimedia.org/wikipedia/commons/thumb/c/c5/Big_buck_bunny_poster_big.jpg/848px-Big_buck_bunny_poster_big.jpg"))

playerView.set(resource: asset)

设置 HTTP header

let header = ["User-Agent":"KSPlayer"]
let options = ["AVURLAssetHTTPHeaderFieldsKey":header]
  
let definition = KSPlayerResourceDefinition(url: URL(string: "http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")!,
                                            definition: "高清",
                                            options: options)
  
let asset = KSPlayerResource(name: "Video Name",
                             definitions: [definition])
playerView.set(resource: asset)

监听状态变化

//Listen to when the play time changes
playerView.playTimeDidChange = { (currentTime: TimeInterval, totalTime: TimeInterval) in
    print("playTimeDidChange currentTime: \(currentTime) totalTime: \(totalTime)")
}
///协议方式
public protocol PlayerControllerDelegate: class {
    func playerController(state: KSPlayerState)
    func playerController(currentTime: TimeInterval, totalTime: TimeInterval)
    func playerController(finish error: Error?)
    func playerController(maskShow: Bool)
    func playerController(action: PlayerButtonType)
    // bufferedCount: 0代表首次加载
    func playerController(bufferedCount: Int, consumeTime: TimeInterval)
}

六、进阶用法

  • 继承 PlayerView 自定义播放逻辑和UI。

  • 设置KSPlayerManager 、KSDefaultParameter里面的属性

    public struct KSPlayerManager {
        /// 是否自动播放,默认false
        public static var isAutoPlay = false
        /// seek完是否自动播放
        public static var isSeekedAutoPlay = true
        /// 顶部返回、标题、AirPlay按钮 显示选项,默认.Always,可选.HorizantalOnly、.None
        public static var topBarShowInCase = KSPlayerTopBarShowCase.always
        /// 自动隐藏操作栏的时间间隔 默认5秒
        public static var animateDelayTimeInterval = TimeInterval(5)
        /// 开启亮度手势 默认true
        public static var enableBrightnessGestures = true
        /// 开启音量手势 默认true
        public static var enableVolumeGestures = true
        /// 开启进度滑动手势 默认true
        public static var enablePlaytimeGestures = true
        /// 竖屏是否开启手势控制 默认false
        public static var enablePortraitGestures = false
        /// 最低缓存视频时间
        public static var preferredForwardBufferDuration = 3.0
         /// 最大缓存视频时间
        public static var maxBufferDuration = 30.0
        /// 播放内核选择策略 先使用firstPlayer,失败了自动切换到secondPlayer,播放内核有KSAVPlayer、KSMEPlayer两个选项
        public static var firstPlayerType: MediaPlayerProtocol.Type = KSAVPlayer.self
        public static var secondPlayerType: MediaPlayerProtocol.Type?
        /// 是否开启秒开
        public static var isSecondOpen = false
        /// 开启精确seek
        public static var isAccurateSeek = true
        /// 开启无缝循环播放
        public static var isLoopPlay = false
        /// 日志输出方式
        public static var logFunctionPoint: (String) -> Void = {
            print($0)
        }
    }
    public struct KSDefaultParameter {
        /// 视频颜色编码方式 支持kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange kCVPixelFormatType_420YpCbCr8BiPlanarFullRange kCVPixelFormatType_32BGRA 默认是kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
        public static var bufferPixelFormatType = kCVPixelFormatType_420YpCbCr8BiPlanarFullRange
        /// 开启 硬解 默认true
        public static var enableVideotoolbox = true
        /// 日志级别
        public static var logLevel = AV_LOG_WARNING
        public static var audioPlayerMaximumFramesPerSlice = Int32(4096)
        public static var audioPlayerMaximumChannels = Int32(2)
        public static var audioPlayerSampleRate = Int32(44100)
        // 视频缓冲算法函数
        public static var playable: (LoadingStatus) -> Bool = { status in
            guard status.frameCount > 0 else { return false }
            if status.isSecondOpen, status.isFirst || status.isSeek, status.frameCount == status.frameMaxCount {
                if status.isFirst {
                    return true
                } else if status.isSeek {
                    return status.packetCount >= status.fps
                }
            }
            return status.packetCount > status.fps * Int(KSPlayerManager.preferredForwardBufferDuration)
        }
    
        // 画面绘制类
        public static var renderViewType: (PixelRenderView & UIView).Type = {
            #if arch(arm)
            return OpenGLPlayView.self
            #else
            #if targetEnvironment(simulator)
            return SampleBufferPlayerView.self
            #else
            return MetalPlayView.self
            #endif
            #endif
        }()
    }

七、效果:

gif

八、参考:

本项目参考了 ZFPlayerSGPlayer

About

iOS/macOS/tvOS video player

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Swift 99.0%
  • Other 1.0%