expo-libmpv 0.5.1 → 0.5.4
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/LibmpvRenderer.kt +226 -114
- package/android/src/main/java/com/libmpv/LibmpvView.kt +18 -15
- package/build/LibmpvView.d.ts.map +1 -1
- package/build/LibmpvView.js +1 -5
- package/build/LibmpvView.js.map +1 -1
- package/package.json +1 -1
- package/src/LibmpvView.tsx +1 -6
package/android/build.gradle
CHANGED
|
@@ -27,6 +27,7 @@ class LibmpvRenderer(
|
|
|
27
27
|
|
|
28
28
|
companion object {
|
|
29
29
|
private const val TAG = "expo-libmpv"
|
|
30
|
+
private const val LOG_LEVEL_INFO = 20
|
|
30
31
|
private const val LOG_LEVEL_WARN = 30
|
|
31
32
|
}
|
|
32
33
|
|
|
@@ -35,22 +36,32 @@ class LibmpvRenderer(
|
|
|
35
36
|
@Volatile private var state: State = State.NEW
|
|
36
37
|
@Volatile private var destroyed = false
|
|
37
38
|
@Volatile private var loadedUrl: String? = null
|
|
39
|
+
@Volatile private var surfaceAttached = false
|
|
40
|
+
@Volatile var surfaceReady = false
|
|
38
41
|
|
|
39
42
|
private var mpvDirectory: String? = null
|
|
40
43
|
|
|
41
44
|
private inline val mpvAlive: Boolean
|
|
42
|
-
get()
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
get() {
|
|
46
|
+
return when (state) {
|
|
47
|
+
State.CREATED,
|
|
48
|
+
State.INITIALIZED,
|
|
49
|
+
State.ACTIVE -> true
|
|
50
|
+
else -> false
|
|
51
|
+
}
|
|
45
52
|
}
|
|
46
53
|
|
|
47
54
|
private inline val shuttingDown: Boolean
|
|
48
|
-
get()
|
|
55
|
+
get() {
|
|
56
|
+
return state == State.SHUTTING_DOWN || state == State.DESTROYED
|
|
57
|
+
}
|
|
49
58
|
|
|
50
59
|
private val mainHandler = Handler(Looper.getMainLooper())
|
|
51
60
|
|
|
52
61
|
fun runCommand(command: Array<String>) {
|
|
53
|
-
if (!mpvAlive || shuttingDown)
|
|
62
|
+
if (!mpvAlive || shuttingDown) {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
54
65
|
try {
|
|
55
66
|
MPVLib.command(command)
|
|
56
67
|
} catch (e: Exception) {
|
|
@@ -59,7 +70,9 @@ class LibmpvRenderer(
|
|
|
59
70
|
}
|
|
60
71
|
|
|
61
72
|
fun setOptionString(option: String, value: String) {
|
|
62
|
-
if (!mpvAlive || shuttingDown)
|
|
73
|
+
if (!mpvAlive || shuttingDown) {
|
|
74
|
+
return
|
|
75
|
+
}
|
|
63
76
|
try {
|
|
64
77
|
MPVLib.setOptionString(option, value)
|
|
65
78
|
} catch (e: Exception) {
|
|
@@ -67,70 +80,104 @@ class LibmpvRenderer(
|
|
|
67
80
|
}
|
|
68
81
|
}
|
|
69
82
|
|
|
70
|
-
|
|
71
83
|
fun start() {
|
|
72
84
|
synchronized(stateLock) {
|
|
73
|
-
if (state != State.NEW && state != State.DESTROYED) return
|
|
74
85
|
try {
|
|
75
86
|
MPVLib.create(surfaceView.context.applicationContext)
|
|
76
87
|
createMpvDirectory()
|
|
77
88
|
state = State.CREATED
|
|
78
89
|
} catch (e: Exception) {
|
|
79
90
|
logException(e)
|
|
80
|
-
return
|
|
81
91
|
}
|
|
82
92
|
}
|
|
83
|
-
|
|
84
|
-
initMpv()
|
|
85
|
-
attachSurfaceAndConfigure()
|
|
86
93
|
}
|
|
87
94
|
|
|
88
95
|
fun destroy() {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
96
|
+
val doTeardown: Boolean
|
|
97
|
+
synchronized(stateLock) {
|
|
98
|
+
doTeardown = when (state) {
|
|
99
|
+
State.NEW,
|
|
100
|
+
State.SHUTTING_DOWN,
|
|
101
|
+
State.DESTROYED -> false
|
|
102
|
+
else -> true
|
|
103
|
+
}
|
|
104
|
+
if (doTeardown) {
|
|
105
|
+
state = State.SHUTTING_DOWN
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (!doTeardown) {
|
|
109
|
+
return
|
|
94
110
|
}
|
|
95
|
-
if (doTeardown) state = State.SHUTTING_DOWN
|
|
96
|
-
}
|
|
97
|
-
if (!doTeardown) return
|
|
98
|
-
|
|
99
|
-
destroyed = true
|
|
100
111
|
|
|
101
|
-
|
|
102
|
-
loadedUrl = null
|
|
103
|
-
stopPlayback()
|
|
104
|
-
detachSurfaceInternal()
|
|
112
|
+
destroyed = true
|
|
105
113
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
114
|
+
try {
|
|
115
|
+
loadedUrl = null
|
|
116
|
+
stopPlayback()
|
|
117
|
+
|
|
118
|
+
mainHandler.post {
|
|
119
|
+
try {
|
|
120
|
+
detachSurfaceForDestroy()
|
|
121
|
+
MPVLib.destroy()
|
|
122
|
+
} finally {
|
|
123
|
+
synchronized(stateLock) {
|
|
124
|
+
state = State.DESTROYED
|
|
125
|
+
}
|
|
112
126
|
}
|
|
113
127
|
}
|
|
128
|
+
} catch (e: Exception) {
|
|
129
|
+
logException(e)
|
|
130
|
+
synchronized(stateLock) {
|
|
131
|
+
state = State.DESTROYED
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
fun attachSurfaceIfNeeded() {
|
|
137
|
+
if (!surfaceReady || surfaceAttached) {
|
|
138
|
+
return
|
|
114
139
|
}
|
|
115
|
-
|
|
116
|
-
|
|
140
|
+
|
|
141
|
+
MPVLib.attachSurface(surfaceView.holder.surface)
|
|
142
|
+
surfaceAttached = true
|
|
143
|
+
|
|
117
144
|
synchronized(stateLock) {
|
|
118
|
-
|
|
145
|
+
MPVLib.init()
|
|
146
|
+
state = State.INITIALIZED
|
|
119
147
|
}
|
|
148
|
+
|
|
149
|
+
addObservers()
|
|
150
|
+
applyConfiguration()
|
|
151
|
+
state = State.ACTIVE
|
|
152
|
+
maybeStartPlayback()
|
|
120
153
|
}
|
|
121
|
-
}
|
|
122
154
|
|
|
155
|
+
private fun detachSurfaceForDestroy() {
|
|
156
|
+
if (!surfaceAttached) {
|
|
157
|
+
return
|
|
158
|
+
}
|
|
159
|
+
try {
|
|
160
|
+
MPVLib.detachSurface()
|
|
161
|
+
} catch (e: Exception) {
|
|
162
|
+
logException(e)
|
|
163
|
+
} finally {
|
|
164
|
+
surfaceAttached = false
|
|
165
|
+
}
|
|
166
|
+
}
|
|
123
167
|
|
|
124
168
|
fun onSessionUpdated() {
|
|
125
|
-
if (!mpvAlive || shuttingDown)
|
|
126
|
-
|
|
169
|
+
if (!mpvAlive || shuttingDown) {
|
|
170
|
+
return
|
|
171
|
+
}
|
|
127
172
|
applyDeferredState()
|
|
128
173
|
applyContinuousState()
|
|
129
174
|
}
|
|
130
175
|
|
|
131
176
|
private fun initMpv() {
|
|
132
177
|
synchronized(stateLock) {
|
|
133
|
-
if (shuttingDown || state != State.CREATED)
|
|
178
|
+
if (shuttingDown || state != State.CREATED) {
|
|
179
|
+
return
|
|
180
|
+
}
|
|
134
181
|
try {
|
|
135
182
|
MPVLib.init()
|
|
136
183
|
state = State.INITIALIZED
|
|
@@ -142,25 +189,10 @@ class LibmpvRenderer(
|
|
|
142
189
|
addObservers()
|
|
143
190
|
}
|
|
144
191
|
|
|
145
|
-
private fun attachSurfaceAndConfigure() {
|
|
146
|
-
if (!mpvAlive || shuttingDown) return
|
|
147
|
-
try {
|
|
148
|
-
MPVLib.attachSurface(surfaceView.holder.surface)
|
|
149
|
-
synchronized(stateLock) {
|
|
150
|
-
if (state == State.CREATED || state == State.INITIALIZED) {
|
|
151
|
-
state = State.ACTIVE
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
applyConfiguration()
|
|
155
|
-
MPVLib.setPropertyString("pause", "yes")
|
|
156
|
-
maybeStartPlayback()
|
|
157
|
-
} catch (e: Exception) {
|
|
158
|
-
logException(e)
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
192
|
private fun addObservers() {
|
|
163
|
-
if (!mpvAlive || shuttingDown)
|
|
193
|
+
if (!mpvAlive || shuttingDown) {
|
|
194
|
+
return
|
|
195
|
+
}
|
|
164
196
|
try {
|
|
165
197
|
MPVLib.removeObservers()
|
|
166
198
|
MPVLib.addObserver(this)
|
|
@@ -181,19 +213,23 @@ class LibmpvRenderer(
|
|
|
181
213
|
}
|
|
182
214
|
|
|
183
215
|
private fun applyConfiguration() {
|
|
184
|
-
if (!mpvAlive || shuttingDown)
|
|
216
|
+
if (!mpvAlive || shuttingDown) {
|
|
217
|
+
return
|
|
218
|
+
}
|
|
185
219
|
try {
|
|
186
|
-
MPVLib.setOptionString("force-window", "
|
|
220
|
+
MPVLib.setOptionString("force-window", "yes")
|
|
187
221
|
MPVLib.setOptionString("config", "yes")
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
222
|
+
|
|
223
|
+
mpvDirectory?.let { mpvDir ->
|
|
224
|
+
val fontsPath = "$mpvDir/fonts"
|
|
225
|
+
MPVLib.setOptionString("config-dir", mpvDir)
|
|
226
|
+
MPVLib.setOptionString("sub-fonts-dir", fontsPath)
|
|
227
|
+
MPVLib.setOptionString("sub-font", "Droid Sans Fallback")
|
|
191
228
|
}
|
|
192
229
|
|
|
193
230
|
MPVLib.setOptionString("keep-open", "always")
|
|
194
231
|
MPVLib.setOptionString("save-position-on-quit", "no")
|
|
195
232
|
MPVLib.setOptionString("ytdl", "no")
|
|
196
|
-
MPVLib.setOptionString("msg-level", "all=no")
|
|
197
233
|
|
|
198
234
|
session.videoOutput?.let { videoOutput ->
|
|
199
235
|
MPVLib.setOptionString("vo", videoOutput)
|
|
@@ -203,7 +239,7 @@ class LibmpvRenderer(
|
|
|
203
239
|
val acceleratedCodecs = session.acceleratedCodecs
|
|
204
240
|
if (!decodingMode.isNullOrBlank() && !acceleratedCodecs.isNullOrBlank()) {
|
|
205
241
|
MPVLib.setOptionString("hwdec", decodingMode)
|
|
206
|
-
if (decodingMode != "no"){
|
|
242
|
+
if (decodingMode != "no") {
|
|
207
243
|
MPVLib.setOptionString("hwdec-codecs", acceleratedCodecs)
|
|
208
244
|
}
|
|
209
245
|
}
|
|
@@ -212,48 +248,56 @@ class LibmpvRenderer(
|
|
|
212
248
|
MPVLib.setOptionString("opengl-es", "yes")
|
|
213
249
|
|
|
214
250
|
val videoSync = session.videoSync
|
|
215
|
-
if(!videoSync.isNullOrBlank()){
|
|
216
|
-
if(videoSync == "display-resample"){
|
|
251
|
+
if (!videoSync.isNullOrBlank()) {
|
|
252
|
+
if (videoSync == "display-resample") {
|
|
217
253
|
MPVLib.setOptionString("video-sync", "display-resample")
|
|
218
|
-
MPVLib.setOptionString("audio-pitch-correction","no")
|
|
254
|
+
MPVLib.setOptionString("audio-pitch-correction", "no")
|
|
219
255
|
MPVLib.setOptionString("autosync", "1")
|
|
220
|
-
MPVLib.setOptionString("correct-pts","no")
|
|
256
|
+
MPVLib.setOptionString("correct-pts", "no")
|
|
221
257
|
}
|
|
222
|
-
if(videoSync == "audio"){
|
|
258
|
+
if (videoSync == "audio") {
|
|
223
259
|
MPVLib.setOptionString("video-sync", "audio")
|
|
224
|
-
MPVLib.setOptionString("audio-pitch-correction","yes")
|
|
260
|
+
MPVLib.setOptionString("audio-pitch-correction", "yes")
|
|
225
261
|
MPVLib.setOptionString("autosync", "0")
|
|
226
|
-
MPVLib.setOptionString("correct-pts","yes")
|
|
262
|
+
MPVLib.setOptionString("correct-pts", "yes")
|
|
227
263
|
}
|
|
228
264
|
}
|
|
229
265
|
|
|
230
266
|
MPVLib.setOptionString("scale", "bilinear")
|
|
231
267
|
MPVLib.setOptionString("dscale", "bilinear")
|
|
232
|
-
MPVLib.setOptionString("tscale","off")
|
|
233
|
-
MPVLib.setOptionString("interpolation","no")
|
|
268
|
+
MPVLib.setOptionString("tscale", "off")
|
|
269
|
+
MPVLib.setOptionString("interpolation", "no")
|
|
234
270
|
|
|
235
|
-
MPVLib.setOptionString("ao", "audiotrack")
|
|
236
271
|
MPVLib.setOptionString("alang", "")
|
|
272
|
+
MPVLib.setOptionString("ao", "audiotrack")
|
|
237
273
|
|
|
238
|
-
MPVLib.setOptionString("sub-font-provider", "none")
|
|
239
274
|
MPVLib.setOptionString("slang", "")
|
|
240
275
|
MPVLib.setOptionString("sub-scale-with-window", "yes")
|
|
241
276
|
MPVLib.setOptionString("sub-use-margins", "no")
|
|
242
277
|
|
|
243
278
|
MPVLib.setOptionString("cache", "yes")
|
|
244
279
|
MPVLib.setOptionString("cache-pause-initial", "yes")
|
|
245
|
-
MPVLib.setOptionString("audio-buffer","2.0")
|
|
246
|
-
|
|
280
|
+
MPVLib.setOptionString("audio-buffer", "2.0")
|
|
247
281
|
} catch (e: Exception) {
|
|
248
282
|
logException(e)
|
|
249
283
|
}
|
|
250
284
|
}
|
|
251
285
|
|
|
252
286
|
private fun maybeStartPlayback() {
|
|
287
|
+
if (state != State.ACTIVE) {
|
|
288
|
+
return
|
|
289
|
+
}
|
|
290
|
+
if (!surfaceAttached) {
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
|
|
253
294
|
val url = session.playUrl ?: return
|
|
254
|
-
|
|
295
|
+
if (loadedUrl == url) {
|
|
296
|
+
return
|
|
297
|
+
}
|
|
298
|
+
|
|
255
299
|
try {
|
|
256
|
-
|
|
300
|
+
loadedUrl = url
|
|
257
301
|
MPVLib.command(arrayOf("loadfile", url, "replace"))
|
|
258
302
|
applyContinuousState()
|
|
259
303
|
} catch (e: Exception) {
|
|
@@ -262,8 +306,12 @@ class LibmpvRenderer(
|
|
|
262
306
|
}
|
|
263
307
|
|
|
264
308
|
private fun applyContinuousState() {
|
|
265
|
-
if (!mpvAlive || shuttingDown)
|
|
266
|
-
|
|
309
|
+
if (!mpvAlive || shuttingDown) {
|
|
310
|
+
return
|
|
311
|
+
}
|
|
312
|
+
if (!session.hasFileLoaded) {
|
|
313
|
+
return
|
|
314
|
+
}
|
|
267
315
|
|
|
268
316
|
MPVLib.command(
|
|
269
317
|
arrayOf("set", "pause", if (session.isPlaying) "no" else "yes")
|
|
@@ -271,7 +319,9 @@ class LibmpvRenderer(
|
|
|
271
319
|
}
|
|
272
320
|
|
|
273
321
|
private fun applyDeferredState() {
|
|
274
|
-
if (!mpvAlive || shuttingDown)
|
|
322
|
+
if (!mpvAlive || shuttingDown) {
|
|
323
|
+
return
|
|
324
|
+
}
|
|
275
325
|
|
|
276
326
|
session.seekToSeconds?.let { target ->
|
|
277
327
|
if (session.needsApply(LibmpvSession.MpvIntent.SEEK)) {
|
|
@@ -293,9 +343,13 @@ class LibmpvRenderer(
|
|
|
293
343
|
}
|
|
294
344
|
}
|
|
295
345
|
|
|
296
|
-
session.selectedSubtitleTrack?.let {
|
|
297
|
-
if (
|
|
298
|
-
|
|
346
|
+
session.selectedSubtitleTrack?.let { trackIndex ->
|
|
347
|
+
if (
|
|
348
|
+
session.needsApply(LibmpvSession.MpvIntent.SUBTITLE_TRACK) &&
|
|
349
|
+
session.hasFileLoaded &&
|
|
350
|
+
surfaceAttached
|
|
351
|
+
) {
|
|
352
|
+
val sid = if (trackIndex == -1) "no" else (trackIndex + 1).toString()
|
|
299
353
|
MPVLib.command(arrayOf("set", "sid", sid))
|
|
300
354
|
session.markApplied(LibmpvSession.MpvIntent.SUBTITLE_TRACK)
|
|
301
355
|
}
|
|
@@ -303,7 +357,9 @@ class LibmpvRenderer(
|
|
|
303
357
|
}
|
|
304
358
|
|
|
305
359
|
private fun stopPlayback() {
|
|
306
|
-
if (!mpvAlive)
|
|
360
|
+
if (!mpvAlive) {
|
|
361
|
+
return
|
|
362
|
+
}
|
|
307
363
|
try {
|
|
308
364
|
MPVLib.command(arrayOf("stop"))
|
|
309
365
|
MPVLib.setPropertyString("pause", "yes")
|
|
@@ -314,17 +370,13 @@ class LibmpvRenderer(
|
|
|
314
370
|
}
|
|
315
371
|
}
|
|
316
372
|
|
|
317
|
-
private fun detachSurfaceInternal() {
|
|
318
|
-
try {
|
|
319
|
-
MPVLib.detachSurface()
|
|
320
|
-
} catch (e: Exception) {
|
|
321
|
-
logException(e)
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
|
|
325
373
|
override fun logMessage(prefix: String, level: Int, text: String) {
|
|
326
|
-
if (shuttingDown)
|
|
327
|
-
|
|
374
|
+
if (shuttingDown) {
|
|
375
|
+
return
|
|
376
|
+
}
|
|
377
|
+
if (level <= LOG_LEVEL_WARN) {
|
|
378
|
+
Log.w(TAG, "[$prefix] $text")
|
|
379
|
+
}
|
|
328
380
|
onLog(mapOf("prefix" to prefix, "level" to level, "text" to text))
|
|
329
381
|
}
|
|
330
382
|
|
|
@@ -333,56 +385,110 @@ class LibmpvRenderer(
|
|
|
333
385
|
MPVLib.MpvEvent.MPV_EVENT_FILE_LOADED,
|
|
334
386
|
MPVLib.MpvEvent.MPV_EVENT_PLAYBACK_RESTART -> {
|
|
335
387
|
session.hasFileLoaded = true
|
|
336
|
-
|
|
337
|
-
applyDeferredState()
|
|
338
|
-
MPVLib.setPropertyString("pause", if (session.isPlaying) "no" else "yes")
|
|
339
|
-
}
|
|
388
|
+
applyDeferredState()
|
|
340
389
|
}
|
|
341
390
|
}
|
|
342
391
|
}
|
|
343
392
|
|
|
344
|
-
|
|
345
|
-
override fun eventProperty(property: String) =
|
|
393
|
+
override fun eventProperty(property: String) {
|
|
346
394
|
onEvent(mapOf("property" to property, "kind" to "none"))
|
|
395
|
+
}
|
|
347
396
|
|
|
348
|
-
override fun eventProperty(property: String, value: Long)
|
|
397
|
+
override fun eventProperty(property: String, value: Long) {
|
|
349
398
|
onEvent(mapOf("property" to property, "kind" to "long", "value" to value))
|
|
399
|
+
}
|
|
350
400
|
|
|
351
|
-
override fun eventProperty(property: String, value: Double)
|
|
401
|
+
override fun eventProperty(property: String, value: Double) {
|
|
352
402
|
onEvent(mapOf("property" to property, "kind" to "double", "value" to value))
|
|
403
|
+
}
|
|
353
404
|
|
|
354
|
-
override fun eventProperty(property: String, value: Boolean)
|
|
405
|
+
override fun eventProperty(property: String, value: Boolean) {
|
|
355
406
|
onEvent(mapOf("property" to property, "kind" to "boolean", "value" to value))
|
|
407
|
+
}
|
|
356
408
|
|
|
357
|
-
override fun eventProperty(property: String, value: String)
|
|
409
|
+
override fun eventProperty(property: String, value: String) {
|
|
358
410
|
onEvent(mapOf("property" to property, "kind" to "string", "value" to value))
|
|
411
|
+
}
|
|
359
412
|
|
|
360
413
|
private fun createMpvDirectory() {
|
|
361
|
-
if (shuttingDown)
|
|
414
|
+
if (shuttingDown) {
|
|
415
|
+
return
|
|
416
|
+
}
|
|
362
417
|
|
|
363
418
|
val ctx = surfaceView.context.applicationContext
|
|
364
|
-
val
|
|
419
|
+
val mpvRoot = File(ctx.getExternalFilesDir("mpv"), "mpv")
|
|
420
|
+
val fontsDir = File(mpvRoot, "fonts")
|
|
365
421
|
|
|
366
422
|
try {
|
|
367
|
-
|
|
368
|
-
|
|
423
|
+
logMessage(
|
|
424
|
+
"LimpbvRenderer->createMpvDirectory",
|
|
425
|
+
LOG_LEVEL_INFO,
|
|
426
|
+
"expo-libmpv version 0.5.4-0"
|
|
427
|
+
)
|
|
428
|
+
logMessage(
|
|
429
|
+
"LimpbvRenderer->createMpvDirectory",
|
|
430
|
+
LOG_LEVEL_INFO,
|
|
431
|
+
"Attempting to create the MPV dir"
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
if (!mpvRoot.exists() && !mpvRoot.mkdirs()) {
|
|
435
|
+
logMessage(
|
|
436
|
+
"LimpbvRenderer->createMpvDirectory",
|
|
437
|
+
LOG_LEVEL_INFO,
|
|
438
|
+
"Cannot make mpv directory"
|
|
439
|
+
)
|
|
440
|
+
return
|
|
441
|
+
}
|
|
369
442
|
|
|
370
|
-
|
|
443
|
+
if (!fontsDir.exists() && !fontsDir.mkdirs()) {
|
|
444
|
+
logMessage(
|
|
445
|
+
"LimpbvRenderer->createMpvDirectory",
|
|
446
|
+
LOG_LEVEL_INFO,
|
|
447
|
+
"Cannot make fonts directory"
|
|
448
|
+
)
|
|
449
|
+
return
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
mpvDirectory = mpvRoot.absolutePath
|
|
453
|
+
|
|
454
|
+
val subFont = File(fontsDir, "subfont.ttf")
|
|
371
455
|
if (!subFont.exists()) {
|
|
456
|
+
logMessage(
|
|
457
|
+
"LimpbvRenderer->createMpvDirectory",
|
|
458
|
+
LOG_LEVEL_INFO,
|
|
459
|
+
"Creating font files"
|
|
460
|
+
)
|
|
372
461
|
ctx.assets.open("subfont.ttf").use { inS ->
|
|
373
462
|
FileOutputStream(subFont).use { outS ->
|
|
374
463
|
inS.copyTo(outS)
|
|
375
464
|
}
|
|
376
465
|
}
|
|
466
|
+
} else {
|
|
467
|
+
logMessage(
|
|
468
|
+
"LimpbvRenderer->createMpvDirectory",
|
|
469
|
+
LOG_LEVEL_INFO,
|
|
470
|
+
"Font files already exist"
|
|
471
|
+
)
|
|
377
472
|
}
|
|
378
473
|
|
|
379
|
-
val mpvConf = File(
|
|
474
|
+
val mpvConf = File(mpvRoot, "mpv.conf")
|
|
380
475
|
if (!mpvConf.exists()) {
|
|
476
|
+
logMessage(
|
|
477
|
+
"LimpbvRenderer->createMpvDirectory",
|
|
478
|
+
LOG_LEVEL_INFO,
|
|
479
|
+
"Creating mpv conf"
|
|
480
|
+
)
|
|
381
481
|
ctx.assets.open("mpv.conf").use { inS ->
|
|
382
482
|
FileOutputStream(mpvConf).use { outS ->
|
|
383
483
|
inS.copyTo(outS)
|
|
384
484
|
}
|
|
385
485
|
}
|
|
486
|
+
} else {
|
|
487
|
+
logMessage(
|
|
488
|
+
"LimpbvRenderer->createMpvDirectory",
|
|
489
|
+
LOG_LEVEL_INFO,
|
|
490
|
+
"mpv conf already exists"
|
|
491
|
+
)
|
|
386
492
|
}
|
|
387
493
|
} catch (e: Exception) {
|
|
388
494
|
Log.e(TAG, "mpv directory init failed", e)
|
|
@@ -390,9 +496,15 @@ class LibmpvRenderer(
|
|
|
390
496
|
}
|
|
391
497
|
|
|
392
498
|
private fun logException(e: Exception) {
|
|
393
|
-
if (shuttingDown)
|
|
499
|
+
if (shuttingDown) {
|
|
500
|
+
return
|
|
501
|
+
}
|
|
394
502
|
try {
|
|
395
|
-
MPVLib.logMessage(
|
|
503
|
+
MPVLib.logMessage(
|
|
504
|
+
"LimpbvRenderer->logException",
|
|
505
|
+
LOG_LEVEL_INFO,
|
|
506
|
+
e.message ?: "Unknown mpv error"
|
|
507
|
+
)
|
|
396
508
|
} catch (_: Exception) {
|
|
397
509
|
Log.e(TAG, "mpv error", e)
|
|
398
510
|
}
|
|
@@ -48,23 +48,24 @@ class LibmpvView(
|
|
|
48
48
|
return attached && surfaceReady
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
}
|
|
51
|
+
private fun reconcileRenderer() {
|
|
52
|
+
if (renderer == null && attached) {
|
|
53
|
+
renderer = LibmpvRenderer(
|
|
54
|
+
session = session,
|
|
55
|
+
surfaceView = surfaceView,
|
|
56
|
+
onLog = { payload -> onLibmpvLog(payload) },
|
|
57
|
+
onEvent = { payload -> onLibmpvEvent(payload) }
|
|
58
|
+
)
|
|
59
|
+
renderer!!.start()
|
|
60
|
+
}
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
renderer?.let { r ->
|
|
63
|
+
if (surfaceReady) {
|
|
64
|
+
r.attachSurfaceIfNeeded()
|
|
66
65
|
}
|
|
67
66
|
}
|
|
67
|
+
}
|
|
68
|
+
|
|
68
69
|
|
|
69
70
|
fun onSessionUpdatedFromProps() {
|
|
70
71
|
reconcileRenderer()
|
|
@@ -85,11 +86,13 @@ class LibmpvView(
|
|
|
85
86
|
|
|
86
87
|
override fun surfaceCreated(holder: SurfaceHolder) {
|
|
87
88
|
surfaceReady = true
|
|
88
|
-
|
|
89
|
+
renderer?.surfaceReady = true
|
|
90
|
+
renderer?.attachSurfaceIfNeeded()
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
|
92
94
|
surfaceReady = false
|
|
95
|
+
renderer?.surfaceReady = false
|
|
93
96
|
reconcileRenderer()
|
|
94
97
|
}
|
|
95
98
|
|
|
@@ -1 +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,qBAAqB,EAAE,MAA0B,CAAA;AAE9D,eAAO,MAAM,0BAA0B,EAAE,MAAiD,CAAA;AAE1F,eAAO,MAAM,UAAU,
|
|
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,qBAAqB,EAAE,MAA0B,CAAA;AAE9D,eAAO,MAAM,0BAA0B,EAAE,MAAiD,CAAA;AAE1F,eAAO,MAAM,UAAU,8GA0DrB,CAAA;AAEF,eAAe,UAAU,CAAA"}
|
package/build/LibmpvView.js
CHANGED
|
@@ -66,14 +66,10 @@ export const LibmpvView = React.forwardRef((props, parentRef) => {
|
|
|
66
66
|
return props.onLibmpvLog(libmpvLog);
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
|
-
let seekProps = {};
|
|
70
|
-
if (typeof props?.seekToSeconds === 'number' && props?.seekToSeconds >= 0) {
|
|
71
|
-
seekProps.seekToSeconds = props.seekToSeconds;
|
|
72
|
-
}
|
|
73
69
|
// The order props are handled in the native code is non-deterministic
|
|
74
70
|
// Each native prop setter checks to see if all required props are set
|
|
75
71
|
// Only then will it try to create an instance of mpv
|
|
76
|
-
return <LibmpvViewNative ref={parentRef}
|
|
72
|
+
return <LibmpvViewNative ref={parentRef} style={props.surfaceStyle ? props.surfaceStyle : styles.videoPlayer} videoOutput={props.videoOutput} playUrl={props.playUrl} isPlaying={props.isPlaying} decodingMode={props.decodingMode} acceleratedCodecs={props.acceleratedCodecs} videoSync={props.videoSync} surfaceWidth={props.surfaceWidth} surfaceHeight={props.surfaceHeight} seekToSeconds={props.seekToSeconds} selectedAudioTrack={props.selectedAudioTrack} selectedSubtitleTrack={props.selectedSubtitleTrack} onLibmpvEvent={onLogEvent} onLibmpvLog={onLibmpvLog}/>;
|
|
77
73
|
});
|
|
78
74
|
export default LibmpvView;
|
|
79
75
|
//# sourceMappingURL=LibmpvView.js.map
|
package/build/LibmpvView.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LibmpvView.js","sourceRoot":"","sources":["../src/LibmpvView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AACzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,MAAM,GAAQ;IAClB,WAAW,EAAE;QACX,QAAQ,EAAE,UAAU;QACpB,IAAI,EAAE,CAAC;QACP,MAAM,EAAE,CAAC;QACT,KAAK,EAAE,CAAC;QACR,GAAG,EAAE,CAAC;KACP;CACF,CAAC;AAEF,MAAM,YAAY,GAAQ;IACxB,CAAC,EAAE,MAAM;IACT,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,aAAa;IAChB,CAAC,EAAE,oBAAoB;IACvB,CAAC,EAAE,oBAAoB;IACvB,CAAC,EAAE,eAAe;IAClB,CAAC,EAAE,YAAY;IACf,CAAC,EAAE,UAAU;IACb,CAAC,EAAE,aAAa;IAChB,EAAE,EAAE,gBAAgB;IACpB,EAAE,EAAE,gBAAgB;IACpB,EAAE,EAAE,gBAAgB;IACpB,EAAE,EAAE,MAAM;IACV,EAAE,EAAE,kBAAkB;IACtB,EAAE,EAAE,iBAAiB;IACrB,EAAE,EAAE,gBAAgB;IACpB,EAAE,EAAE,MAAM;CACX,CAAA;AAED,MAAM,gBAAgB,GAAyC,iBAAiB,CAAC,YAAY,CAAC,CAAC;AAE/F,MAAM,CAAC,MAAM,qBAAqB,GAAW,iBAAiB,CAAA;AAE9D,MAAM,CAAC,MAAM,0BAA0B,GAAW,wCAAwC,CAAA;AAE1F,MAAM,CAAC,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,CAA2C,CAAC,KAAU,EAAE,SAAc,EAAE,EAAE;IAClH,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,OAAO,GAAG,EAAE;YACV,IAAI,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;gBAChC,SAAS,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;YAC9B,CAAC;QACH,CAAC,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,iDAAiD;IACjD,MAAM,UAAU,GAAG,CAAC,WAAgB,EAAE,EAAE;QACtC,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;YACxB,IAAI,WAAW,IAAI,WAAW,CAAC,WAAW,EAAE,CAAC;gBAC3C,WAAW,GAAG,WAAW,CAAC,WAAW,CAAA;YACvC,CAAC;YACD,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;gBACxB,WAAW,CAAC,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;gBACrD,WAAW,CAAC,SAAS,GAAG,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAC3D,CAAC;iBACI,IAAI,WAAW,CAAC,IAAI,KAAK,MAAM,IAAI,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtE,WAAW,CAAC,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAA;YAC/C,CAAC;iBACI,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACxC,WAAW,CAAC,KAAK,GAAG,WAAW,CAAC,KAAK,KAAK,MAAM,CAAA;YAClD,CAAC;YACD,OAAO,KAAK,CAAC,aAAa,CAAC,WAAW,CAAC,CAAA;QACzC,CAAC;IACH,CAAC,CAAA;IACD,MAAM,WAAW,GAAG,CAAC,SAAc,EAAE,EAAE;QACrC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,IAAI,SAAS,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;gBACvC,SAAS,GAAG,SAAS,CAAC,WAAW,CAAA;YACnC,CAAC;YACD,OAAO,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAA;IAED,
|
|
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 DEFAULT_DECODING_MODE: string = \"mediacodec-copy\"\n\nexport const DEFAULT_ACCELERATED_CODECS: string = \"h264,hevc,mpeg4,mpeg2video,vp8,vp9,av1\"\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\n return <LibmpvViewNative\n ref={parentRef}\n style={props.surfaceStyle ? props.surfaceStyle : styles.videoPlayer}\n videoOutput={props.videoOutput}\n playUrl={props.playUrl}\n isPlaying={props.isPlaying}\n decodingMode={props.decodingMode}\n acceleratedCodecs={props.acceleratedCodecs}\n videoSync={props.videoSync}\n surfaceWidth={props.surfaceWidth}\n surfaceHeight={props.surfaceHeight}\n seekToSeconds={props.seekToSeconds}\n selectedAudioTrack={props.selectedAudioTrack}\n selectedSubtitleTrack={props.selectedSubtitleTrack}\n onLibmpvEvent={onLogEvent}\n onLibmpvLog={onLibmpvLog}\n />\n})\n\nexport default LibmpvView"]}
|
package/package.json
CHANGED
package/src/LibmpvView.tsx
CHANGED
|
@@ -75,18 +75,12 @@ export const LibmpvView = React.forwardRef<LibmpvViewNativeMethods, LibmpvViewPr
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
let seekProps: any = {}
|
|
79
|
-
if (typeof props?.seekToSeconds === 'number' && props?.seekToSeconds >= 0) {
|
|
80
|
-
seekProps.seekToSeconds = props.seekToSeconds
|
|
81
|
-
}
|
|
82
|
-
|
|
83
78
|
// The order props are handled in the native code is non-deterministic
|
|
84
79
|
// Each native prop setter checks to see if all required props are set
|
|
85
80
|
// Only then will it try to create an instance of mpv
|
|
86
81
|
|
|
87
82
|
return <LibmpvViewNative
|
|
88
83
|
ref={parentRef}
|
|
89
|
-
{...seekProps}
|
|
90
84
|
style={props.surfaceStyle ? props.surfaceStyle : styles.videoPlayer}
|
|
91
85
|
videoOutput={props.videoOutput}
|
|
92
86
|
playUrl={props.playUrl}
|
|
@@ -96,6 +90,7 @@ export const LibmpvView = React.forwardRef<LibmpvViewNativeMethods, LibmpvViewPr
|
|
|
96
90
|
videoSync={props.videoSync}
|
|
97
91
|
surfaceWidth={props.surfaceWidth}
|
|
98
92
|
surfaceHeight={props.surfaceHeight}
|
|
93
|
+
seekToSeconds={props.seekToSeconds}
|
|
99
94
|
selectedAudioTrack={props.selectedAudioTrack}
|
|
100
95
|
selectedSubtitleTrack={props.selectedSubtitleTrack}
|
|
101
96
|
onLibmpvEvent={onLogEvent}
|