@capgo/capacitor-jw-player 0.0.1
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.
- package/CapgoCapacitorJwPlayer.podspec +18 -0
- package/Package.swift +30 -0
- package/README.md +493 -0
- package/android/build.gradle +83 -0
- package/android/src/main/AndroidManifest.xml +37 -0
- package/android/src/main/java/ee/forgr/capacitor_jw_player/JwPlayerPlugin.java +529 -0
- package/android/src/main/java/ee/forgr/capacitor_jw_player/PlayerActivity.java +469 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/android/src/main/res/drawable/close_button_background.xml +5 -0
- package/android/src/main/res/layout/activity_player.xml +28 -0
- package/android/src/main/res/values/colors.xml +16 -0
- package/android/src/main/res/values/strings.xml +3 -0
- package/android/src/main/res/values/styles.xml +32 -0
- package/dist/docs.json +459 -0
- package/dist/esm/definitions.d.ts +156 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +57 -0
- package/dist/esm/web.js +65 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +79 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +82 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/JwPlayerPlugin/JwPlayer.swift +24 -0
- package/ios/Sources/JwPlayerPlugin/JwPlayerPlugin.swift +749 -0
- package/ios/Sources/JwPlayerPlugin/LinkedList.swift +219 -0
- package/ios/Sources/JwPlayerPlugin/VideosToPlay.swift +56 -0
- package/ios/Tests/JwPlayerPluginTests/JwPlayerPluginTests.swift +15 -0
- package/package.json +80 -0
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
//
|
|
2
|
+
// LinkedList.swift
|
|
3
|
+
// Pods
|
|
4
|
+
//
|
|
5
|
+
// Created by WcaleNieWolny on 18/04/2025.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
public class Node<Value> {
|
|
9
|
+
public var value: Value
|
|
10
|
+
public var next: Node?
|
|
11
|
+
|
|
12
|
+
public init(value: Value, next: Node? = nil) {
|
|
13
|
+
self.value = value
|
|
14
|
+
self.next = next
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
extension Node: CustomStringConvertible {
|
|
19
|
+
public var description: String {
|
|
20
|
+
guard let next = next else {
|
|
21
|
+
return "\(value)"
|
|
22
|
+
}
|
|
23
|
+
return "\(value) -> \(next)"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
public struct LinkedList<Value> {
|
|
28
|
+
public var head: Node<Value>?
|
|
29
|
+
public var tail: Node<Value>?
|
|
30
|
+
|
|
31
|
+
public init() {}
|
|
32
|
+
|
|
33
|
+
public var isEmpty: Bool {
|
|
34
|
+
head == nil
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public mutating func push(_ value: Value) {
|
|
38
|
+
copyNodes()
|
|
39
|
+
head = Node(value: value, next: head)
|
|
40
|
+
if tail == nil {
|
|
41
|
+
tail = head
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public mutating func append(_ value: Value) {
|
|
46
|
+
copyNodes()
|
|
47
|
+
guard !isEmpty else {
|
|
48
|
+
push(value)
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
tail!.next = Node(value: value)
|
|
52
|
+
tail = tail!.next
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
public func node(at index: Int) -> Node<Value>? {
|
|
56
|
+
var currentNode = head
|
|
57
|
+
var currentIndex = 0
|
|
58
|
+
|
|
59
|
+
while currentNode != nil && currentIndex < index {
|
|
60
|
+
currentNode = currentNode!.next
|
|
61
|
+
currentIndex += 1
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return currentNode
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@discardableResult
|
|
68
|
+
public mutating func insert(_ value: Value, after node: Node<Value>) -> Node<Value> {
|
|
69
|
+
copyNodes()
|
|
70
|
+
guard tail !== node else {
|
|
71
|
+
append(value)
|
|
72
|
+
return tail!
|
|
73
|
+
}
|
|
74
|
+
node.next = Node(value: value, next: node.next)
|
|
75
|
+
return node.next!
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
@discardableResult
|
|
79
|
+
public mutating func pop() -> Value? {
|
|
80
|
+
copyNodes()
|
|
81
|
+
defer {
|
|
82
|
+
head = head?.next
|
|
83
|
+
if isEmpty {
|
|
84
|
+
tail = nil
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return head?.value
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@discardableResult
|
|
91
|
+
public mutating func removeLast() -> Value? {
|
|
92
|
+
copyNodes()
|
|
93
|
+
guard let head = head else {
|
|
94
|
+
return nil
|
|
95
|
+
}
|
|
96
|
+
guard head.next != nil else {
|
|
97
|
+
return pop()
|
|
98
|
+
}
|
|
99
|
+
var prev = head
|
|
100
|
+
var current = head
|
|
101
|
+
while let next = current.next {
|
|
102
|
+
prev = current
|
|
103
|
+
current = next
|
|
104
|
+
}
|
|
105
|
+
prev.next = nil
|
|
106
|
+
tail = prev
|
|
107
|
+
return current.value
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
@discardableResult
|
|
111
|
+
public mutating func remove(after node: Node<Value>) -> Value? {
|
|
112
|
+
guard let node = copyNodes(returningCopyOf: node) else { return nil }
|
|
113
|
+
defer {
|
|
114
|
+
if node.next === tail {
|
|
115
|
+
tail = node
|
|
116
|
+
}
|
|
117
|
+
node.next = node.next?.next
|
|
118
|
+
}
|
|
119
|
+
return node.next?.value
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private mutating func copyNodes() {
|
|
123
|
+
guard !isKnownUniquelyReferenced(&head) else {
|
|
124
|
+
return
|
|
125
|
+
}
|
|
126
|
+
guard var oldNode = head else {
|
|
127
|
+
return
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
head = Node(value: oldNode.value)
|
|
131
|
+
var newNode = head
|
|
132
|
+
|
|
133
|
+
while let nextOldNode = oldNode.next {
|
|
134
|
+
newNode!.next = Node(value: nextOldNode.value)
|
|
135
|
+
newNode = newNode!.next
|
|
136
|
+
oldNode = nextOldNode
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
tail = newNode
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
private mutating func copyNodes(returningCopyOf node: Node<Value>?) -> Node<Value>? {
|
|
143
|
+
guard !isKnownUniquelyReferenced(&head) else {
|
|
144
|
+
return nil
|
|
145
|
+
}
|
|
146
|
+
guard var oldNode = head else {
|
|
147
|
+
return nil
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
head = Node(value: oldNode.value)
|
|
151
|
+
var newNode = head
|
|
152
|
+
var nodeCopy: Node<Value>?
|
|
153
|
+
|
|
154
|
+
while let nextOldNode = oldNode.next {
|
|
155
|
+
if oldNode === node {
|
|
156
|
+
nodeCopy = newNode
|
|
157
|
+
}
|
|
158
|
+
newNode!.next = Node(value: nextOldNode.value)
|
|
159
|
+
newNode = newNode!.next
|
|
160
|
+
oldNode = nextOldNode
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return nodeCopy
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
extension LinkedList: CustomStringConvertible {
|
|
168
|
+
public var description: String {
|
|
169
|
+
guard let head = head else {
|
|
170
|
+
return "Empty list"
|
|
171
|
+
}
|
|
172
|
+
return "\(head)"
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
extension LinkedList: Collection {
|
|
177
|
+
public struct Index: Comparable {
|
|
178
|
+
public var node: Node<Value>?
|
|
179
|
+
|
|
180
|
+
static public func ==(lhs: Index, rhs: Index) -> Bool {
|
|
181
|
+
switch (lhs.node, rhs.node) {
|
|
182
|
+
case let (left?, right?):
|
|
183
|
+
return left === right
|
|
184
|
+
case (nil, nil):
|
|
185
|
+
return true
|
|
186
|
+
default:
|
|
187
|
+
return false
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
static public func <(lhs: Index, rhs: Index) -> Bool {
|
|
192
|
+
guard lhs != rhs else {
|
|
193
|
+
return false
|
|
194
|
+
}
|
|
195
|
+
guard let leftNode = lhs.node else {
|
|
196
|
+
return false
|
|
197
|
+
}
|
|
198
|
+
let nodes = sequence(first: leftNode) { $0.next }
|
|
199
|
+
return nodes.contains { $0 === rhs.node }
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
public var startIndex: Index {
|
|
204
|
+
Index(node: head)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
public var endIndex: Index {
|
|
208
|
+
Index(node: nil)
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
public func index(after i: Index) -> Index {
|
|
212
|
+
Index(node: i.node?.next)
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
public subscript(position: Index) -> Value {
|
|
216
|
+
position.node!.value
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
//
|
|
2
|
+
// VideosToPlay.swift
|
|
3
|
+
// Pods
|
|
4
|
+
//
|
|
5
|
+
// Created by WcaleNieWolny on 18/04/2025.
|
|
6
|
+
//
|
|
7
|
+
|
|
8
|
+
/// Type alias for a LinkedList of MediaNodeType, representing a queue of videos to play
|
|
9
|
+
public typealias VideosToPlay = LinkedList<MediaNodeType>
|
|
10
|
+
|
|
11
|
+
/// An enum to represent the type of media node
|
|
12
|
+
public enum MediaNodeType {
|
|
13
|
+
/// A playlist that contains multiple video URLs
|
|
14
|
+
case playlist(loadedUrls: [URL], isLoaded: Bool, playlistUrl: URL)
|
|
15
|
+
/// A single video URL
|
|
16
|
+
case video(url: URL)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/// A specialized node for the VideosToPlay linked list
|
|
20
|
+
public class MediaNode: Node<MediaNodeType> {
|
|
21
|
+
/// The type of the media node
|
|
22
|
+
public var nodeType: MediaNodeType {
|
|
23
|
+
return value
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/// Whether this node is a playlist
|
|
27
|
+
public var isPlaylist: Bool {
|
|
28
|
+
switch value {
|
|
29
|
+
case .playlist:
|
|
30
|
+
return true
|
|
31
|
+
case .video:
|
|
32
|
+
return false
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/// Whether this node is a video
|
|
37
|
+
public var isVideo: Bool {
|
|
38
|
+
switch value {
|
|
39
|
+
case .video:
|
|
40
|
+
return true
|
|
41
|
+
case .playlist:
|
|
42
|
+
return false
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/// Create a new playlist node
|
|
47
|
+
public static func createPlaylist(playlistUrl: URL) -> MediaNode {
|
|
48
|
+
return MediaNode(value: .playlist(loadedUrls: [], isLoaded: false, playlistUrl: playlistUrl))
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/// Create a new video node
|
|
52
|
+
public static func createVideo(url: URL) -> MediaNode {
|
|
53
|
+
return MediaNode(value: .video(url: url))
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import XCTest
|
|
2
|
+
@testable import JwPlayerPlugin
|
|
3
|
+
|
|
4
|
+
class JwPlayerTests: XCTestCase {
|
|
5
|
+
func testEcho() {
|
|
6
|
+
// This is an example of a functional test case for a plugin.
|
|
7
|
+
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
|
8
|
+
|
|
9
|
+
let implementation = JwPlayer()
|
|
10
|
+
let value = "Hello, World!"
|
|
11
|
+
let result = implementation.echo(value)
|
|
12
|
+
|
|
13
|
+
XCTAssertEqual(value, result)
|
|
14
|
+
}
|
|
15
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@capgo/capacitor-jw-player",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Playes videos from jwplayer.com",
|
|
5
|
+
"main": "dist/plugin.cjs.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"types": "dist/esm/index.d.ts",
|
|
8
|
+
"unpkg": "dist/plugin.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"android/src/main/",
|
|
11
|
+
"android/build.gradle",
|
|
12
|
+
"dist/",
|
|
13
|
+
"ios/Sources",
|
|
14
|
+
"ios/Tests",
|
|
15
|
+
"Package.swift",
|
|
16
|
+
"CapgoCapacitorJwPlayer.podspec"
|
|
17
|
+
],
|
|
18
|
+
"author": "Martin Donadieu <martin@capgo.app>",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/Cap-go/capacitor-jw-player.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/Cap-go/capacitor-jw-player/issues"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"capacitor",
|
|
29
|
+
"plugin",
|
|
30
|
+
"native"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
34
|
+
"verify:ios": "xcodebuild -scheme CapgoCapacitorJwPlayer -destination generic/platform=iOS",
|
|
35
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
36
|
+
"verify:web": "npm run build",
|
|
37
|
+
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
38
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
|
|
39
|
+
"eslint": "eslint . --ext ts",
|
|
40
|
+
"prettier": "prettier \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
|
|
41
|
+
"swiftlint": "node-swiftlint",
|
|
42
|
+
"docgen": "docgen --api JwPlayerPlugin --output-readme README.md --output-json dist/docs.json",
|
|
43
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.mjs",
|
|
44
|
+
"clean": "rimraf ./dist",
|
|
45
|
+
"watch": "tsc --watch",
|
|
46
|
+
"prepublishOnly": "npm run build"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@capacitor/android": "^7.0.0",
|
|
50
|
+
"@capacitor/core": "^7.0.0",
|
|
51
|
+
"@capacitor/docgen": "^0.3.0",
|
|
52
|
+
"@capacitor/ios": "^7.0.0",
|
|
53
|
+
"@ionic/eslint-config": "^0.4.0",
|
|
54
|
+
"@ionic/prettier-config": "^4.0.0",
|
|
55
|
+
"@ionic/swiftlint-config": "^2.0.0",
|
|
56
|
+
"eslint": "^8.57.0",
|
|
57
|
+
"prettier": "^3.4.2",
|
|
58
|
+
"prettier-plugin-java": "^2.6.6",
|
|
59
|
+
"rimraf": "^6.0.1",
|
|
60
|
+
"rollup": "^4.30.1",
|
|
61
|
+
"swiftlint": "^2.0.0",
|
|
62
|
+
"typescript": "~4.1.5"
|
|
63
|
+
},
|
|
64
|
+
"peerDependencies": {
|
|
65
|
+
"@capacitor/core": ">=7.0.0"
|
|
66
|
+
},
|
|
67
|
+
"prettier": "@ionic/prettier-config",
|
|
68
|
+
"swiftlint": "@ionic/swiftlint-config",
|
|
69
|
+
"eslintConfig": {
|
|
70
|
+
"extends": "@ionic/eslint-config/recommended"
|
|
71
|
+
},
|
|
72
|
+
"capacitor": {
|
|
73
|
+
"ios": {
|
|
74
|
+
"src": "ios"
|
|
75
|
+
},
|
|
76
|
+
"android": {
|
|
77
|
+
"src": "android"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|