Build Status Platform License

KSPlayer

KSPlayer 是一个强大的媒体播放框架,适用于 iOS、tvOS、macOS、xrOS、visionOS、Mac Catalyst、SwiftUI、Apple Silicon M1 等平台。

English | 简体中文

特性

GPL 版本和 LGPL 版本的功能差异

特性 LGPL GPL
Dolby AC-4
AV1 硬件解码
所有解封装器,所有解码器
随时录制视频片段
流畅播放 8K 或 120 FPS 视频
Dovi P5 显示 HDR (不发热)
直播支持倒退观看
画中画支持字幕显示
在所有 Apple 平台上播放蓝光光盘
Annex-B 异步硬件解码(直播)
使用视频中的字体渲染字幕
使用内存缓存,在短时间内快速Seek
缓存数据到硬盘,预加载数据到硬盘
离线 AI 实时字幕生成和翻译
完整显示 ass 字幕效果 (使用 libass 渲染为图像)
在 App 的小窗口中播放视频(可恢复,支持 tvos 和 ios)
FFmpeg 版本 7.0.2 6.1.0
录制视频
360° 全景视频
画中画
硬件加速
无缝循环播放
自动检测去隔行
4k/HDR/HDR10/HDR10+/杜比视界
自定义 URL 协议,例如 nfs/smb/UPnP
多声道音频/空间音频
文本字幕/图像字幕/隐藏式字幕
搜索在线字幕 (shooter/assrt/opensubtitles)
低延迟 4K 直播 (局域网内小于 200 毫秒)
根据网络自动切换到多码率流

使用此 SDK 的 App 列表

App Store 链接 Logo
Alplayer
APTV
homeTV IPTV Player
IPTV +
LillyPlayer Video Player
SenPlayer
Smart IPTV
Snappier IPTV
Spatial Video Studio
SWIPTV - IPTV Smart Player
TracyPlayer
UHF - Love your IPTV logo
Zen IPTV

许可协议

KSPlayer 默认采用 GPL 许可(需要开源您自己的项目代码),我们希望大家自觉遵守 KSPlayer 项目的许可协议。 此外,还有一个付费版本,采用 LGPL 许可(请联系我们)。

如果由于商业原因,您不想遵守 GPL 许可或 LGPL 许可,您可以联系我们。 通过我们的授权,您可以获得更灵活的许可协议。 邮箱:kingslay@icloud.com

要求

演示

cd Demo
pod install

快速开始

CocoaPods

确保使用最新版本的 cocoapods 1.10.1+,可以使用命令 brew install cocoapods 安装

target 'ProjectName' do
    use_frameworks!
    pod 'KSPlayer',:git => 'https://github.com/kingslay/KSPlayer.git', :branch => 'main'
    pod 'DisplayCriteria',:git => 'https://github.com/kingslay/KSPlayer.git', :branch => 'main'
    pod 'FFmpegKit',:git => 'https://github.com/kingslay/FFmpegKit.git', :branch => 'main'
    pod 'Libass',:git => 'https://github.com/kingslay/FFmpegKit.git', :branch => 'main'
end

Swift Package Manager

dependencies: [
    .package(url: "https://github.com/kingslay/KSPlayer.git", .branch("main"))
]

用法

初始化

KSOptions.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"), subtitleURL: URL(string: "http://example.ksplay.subtitle")))

多分辨率,带有封面视频

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 options = KSOptions()
options.appendHeader(["Referer":"https:www.xxx.com"])
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 play time change
playerView.playTimeDidChange = { (currentTime: TimeInterval, totalTime: TimeInterval) in
    print("playTimeDidChange currentTime: \(currentTime) totalTime: \(totalTime)")
}

// Delegates
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` indicates first time loading
    func playerController(bufferedCount: Int, consumeTime: TimeInterval)
}

高级用法

效果

gif

开发与测试

欢迎任何贡献和 pull requests。但是,在您计划实现某些功能或尝试修复不确定的问题之前,建议先进行讨论。 如果您的 pull requests 可以构建并通过所有测试,我们将不胜感激。 :)

赞助者 & 赞助商

没有您的帮助,开源项目无法长久存在。 如果您发现 KSPlayer 有用,请考虑成为赞助商来支持这个项目。

通过 GitHub Sponsors 成为赞助商。 ❤️

您的用户图标或公司徽标将显示在此处,并链接到您的主页。

名字 Logo
UnknownCoder807
skrew
Kimentanm
byMohamedali
nakiostudio logo
CodingByJerez
andrefmsilva
romaingyh
FantasyKingdom
aart-rainey
nihalahmed
HatimDa
johnil

感谢 nightfall708 赞助了一台 mac mini

感谢 cdguy UnknownCoder807 skrew 和 LillyPlayer 社区赞助了一台 LG S95QR Sound Bar

感谢 skrew 和 LillyPlayer 社区赞助了一台 2022 Apple TV 4K

联系方式

如果您有商务合作项目或想要发起付费咨询,您可以通过电子邮件与我联系

1