YouTubeKit

此软件包允许提取任何 YouTube 视频的直接视频 URL 或音频 URL。 因此,它允许在原生 UI 组件中播放 YouTube 视频。

免责声明: YouTubeKit 目前仍在开发中,因此可能并非在所有地区都有效。

代码的结构与 pytube 项目(用 Python 编写)高度一致。 这应该使未来(由于 YouTube API 引起的)的重大更改更容易修复。

兼容性

它需要 iOS 13、watchOS 6、tvOS 13 或 macOS 10.15,因为它依赖于 Swift 5.5 并发模块。 visionOS 也受到支持。

用法

  1. 使用视频的 videoURLvideoID 创建一个 YouTube 对象
let video = YouTube(url: videoURL)

或者

let video = YouTube(videoID: videoID)
  1. 提取所有流
let streams = try await video.streams

这将返回一个 Stream 对象数组。

  1. 使用普通过滤器或提供的辅助函数(例如)过滤您想要的流
let streamsAt1080 = streams.streams(withExactResolution: 1080)
let streamsBelow1080 = streams.filter(byResolution: $0 < 1080)  // all streams with resolution lower than 1080p
let lowestResolution = streams.lowestResolutionStream()
let highestResolution = streams.highestResolutionStream()
let lowestAudioBitrate = streams.lowestAudioBitrateStream()
let highestAudioBitrate = streams.highestAudioBitrateStream()
let audioOnlyStreams = streams.filterAudioOnly()  // all streams without video track
let videoOnlyStreams = streams.filterVideoOnly()  // all streams without audio track
let combinedStreams = streams.filterVideoAndAudio()  // all streams with both video and audio track
  1. 检索元数据
let metadata = try await video.metadata

这将返回一个 YouTubeMetadata 对象。

示例 1

在 AVPlayer 中播放 YouTube 视频

let stream = try await YouTube(videoID: "QdBZY2fkU-0").streams
                          .filterVideoAndAudio()
                          .filter { $0.isNativelyPlayable }
                          .highestResolutionStream()

let player = AVPlayer(url: stream!.url)
// -> Now present the player however you like

isNativelyPlayable 参数用于仅过滤可以在当前操作系统和设备上原生解码的流。

示例 2

获取给定 YouTube ID 的最佳 m4a 纯音频 URL

let stream = try await YouTube(videoID: "9bZkp7q19f0").streams
                          .filterAudioOnly()
                          .filter { $0.fileExtension == .m4a }
                          .highestAudioBitrateStream()

let streamURL = stream.url

示例 3

获取给定 YouTube URL 的 mp4 类型且分辨率最高的视频 URL

let stream = try await YouTube(url: youtubeURL).streams
                          .filter { $0.includesVideoAndAudioTrack && $0.fileExtension == .mp4 }
                          .highestResolutionStream()

let streamURL = stream.url                      

isProgressive 参数用于仅过滤包含视频和音频的流。

示例 4

获取给定 YouTube ID 的直播 HLS URL

let hlsManifestUrl = try await YouTube(videoID: "21X5lGlDOfg").livestreams
                          .filter { $0.streamType == .hls }
                          .first

远程回退

使用本地 YouTube 提取器,存在 YouTube 可能突然更改其非官方 API 的问题,这可能会破坏您已发布的应用程序。 用户可能需要几天或几周的时间才能更新您的应用程序,导致某些功能在这段时间内无法使用。 为了防止这种情况,YouTubeKit 包含一个功能,允许您启用远程回退。 一旦本地提取失败,它就会切换到使用运行 youtube-dl 的远程服务器,该服务器会经常更新。 只需指定 YouTubeKit 应该按优先级顺序使用的 methods 即可。 其余的 API 保持完全相同 — 一切都由库处理。

let streams = try await YouTube(videoID: "2lAe1cqCOXo", methods: [.local, .remote]).streams

如果您只想进行远程提取,您也可以设置 methods: [.remote]

工作原理

由于流通常绑定到设备的位置或 IP 地址,因此我们不能简单地在远程服务器上使用 youtube-dl 并将流 URL 发送回去。 相反,服务器通过请求设备发出所有 HTTP 请求。 启动远程提取时,设备会打开与远程服务器的 WebSocket 连接。 然后,服务器将多个 HTTP 请求数据包发送到设备。 设备代表服务器执行这些请求并返回完整的响应。 然后,服务器处理并提取流 URL,并将它们发送回设备。 这确保了检索到的流 URL 可以在您的设备上播放。

目前,默认的远程服务器由我托管。 让你自己托管它的方法即将推出。