@capgo/capacitor-video-player 8.1.24 → 8.1.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -41,7 +41,7 @@ import java.util.Map;
|
|
|
41
41
|
)
|
|
42
42
|
public class VideoPlayerPlugin extends Plugin {
|
|
43
43
|
|
|
44
|
-
private final String pluginVersion = "8.1.
|
|
44
|
+
private final String pluginVersion = "8.1.25";
|
|
45
45
|
|
|
46
46
|
// Permission alias constants
|
|
47
47
|
private static final String PERMISSION_DENIED_ERROR = "Unable to access media videos, user denied permission request";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import AVFoundation
|
|
2
2
|
import Foundation
|
|
3
|
+
import UniformTypeIdentifiers
|
|
3
4
|
|
|
4
5
|
enum HLSVideoAssetFactory {
|
|
5
6
|
static func isHLSStream(_ url: URL) -> Bool {
|
|
@@ -43,11 +44,17 @@ final class HLSSubtitleResourceLoader: NSObject, AVAssetResourceLoaderDelegate {
|
|
|
43
44
|
static let videoScheme = "capgohls"
|
|
44
45
|
static let subtitlePlaylistScheme = "capgohls-sub"
|
|
45
46
|
private static let subtitleGroupID = "capgosubs"
|
|
47
|
+
private static let mpegURLContentType = UTType.m3uPlaylist.identifier
|
|
46
48
|
|
|
47
49
|
private let originalVideoURL: URL
|
|
48
50
|
private let subtitleURL: URL
|
|
49
51
|
private let language: String
|
|
50
52
|
|
|
53
|
+
private struct LoadedResource {
|
|
54
|
+
let data: Data
|
|
55
|
+
let contentType: String?
|
|
56
|
+
}
|
|
57
|
+
|
|
51
58
|
init(videoURL: URL, subtitleURL: URL, language: String) {
|
|
52
59
|
self.originalVideoURL = videoURL
|
|
53
60
|
self.subtitleURL = subtitleURL
|
|
@@ -80,8 +87,8 @@ final class HLSSubtitleResourceLoader: NSObject, AVAssetResourceLoaderDelegate {
|
|
|
80
87
|
|
|
81
88
|
Task {
|
|
82
89
|
do {
|
|
83
|
-
let
|
|
84
|
-
fulfill(loadingRequest, with:
|
|
90
|
+
let resource = try await loadData(for: requestURL)
|
|
91
|
+
fulfill(loadingRequest, with: resource)
|
|
85
92
|
} catch {
|
|
86
93
|
loadingRequest.finishLoading(with: error)
|
|
87
94
|
}
|
|
@@ -90,25 +97,36 @@ final class HLSSubtitleResourceLoader: NSObject, AVAssetResourceLoaderDelegate {
|
|
|
90
97
|
return true
|
|
91
98
|
}
|
|
92
99
|
|
|
93
|
-
private func loadData(for requestURL: URL) async throws ->
|
|
100
|
+
private func loadData(for requestURL: URL) async throws -> LoadedResource {
|
|
94
101
|
if requestURL.scheme == Self.subtitlePlaylistScheme {
|
|
95
|
-
|
|
102
|
+
let data = Data(subtitleMediaPlaylist().utf8)
|
|
103
|
+
return LoadedResource(data: data, contentType: Self.mpegURLContentType)
|
|
96
104
|
}
|
|
97
105
|
|
|
98
106
|
let fetchURL = originalURL(for: requestURL)
|
|
99
|
-
let (data,
|
|
107
|
+
let (data, response) = try await URLSession.shared.data(from: fetchURL)
|
|
108
|
+
if let http = response as? HTTPURLResponse, !(200...299).contains(http.statusCode) {
|
|
109
|
+
throw URLError(.badServerResponse)
|
|
110
|
+
}
|
|
111
|
+
|
|
100
112
|
let manifest = String(data: data, encoding: .utf8) ?? ""
|
|
101
113
|
|
|
102
114
|
guard hasStreamInfTags(manifest) else {
|
|
103
|
-
|
|
115
|
+
let contentType = Self.contentTypeIdentifier(from: response)
|
|
116
|
+
return LoadedResource(data: data, contentType: contentType)
|
|
104
117
|
}
|
|
105
118
|
|
|
106
119
|
guard let subtitlePlaylistURI = Self.subtitlePlaylistURL(for: originalVideoURL)?.absoluteString else {
|
|
107
|
-
|
|
120
|
+
let contentType = Self.contentTypeIdentifier(from: response) ?? Self.mpegURLContentType
|
|
121
|
+
return LoadedResource(data: data, contentType: contentType)
|
|
108
122
|
}
|
|
109
123
|
|
|
110
|
-
let modified = injectSubtitle(
|
|
111
|
-
|
|
124
|
+
let modified = injectSubtitle(
|
|
125
|
+
into: manifest,
|
|
126
|
+
subtitlePlaylistURI: subtitlePlaylistURI,
|
|
127
|
+
baseURL: response.url ?? fetchURL
|
|
128
|
+
)
|
|
129
|
+
return LoadedResource(data: Data(modified.utf8), contentType: Self.mpegURLContentType)
|
|
112
130
|
}
|
|
113
131
|
|
|
114
132
|
private func originalURL(for requestURL: URL) -> URL {
|
|
@@ -125,7 +143,22 @@ final class HLSSubtitleResourceLoader: NSObject, AVAssetResourceLoaderDelegate {
|
|
|
125
143
|
manifest.contains("#EXT-X-STREAM-INF")
|
|
126
144
|
}
|
|
127
145
|
|
|
128
|
-
private func
|
|
146
|
+
private static func contentTypeIdentifier(from response: URLResponse) -> String? {
|
|
147
|
+
guard let mimeType = (response as? HTTPURLResponse)?.mimeType else {
|
|
148
|
+
return nil
|
|
149
|
+
}
|
|
150
|
+
return UTType(mimeType: mimeType)?.identifier
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private func absoluteURI(for uri: String, relativeTo baseURL: URL) -> String {
|
|
154
|
+
let trimmed = uri.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
155
|
+
guard let url = URL(string: trimmed, relativeTo: baseURL)?.absoluteURL else {
|
|
156
|
+
return trimmed
|
|
157
|
+
}
|
|
158
|
+
return url.absoluteString
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
private func injectSubtitle(into manifest: String, subtitlePlaylistURI: String, baseURL: URL) -> String {
|
|
129
162
|
let mediaTag = """
|
|
130
163
|
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="\(Self.subtitleGroupID)",NAME="Subtitles",DEFAULT=YES,AUTOSELECT=YES,FORCED=NO,LANGUAGE="\(language)",URI="\(subtitlePlaylistURI)"
|
|
131
164
|
"""
|
|
@@ -133,9 +166,10 @@ final class HLSSubtitleResourceLoader: NSObject, AVAssetResourceLoaderDelegate {
|
|
|
133
166
|
var lines = manifest.components(separatedBy: .newlines)
|
|
134
167
|
var result: [String] = []
|
|
135
168
|
var insertedMediaTag = false
|
|
169
|
+
var expectingVariantURI = false
|
|
136
170
|
|
|
137
171
|
for line in lines {
|
|
138
|
-
if line.hasPrefix("#EXT-X-STREAM-INF") {
|
|
172
|
+
if line.hasPrefix("#EXT-X-STREAM-INF") || line.hasPrefix("#EXT-X-I-FRAME-STREAM-INF") {
|
|
139
173
|
if !insertedMediaTag {
|
|
140
174
|
result.append(mediaTag)
|
|
141
175
|
insertedMediaTag = true
|
|
@@ -146,9 +180,17 @@ final class HLSSubtitleResourceLoader: NSObject, AVAssetResourceLoaderDelegate {
|
|
|
146
180
|
} else {
|
|
147
181
|
result.append("\(line),SUBTITLES=\"\(Self.subtitleGroupID)\"")
|
|
148
182
|
}
|
|
183
|
+
expectingVariantURI = true
|
|
149
184
|
continue
|
|
150
185
|
}
|
|
151
186
|
|
|
187
|
+
if expectingVariantURI, !line.hasPrefix("#"), !line.isEmpty {
|
|
188
|
+
result.append(absoluteURI(for: line, relativeTo: baseURL))
|
|
189
|
+
expectingVariantURI = false
|
|
190
|
+
continue
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
expectingVariantURI = false
|
|
152
194
|
result.append(line)
|
|
153
195
|
}
|
|
154
196
|
|
|
@@ -172,14 +214,16 @@ final class HLSSubtitleResourceLoader: NSObject, AVAssetResourceLoaderDelegate {
|
|
|
172
214
|
"""
|
|
173
215
|
}
|
|
174
216
|
|
|
175
|
-
private func fulfill(_ loadingRequest: AVAssetResourceLoadingRequest, with
|
|
217
|
+
private func fulfill(_ loadingRequest: AVAssetResourceLoadingRequest, with resource: LoadedResource) {
|
|
176
218
|
if let contentRequest = loadingRequest.contentInformationRequest {
|
|
177
|
-
|
|
178
|
-
|
|
219
|
+
if let contentType = resource.contentType {
|
|
220
|
+
contentRequest.contentType = contentType
|
|
221
|
+
}
|
|
222
|
+
contentRequest.contentLength = Int64(resource.data.count)
|
|
179
223
|
contentRequest.isByteRangeAccessSupported = false
|
|
180
224
|
}
|
|
181
225
|
|
|
182
|
-
loadingRequest.dataRequest?.respond(with: data)
|
|
226
|
+
loadingRequest.dataRequest?.respond(with: resource.data)
|
|
183
227
|
loadingRequest.finishLoading()
|
|
184
228
|
}
|
|
185
229
|
}
|
|
@@ -8,7 +8,7 @@ import AVKit
|
|
|
8
8
|
*/
|
|
9
9
|
@objc(VideoPlayerPlugin)
|
|
10
10
|
public class VideoPlayerPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
11
|
-
private let pluginVersion: String = "8.1.
|
|
11
|
+
private let pluginVersion: String = "8.1.25"
|
|
12
12
|
public let identifier = "VideoPlayerPlugin"
|
|
13
13
|
public let jsName = "VideoPlayer"
|
|
14
14
|
public let pluginMethods: [CAPPluginMethod] = [
|