expo-libmpv 0.3.1 → 0.3.3
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/android/build.gradle +1 -1
- package/android/src/main/java/com/libmpv/LibmpvModule.kt +15 -0
- package/android/src/main/java/com/libmpv/{LibmpvVideoView.kt → LibmpvView.kt} +95 -125
- package/android/src/main/java/com/libmpv/{LibmpvVideoModule.kt → LibmpvViewModule.kt} +18 -15
- package/android/src/main/java/com/libmpv/LibmpvWrapper.kt +156 -193
- package/build/Libmpv.d.ts +5 -0
- package/build/Libmpv.d.ts.map +1 -0
- package/build/Libmpv.js +4 -0
- package/build/Libmpv.js.map +1 -0
- package/build/LibmpvView.d.ts +5 -0
- package/build/LibmpvView.d.ts.map +1 -0
- package/build/{LibmpvVideoView.js → LibmpvView.js} +5 -5
- package/build/LibmpvView.js.map +1 -0
- package/build/{LibmpvVideo.types.d.ts → LibmpvViewTypes.d.ts} +3 -3
- package/build/LibmpvViewTypes.d.ts.map +1 -0
- package/build/LibmpvViewTypes.js +2 -0
- package/build/LibmpvViewTypes.js.map +1 -0
- package/build/index.d.ts +12 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +11 -2
- package/build/index.js.map +1 -1
- package/expo-module.config.json +2 -1
- package/package.json +1 -1
- package/src/Libmpv.tsx +7 -0
- package/src/{LibmpvVideoView.tsx → LibmpvView.tsx} +5 -7
- package/src/{LibmpvVideo.types.ts → LibmpvViewTypes.ts} +2 -2
- package/src/index.ts +14 -2
- package/build/LibmpvVideo.types.d.ts.map +0 -1
- package/build/LibmpvVideo.types.js +0 -2
- package/build/LibmpvVideo.types.js.map +0 -1
- package/build/LibmpvVideoView.d.ts +0 -5
- package/build/LibmpvVideoView.d.ts.map +0 -1
- package/build/LibmpvVideoView.js.map +0 -1
package/android/build.gradle
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
package com.libmpv
|
|
2
|
+
|
|
3
|
+
import expo.modules.kotlin.modules.Module
|
|
4
|
+
import expo.modules.kotlin.modules.ModuleDefinition
|
|
5
|
+
|
|
6
|
+
class LibmpvModule : Module() {
|
|
7
|
+
override fun definition() = ModuleDefinition {
|
|
8
|
+
Name("Libmpv")
|
|
9
|
+
|
|
10
|
+
AsyncFunction("getProperty") { viewTag: Int, name: String ->
|
|
11
|
+
val view = appContext.findView<LibmpvView>(viewTag)
|
|
12
|
+
view?.getProperty(name)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -12,9 +12,10 @@ import dev.jdtech.mpv.MPVLib
|
|
|
12
12
|
import expo.modules.kotlin.AppContext
|
|
13
13
|
import expo.modules.kotlin.views.ExpoView
|
|
14
14
|
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
15
|
+
import kotlinx.coroutines.runBlocking
|
|
15
16
|
|
|
16
|
-
class
|
|
17
|
-
ExpoView(context,appContext),
|
|
17
|
+
class LibmpvView(context: Context, appContext: AppContext) :
|
|
18
|
+
ExpoView(context, appContext),
|
|
18
19
|
SurfaceHolder.Callback,
|
|
19
20
|
MPVLib.LogObserver,
|
|
20
21
|
MPVLib.EventObserver {
|
|
@@ -27,7 +28,10 @@ class LibmpvVideoView(context: Context, appContext: AppContext) :
|
|
|
27
28
|
private val onLibmpvLog by EventDispatcher()
|
|
28
29
|
private val onLibmpvEvent by EventDispatcher()
|
|
29
30
|
|
|
30
|
-
private var isSurfaceCreated
|
|
31
|
+
@Volatile private var isSurfaceCreated = false
|
|
32
|
+
@Volatile private var cleaning = false
|
|
33
|
+
private val mainHandler = Handler(Looper.getMainLooper())
|
|
34
|
+
|
|
31
35
|
val mpv: LibmpvWrapper = LibmpvWrapper(context)
|
|
32
36
|
private val surfaceView: SurfaceView = SurfaceView(context)
|
|
33
37
|
|
|
@@ -38,77 +42,82 @@ class LibmpvVideoView(context: Context, appContext: AppContext) :
|
|
|
38
42
|
var audioIndex: Int? = null
|
|
39
43
|
var subtitleIndex: Int? = null
|
|
40
44
|
var useHardwareDecoder: Boolean? = null
|
|
45
|
+
var seekToSeconds: Int? = null
|
|
41
46
|
|
|
42
47
|
init {
|
|
43
48
|
surfaceView.holder.addCallback(this)
|
|
44
49
|
val layoutParams = FrameLayout.LayoutParams(
|
|
45
|
-
|
|
46
|
-
|
|
50
|
+
FrameLayout.LayoutParams.MATCH_PARENT,
|
|
51
|
+
FrameLayout.LayoutParams.MATCH_PARENT
|
|
47
52
|
)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
activity.lifecycle.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
53
|
+
|
|
54
|
+
appContext.activityProvider?.currentActivity?.let { activity ->
|
|
55
|
+
if (activity is androidx.lifecycle.LifecycleOwner) {
|
|
56
|
+
activity.lifecycle.addObserver(object : DefaultLifecycleObserver {
|
|
57
|
+
override fun onDestroy(owner: LifecycleOwner) {
|
|
58
|
+
log("LibmpvView", "Lifecycle onDestroy -> cleanup()")
|
|
59
|
+
cleanup()
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
}
|
|
56
63
|
}
|
|
57
|
-
}
|
|
58
64
|
|
|
59
65
|
addView(surfaceView, layoutParams)
|
|
60
66
|
}
|
|
61
67
|
|
|
62
68
|
fun isSurfaceReady(): Boolean = isSurfaceCreated
|
|
63
69
|
|
|
64
|
-
fun attemptCreation(){
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
fun attemptCreation() {
|
|
71
|
+
val allPropsReady = playUrl != null &&
|
|
72
|
+
surfaceWidth != null &&
|
|
73
|
+
surfaceHeight != null &&
|
|
74
|
+
audioIndex != null &&
|
|
75
|
+
subtitleIndex != null &&
|
|
76
|
+
useHardwareDecoder != null
|
|
77
|
+
|
|
78
|
+
if (allPropsReady) {
|
|
79
|
+
log("LibmpvView.attemptCreation", "Initializing MPV instance")
|
|
80
|
+
createNativePlayer()
|
|
81
|
+
} else {
|
|
82
|
+
log("LibmpvView.attemptCreation", "attemptCreation wasn't ready")
|
|
83
|
+
}
|
|
78
84
|
}
|
|
79
85
|
|
|
80
86
|
fun createNativePlayer() {
|
|
81
87
|
mpv.create()
|
|
82
88
|
prepareMpvSettings()
|
|
83
|
-
log("
|
|
89
|
+
log("LibmpvView.createNativePlayer", "mpv settings prepared. Waiting on surface creation.")
|
|
84
90
|
}
|
|
85
91
|
|
|
86
|
-
fun runCommand(orders: String){
|
|
92
|
+
fun runCommand(orders: String) {
|
|
87
93
|
mpv.command(orders.split("|").toTypedArray())
|
|
88
94
|
}
|
|
89
95
|
|
|
90
|
-
fun setOptionString(options: String){
|
|
96
|
+
fun setOptionString(options: String) {
|
|
91
97
|
val parts = options.split("|").toTypedArray()
|
|
92
|
-
mpv.setOptionString(parts[0],parts[1])
|
|
98
|
+
if (parts.size == 2) mpv.setOptionString(parts[0], parts[1])
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
fun getProperty(name: String): String? {
|
|
102
|
+
return runBlocking { mpv.getProperty(name) }
|
|
93
103
|
}
|
|
94
104
|
|
|
95
105
|
private fun prepareMpvSettings() {
|
|
96
106
|
mpv.addLogObserver(this)
|
|
97
107
|
mpv.addEventObserver(this)
|
|
98
|
-
mpv.setOptionString("force-window", "no")
|
|
99
108
|
|
|
109
|
+
mpv.setOptionString("force-window", "no")
|
|
100
110
|
mpv.setOptionString("config", "yes")
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
mpv.setOptionString("config-dir",
|
|
104
|
-
mpv.setOptionString("sub-font-dir",
|
|
111
|
+
|
|
112
|
+
mpv.getMpvDirectoryPath()?.let { dir ->
|
|
113
|
+
mpv.setOptionString("config-dir", dir)
|
|
114
|
+
mpv.setOptionString("sub-font-dir", dir)
|
|
105
115
|
}
|
|
106
116
|
|
|
107
117
|
mpv.setOptionString("keep-open", "always")
|
|
108
118
|
mpv.setOptionString("save-position-on-quit", "no")
|
|
109
119
|
mpv.setOptionString("ytdl", "no")
|
|
110
120
|
mpv.setOptionString("msg-level", "all=no")
|
|
111
|
-
|
|
112
121
|
mpv.setOptionString("profile", "fast")
|
|
113
122
|
mpv.setOptionString("vo", "gpu-next")
|
|
114
123
|
|
|
@@ -122,19 +131,15 @@ class LibmpvVideoView(context: Context, appContext: AppContext) :
|
|
|
122
131
|
mpv.setOptionString("gpu-context", "android")
|
|
123
132
|
mpv.setOptionString("opengl-es", "yes")
|
|
124
133
|
mpv.setOptionString("video-sync", "audio")
|
|
125
|
-
|
|
126
|
-
mpv.setOptionString("audio-
|
|
127
|
-
mpv.setOptionString("audio-
|
|
128
|
-
mpv.setOptionString("audio-buffer","2.0")
|
|
129
|
-
|
|
134
|
+
mpv.setOptionString("audio-samplerate", "48000")
|
|
135
|
+
mpv.setOptionString("audio-format", "float")
|
|
136
|
+
mpv.setOptionString("audio-buffer", "2.0")
|
|
130
137
|
mpv.setOptionString("ao", "audiotrack")
|
|
131
138
|
mpv.setOptionString("alang", "")
|
|
132
|
-
|
|
133
139
|
mpv.setOptionString("sub-font-provider", "none")
|
|
134
140
|
mpv.setOptionString("slang", "")
|
|
135
141
|
mpv.setOptionString("sub-scale-with-window", "yes")
|
|
136
142
|
mpv.setOptionString("sub-use-margins", "no")
|
|
137
|
-
|
|
138
143
|
mpv.setOptionString("cache", "yes")
|
|
139
144
|
mpv.setOptionString("cache-pause-initial", "yes")
|
|
140
145
|
mpv.setOptionString("cache-secs", "5")
|
|
@@ -142,45 +147,34 @@ class LibmpvVideoView(context: Context, appContext: AppContext) :
|
|
|
142
147
|
}
|
|
143
148
|
|
|
144
149
|
fun log(method: String, argument: String) {
|
|
145
|
-
onLibmpvLog(mapOf(
|
|
146
|
-
"method" to method,
|
|
147
|
-
"argument" to argument
|
|
148
|
-
))
|
|
150
|
+
onLibmpvLog(mapOf("method" to method, "argument" to argument))
|
|
149
151
|
}
|
|
150
152
|
|
|
151
153
|
override fun surfaceCreated(holder: SurfaceHolder) {
|
|
152
|
-
val width = surfaceWidth ?: 0
|
|
153
|
-
val height = surfaceHeight ?: 0
|
|
154
|
-
// In the new Fabric version, this is stretching the content
|
|
155
|
-
//holder.setFixedSize(width, height)
|
|
156
|
-
//mpv.setPropertyString("android-surface-size", "${width}x${height}")
|
|
157
154
|
mpv.attachSurface(surfaceView)
|
|
158
155
|
prepareMpvPlayback()
|
|
159
156
|
isSurfaceCreated = true
|
|
160
|
-
log("
|
|
157
|
+
log("LibmpvView.surfaceCreated", "Surface created and MPV attached")
|
|
161
158
|
}
|
|
162
159
|
|
|
163
160
|
private fun prepareMpvPlayback() {
|
|
164
161
|
mpv.init()
|
|
165
162
|
mpv.setOptionString("force-window", "yes")
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
",sid=${(subtitleIndex ?: 0) + 1}"
|
|
163
|
+
|
|
164
|
+
val aid = if (audioIndex == -1) "aid=no" else "aid=${(audioIndex ?: 0) + 1}"
|
|
165
|
+
val sid = if (subtitleIndex == -1) "sid=no" else "sid=${(subtitleIndex ?: 0) + 1}"
|
|
166
|
+
val opts = "vid=1,$aid,$sid"
|
|
167
|
+
val url = playUrl ?: ""
|
|
168
|
+
mpv.play(url, opts)
|
|
169
|
+
if (seekToSeconds != null && seekToSeconds!! > 0) {
|
|
170
|
+
mpv.seekToSeconds(seekToSeconds!!)
|
|
171
|
+
log("LibmpvView.prepareMpvPlayback", "Applied initial seek to $seekToSeconds")
|
|
176
172
|
}
|
|
177
|
-
val url: String = (playUrl as? String) ?: ""
|
|
178
|
-
mpv.play(url, options)
|
|
179
173
|
}
|
|
180
174
|
|
|
181
175
|
fun setHardwareDecoder(useHardware: Boolean) {
|
|
182
176
|
useHardwareDecoder = useHardware
|
|
183
|
-
if (
|
|
177
|
+
if (useHardware) {
|
|
184
178
|
mpv.setOptionString("hwdec", HARDWARE_OPTIONS)
|
|
185
179
|
mpv.setOptionString("hwdec-codecs", ACCELERATED_CODECS)
|
|
186
180
|
} else {
|
|
@@ -190,90 +184,66 @@ class LibmpvVideoView(context: Context, appContext: AppContext) :
|
|
|
190
184
|
|
|
191
185
|
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {}
|
|
192
186
|
|
|
193
|
-
fun cleanup() {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
try {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
187
|
+
fun cleanup() {
|
|
188
|
+
if (cleaning) return
|
|
189
|
+
cleaning = true
|
|
190
|
+
Thread {
|
|
191
|
+
try {
|
|
192
|
+
runCatching { mpv.setPropertyString("pause", "yes") }
|
|
193
|
+
runCatching { mpv.setPropertyString("ao", "null") }
|
|
194
|
+
|
|
195
|
+
mainHandler.post {
|
|
196
|
+
try {
|
|
197
|
+
surfaceView.holder.removeCallback(this@LibmpvView)
|
|
198
|
+
mpv.cleanup()
|
|
199
|
+
} catch (_: Exception) {}
|
|
200
|
+
cleaning = false
|
|
204
201
|
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
202
|
+
} catch (_: Throwable) {}
|
|
203
|
+
}.start()
|
|
204
|
+
}
|
|
209
205
|
|
|
210
206
|
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
try { mpv.detachSurface() } catch (_: Throwable) {}
|
|
207
|
+
runCatching { mpv.setPropertyString("pause", "yes") }
|
|
208
|
+
runCatching { mpv.setPropertyString("vo", "null") }
|
|
209
|
+
runCatching { mpv.setPropertyString("force-window", "no") }
|
|
210
|
+
runCatching { mpv.detachSurface() }
|
|
211
|
+
isSurfaceCreated = false
|
|
217
212
|
}
|
|
218
213
|
|
|
219
|
-
// MPVLib.LogObserver
|
|
220
214
|
override fun logMessage(prefix: String, level: Int, text: String) {
|
|
221
|
-
onLibmpvLog(mapOf(
|
|
222
|
-
"prefix" to prefix,
|
|
223
|
-
"level" to "$level",
|
|
224
|
-
"text" to text
|
|
225
|
-
))
|
|
215
|
+
onLibmpvLog(mapOf("prefix" to prefix, "level" to "$level", "text" to text))
|
|
226
216
|
}
|
|
227
217
|
|
|
228
|
-
// MPVLib.EventObserver
|
|
229
218
|
override fun eventProperty(property: String) {
|
|
230
|
-
onLibmpvEvent(mapOf(
|
|
231
|
-
"property" to property,
|
|
232
|
-
"kind" to "none"
|
|
233
|
-
))
|
|
219
|
+
onLibmpvEvent(mapOf("property" to property, "kind" to "none"))
|
|
234
220
|
}
|
|
235
221
|
|
|
236
222
|
override fun eventProperty(property: String, value: Long) {
|
|
237
|
-
onLibmpvEvent(mapOf(
|
|
238
|
-
"property" to property,
|
|
239
|
-
"kind" to "long",
|
|
240
|
-
"value" to "$value"
|
|
241
|
-
))
|
|
223
|
+
onLibmpvEvent(mapOf("property" to property, "kind" to "long", "value" to "$value"))
|
|
242
224
|
}
|
|
243
225
|
|
|
244
226
|
override fun eventProperty(property: String, value: Double) {
|
|
245
|
-
onLibmpvEvent(mapOf(
|
|
246
|
-
"property" to property,
|
|
247
|
-
"kind" to "double",
|
|
248
|
-
"value" to "$value"
|
|
249
|
-
))
|
|
227
|
+
onLibmpvEvent(mapOf("property" to property, "kind" to "double", "value" to "$value"))
|
|
250
228
|
}
|
|
251
229
|
|
|
252
230
|
override fun eventProperty(property: String, value: Boolean) {
|
|
253
|
-
onLibmpvEvent(mapOf(
|
|
254
|
-
"property" to property,
|
|
255
|
-
"kind" to "boolean",
|
|
256
|
-
"value" to if (value) "true" else "false"
|
|
257
|
-
))
|
|
231
|
+
onLibmpvEvent(mapOf("property" to property, "kind" to "boolean", "value" to if (value) "true" else "false"))
|
|
258
232
|
}
|
|
259
233
|
|
|
260
234
|
override fun eventProperty(property: String, value: String) {
|
|
261
|
-
onLibmpvEvent(mapOf(
|
|
262
|
-
"property" to property,
|
|
263
|
-
"kind" to "string",
|
|
264
|
-
"value" to value
|
|
265
|
-
))
|
|
235
|
+
onLibmpvEvent(mapOf("property" to property, "kind" to "string", "value" to value))
|
|
266
236
|
}
|
|
267
237
|
|
|
268
238
|
override fun event(eventId: Int) {
|
|
269
|
-
onLibmpvEvent(mapOf(
|
|
270
|
-
"eventId" to "$eventId",
|
|
271
|
-
"kind" to "eventId"
|
|
272
|
-
))
|
|
239
|
+
onLibmpvEvent(mapOf("eventId" to "$eventId", "kind" to "eventId"))
|
|
273
240
|
}
|
|
274
241
|
|
|
275
242
|
override fun onDetachedFromWindow() {
|
|
276
243
|
super.onDetachedFromWindow()
|
|
277
|
-
|
|
244
|
+
if (!cleaning) {
|
|
245
|
+
cleaning = true
|
|
246
|
+
cleanup()
|
|
247
|
+
}
|
|
278
248
|
}
|
|
279
249
|
}
|
|
@@ -3,25 +3,26 @@ package com.libmpv
|
|
|
3
3
|
import expo.modules.kotlin.modules.Module
|
|
4
4
|
import expo.modules.kotlin.modules.ModuleDefinition
|
|
5
5
|
|
|
6
|
-
class
|
|
6
|
+
class LibmpvViewModule : Module() {
|
|
7
7
|
override fun definition() = ModuleDefinition {
|
|
8
|
-
Name("
|
|
9
|
-
|
|
8
|
+
Name("LibmpvView")
|
|
9
|
+
|
|
10
|
+
View(LibmpvView::class) {
|
|
10
11
|
Events("onLibmpvLog", "onLibmpvEvent")
|
|
11
12
|
|
|
12
|
-
AsyncFunction("runCommand") { view:
|
|
13
|
+
AsyncFunction("runCommand") { view: LibmpvView, orders: String ->
|
|
13
14
|
view.runCommand(orders)
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
AsyncFunction("setOptionString") { view:
|
|
17
|
+
AsyncFunction("setOptionString") { view: LibmpvView, options: String ->
|
|
17
18
|
view.setOptionString(options)
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
AsyncFunction("cleanup") { view:
|
|
21
|
+
AsyncFunction("cleanup") { view: LibmpvView ->
|
|
21
22
|
view.cleanup()
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
Prop("playUrl") { view:
|
|
25
|
+
Prop("playUrl") { view: LibmpvView, playUrl: String ->
|
|
25
26
|
view.playUrl = playUrl
|
|
26
27
|
if (view.isSurfaceReady()) {
|
|
27
28
|
view.mpv.play(playUrl)
|
|
@@ -31,7 +32,7 @@ class LibmpvVideoModule : Module() {
|
|
|
31
32
|
view.log("setPlayUrl", playUrl)
|
|
32
33
|
}
|
|
33
34
|
|
|
34
|
-
Prop("useHardwareDecoder") { view:
|
|
35
|
+
Prop("useHardwareDecoder") { view: LibmpvView, useHardwareDecoder: Boolean ->
|
|
35
36
|
view.useHardwareDecoder = useHardwareDecoder
|
|
36
37
|
if (view.isSurfaceReady()) {
|
|
37
38
|
view.setHardwareDecoder(useHardwareDecoder)
|
|
@@ -41,7 +42,7 @@ class LibmpvVideoModule : Module() {
|
|
|
41
42
|
view.log("setUseHardwareDecoder", "$useHardwareDecoder")
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
Prop("surfaceWidth") { view:
|
|
45
|
+
Prop("surfaceWidth") { view: LibmpvView, surfaceWidth: Int ->
|
|
45
46
|
view.surfaceWidth = surfaceWidth
|
|
46
47
|
if (view.isSurfaceReady()) {
|
|
47
48
|
view.mpv.setSurfaceWidth(surfaceWidth)
|
|
@@ -51,7 +52,7 @@ class LibmpvVideoModule : Module() {
|
|
|
51
52
|
view.log("setSurfaceWidth", "$surfaceWidth")
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
Prop("surfaceHeight") { view:
|
|
55
|
+
Prop("surfaceHeight") { view: LibmpvView, surfaceHeight: Int ->
|
|
55
56
|
view.surfaceHeight = surfaceHeight
|
|
56
57
|
if (view.isSurfaceReady()) {
|
|
57
58
|
view.mpv.setSurfaceHeight(surfaceHeight)
|
|
@@ -61,7 +62,7 @@ class LibmpvVideoModule : Module() {
|
|
|
61
62
|
view.log("setSurfaceHeight", "$surfaceHeight")
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
Prop("selectedAudioTrack") { view:
|
|
65
|
+
Prop("selectedAudioTrack") { view: LibmpvView, audioTrackIndex: Int ->
|
|
65
66
|
view.audioIndex = audioTrackIndex
|
|
66
67
|
if (view.isSurfaceReady()) {
|
|
67
68
|
val mpvIndex = if (audioTrackIndex != -1) (audioTrackIndex + 1).toString() else "no"
|
|
@@ -72,7 +73,7 @@ class LibmpvVideoModule : Module() {
|
|
|
72
73
|
view.log("selectAudioTrack", "$audioTrackIndex")
|
|
73
74
|
}
|
|
74
75
|
|
|
75
|
-
Prop("selectedSubtitleTrack") { view:
|
|
76
|
+
Prop("selectedSubtitleTrack") { view: LibmpvView, subtitleTrackIndex: Int ->
|
|
76
77
|
view.subtitleIndex = subtitleTrackIndex
|
|
77
78
|
if (view.isSurfaceReady()) {
|
|
78
79
|
val mpvIndex = if (subtitleTrackIndex != -1) (subtitleTrackIndex + 1).toString() else "no"
|
|
@@ -83,14 +84,16 @@ class LibmpvVideoModule : Module() {
|
|
|
83
84
|
view.log("selectSubtitleTrack", "$subtitleTrackIndex")
|
|
84
85
|
}
|
|
85
86
|
|
|
86
|
-
Prop("seekToSeconds") { view:
|
|
87
|
+
Prop("seekToSeconds") { view: LibmpvView, seconds: Int ->
|
|
87
88
|
if (view.isSurfaceReady()) {
|
|
88
89
|
view.mpv.seekToSeconds(seconds)
|
|
90
|
+
} else {
|
|
91
|
+
view.seekToSeconds = seconds
|
|
89
92
|
}
|
|
90
93
|
view.log("seekToSeconds", "$seconds")
|
|
91
94
|
}
|
|
92
95
|
|
|
93
|
-
Prop("isPlaying") { view:
|
|
96
|
+
Prop("isPlaying") { view: LibmpvView, isPlaying: Boolean ->
|
|
94
97
|
if (view.isSurfaceReady() && view.mpv.hasPlayedOnce()) {
|
|
95
98
|
when {
|
|
96
99
|
isPlaying && !view.mpv.isPlaying() -> {
|
|
@@ -105,7 +108,7 @@ class LibmpvVideoModule : Module() {
|
|
|
105
108
|
}
|
|
106
109
|
}
|
|
107
110
|
|
|
108
|
-
OnViewDestroys { view:
|
|
111
|
+
OnViewDestroys { view: LibmpvView ->
|
|
109
112
|
view.cleanup()
|
|
110
113
|
}
|
|
111
114
|
}
|
|
@@ -1,274 +1,237 @@
|
|
|
1
1
|
package com.libmpv
|
|
2
2
|
|
|
3
|
+
import android.content.Context
|
|
3
4
|
import android.os.Handler
|
|
4
5
|
import android.os.Looper
|
|
5
|
-
import android.content.Context
|
|
6
6
|
import android.util.Log
|
|
7
7
|
import android.view.SurfaceView
|
|
8
8
|
import dev.jdtech.mpv.MPVLib
|
|
9
9
|
import java.io.File
|
|
10
10
|
import java.io.FileOutputStream
|
|
11
|
-
import
|
|
12
|
-
import
|
|
11
|
+
import kotlinx.coroutines.suspendCancellableCoroutine
|
|
12
|
+
import kotlin.coroutines.resume
|
|
13
13
|
|
|
14
14
|
class LibmpvWrapper(private val applicationContext: Context) {
|
|
15
15
|
companion object {
|
|
16
16
|
private const val TAG = "react-native-libmpv"
|
|
17
|
-
private var swallow = true
|
|
18
17
|
}
|
|
19
18
|
|
|
19
|
+
private enum class State { NEW, CREATED, INIT, RUNNING, CLEANUP, DESTROYED }
|
|
20
|
+
|
|
21
|
+
private val mainHandler = Handler(Looper.getMainLooper())
|
|
22
|
+
private val mpv = MPVLib()
|
|
23
|
+
|
|
20
24
|
@Volatile private var created = false
|
|
21
|
-
@Volatile private var destroying = false
|
|
22
|
-
@Volatile private var isDestroyed = false
|
|
23
25
|
@Volatile private var cleaning = false
|
|
26
|
+
@Volatile private var isDestroyed = false
|
|
27
|
+
@Volatile private var state = State.NEW
|
|
28
|
+
|
|
24
29
|
private var isPlaying = false
|
|
25
30
|
private var hasPlayedOnce = false
|
|
31
|
+
private var mpvDirectory: String? = null
|
|
26
32
|
private var eventObserver: MPVLib.EventObserver? = null
|
|
27
33
|
private var logObserver: MPVLib.LogObserver? = null
|
|
28
|
-
private var
|
|
34
|
+
private var surfaceView: SurfaceView? = null
|
|
29
35
|
private var surfaceWidth: Int = -1
|
|
30
36
|
private var surfaceHeight: Int = -1
|
|
31
|
-
private var surfaceView: SurfaceView? = null
|
|
32
|
-
private val mpv: MPVLib = MPVLib()
|
|
33
37
|
|
|
34
|
-
fun
|
|
35
|
-
|
|
36
|
-
createMpvDirectory()
|
|
37
|
-
created = true
|
|
38
|
-
return true
|
|
38
|
+
private inline fun safe(block: () -> Unit) {
|
|
39
|
+
try { block() } catch (e: Exception) { logException(e) }
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
fun
|
|
42
|
-
fun isPlaying(): Boolean = isPlaying
|
|
43
|
-
fun hasPlayedOnce(): Boolean = hasPlayedOnce
|
|
44
|
-
fun getMpvDirectoryPath(): String? = mpvDirectory
|
|
45
|
-
|
|
46
|
-
private fun createMpvDirectory() {
|
|
47
|
-
if (isDestroyed) return
|
|
48
|
-
val mpvDir = File(applicationContext.getExternalFilesDir("mpv"), "mpv")
|
|
42
|
+
private fun logException(e: Exception) {
|
|
49
43
|
try {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
44
|
+
Log.e(TAG, "mpv exception", e)
|
|
45
|
+
logObserver?.logMessage("RNLE", 20, e.message ?: "unknown native error")
|
|
46
|
+
} catch (_: Throwable) {}
|
|
47
|
+
}
|
|
55
48
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
private fun ensureUi(block: () -> Unit) {
|
|
50
|
+
if (Looper.myLooper() == Looper.getMainLooper()) block()
|
|
51
|
+
else mainHandler.post(block)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
fun create(): Boolean {
|
|
55
|
+
ensureUi {
|
|
56
|
+
safe {
|
|
57
|
+
mpv.create(applicationContext)
|
|
58
|
+
createMpvDirectory()
|
|
59
|
+
created = true
|
|
60
|
+
state = State.CREATED
|
|
62
61
|
}
|
|
62
|
+
}
|
|
63
|
+
return true
|
|
64
|
+
}
|
|
63
65
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
fun init() {
|
|
67
|
+
ensureUi {
|
|
68
|
+
safe {
|
|
69
|
+
if (state == State.CREATED) {
|
|
70
|
+
mpv.init()
|
|
71
|
+
state = State.RUNNING
|
|
69
72
|
}
|
|
70
73
|
}
|
|
71
|
-
} catch (e: Exception) {
|
|
72
|
-
Log.e(TAG, "Unable to create the directory $mpvDir", e)
|
|
73
74
|
}
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
77
|
+
fun destroy() = cleanup()
|
|
78
|
+
|
|
79
|
+
fun cleanup() {
|
|
80
|
+
if (!created || cleaning || state >= State.CLEANUP) return
|
|
81
|
+
cleaning = true
|
|
82
|
+
state = State.CLEANUP
|
|
83
|
+
ensureUi {
|
|
84
|
+
safe { mpv.command(arrayOf("stop")) }
|
|
85
|
+
safe { mpv.setPropertyString("pause", "yes") }
|
|
86
|
+
safe { mpv.detachSurface() }
|
|
87
|
+
safe { mpv.removeObservers() }
|
|
88
|
+
safe { mpv.removeLogObservers() }
|
|
89
|
+
safe { mpv.destroy() }
|
|
90
|
+
created = false
|
|
91
|
+
isDestroyed = true
|
|
92
|
+
cleaning = false
|
|
93
|
+
state = State.DESTROYED
|
|
83
94
|
}
|
|
84
95
|
}
|
|
85
96
|
|
|
97
|
+
fun isCreated() = created
|
|
98
|
+
fun isAlive() = !isDestroyed
|
|
99
|
+
fun isPlaying() = isPlaying
|
|
100
|
+
fun hasPlayedOnce() = hasPlayedOnce
|
|
101
|
+
fun getMpvDirectoryPath() = mpvDirectory
|
|
102
|
+
|
|
86
103
|
fun addEventObserver(observer: MPVLib.EventObserver) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
} catch (e: Exception) {
|
|
102
|
-
logException(e)
|
|
103
|
-
if (!swallow) throw e
|
|
104
|
+
ensureUi {
|
|
105
|
+
safe {
|
|
106
|
+
mpv.removeObservers()
|
|
107
|
+
eventObserver = observer
|
|
108
|
+
mpv.addObserver(observer)
|
|
109
|
+
mpv.observeProperty("demuxer-cache-time", MPVLib.MPV_FORMAT_INT64)
|
|
110
|
+
mpv.observeProperty("duration", MPVLib.MPV_FORMAT_INT64)
|
|
111
|
+
mpv.observeProperty("eof-reached", MPVLib.MPV_FORMAT_FLAG)
|
|
112
|
+
mpv.observeProperty("paused-for-cache", MPVLib.MPV_FORMAT_FLAG)
|
|
113
|
+
mpv.observeProperty("seekable", MPVLib.MPV_FORMAT_FLAG)
|
|
114
|
+
mpv.observeProperty("speed", MPVLib.MPV_FORMAT_DOUBLE)
|
|
115
|
+
mpv.observeProperty("time-pos", MPVLib.MPV_FORMAT_INT64)
|
|
116
|
+
mpv.observeProperty("track-list", MPVLib.MPV_FORMAT_STRING)
|
|
117
|
+
}
|
|
104
118
|
}
|
|
105
119
|
}
|
|
106
120
|
|
|
107
121
|
fun addLogObserver(observer: MPVLib.LogObserver) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
} catch (e: Exception) {
|
|
115
|
-
logException(e)
|
|
116
|
-
if (!swallow) throw e
|
|
122
|
+
ensureUi {
|
|
123
|
+
safe {
|
|
124
|
+
mpv.removeLogObservers()
|
|
125
|
+
logObserver = observer
|
|
126
|
+
mpv.addLogObserver(observer)
|
|
127
|
+
}
|
|
117
128
|
}
|
|
118
129
|
}
|
|
119
130
|
|
|
120
|
-
fun setOptionString(option: String,
|
|
121
|
-
|
|
122
|
-
try {
|
|
123
|
-
if (created) mpv.setOptionString(option, setting)
|
|
124
|
-
} catch (e: Exception) {
|
|
125
|
-
logException(e)
|
|
126
|
-
if (!swallow) throw e
|
|
127
|
-
}
|
|
131
|
+
fun setOptionString(option: String, value: String) {
|
|
132
|
+
ensureUi { safe { mpv.setOptionString(option, value) } }
|
|
128
133
|
}
|
|
129
134
|
|
|
130
|
-
fun setPropertyString(property: String,
|
|
131
|
-
|
|
132
|
-
try {
|
|
133
|
-
if (created) mpv.setPropertyString(property, setting)
|
|
134
|
-
} catch (e: Exception) {
|
|
135
|
-
logException(e)
|
|
136
|
-
if (!swallow) throw e
|
|
137
|
-
}
|
|
135
|
+
fun setPropertyString(property: String, value: String) {
|
|
136
|
+
ensureUi { safe { mpv.setPropertyString(property, value) } }
|
|
138
137
|
}
|
|
139
138
|
|
|
140
|
-
fun
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
if (!swallow) throw e
|
|
139
|
+
suspend fun getProperty(name: String): String? =
|
|
140
|
+
suspendCancellableCoroutine { cont ->
|
|
141
|
+
ensureUi {
|
|
142
|
+
try { cont.resume(mpv.getPropertyString(name)) }
|
|
143
|
+
catch (e: Exception) { logException(e); cont.resume(null) }
|
|
144
|
+
}
|
|
147
145
|
}
|
|
148
|
-
}
|
|
149
146
|
|
|
150
147
|
fun command(orders: Array<String>) {
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
if (created) mpv.command(orders)
|
|
154
|
-
} catch (e: Exception) {
|
|
155
|
-
logException(e)
|
|
156
|
-
if (!swallow) throw e
|
|
157
|
-
}
|
|
148
|
+
ensureUi { safe { mpv.command(orders) } }
|
|
158
149
|
}
|
|
159
150
|
|
|
160
151
|
fun attachSurface(surfaceView: SurfaceView) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
152
|
+
this.surfaceView = surfaceView
|
|
153
|
+
applySurfaceDimensions()
|
|
154
|
+
ensureUi {
|
|
155
|
+
safe {
|
|
156
|
+
if (state >= State.CREATED && state < State.CLEANUP) {
|
|
157
|
+
mpv.attachSurface(surfaceView.holder.surface)
|
|
158
|
+
}
|
|
167
159
|
}
|
|
168
|
-
} catch (e: Exception) {
|
|
169
|
-
logException(e)
|
|
170
|
-
if (!swallow) throw e
|
|
171
160
|
}
|
|
172
161
|
}
|
|
173
162
|
|
|
174
|
-
fun
|
|
175
|
-
|
|
176
|
-
if (!isPlaying) {
|
|
177
|
-
if (options == null) {
|
|
178
|
-
command(arrayOf("loadfile", url))
|
|
179
|
-
} else {
|
|
180
|
-
command(arrayOf("loadfile", url, "replace", "0", options))
|
|
181
|
-
}
|
|
182
|
-
command(arrayOf("set", "pause", "no"))
|
|
183
|
-
hasPlayedOnce = true
|
|
184
|
-
isPlaying = true
|
|
185
|
-
}
|
|
163
|
+
fun detachSurface() {
|
|
164
|
+
ensureUi { safe { mpv.detachSurface() } }
|
|
186
165
|
}
|
|
187
166
|
|
|
188
|
-
fun
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (isPlaying) pause() else unpause()
|
|
167
|
+
fun setSurfaceWidth(width: Int) {
|
|
168
|
+
surfaceWidth = width
|
|
169
|
+
applySurfaceDimensions()
|
|
192
170
|
}
|
|
193
171
|
|
|
194
|
-
fun
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (isPlaying) {
|
|
198
|
-
command(arrayOf("set", "pause", "yes"))
|
|
199
|
-
isPlaying = false
|
|
200
|
-
}
|
|
172
|
+
fun setSurfaceHeight(height: Int) {
|
|
173
|
+
surfaceHeight = height
|
|
174
|
+
applySurfaceDimensions()
|
|
201
175
|
}
|
|
202
176
|
|
|
203
|
-
fun
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
177
|
+
private fun applySurfaceDimensions() {
|
|
178
|
+
ensureUi {
|
|
179
|
+
try {
|
|
180
|
+
if (surfaceWidth > 0 && surfaceHeight > 0 && surfaceView != null) {
|
|
181
|
+
surfaceView?.holder?.setFixedSize(surfaceWidth, surfaceHeight)
|
|
182
|
+
}
|
|
183
|
+
} catch (e: Exception) { logException(e) }
|
|
209
184
|
}
|
|
210
185
|
}
|
|
211
186
|
|
|
212
|
-
fun
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
187
|
+
fun play(url: String, options: String? = null) {
|
|
188
|
+
ensureUi {
|
|
189
|
+
safe {
|
|
190
|
+
if (!isPlaying) {
|
|
191
|
+
if (options == null)
|
|
192
|
+
mpv.command(arrayOf("loadfile", url))
|
|
193
|
+
else
|
|
194
|
+
mpv.command(arrayOf("loadfile", url, "replace", "0", options))
|
|
195
|
+
mpv.command(arrayOf("set", "pause", "no"))
|
|
196
|
+
hasPlayedOnce = true
|
|
197
|
+
isPlaying = true
|
|
198
|
+
}
|
|
199
|
+
}
|
|
216
200
|
}
|
|
217
201
|
}
|
|
218
202
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
if (surfaceHeight != -1 && surfaceWidth != -1 && surfaceView != null) {
|
|
222
|
-
surfaceView?.holder?.setFixedSize(surfaceWidth, surfaceHeight)
|
|
223
|
-
}
|
|
203
|
+
fun pause() {
|
|
204
|
+
ensureUi { safe { mpv.command(arrayOf("set", "pause", "yes")); isPlaying = false } }
|
|
224
205
|
}
|
|
225
206
|
|
|
226
|
-
fun
|
|
227
|
-
|
|
228
|
-
applySurfaceDimensions()
|
|
207
|
+
fun unpause() {
|
|
208
|
+
ensureUi { safe { mpv.command(arrayOf("set", "pause", "no")); isPlaying = true } }
|
|
229
209
|
}
|
|
230
210
|
|
|
231
|
-
fun
|
|
232
|
-
|
|
233
|
-
applySurfaceDimensions()
|
|
211
|
+
fun pauseOrUnpause() {
|
|
212
|
+
ensureUi { if (isPlaying) pause() else unpause() }
|
|
234
213
|
}
|
|
235
214
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
try{
|
|
239
|
-
|
|
240
|
-
}catch(swallow:Exception){}
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
fun cleanup() {
|
|
245
|
-
if (!created || cleaning) return
|
|
246
|
-
cleaning = true
|
|
247
|
-
|
|
248
|
-
Thread {
|
|
249
|
-
try {
|
|
250
|
-
safe { command(arrayOf("stop")) }
|
|
251
|
-
safe { setPropertyString("pause", "yes") }
|
|
252
|
-
safe { setPropertyString("vo", "null") }
|
|
253
|
-
safe { setPropertyString("ao", "null") }
|
|
254
|
-
safe { detachSurface() }
|
|
255
|
-
Handler(Looper.getMainLooper()).post {
|
|
256
|
-
safe { mpv.removeObservers() }
|
|
257
|
-
safe { mpv.removeLogObservers() }
|
|
258
|
-
safe { mpv.destroy() }
|
|
259
|
-
created = false
|
|
260
|
-
cleaning = false
|
|
261
|
-
}
|
|
262
|
-
} catch (e: Exception) {
|
|
263
|
-
logException(e)
|
|
264
|
-
cleaning = false
|
|
215
|
+
fun seekToSeconds(seconds: Int) {
|
|
216
|
+
ensureUi { safe { mpv.command(arrayOf("seek", seconds.toString(), "absolute")) } }
|
|
265
217
|
}
|
|
266
|
-
}.start()
|
|
267
|
-
}
|
|
268
218
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
219
|
+
private fun createMpvDirectory() {
|
|
220
|
+
val dir = File(applicationContext.getExternalFilesDir("mpv"), "mpv")
|
|
221
|
+
try {
|
|
222
|
+
mpvDirectory = dir.absolutePath
|
|
223
|
+
if (!dir.exists() && !dir.mkdirs()) {
|
|
224
|
+
Log.e(TAG, "Unable to create $dir")
|
|
225
|
+
return
|
|
226
|
+
}
|
|
227
|
+
applicationContext.assets.open("subfont.ttf").use { inp ->
|
|
228
|
+
FileOutputStream("${dir}/subfont.ttf").use { out -> inp.copyTo(out) }
|
|
229
|
+
}
|
|
230
|
+
applicationContext.assets.open("mpv.conf").use { inp ->
|
|
231
|
+
FileOutputStream("${dir}/mpv.conf").use { out -> inp.copyTo(out) }
|
|
232
|
+
}
|
|
233
|
+
} catch (e: Exception) {
|
|
234
|
+
logException(e)
|
|
235
|
+
}
|
|
236
|
+
}
|
|
274
237
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Libmpv.d.ts","sourceRoot":"","sources":["../src/Libmpv.tsx"],"names":[],"mappings":"AAEA,eAAO,MAAM,MAAM;yBACM,MAAM,QAAQ,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAC1D,CAAC;AAEb,eAAe,MAAM,CAAA"}
|
package/build/Libmpv.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Libmpv.js","sourceRoot":"","sources":["../src/Libmpv.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,MAAM,CAAC,MAAM,MAAM,GAAG,mBAAmB,CAEtC,QAAQ,CAAC,CAAC;AAEb,eAAe,MAAM,CAAA","sourcesContent":["import { requireNativeModule } from 'expo-modules-core';\n\nexport const Libmpv = requireNativeModule<'getProperty' extends never ? any : {\n getProperty(viewTag: number, name: string): Promise<string | null>;\n}>('Libmpv');\n\nexport default Libmpv"]}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { LibmpvViewProps, LibmpvViewNativeMethods } from './LibmpvViewTypes';
|
|
3
|
+
export declare const LibmpvView: React.ForwardRefExoticComponent<Omit<LibmpvViewProps, "ref"> & React.RefAttributes<LibmpvViewNativeMethods>>;
|
|
4
|
+
export default LibmpvView;
|
|
5
|
+
//# sourceMappingURL=LibmpvView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LibmpvView.d.ts","sourceRoot":"","sources":["../src/LibmpvView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAkC7E,eAAO,MAAM,UAAU,8GAsDrB,CAAA;AAEF,eAAe,UAAU,CAAA"}
|
|
@@ -28,8 +28,8 @@ const EVENT_LOOKUP = {
|
|
|
28
28
|
24: 'QUEUE_OVERFLOW',
|
|
29
29
|
25: 'HOOK'
|
|
30
30
|
};
|
|
31
|
-
const
|
|
32
|
-
export const
|
|
31
|
+
const LibmpvViewNative = requireNativeView('LibmpvView');
|
|
32
|
+
export const LibmpvView = React.forwardRef((props, parentRef) => {
|
|
33
33
|
React.useEffect(() => {
|
|
34
34
|
return () => {
|
|
35
35
|
if (parentRef?.current?.cleanup) {
|
|
@@ -67,7 +67,7 @@ export const LibmpvVideo = React.forwardRef((props, parentRef) => {
|
|
|
67
67
|
// The order props are handled in the native code is non-deterministic
|
|
68
68
|
// Each native prop setter checks to see if all required props are set
|
|
69
69
|
// Only then will it try to create an instance of mpv
|
|
70
|
-
return <
|
|
70
|
+
return <LibmpvViewNative ref={parentRef} style={props.surfaceStyle ? props.surfaceStyle : styles.videoPlayer} playUrl={props.playUrl} isPlaying={props.isPlaying} useHardwareDecoder={props.useHardwareDecoder} surfaceWidth={props.surfaceWidth} surfaceHeight={props.surfaceHeight} selectedAudioTrack={props.selectedAudioTrack} selectedSubtitleTrack={props.selectedSubtitleTrack} seekToSeconds={props.seekToSeconds} onLibmpvEvent={onLogEvent} onLibmpvLog={onLibmpvLog}/>;
|
|
71
71
|
});
|
|
72
|
-
export default
|
|
73
|
-
//# sourceMappingURL=
|
|
72
|
+
export default LibmpvView;
|
|
73
|
+
//# sourceMappingURL=LibmpvView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LibmpvView.js","sourceRoot":"","sources":["../src/LibmpvView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeView } from 'expo';\nimport * as React from 'react';\nimport { LibmpvViewProps, LibmpvViewNativeMethods } from './LibmpvViewTypes';\n\nconst styles: any = {\n videoPlayer: {\n position: \"absolute\",\n left: 0,\n bottom: 0,\n right: 0,\n top: 0\n }\n};\n\nconst EVENT_LOOKUP: any = {\n 0: 'NONE',\n 1: 'SHUTDOWN',\n 2: 'LOG_MESSAGE',\n 3: 'GET_PROPERTY_REPLY',\n 4: 'SET_PROPERTY_REPLY',\n 5: 'COMMAND_REPLY',\n 6: 'START_FILE',\n 7: 'END_FILE',\n 8: 'FILE_LOADED',\n 16: 'CLIENT_MESSAGE',\n 17: 'VIDEO_RECONFIG',\n 18: 'AUDIO_RECONFIG',\n 20: 'SEEK',\n 21: 'PLAYBACK_RESTART',\n 22: 'PROPERTY_CHANGE',\n 24: 'QUEUE_OVERFLOW',\n 25: 'HOOK'\n}\n\nconst LibmpvViewNative: React.ComponentType<LibmpvViewProps> = requireNativeView('LibmpvView');\n\nexport const LibmpvView = React.forwardRef<LibmpvViewNativeMethods, LibmpvViewProps>((props: any, parentRef: any) => {\n React.useEffect(() => {\n return () => {\n if (parentRef?.current?.cleanup) {\n parentRef.current.cleanup();\n }\n };\n }, []);\n\n // Pass mpv events and logs back up to the parent\n const onLogEvent = (libmpvEvent: any) => {\n if (props.onLibmpvEvent) {\n if (libmpvEvent && libmpvEvent.nativeEvent) {\n libmpvEvent = libmpvEvent.nativeEvent\n }\n if (libmpvEvent.eventId) {\n libmpvEvent.value = parseInt(libmpvEvent.eventId, 10)\n libmpvEvent.eventKind = EVENT_LOOKUP[libmpvEvent.eventId]\n }\n else if (libmpvEvent.kind === 'long' || libmpvEvent.kind === 'double') {\n libmpvEvent.value = Number(libmpvEvent.value)\n }\n else if (libmpvEvent.kind === 'boolean') {\n libmpvEvent.value = libmpvEvent.value === 'true'\n }\n return props.onLibmpvEvent(libmpvEvent)\n }\n }\n const onLibmpvLog = (libmpvLog: any) => {\n if (props.onLibmpvLog) {\n if (libmpvLog && libmpvLog.nativeEvent) {\n libmpvLog = libmpvLog.nativeEvent\n }\n return props.onLibmpvLog(libmpvLog);\n }\n }\n\n // The order props are handled in the native code is non-deterministic\n // Each native prop setter checks to see if all required props are set\n // Only then will it try to create an instance of mpv\n return <LibmpvViewNative\n ref={parentRef}\n style={props.surfaceStyle ? props.surfaceStyle : styles.videoPlayer}\n playUrl={props.playUrl}\n isPlaying={props.isPlaying}\n useHardwareDecoder={props.useHardwareDecoder}\n surfaceWidth={props.surfaceWidth}\n surfaceHeight={props.surfaceHeight}\n selectedAudioTrack={props.selectedAudioTrack}\n selectedSubtitleTrack={props.selectedSubtitleTrack}\n seekToSeconds={props.seekToSeconds}\n onLibmpvEvent={onLogEvent}\n onLibmpvLog={onLibmpvLog}\n />\n})\n\nexport default LibmpvView"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type LibmpvViewProps = {
|
|
2
2
|
ref: any;
|
|
3
3
|
style: any;
|
|
4
4
|
playUrl: string;
|
|
@@ -12,8 +12,8 @@ export type LibmpvVideoViewProps = {
|
|
|
12
12
|
onLibmpvEvent: (libmpvEvent: any) => void;
|
|
13
13
|
onLibmpvLog: (libmpvLog: any) => void;
|
|
14
14
|
};
|
|
15
|
-
export type
|
|
15
|
+
export type LibmpvViewNativeMethods = {
|
|
16
16
|
runCommand: (pipeDelimitedArguments: string) => void | Promise<void>;
|
|
17
17
|
setOptionString: (pipeDelimitedArguments: string) => void | Promise<void>;
|
|
18
18
|
};
|
|
19
|
-
//# sourceMappingURL=
|
|
19
|
+
//# sourceMappingURL=LibmpvViewTypes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LibmpvViewTypes.d.ts","sourceRoot":"","sources":["../src/LibmpvViewTypes.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,GAAG,CAAC;IACT,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,CAAC,WAAW,EAAE,GAAG,KAAK,IAAI,CAAC;IAC1C,WAAW,EAAE,CAAC,SAAS,EAAE,GAAG,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,UAAU,EAAE,CAAC,sBAAsB,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,eAAe,EAAE,CAAC,sBAAsB,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LibmpvViewTypes.js","sourceRoot":"","sources":["../src/LibmpvViewTypes.ts"],"names":[],"mappings":"","sourcesContent":["export type LibmpvViewProps = {\n ref: any,\n style: any,\n playUrl: string,\n isPlaying: boolean,\n useHardwareDecoder: boolean,\n selectedAudioTrack: number,\n selectedSubtitleTrack: number,\n seekToSeconds: number,\n surfaceWidth: number,\n surfaceHeight: number,\n onLibmpvEvent: (libmpvEvent: any) => void,\n onLibmpvLog: (libmpvLog: any) => void,\n};\n\nexport type LibmpvViewNativeMethods = {\n runCommand: (pipeDelimitedArguments: string) => void | Promise<void>;\n setOptionString: (pipeDelimitedArguments: string) => void | Promise<void>;\n};"]}
|
package/build/index.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
-
export { default as
|
|
2
|
-
export
|
|
1
|
+
export { default as Libmpv } from './Libmpv';
|
|
2
|
+
export { default as LibmpvView } from './LibmpvView';
|
|
3
|
+
import * as LibmpvViewTypes from './LibmpvViewTypes';
|
|
4
|
+
export * as LibmpvViewTypes from './LibmpvViewTypes';
|
|
5
|
+
declare const _default: {
|
|
6
|
+
Module: {
|
|
7
|
+
getProperty(viewTag: number, name: string): Promise<string | null>;
|
|
8
|
+
};
|
|
9
|
+
View: import("react").ForwardRefExoticComponent<Omit<LibmpvViewTypes.LibmpvViewProps, "ref"> & import("react").RefAttributes<LibmpvViewTypes.LibmpvViewNativeMethods>>;
|
|
10
|
+
Types: typeof LibmpvViewTypes;
|
|
11
|
+
};
|
|
12
|
+
export default _default;
|
|
3
13
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAA;AAG5C,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,eAAe,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,eAAe,MAAM,mBAAmB,CAAC;;;;;;;;AAErD,wBAIC"}
|
package/build/index.js
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
import { default as Libmpv } from './Libmpv';
|
|
2
|
+
export { default as Libmpv } from './Libmpv';
|
|
3
|
+
import { default as LibmpvView } from './LibmpvView';
|
|
4
|
+
export { default as LibmpvView } from './LibmpvView';
|
|
5
|
+
import * as LibmpvViewTypes from './LibmpvViewTypes';
|
|
6
|
+
export * as LibmpvViewTypes from './LibmpvViewTypes';
|
|
7
|
+
export default {
|
|
8
|
+
Module: Libmpv,
|
|
9
|
+
View: LibmpvView,
|
|
10
|
+
Types: LibmpvViewTypes
|
|
11
|
+
};
|
|
3
12
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,UAAU,CAAA;AAE5C,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,cAAc,CAAC;AAErD,OAAO,KAAK,eAAe,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,eAAe,MAAM,mBAAmB,CAAC;AAErD,eAAe;IACX,MAAM,EAAE,MAAM;IACd,IAAI,EAAE,UAAU;IAChB,KAAK,EAAE,eAAe;CACzB,CAAA","sourcesContent":["import { default as Libmpv } from './Libmpv'\nexport { default as Libmpv } from './Libmpv'\n\nimport { default as LibmpvView } from './LibmpvView';\nexport { default as LibmpvView } from './LibmpvView';\n\nimport * as LibmpvViewTypes from './LibmpvViewTypes';\nexport * as LibmpvViewTypes from './LibmpvViewTypes';\n\nexport default {\n Module: Libmpv,\n View: LibmpvView,\n Types: LibmpvViewTypes\n}\n"]}
|
package/expo-module.config.json
CHANGED
package/package.json
CHANGED
package/src/Libmpv.tsx
ADDED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { requireNativeView } from 'expo';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
|
|
4
|
-
import { LibmpvVideoViewProps, LibmpvNativeMethods } from './LibmpvVideo.types';
|
|
3
|
+
import { LibmpvViewProps, LibmpvViewNativeMethods } from './LibmpvViewTypes';
|
|
5
4
|
|
|
6
5
|
const styles: any = {
|
|
7
6
|
videoPlayer: {
|
|
@@ -33,10 +32,9 @@ const EVENT_LOOKUP: any = {
|
|
|
33
32
|
25: 'HOOK'
|
|
34
33
|
}
|
|
35
34
|
|
|
36
|
-
const
|
|
37
|
-
requireNativeView('LibmpvVideo');
|
|
35
|
+
const LibmpvViewNative: React.ComponentType<LibmpvViewProps> = requireNativeView('LibmpvView');
|
|
38
36
|
|
|
39
|
-
export const
|
|
37
|
+
export const LibmpvView = React.forwardRef<LibmpvViewNativeMethods, LibmpvViewProps>((props: any, parentRef: any) => {
|
|
40
38
|
React.useEffect(() => {
|
|
41
39
|
return () => {
|
|
42
40
|
if (parentRef?.current?.cleanup) {
|
|
@@ -76,7 +74,7 @@ export const LibmpvVideo = React.forwardRef<LibmpvNativeMethods, LibmpvVideoView
|
|
|
76
74
|
// The order props are handled in the native code is non-deterministic
|
|
77
75
|
// Each native prop setter checks to see if all required props are set
|
|
78
76
|
// Only then will it try to create an instance of mpv
|
|
79
|
-
return <
|
|
77
|
+
return <LibmpvViewNative
|
|
80
78
|
ref={parentRef}
|
|
81
79
|
style={props.surfaceStyle ? props.surfaceStyle : styles.videoPlayer}
|
|
82
80
|
playUrl={props.playUrl}
|
|
@@ -92,4 +90,4 @@ export const LibmpvVideo = React.forwardRef<LibmpvNativeMethods, LibmpvVideoView
|
|
|
92
90
|
/>
|
|
93
91
|
})
|
|
94
92
|
|
|
95
|
-
export default
|
|
93
|
+
export default LibmpvView
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type
|
|
1
|
+
export type LibmpvViewProps = {
|
|
2
2
|
ref: any,
|
|
3
3
|
style: any,
|
|
4
4
|
playUrl: string,
|
|
@@ -13,7 +13,7 @@ export type LibmpvVideoViewProps = {
|
|
|
13
13
|
onLibmpvLog: (libmpvLog: any) => void,
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
export type
|
|
16
|
+
export type LibmpvViewNativeMethods = {
|
|
17
17
|
runCommand: (pipeDelimitedArguments: string) => void | Promise<void>;
|
|
18
18
|
setOptionString: (pipeDelimitedArguments: string) => void | Promise<void>;
|
|
19
19
|
};
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
1
|
+
import { default as Libmpv } from './Libmpv'
|
|
2
|
+
export { default as Libmpv } from './Libmpv'
|
|
3
|
+
|
|
4
|
+
import { default as LibmpvView } from './LibmpvView';
|
|
5
|
+
export { default as LibmpvView } from './LibmpvView';
|
|
6
|
+
|
|
7
|
+
import * as LibmpvViewTypes from './LibmpvViewTypes';
|
|
8
|
+
export * as LibmpvViewTypes from './LibmpvViewTypes';
|
|
9
|
+
|
|
10
|
+
export default {
|
|
11
|
+
Module: Libmpv,
|
|
12
|
+
View: LibmpvView,
|
|
13
|
+
Types: LibmpvViewTypes
|
|
14
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LibmpvVideo.types.d.ts","sourceRoot":"","sources":["../src/LibmpvVideo.types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,GAAG,CAAC;IACT,KAAK,EAAE,GAAG,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,CAAC,WAAW,EAAE,GAAG,KAAK,IAAI,CAAC;IAC1C,WAAW,EAAE,CAAC,SAAS,EAAE,GAAG,KAAK,IAAI,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,CAAC,sBAAsB,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,eAAe,EAAE,CAAC,sBAAsB,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3E,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LibmpvVideo.types.js","sourceRoot":"","sources":["../src/LibmpvVideo.types.ts"],"names":[],"mappings":"","sourcesContent":["export type LibmpvVideoViewProps = {\n ref: any,\n style: any,\n playUrl: string,\n isPlaying: boolean,\n useHardwareDecoder: boolean,\n selectedAudioTrack: number,\n selectedSubtitleTrack: number,\n seekToSeconds: number,\n surfaceWidth: number,\n surfaceHeight: number,\n onLibmpvEvent: (libmpvEvent: any) => void,\n onLibmpvLog: (libmpvLog: any) => void,\n};\n\nexport type LibmpvNativeMethods = {\n runCommand: (pipeDelimitedArguments: string) => void | Promise<void>;\n setOptionString: (pipeDelimitedArguments: string) => void | Promise<void>;\n};"]}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import * as React from 'react';
|
|
2
|
-
import { LibmpvVideoViewProps, LibmpvNativeMethods } from './LibmpvVideo.types';
|
|
3
|
-
export declare const LibmpvVideo: React.ForwardRefExoticComponent<Omit<LibmpvVideoViewProps, "ref"> & React.RefAttributes<LibmpvNativeMethods>>;
|
|
4
|
-
export default LibmpvVideo;
|
|
5
|
-
//# sourceMappingURL=LibmpvVideoView.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LibmpvVideoView.d.ts","sourceRoot":"","sources":["../src/LibmpvVideoView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAmChF,eAAO,MAAM,WAAW,+GAsDtB,CAAA;AAEF,eAAe,WAAW,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"LibmpvVideoView.js","sourceRoot":"","sources":["../src/LibmpvVideoView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeView } from 'expo';\nimport * as React from 'react';\n\nimport { LibmpvVideoViewProps, LibmpvNativeMethods } from './LibmpvVideo.types';\n\nconst styles: any = {\n videoPlayer: {\n position: \"absolute\",\n left: 0,\n bottom: 0,\n right: 0,\n top: 0\n }\n};\n\nconst EVENT_LOOKUP: any = {\n 0: 'NONE',\n 1: 'SHUTDOWN',\n 2: 'LOG_MESSAGE',\n 3: 'GET_PROPERTY_REPLY',\n 4: 'SET_PROPERTY_REPLY',\n 5: 'COMMAND_REPLY',\n 6: 'START_FILE',\n 7: 'END_FILE',\n 8: 'FILE_LOADED',\n 16: 'CLIENT_MESSAGE',\n 17: 'VIDEO_RECONFIG',\n 18: 'AUDIO_RECONFIG',\n 20: 'SEEK',\n 21: 'PLAYBACK_RESTART',\n 22: 'PROPERTY_CHANGE',\n 24: 'QUEUE_OVERFLOW',\n 25: 'HOOK'\n}\n\nconst LibmpvVideoView: React.ComponentType<LibmpvVideoViewProps> =\n requireNativeView('LibmpvVideo');\n\nexport const LibmpvVideo = React.forwardRef<LibmpvNativeMethods, LibmpvVideoViewProps>((props: any, parentRef: any) => {\n React.useEffect(() => {\n return () => {\n if (parentRef?.current?.cleanup) {\n parentRef.current.cleanup();\n }\n };\n }, []);\n\n // Pass mpv events and logs back up to the parent\n const onLogEvent = (libmpvEvent: any) => {\n if (props.onLibmpvEvent) {\n if (libmpvEvent && libmpvEvent.nativeEvent) {\n libmpvEvent = libmpvEvent.nativeEvent\n }\n if (libmpvEvent.eventId) {\n libmpvEvent.value = parseInt(libmpvEvent.eventId, 10)\n libmpvEvent.eventKind = EVENT_LOOKUP[libmpvEvent.eventId]\n }\n else if (libmpvEvent.kind === 'long' || libmpvEvent.kind === 'double') {\n libmpvEvent.value = Number(libmpvEvent.value)\n }\n else if (libmpvEvent.kind === 'boolean') {\n libmpvEvent.value = libmpvEvent.value === 'true'\n }\n return props.onLibmpvEvent(libmpvEvent)\n }\n }\n const onLibmpvLog = (libmpvLog: any) => {\n if (props.onLibmpvLog) {\n if (libmpvLog && libmpvLog.nativeEvent) {\n libmpvLog = libmpvLog.nativeEvent\n }\n return props.onLibmpvLog(libmpvLog);\n }\n }\n\n // The order props are handled in the native code is non-deterministic\n // Each native prop setter checks to see if all required props are set\n // Only then will it try to create an instance of mpv\n return <LibmpvVideoView\n ref={parentRef}\n style={props.surfaceStyle ? props.surfaceStyle : styles.videoPlayer}\n playUrl={props.playUrl}\n isPlaying={props.isPlaying}\n useHardwareDecoder={props.useHardwareDecoder}\n surfaceWidth={props.surfaceWidth}\n surfaceHeight={props.surfaceHeight}\n selectedAudioTrack={props.selectedAudioTrack}\n selectedSubtitleTrack={props.selectedSubtitleTrack}\n seekToSeconds={props.seekToSeconds}\n onLibmpvEvent={onLogEvent}\n onLibmpvLog={onLibmpvLog}\n />\n})\n\nexport default LibmpvVideo\n"]}
|