kingslay/KSPlayer

GitHub: kingslay/KSPlayer

KSPlayer是一个基于AVPlayer和FFmpeg的Apple平台视频播放框架,用于解决开发者在多设备上集成丰富媒体播放功能的需求。

Stars: 1567 | Forks: 300

![构建状态](https://img.shields.io/badge/build-%20passing%20-blue.svg) ![平台](https://img.shields.io/badge/Platform-%20iOS%20macOS%20tvOS%20visionOS%20-blue.svg) ![许可证](https://img.shields.io/badge/license-GPL-blue.svg) # KSPlayer KSPlayer 是一个强大的媒体播放框架,适用于 iOS、tvOS、macOS、xrOS、visionOS 和 Mac Catalyst。基于 AVPlayer 和 FFmpeg 构建,支持 AppKit/UIKit/SwiftUI。 English | [简体中文](./README_CN.md) ## 交流 - 邮箱: kingslay@icloud.com ## 许可证 KSPlayer 默认采用 GPL 许可证(需要开源您自己的项目代码),我们希望大家能够自觉遵守 KSPlayer 项目的许可协议。此外,还有一个采用 LGPL 许可证的付费版本(请联系我们)。 如果由于商业原因,您不希望遵守 GPL 或 LGPL 许可证,请联系我们。通过我们的授权,您可以获得更灵活的许可协议。 ## 功能 GPL 版本与 LGPL 版本的功能差异。 LGPL 版本的部分功能需要一次性付费,我已用 💰 标记出来。 | 功能 | LGPL | GPL | | ----------- | --------- | ------ | |视频超分辨率 |💰|❌| |进度条预览 |💰|❌| |将数据预缓存到硬盘|💰|❌| |零延迟切换视频|💰|❌| |通过 Wi-Fi 直通输出音频|💰|❌| |杜比视界 P5、P8(动态元数据)|💰|❌| |直播流支持回看|💰|❌| |在所有 Apple 平台上播放 ISO 蓝光碟|💰|❌| |同时播放独立的音频和视频 URL|💰|❌| |离线 AI 实时字幕生成与翻译|💰|❌| |ProAVPlayer 支持 MKV、原生杜比视界和杜比全景声。|💰|❌| |在 App 中以小窗口播放视频(可恢复,支持 iOS 和 tvOS)|💰|❌| |杜比 AC-4|✅|❌| |Swift Concurrency|✅|❌| |AV1 硬件解码|✅|❌| |逐词字幕|✅|❌| |HDR10+(动态元数据)|✅|❌| |文本字幕翻译|✅|❌| |使用系统字幕外观|✅|❌| |随时录制视频片段|✅|❌| |流畅播放 8K 或 120 FPS 视频|✅|❌| |显示带 HDR 效果的字幕|✅|❌| |视频下载与格式转换|✅|❌| |外部图像字幕,例如 SUP|✅|❌| |主字幕和副字幕|✅|❌| |调整饱和度、亮度和对比度|✅|❌| |画中画支持字幕显示|✅|❌| |Annex-B 异步硬件解码(直播流)|✅|❌| |使用视频中的字体渲染字幕|✅|❌| |使用内存缓存实现短时间范围内的快速搜索|✅|❌| |KSMEPlayer 支持所有解复用和解码格式|✅|❌| |完整显示 ass 字幕效果(使用 libass 渲染为图像)|✅|❌| |FFmpeg 版本|8.1.0|6.1.0| |录制视频|✅|✅| |4k/HDR/HDR10|✅|✅| |360° 全景视频|✅|✅| |画中画|✅|✅| |硬件加速器|✅|✅| |无缝循环播放|✅|✅| |自动检测隔行扫描|✅|✅| |多声道音频/空间音频|✅|✅| |自定义 URL 协议,如 nfs/smb/UPnP |✅|✅| |文本字幕/图像字幕/隐藏式字幕|✅|✅| |在线搜索字幕(shooter/assrt/opensubtitles)|✅|✅| |低延迟 4K 直播流(局域网内低于 200ms)|✅|✅| |根据网络自动切换多码率流|✅|✅| ## 要求 - iOS 13+,macOS 10.15+,tvOS 13+,xrOS 1+ ## 已授权使用此 SDK 的应用列表 此表未列出所有授权应用。如果您希望您的应用出现在上方列表中,请给我发送邮件。 | App Store 链接 | Logo | | -------------- | ---- | |[APTV](https://apps.apple.com/app/aptv/id1630403500)|| |[homeTV IPTV Player](https://apps.apple.com/app/hometv-iptv-player/id1636701357)|| |[IPTV +](https://apps.apple.com/app/iptv-my-smart-iptv-player/id1525121231)|| |[LillyPlayer Video Player](https://apps.apple.com/app/lillyplayer-video-player/id1446967273)|| |[SenPlayer](https://apps.apple.com/app/senplayer-hdr-media-player/id6443975850)|| |[Smart IPTV](https://apps.apple.com/app/smart-iptv-tv-and-movies-ott/id1492738910)|| |[Snappier IPTV](https://apps.apple.com/app/snappier-iptv/id1579702567)|| |[Spatial Video Studio](https://apps.apple.com/app/id6523429904)|| |[SWIPTV - IPTV Smart Player](https://apps.apple.com/app/swiptv-iptv-smart-player/id1658538188)|| |[TracyPlayer](https://apps.apple.com/app/tracyplayer/id6450770064)|| |[UHF - Love your IPTV](https://apps.apple.com/app/uhf-love-your-iptv/id6443751726)|| |[Zen IPTV](https://apps.apple.com/fr/app/zen-iptv/id6458223193)|| ## 演示 ``` cd Demo pod install ``` - 使用 Xcode 打开 Demo/Demo.xcworkspace。 ## 快速开始 #### 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 头 ``` 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) } ``` ## 高级用法 - 继承 PlayerView 以自定义播放逻辑和 UI。 class CustomVideoPlayerView: IOSVideoPlayerView { override func updateUI(isLandscape: Bool) { super.updateUI(isLandscape: isLandscape) toolBar.playbackRateButton.isHidden = true } override func onButtonPressed(type: PlayerButtonType, button: UIButton) { if type == .landscape { // 在此处添加您自己的按钮按下行为 } else { super.onButtonPressed(type: type, button: button) } } } - 选择轨道 override open func player(layer: KSPlayerLayer, state: KSPlayerState) { super.player(layer: layer, state: state) if state == .readyToPlay, let player = layer.player { let tracks = player.tracks(mediaType: .audio) let track = tracks[1] /// 轨道的名称 let name = track.name /// 轨道的语言 let language = track.language /// 选择该轨道 player.select(track: track) } } - 在 KSOptions 中设置属性 open class KSOptions { /// 最低缓存视频时间 @Published public var preferredForwardBufferDuration = KSOptions.preferredForwardBufferDuration /// 最大缓存视频时间 public var maxBufferDuration = KSOptions.maxBufferDuration /// 是否开启秒开 public var isSecondOpen = KSOptions.isSecondOpen /// 开启精确 seek public var isAccurateSeek = KSOptions.isAccurateSeek /// 仅适用于短视频 public var isLoopPlay = KSOptions.isLoopPlay /// 是否自动播放,默认 false public var isAutoPlay = KSOptions.isAutoPlay /// seek 完是否自动播放 public var isSeekedAutoPlay = KSOptions.isSeekedAutoPlay /* AVSEEK_FLAG_BACKWARD: 1 AVSEEK_FLAG_BYTE: 2 AVSEEK_FLAG_ANY: 4 AVSEEK_FLAG_FRAME: 8 */ public var seekFlags = Int32(0) // ffmpeg 仅缓存 http public var cache = false public var outputURL: URL? public var display = DisplayEnum.plane public var avOptions = [String: Any]() public var formatContextOptions = [String: Any]() public var decoderOptions = [String: Any]() public var probesize: Int64? public var maxAnalyzeDuration: Int64? public var lowres = UInt8(0) public var startPlayTime: TimeInterval = 0 public var startPlayRate: Float = 1.0 public var registerRemoteControll: Bool = true // 默认支持来自系统控制中心的控制 public var referer: String? public var userAgent: String? // 音频 public var audioFilters = [String]() public var syncDecodeAudio = false // 字幕 public var autoSelectEmbedSubtitle = true public var subtitleDisable = false public var isSeekImageSubtitle = false // 视频 public var videoDelay = 0.0 // 秒 public var autoDeInterlace = false public var autoRotate = true public var destinationDynamicRange: DynamicRange? public var videoAdaptable = true public var videoFilters = [String]() public var syncDecodeVideo = false public var hardwareDecode = KSOptions.hardwareDecode public var asynchronousDecompression = true public var videoDisable = false public var canStartPictureInPictureAutomaticallyFromInline = true } ## 效果 ![gif](https://raw.githubusercontent.com/kingslay/KSPlayer/main/Demo/demo.gif) ## 开发与测试 非常欢迎任何形式的贡献和拉取请求。然而,在您计划实现某些功能或尝试修复不确定的问题之前,建议先发起讨论。如果您的拉取请求能够构建成功并且所有测试都通过,我们将不胜感激。:) ## 支持者与赞助商 没有您的帮助,开源项目无法长久发展。如果您觉得 KSPlayer 有用,请考虑通过成为赞助商来支持此项目。 通过 [GitHub Sponsors](https://github.com/sponsors/kingslay/) 成为赞助商。:heart: 您的用户头像或公司 logo 将显示在此处,并附有指向您主页的链接。 |姓名| 应用名称 | 应用 Logo | | ----------- | ----------- |----------- | |[UnknownCoder807](https://github.com/UnknownCoder807)|[Snappier](https://apps.apple.com/app/snappier-iptv/id1579702567)|| |[skrew](https://github.com/skrew)|| |[Kimentanm](https://github.com/Kimentanm)|| |[nakiostudio](https://github.com/nakiostudio)|[UHF](https://apps.apple.com/app/uhf-love-your-iptv/id6443751726)|| |[CodingByJerez](https://github.com/CodingByJerez)|| |[andrefmsilva](https://github.com/andrefmsilva)|| |[romaingyh](https://github.com/romaingyh)|[Zen IPTV](https://apps.apple.com/fr/app/zen-iptv/id6458223193)|| |[FantasyKingdom](https://github.com/FantasyKingdom)|[Senplayer](https://apps.apple.com/us/app/senplayer-hdr-media-player/id6443975850)|| |[aart-rainey](https://github.com/aart-rainey)|| |[nihalahmed](https://github.com/nihalahmed)|| |[johnil](https://github.com/johnil)|| |[MeloDreek](https://github.com/MeloDreek)|| |[nsplay1990](https://github.com/nsplay1990)|| |[AppleChillVibez](https://github.com/AppleChillVibez)|| |[stekc](https://github.com/stekc)|| |[AstroChivs](https://github.com/AstroChivs)|| |[bmob222](https://github.com/bmob222)|| |[pateltejas](https://github.com/pateltejas)|| |[ewanl2001](https://github.com/ewanl2001)|| |[themisterholliday](https://github.com/themisterholliday)|| |[JulienDev](https://github.com/JulienDev)|| |[Sheinices](https://github.com/Sheinices)|| |[Etheirystech](https://github.com/Etheirystech)|| |[loicleser](https://github.com/loicleser)|| 感谢 [nightfall708](https://github.com/nightfall708) 赞助一台 Mac mini 感谢 [cdguy](https://github.com/cdguy)、[UnknownCoder807](https://github.com/UnknownCoder807)、[skrew](https://github.com/skrew) 和 LillyPlayer 社区赞助一台 LG S95QR Sound Bar 感谢 [skrew](https://github.com/skrew) 和 LillyPlayer 社区赞助一台 2022 Apple TV 4K 感谢 [bgoncal](https://github.com/bgoncal) 赞助一台 HomePod mini ![1](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/e40aea5842203145.jpg)
标签:AI字幕生成, API框架, AV1解码, AVPlayer, DNS解析, Dolby Atmos, Dolby Vision, FFmpeg, GPL许可, HDR视频, iOS开发, LGPL许可, macOS开发, SwiftUI, Swift编程, tvOS开发, visionOS开发, 亮度调节, 增强现实, 多媒体框架, 字幕功能, 实时翻译, 小窗播放, 开源项目, 数据预缓存, 桌面应用, 横屏支持, 电视应用, 直播回放, 硬件解码, 移动应用, 竖屏支持, 苹果平台, 蓝光光盘播放, 视频升频, 视频播放器, 进度控制, 进度条预览, 零延迟切换, 音量调节, 音频直通