一个 Swift 包,可以轻松播放 YouTube 视频。
import SwiftUI
import YouTubePlayerKit
struct ContentView: View {
var body: some View {
// WWDC 2019 Keynote
YouTubePlayerView(
"https://youtube.com/watch?v=psL_5RIBqnY"
)
}
}
查看示例应用程序,了解 YouTubePlayerKit 的实际应用。只需打开 Example/Example.xcodeproj
并运行 "Example" scheme。
要使用 Apple 的 Swift Package Manager 进行集成,请将以下内容作为依赖项添加到您的 Package.swift
中
dependencies: [
.package(url: "https://github.com/SvenTiigi/YouTubePlayerKit.git", from: "2.0.0")
]
或者导航到您的 Xcode 项目,然后选择 Swift Packages
,单击“+”图标并搜索 YouTubePlayerKit
。
注意
将 YouTubePlayerKit 集成到 macOS 或 Mac Catalyst 目标时,请务必在“Signing & Capabilities”部分中启用“Outgoing Connections (Client)”。
向 App Store 提交包含 YouTubePlayerKit
的应用程序时,请务必在审核备注中添加指向 YouTube API 服务条款 的链接。
https://developers.google.com/youtube/terms/api-services-terms-of-service
提示
请参阅 YouTubePlayerKit 文档 以获取完整概述。
使用 SwiftUI
时,可以通过声明 YouTubePlayerView
轻松显示 YouTubePlayer
。
import SwiftUI
import YouTubePlayerKit
struct ContentView: View {
let youTubePlayer: YouTubePlayer = "https://youtube.com/watch?v=psL_5RIBqnY"
var body: some View {
YouTubePlayerView(self.youTubePlayer) { state in
// An optional overlay view for the current state of the player
switch state {
case .idle:
ProgressView()
case .ready:
EmptyView()
case .error(let error):
ContentUnavailableView(
"Error",
systemImage: "exclamationmark.triangle.fill",
description: Text("YouTube player couldn't be loaded: \(error)")
)
}
}
// Optionally react to specific updates such as the fullscreen state
.onReceive(
self.youTubePlayer.fullscreenStatePublisher
) { fullscreenState in
if fullscreenState.isFullscreen {
// ...
}
}
}
}
提示
您可以选择使用 @StateObject
或 @ObservedObject
标记 YouTubePlayer,以便在源、参数或 isLoggingEnabled 更改时自动更新您的视图。
使用 UIKit
或 AppKit
时,您可以使用 YouTubePlayerViewController
或 YouTubePlayerHostingView
。
import UIKit
import YouTubePlayerKit
let youTubePlayerViewController = YouTubePlayerViewController(
player: "https://youtube.com/watch?v=psL_5RIBqnY"
)
let youTubePlayerHostingView = YouTubePlayerHostingView(
player: "https://youtube.com/watch?v=psL_5RIBqnY"
)
// Access the player on both instances via the `.player` property
// Example: youTubePlayerViewController.player
YouTubePlayer
是播放特定 YouTube 视频并与底层 YouTube iFrame API 交互的核心对象。
如前面的示例所示,您可以使用字符串文字初始化播放器
let youTubePlayer: YouTubePlayer = "https://youtube.com/watch?v=psL_5RIBqnY"
要完全控制,您可以使用 YouTubePlayer.Source
、YouTubePlayer.Parameters
和 YouTubePlayer.Configuration
初始化 YouTubePlayer
let youTubePlayer = YouTubePlayer(
// Possible values: .video, .videos, .playlist, .channel
source: .video(id: "psL_5RIBqnY"),
// The parameters of the player
parameters: .init(
autoPlay: true,
showControls: true,
loopEnabled: true,
startTime: .init(value: 5, unit: .minutes),
// ...
),
// The configuration of the underlying web view
configuration: .init(
fullscreenMode: .system,
allowsInlineMediaPlayback: true,
customUserAgent: "MyCustomUserAgent",
// ...
)
)
要区分参数和配置,请理解参数控制 YouTube 播放器的行为和样式,而配置与底层 web 视图相关联。 实例化后无法修改配置;但是,可以更新参数,如下所示
youTubePlayer.parameters.showControls = false
警告
在运行时更新 YouTubePlayer.Parameters
将导致播放器重新加载。
YouTubePlayer.Source
是一个枚举,允许您指定应加载/提示哪个 YouTube 源。
// A single video
let video: YouTubePlayer.Source = .video(id: "psL_5RIBqnY")
// Series of videos
let videos: YouTubePlayer.Source = .videos(ids: ["w87fOAG8fjk", "RXeOiIDNNek", "psL_5RIBqnY"])
// Playlist
let playlist: YouTubePlayer.Source = .playlist(id: "PLHFlHpPjgk72Si7r1kLGt1_aD3aJDu092")
// Channel
let channel: YouTubePlayer.Source = .channel(name: "GoogleDevelopers")
您也可以使用 URL 初始化源。
let source: YouTubePlayer.Source? = .init(urlString: "https://youtube.com/watch?v=psL_5RIBqnY")
注意
URL 解析逻辑旨在处理大多数已知的 YouTube URL 格式,但可能存在一些它未涵盖的变体。
YouTubePlayer
允许您访问底层的 YouTube Player iFrame API 以播放、暂停、查找、检索视频信息等等。
大多数 API 都是 async
和 throwable
函数。
// Pauses the currently playing video
try await youTubePlayer.pause()
提示
请参阅 文档 以获取可用 API 的完整概述。
如果发生错误,大多数函数都会抛出 YouTubePlayer.APIError
。 这使您可以轻松地检查错误的原因、任何底层错误以及执行的 JavaScript 及其响应。
do {
try await youTubePlayer.setCaptions(fontSize: .small)
} catch {
print(
"Failed to set captions font size",
error.reason,
error.underlyingError,
error.javaScript,
error.javaScriptResponse
)
}
此外,还有几个 Publisher 可用于响应播放器的更改
// Observe playback metadata
let cancellable = youTubePlayer
.playbackMetadataPublisher
.sink { playbackMetadata in
// ...
}
您可以通过 YouTubeVideoThumbnail
对象加载 YouTube 视频缩略图。
// Initialize an instance of YouTubeVideoThumbnail
let videoThumbnail = YouTubeVideoThumbnail(
videoID: "psL_5RIBqnY",
// Choose between default, medium, high, standard, maximum
resolution: .high
)
// Retrieve the URL, if available
let url: URL? = videoThumbnail.url
// Retrieve the image, if available.
let image: YouTubeVideoThumbnail.Image? = try await videoThumbnail.image()
此外,播放器允许您轻松检索当前加载视频的缩略图 URL 和图像。
// Returns the video thumbnail URL of the currently loaded video
try await youTubePlayer.getVideoThumbnailURL()
/// Returns the video thumbnail of the currently loaded video
try await youTubePlayer.getVideoThumbnailImage(resolution: .maximum)
如果您希望更深入地了解 YouTube Player iFrame JavaScript API 的底层通信,您可以通过 isLogginEnabled
参数启用播放器的日志记录。
YouTubePlayer
利用 统一日志记录系统 (OSLog) 来记录有关播放器选项、JavaScript 事件和评估的信息。
// Enable or disable logging during initialization
let youTubePlayer = YouTubePlayer(
source: [
"w87fOAG8fjk",
"RXeOiIDNNek",
"psL_5RIBqnY"
],
isLoggingEnabled: true
)
// To update during runtime update the isLoggingEnabled property
youTubePlayer.isLoggingEnabled = false
// Additionally, you can retrieve an instance of the logger if logging is enabled.
let logger: Logger? = youTubePlayer.logger()
您可以通过以下发布者观察来自底层 YouTube Player iFrame API 的 YouTubePlayer.Event
的传入流。
let cancellable = youTubePlayer
.eventPublisher
.sink { event in
switch event.name {
case .playbackQualityChange:
break
case .autoplayBlocked:
break
default:
break
}
}
重要提示
YouTubePlayerKit 支持官方和非官方/未记录的事件。 请参阅 YouTubePlayer.Event.Name
枚举以了解更多详细信息。
要在 YouTube 播放器 JavaScript 实例上运行 自定义 JavaScript
try await youTubePlayer.evaluate(
javaScript: "\(.youTubePlayer).play()"
)
注意
\(.youTubePlayer)
的自定义字符串插值是 YouTube 播放器 JavaScript 变量的占位符。
或者,您可以使用以下便捷函数直接调用 YouTube 播放器 JavaScript 对象上的函数
try await youTubePlayer.evaluate(
javaScript: .youTubePlayer(
functionName: "setLoop",
parameters: [
true
]
)
)
如果您希望进一步自定义底层 HTML,您可以在初始化播放器实例时配置 YouTubePlayer.HTMLBuilder
let youTubePlayer = YouTubePlayer(
source: .video(id: "psL_5RIBqnY"),
configuration: .init(
htmlBuilder: .init(
youTubePlayerJavaScriptVariableName: "youtubePlayer",
youTubePlayerEventCallbackURLScheme: "youtubeplayer",
youTubePlayerEventCallbackDataParameterName: "data",
youTubePlayerIframeAPISourceURL: .init(string: "https://www.youtube.com/iframe_api")!,
htmlProvider: { htmlBuilder, jsonEncodedYouTubePlayerOptions in
// TODO: Return custom HTML string
}
)
)
)