-
-
Notifications
You must be signed in to change notification settings - Fork 72
/
Copy pathYouTubePlayer+Configuration.swift
155 lines (128 loc) · 7.66 KB
/
YouTubePlayer+Configuration.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import Foundation
// MARK: - YouTubePlayer+Configuration
public extension YouTubePlayer {
/// A YouTube player configuration.
struct Configuration: Hashable, Sendable {
// MARK: Properties
/// The fullscreen mode.
/// - Important: Setting the fullscreen mode to ``YouTubePlayer/FullscreenMode/web`` does not guarantee
/// the use of HTML5 fullscreen mode, as the decision ultimately depends on the underlying YouTube Player iFrame API.
public let fullscreenMode: FullscreenMode
/// A Boolean value that indicates whether HTML5 videos play inline or use the native full-screen controller.
public let allowsInlineMediaPlayback: Bool
/// A Boolean value that indicates whether the web view allows media playback over AirPlay.
public let allowsAirPlayForMediaPlayback: Bool
/// A Boolean value that indicates whether HTML5 videos can play Picture in Picture.
/// - Important: Picture-in-Picture mode may not work in every situation or with every video. Its support and availability depend on the underlying YouTube Player iFrame API.
/// - Precondition: Please enable the `Audio`, `AirPlay`, and `Picture in Picture` background modes in your app's capabilities.
/// - Note: Picture-in-Picture media playback is supported only on iOS and visionOS.
public let allowsPictureInPictureMediaPlayback: Bool
/// Boolean value indicating whether a non-persistent website data store should be used to get and set the site’s cookies and track cached data objects.
public let useNonPersistentWebsiteDataStore: Bool
/// A Boolean value indicating if safe area insets should be added automatically to content insets.
public let automaticallyAdjustsContentInsets: Bool
/// A custom user agent of the underlying web view.
public let customUserAgent: String?
/// The HTML builder.
public let htmlBuilder: HTMLBuilder
/// The action to perform when a url gets opened.
public let openURLAction: OpenURLAction
// MARK: Initializer
/// Creates a new instance of ``YouTubePlayer/Configuration``
/// - Parameters:
/// - fullscreenMode: The fullscreen mode. Default value `.preferred`
/// - allowsInlineMediaPlayback: A Boolean value that indicates whether HTML5 videos play inline or use the native full-screen controller. Default value `true`
/// - allowsAirPlayForMediaPlayback: A Boolean value that indicates whether the web view allows media playback over AirPlay. Default value `true`
/// - allowsPictureInPictureMediaPlayback: A Boolean value that indicates whether HTML5 videos can play Picture in Picture. Default value `false`
/// - useNonPersistentWebsiteDataStore: Boolean value indicating whether a non-persistent website data store should be used. Default value `true`
/// - automaticallyAdjustsContentInsets: A Boolean value indicating if safe area insets should be added automatically to content insets. Default value `true`
/// - customUserAgent: A custom user agent of the underlying web view. Default value `nil`
/// - htmlBuilder: The HTML builder. Default value `.init()`
/// - openURLAction: The action to perform when a url gets opened.. Default value `.default`
public init(
fullscreenMode: FullscreenMode = .preferred,
allowsInlineMediaPlayback: Bool = true,
allowsAirPlayForMediaPlayback: Bool = true,
allowsPictureInPictureMediaPlayback: Bool = false,
useNonPersistentWebsiteDataStore: Bool = true,
automaticallyAdjustsContentInsets: Bool = true,
customUserAgent: String? = nil,
htmlBuilder: HTMLBuilder = .init(),
openURLAction: OpenURLAction = .default
) {
self.fullscreenMode = fullscreenMode
self.allowsInlineMediaPlayback = allowsInlineMediaPlayback
self.allowsAirPlayForMediaPlayback = allowsAirPlayForMediaPlayback
self.allowsPictureInPictureMediaPlayback = allowsPictureInPictureMediaPlayback
self.useNonPersistentWebsiteDataStore = useNonPersistentWebsiteDataStore
self.automaticallyAdjustsContentInsets = automaticallyAdjustsContentInsets
self.customUserAgent = customUserAgent
self.htmlBuilder = htmlBuilder
self.openURLAction = openURLAction
}
}
}
// MARK: - ExpressibleByURL
extension YouTubePlayer.Configuration: ExpressibleByURL {
/// Creates a new instance of ``YouTubePlayer/Configuration``
/// - Parameter url: The URL.
public init?(
url: URL
) {
let queryItems = URLComponents(
url: url, resolvingAgainstBaseURL: true
)?
.queryItems ?? .init()
self.init(
allowsInlineMediaPlayback: queryItems
.first { $0.name == YouTubePlayer.Parameters.CodingKeys.playInline.rawValue }
.flatMap { $0.value == "1" } ?? true
)
}
}
// MARK: - Codable
extension YouTubePlayer.Configuration: Codable {
/// The coding keys.
private enum CodingKeys: CodingKey {
case fullscreenMode
case allowsInlineMediaPlayback
case allowsAirPlayForMediaPlayback
case allowsPictureInPictureMediaPlayback
case useNonPersistentWebsiteDataStore
case automaticallyAdjustsContentInsets
case customUserAgent
case htmlBuilder
}
/// Creates a new instance of ``YouTubePlayer/Configuration``
/// - Parameter decoder: The decoder.
public init(
from decoder: Decoder
) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
try self.init(
fullscreenMode: container.decode(YouTubePlayer.FullscreenMode.self, forKey: .fullscreenMode),
allowsInlineMediaPlayback: container.decode(Bool.self, forKey: .allowsInlineMediaPlayback),
allowsAirPlayForMediaPlayback: container.decode(Bool.self, forKey: .allowsAirPlayForMediaPlayback),
allowsPictureInPictureMediaPlayback: container.decode(Bool.self, forKey: .allowsPictureInPictureMediaPlayback),
useNonPersistentWebsiteDataStore: container.decode(Bool.self, forKey: .useNonPersistentWebsiteDataStore),
automaticallyAdjustsContentInsets: container.decode(Bool.self, forKey: .automaticallyAdjustsContentInsets),
customUserAgent: container.decodeIfPresent(String.self, forKey: .customUserAgent),
htmlBuilder: container.decode(YouTubePlayer.HTMLBuilder.self, forKey: .htmlBuilder)
)
}
/// Encode.
/// - Parameter encoder: The encoder.
public func encode(
to encoder: Encoder
) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.fullscreenMode, forKey: .fullscreenMode)
try container.encode(self.allowsInlineMediaPlayback, forKey: .allowsInlineMediaPlayback)
try container.encode(self.allowsAirPlayForMediaPlayback, forKey: .allowsAirPlayForMediaPlayback)
try container.encode(self.allowsPictureInPictureMediaPlayback, forKey: .allowsPictureInPictureMediaPlayback)
try container.encode(self.useNonPersistentWebsiteDataStore, forKey: .useNonPersistentWebsiteDataStore)
try container.encode(self.automaticallyAdjustsContentInsets, forKey: .automaticallyAdjustsContentInsets)
try container.encode(self.customUserAgent, forKey: .customUserAgent)
try container.encode(self.htmlBuilder, forKey: .htmlBuilder)
}
}