expo-libvlc-player 3.4.13 → 3.4.14
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 +2 -2
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerModule.kt +26 -28
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerView.kt +179 -68
- package/android/src/main/java/expo/modules/libvlcplayer/constants/MediaPlayerConstants.kt +9 -0
- package/android/src/main/java/expo/modules/libvlcplayer/{AudioFocusManager.kt → managers/AudioFocusManager.kt} +14 -13
- package/android/src/main/java/expo/modules/libvlcplayer/{KeepAwakeManager.kt → managers/KeepAwakeManager.kt} +1 -1
- package/android/src/main/java/expo/modules/libvlcplayer/{MediaPlayerManager.kt → managers/MediaPlayerManager.kt} +2 -1
- package/ios/Constants/MediaPlayerConstants.swift +7 -0
- package/ios/LibVlcPlayerModule.swift +27 -31
- package/ios/LibVlcPlayerView.swift +179 -73
- package/ios/{AudioSessionManager.swift → Managers/AudioSessionManager.swift} +6 -4
- package/ios/{KeepAwakeManager.swift → Managers/KeepAwakeManager.swift} +3 -1
- package/ios/{LocalNetworkManager.swift → Managers/LocalNetworkManager.swift} +1 -1
- package/ios/{MediaPlayerManager.swift → Managers/MediaPlayerManager.swift} +4 -0
- package/package.json +1 -1
- package/android/src/main/java/expo/modules/libvlcplayer/DialogCallbacks.kt +0 -56
- package/android/src/main/java/expo/modules/libvlcplayer/MediaPlayerListener.kt +0 -111
- package/ios/DialogProtocol.swift +0 -75
- package/ios/MediaPlayerDelegate.swift +0 -102
package/android/build.gradle
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
apply plugin: 'com.android.library'
|
|
2
2
|
|
|
3
3
|
group = 'expo.modules.libvlcplayer'
|
|
4
|
-
version = '3.4.
|
|
4
|
+
version = '3.4.14'
|
|
5
5
|
|
|
6
6
|
def expoModulesCorePlugin = new File(project(':expo-modules-core').projectDir.absolutePath, 'ExpoModulesCorePlugin.gradle')
|
|
7
7
|
apply from: expoModulesCorePlugin
|
|
@@ -25,7 +25,7 @@ android {
|
|
|
25
25
|
targetSdkVersion safeExtGet('targetSdkVersion', 35)
|
|
26
26
|
|
|
27
27
|
versionCode 1
|
|
28
|
-
versionName '3.4.
|
|
28
|
+
versionName '3.4.14'
|
|
29
29
|
|
|
30
30
|
consumerProguardFiles('proguard-rules.pro')
|
|
31
31
|
}
|
|
@@ -5,8 +5,10 @@ import android.os.PowerManager
|
|
|
5
5
|
import expo.modules.kotlin.exception.Exceptions
|
|
6
6
|
import expo.modules.kotlin.modules.Module
|
|
7
7
|
import expo.modules.kotlin.modules.ModuleDefinition
|
|
8
|
+
import expo.modules.libvlcplayer.constants.MediaPlayerConstants
|
|
8
9
|
import expo.modules.libvlcplayer.enums.AudioMixingMode
|
|
9
10
|
import expo.modules.libvlcplayer.enums.VideoContentFit
|
|
11
|
+
import expo.modules.libvlcplayer.managers.MediaPlayerManager
|
|
10
12
|
import expo.modules.libvlcplayer.records.Slave
|
|
11
13
|
import expo.modules.libvlcplayer.records.Tracks
|
|
12
14
|
|
|
@@ -83,60 +85,56 @@ class LibVlcPlayerModule : Module() {
|
|
|
83
85
|
view.source = source
|
|
84
86
|
}
|
|
85
87
|
|
|
86
|
-
Prop("options") { view: LibVlcPlayerView, options: ArrayList<String
|
|
87
|
-
view.options = options
|
|
88
|
+
Prop("options", ArrayList<String>()) { view: LibVlcPlayerView, options: ArrayList<String> ->
|
|
89
|
+
view.options = options
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
Prop("tracks") { view: LibVlcPlayerView, tracks: Tracks? ->
|
|
91
93
|
view.tracks = tracks
|
|
92
94
|
}
|
|
93
95
|
|
|
94
|
-
Prop("slaves") { view: LibVlcPlayerView, slaves: ArrayList<Slave
|
|
95
|
-
view.slaves = slaves
|
|
96
|
+
Prop("slaves", ArrayList<Slave>()) { view: LibVlcPlayerView, slaves: ArrayList<Slave> ->
|
|
97
|
+
view.slaves = slaves
|
|
96
98
|
}
|
|
97
99
|
|
|
98
|
-
Prop("scale") { view: LibVlcPlayerView, scale: Float
|
|
99
|
-
view.scale = scale
|
|
100
|
+
Prop("scale", MediaPlayerConstants.DEFAULT_PLAYER_SCALE) { view: LibVlcPlayerView, scale: Float ->
|
|
101
|
+
view.scale = scale
|
|
100
102
|
}
|
|
101
103
|
|
|
102
|
-
Prop("contentFit") { view: LibVlcPlayerView, contentFit: VideoContentFit
|
|
103
|
-
view.contentFit = contentFit
|
|
104
|
+
Prop("contentFit", VideoContentFit.CONTAIN) { view: LibVlcPlayerView, contentFit: VideoContentFit ->
|
|
105
|
+
view.contentFit = contentFit
|
|
104
106
|
}
|
|
105
107
|
|
|
106
|
-
Prop("rate") { view: LibVlcPlayerView, rate: Float
|
|
107
|
-
view.rate = rate
|
|
108
|
+
Prop("rate", MediaPlayerConstants.DEFAULT_PLAYER_RATE) { view: LibVlcPlayerView, rate: Float ->
|
|
109
|
+
view.rate = rate
|
|
108
110
|
}
|
|
109
111
|
|
|
110
|
-
Prop("time") { view: LibVlcPlayerView, time: Int
|
|
111
|
-
view.time = time
|
|
112
|
+
Prop("time", MediaPlayerConstants.DEFAULT_PLAYER_TIME) { view: LibVlcPlayerView, time: Int ->
|
|
113
|
+
view.time = time
|
|
112
114
|
}
|
|
113
115
|
|
|
114
|
-
Prop("volume") { view: LibVlcPlayerView, volume: Int
|
|
115
|
-
view.volume = volume
|
|
116
|
+
Prop("volume", MediaPlayerConstants.MAX_PLAYER_VOLUME) { view: LibVlcPlayerView, volume: Int ->
|
|
117
|
+
view.volume = volume
|
|
116
118
|
}
|
|
117
119
|
|
|
118
|
-
Prop("mute") { view: LibVlcPlayerView, mute: Boolean
|
|
119
|
-
view.mute = mute
|
|
120
|
+
Prop("mute", false) { view: LibVlcPlayerView, mute: Boolean ->
|
|
121
|
+
view.mute = mute
|
|
120
122
|
}
|
|
121
123
|
|
|
122
|
-
Prop("audioMixingMode") { view: LibVlcPlayerView, audioMixingMode: AudioMixingMode
|
|
123
|
-
view.audioMixingMode = audioMixingMode
|
|
124
|
+
Prop("audioMixingMode", AudioMixingMode.AUTO) { view: LibVlcPlayerView, audioMixingMode: AudioMixingMode ->
|
|
125
|
+
view.audioMixingMode = audioMixingMode
|
|
124
126
|
}
|
|
125
127
|
|
|
126
|
-
Prop("playInBackground") { view: LibVlcPlayerView, playInBackground: Boolean
|
|
127
|
-
view.playInBackground = playInBackground
|
|
128
|
+
Prop("playInBackground", false) { view: LibVlcPlayerView, playInBackground: Boolean ->
|
|
129
|
+
view.playInBackground = playInBackground
|
|
128
130
|
}
|
|
129
131
|
|
|
130
|
-
Prop("repeat") { view: LibVlcPlayerView, repeat: Boolean
|
|
131
|
-
view.repeat = repeat
|
|
132
|
+
Prop("repeat", false) { view: LibVlcPlayerView, repeat: Boolean ->
|
|
133
|
+
view.repeat = repeat
|
|
132
134
|
}
|
|
133
135
|
|
|
134
|
-
Prop("autoplay") { view: LibVlcPlayerView, autoplay: Boolean
|
|
135
|
-
view.autoplay = autoplay
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
OnViewDidUpdateProps { view: LibVlcPlayerView ->
|
|
139
|
-
view.createPlayer()
|
|
136
|
+
Prop("autoplay", true) { view: LibVlcPlayerView, autoplay: Boolean ->
|
|
137
|
+
view.autoplay = autoplay
|
|
140
138
|
}
|
|
141
139
|
|
|
142
140
|
OnViewDestroys { view: LibVlcPlayerView ->
|
|
@@ -12,8 +12,10 @@ import android.view.TextureView
|
|
|
12
12
|
import expo.modules.kotlin.AppContext
|
|
13
13
|
import expo.modules.kotlin.viewevent.EventDispatcher
|
|
14
14
|
import expo.modules.kotlin.views.ExpoView
|
|
15
|
+
import expo.modules.libvlcplayer.constants.MediaPlayerConstants
|
|
15
16
|
import expo.modules.libvlcplayer.enums.AudioMixingMode
|
|
16
17
|
import expo.modules.libvlcplayer.enums.VideoContentFit
|
|
18
|
+
import expo.modules.libvlcplayer.managers.MediaPlayerManager
|
|
17
19
|
import expo.modules.libvlcplayer.records.Dialog
|
|
18
20
|
import expo.modules.libvlcplayer.records.MediaInfo
|
|
19
21
|
import expo.modules.libvlcplayer.records.MediaTracks
|
|
@@ -24,6 +26,8 @@ import expo.modules.libvlcplayer.records.Tracks
|
|
|
24
26
|
import org.videolan.libvlc.LibVLC
|
|
25
27
|
import org.videolan.libvlc.Media
|
|
26
28
|
import org.videolan.libvlc.MediaPlayer
|
|
29
|
+
import org.videolan.libvlc.MediaPlayer.Event
|
|
30
|
+
import org.videolan.libvlc.MediaPlayer.EventListener
|
|
27
31
|
import org.videolan.libvlc.interfaces.IMedia
|
|
28
32
|
import org.videolan.libvlc.util.DisplayManager
|
|
29
33
|
import org.videolan.libvlc.util.VLCVideoLayout
|
|
@@ -34,14 +38,6 @@ import java.text.SimpleDateFormat
|
|
|
34
38
|
import java.util.Calendar
|
|
35
39
|
import org.videolan.libvlc.Dialog as VLCDialog
|
|
36
40
|
|
|
37
|
-
const val DEFAULT_PLAYER_RATE: Float = 1f
|
|
38
|
-
const val DEFAULT_PLAYER_TIME: Int = 0
|
|
39
|
-
const val DEFAULT_PLAYER_SCALE: Float = 0f
|
|
40
|
-
|
|
41
|
-
const val MIN_PLAYER_VOLUME: Int = 0
|
|
42
|
-
const val MAX_PLAYER_VOLUME: Int = 100
|
|
43
|
-
const val PLAYER_VOLUME_STEP: Int = 10
|
|
44
|
-
|
|
45
41
|
private val DISPLAY_MANAGER: DisplayManager? = null
|
|
46
42
|
private val ENABLE_SUBTITLES: Boolean = true
|
|
47
43
|
private val USE_TEXTURE_VIEW: Boolean = true
|
|
@@ -62,7 +58,6 @@ class LibVlcPlayerView(
|
|
|
62
58
|
|
|
63
59
|
var mediaLength: Long? = null
|
|
64
60
|
|
|
65
|
-
private var shouldCreate: Boolean = false
|
|
66
61
|
var firstPlay: Boolean = false
|
|
67
62
|
var firstTime: Boolean = false
|
|
68
63
|
|
|
@@ -112,17 +107,14 @@ class LibVlcPlayerView(
|
|
|
112
107
|
fun getTextureView(): TextureView? = playerView.findViewById(org.videolan.R.id.texture_video)
|
|
113
108
|
|
|
114
109
|
fun createPlayer() {
|
|
115
|
-
if (!shouldCreate) {
|
|
116
|
-
return
|
|
117
|
-
}
|
|
118
|
-
|
|
119
110
|
destroyPlayer()
|
|
120
111
|
|
|
121
112
|
val source = source ?: return
|
|
122
113
|
|
|
123
|
-
options
|
|
114
|
+
var initOptions = options
|
|
115
|
+
initOptions.toggleStartPausedOption(autoplay)
|
|
124
116
|
|
|
125
|
-
libVLC = LibVLC(context,
|
|
117
|
+
libVLC = LibVLC(context, initOptions)
|
|
126
118
|
setDialogCallbacks()
|
|
127
119
|
mediaPlayer = MediaPlayer(libVLC)
|
|
128
120
|
setMediaPlayerListener()
|
|
@@ -140,7 +132,6 @@ class LibVlcPlayerView(
|
|
|
140
132
|
addPlayerSlaves()
|
|
141
133
|
mediaPlayer!!.play()
|
|
142
134
|
|
|
143
|
-
shouldCreate = false
|
|
144
135
|
firstPlay = true
|
|
145
136
|
firstTime = true
|
|
146
137
|
}
|
|
@@ -176,6 +167,164 @@ class LibVlcPlayerView(
|
|
|
176
167
|
removeAllViews()
|
|
177
168
|
}
|
|
178
169
|
|
|
170
|
+
fun setMediaPlayerListener() {
|
|
171
|
+
mediaPlayer?.let { player ->
|
|
172
|
+
player.setEventListener(
|
|
173
|
+
EventListener { event ->
|
|
174
|
+
when (event.type) {
|
|
175
|
+
Event.Buffering -> {
|
|
176
|
+
onBuffering(Unit)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
Event.Playing -> {
|
|
180
|
+
onPlaying(Unit)
|
|
181
|
+
|
|
182
|
+
if (firstPlay) {
|
|
183
|
+
attachPlayer()
|
|
184
|
+
|
|
185
|
+
setupPlayer()
|
|
186
|
+
|
|
187
|
+
onFirstPlay(getMediaInfo())
|
|
188
|
+
|
|
189
|
+
firstPlay = false
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
MediaPlayerManager.keepAwakeManager.activateKeepAwake()
|
|
193
|
+
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
Event.Paused -> {
|
|
197
|
+
onPaused(Unit)
|
|
198
|
+
|
|
199
|
+
MediaPlayerManager.keepAwakeManager.deactivateKeepAwake()
|
|
200
|
+
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
Event.Stopped -> {
|
|
204
|
+
onStopped(Unit)
|
|
205
|
+
|
|
206
|
+
detachPlayer()
|
|
207
|
+
|
|
208
|
+
MediaPlayerManager.keepAwakeManager.deactivateKeepAwake()
|
|
209
|
+
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
210
|
+
|
|
211
|
+
firstPlay = true
|
|
212
|
+
firstTime = true
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
Event.EndReached -> {
|
|
216
|
+
onEndReached(Unit)
|
|
217
|
+
|
|
218
|
+
player.stop()
|
|
219
|
+
|
|
220
|
+
if (repeat) {
|
|
221
|
+
player.play()
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
Event.EncounteredError -> {
|
|
226
|
+
onEncounteredError(mapOf("error" to "Media player encountered an error"))
|
|
227
|
+
|
|
228
|
+
MediaPlayerManager.keepAwakeManager.deactivateKeepAwake()
|
|
229
|
+
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
230
|
+
|
|
231
|
+
firstPlay = true
|
|
232
|
+
firstTime = true
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
Event.TimeChanged -> {
|
|
236
|
+
onTimeChanged(mapOf("time" to player.getTime().toInt()))
|
|
237
|
+
|
|
238
|
+
if (firstTime) {
|
|
239
|
+
if (mediaLength == null) {
|
|
240
|
+
onFirstPlay(getMediaInfo())
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
setContentFit()
|
|
244
|
+
|
|
245
|
+
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
246
|
+
|
|
247
|
+
firstTime = false
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
Event.PositionChanged -> {
|
|
252
|
+
onPositionChanged(mapOf("position" to player.getPosition()))
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
Event.ESAdded -> {
|
|
256
|
+
onESAdded(getMediaTracks())
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
Event.RecordChanged -> {
|
|
260
|
+
val recording =
|
|
261
|
+
Recording(
|
|
262
|
+
path = event.getRecordPath(),
|
|
263
|
+
isRecording = event.getRecording(),
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
onRecordChanged(recording)
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
)
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
fun setDialogCallbacks() {
|
|
275
|
+
libVLC?.let {
|
|
276
|
+
VLCDialog.setCallbacks(
|
|
277
|
+
it,
|
|
278
|
+
object : VLCDialog.Callbacks {
|
|
279
|
+
override fun onDisplay(dialog: VLCDialog.ErrorMessage) {
|
|
280
|
+
vlcDialog = dialog
|
|
281
|
+
|
|
282
|
+
val dialog =
|
|
283
|
+
Dialog(
|
|
284
|
+
title = dialog.getTitle(),
|
|
285
|
+
text = dialog.getText(),
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
onDialogDisplay(dialog)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
override fun onDisplay(dialog: VLCDialog.LoginDialog) {
|
|
292
|
+
vlcDialog = dialog
|
|
293
|
+
|
|
294
|
+
val dialog =
|
|
295
|
+
Dialog(
|
|
296
|
+
title = dialog.getTitle(),
|
|
297
|
+
text = dialog.getText(),
|
|
298
|
+
)
|
|
299
|
+
|
|
300
|
+
onDialogDisplay(dialog)
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
override fun onDisplay(dialog: VLCDialog.QuestionDialog) {
|
|
304
|
+
vlcDialog = dialog
|
|
305
|
+
|
|
306
|
+
val dialog =
|
|
307
|
+
Dialog(
|
|
308
|
+
title = dialog.getTitle(),
|
|
309
|
+
text = dialog.getText(),
|
|
310
|
+
cancelText = dialog.getCancelText(),
|
|
311
|
+
action1Text = dialog.getAction1Text(),
|
|
312
|
+
action2Text = dialog.getAction2Text(),
|
|
313
|
+
)
|
|
314
|
+
|
|
315
|
+
onDialogDisplay(dialog)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
override fun onDisplay(dialog: VLCDialog.ProgressDialog) {}
|
|
319
|
+
|
|
320
|
+
override fun onCanceled(dialog: VLCDialog) {}
|
|
321
|
+
|
|
322
|
+
override fun onProgressUpdate(dialog: VLCDialog.ProgressDialog) {}
|
|
323
|
+
},
|
|
324
|
+
)
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
179
328
|
fun setPlayerTracks() {
|
|
180
329
|
mediaPlayer?.let { player ->
|
|
181
330
|
val audioTrack = tracks?.audio ?: player.getAudioTrack()
|
|
@@ -347,22 +496,22 @@ class LibVlcPlayerView(
|
|
|
347
496
|
mediaPlayer?.let { player ->
|
|
348
497
|
setPlayerTracks()
|
|
349
498
|
|
|
350
|
-
if (scale != DEFAULT_PLAYER_SCALE) {
|
|
499
|
+
if (scale != MediaPlayerConstants.DEFAULT_PLAYER_SCALE) {
|
|
351
500
|
player.setScale(scale)
|
|
352
501
|
}
|
|
353
502
|
|
|
354
|
-
if (rate != DEFAULT_PLAYER_RATE) {
|
|
503
|
+
if (rate != MediaPlayerConstants.DEFAULT_PLAYER_RATE) {
|
|
355
504
|
player.setRate(rate)
|
|
356
505
|
}
|
|
357
506
|
|
|
358
|
-
if (time != DEFAULT_PLAYER_TIME) {
|
|
507
|
+
if (time != MediaPlayerConstants.DEFAULT_PLAYER_TIME) {
|
|
359
508
|
player.setTime(time.toLong())
|
|
360
509
|
}
|
|
361
510
|
|
|
362
|
-
if (volume != MAX_PLAYER_VOLUME || mute) {
|
|
511
|
+
if (volume != MediaPlayerConstants.MAX_PLAYER_VOLUME || mute) {
|
|
363
512
|
val newVolume =
|
|
364
513
|
if (mute) {
|
|
365
|
-
MIN_PLAYER_VOLUME
|
|
514
|
+
MediaPlayerConstants.MIN_PLAYER_VOLUME
|
|
366
515
|
} else {
|
|
367
516
|
volume
|
|
368
517
|
}
|
|
@@ -370,7 +519,7 @@ class LibVlcPlayerView(
|
|
|
370
519
|
player.setVolume(newVolume)
|
|
371
520
|
}
|
|
372
521
|
|
|
373
|
-
time = DEFAULT_PLAYER_TIME
|
|
522
|
+
time = MediaPlayerConstants.DEFAULT_PLAYER_TIME
|
|
374
523
|
}
|
|
375
524
|
}
|
|
376
525
|
|
|
@@ -378,14 +527,14 @@ class LibVlcPlayerView(
|
|
|
378
527
|
set(value) {
|
|
379
528
|
val old = field
|
|
380
529
|
field = value
|
|
381
|
-
|
|
530
|
+
createPlayer()
|
|
382
531
|
}
|
|
383
532
|
|
|
384
533
|
var options: ArrayList<String> = ArrayList()
|
|
385
534
|
set(value) {
|
|
386
535
|
val old = field
|
|
387
536
|
field = value
|
|
388
|
-
|
|
537
|
+
createPlayer()
|
|
389
538
|
}
|
|
390
539
|
|
|
391
540
|
var tracks: Tracks? = null
|
|
@@ -405,7 +554,7 @@ class LibVlcPlayerView(
|
|
|
405
554
|
}
|
|
406
555
|
}
|
|
407
556
|
|
|
408
|
-
var scale: Float = DEFAULT_PLAYER_SCALE
|
|
557
|
+
var scale: Float = MediaPlayerConstants.DEFAULT_PLAYER_SCALE
|
|
409
558
|
set(value) {
|
|
410
559
|
field = value
|
|
411
560
|
mediaPlayer?.setScale(value)
|
|
@@ -417,23 +566,19 @@ class LibVlcPlayerView(
|
|
|
417
566
|
setContentFit()
|
|
418
567
|
}
|
|
419
568
|
|
|
420
|
-
var rate: Float = DEFAULT_PLAYER_RATE
|
|
569
|
+
var rate: Float = MediaPlayerConstants.DEFAULT_PLAYER_RATE
|
|
421
570
|
set(value) {
|
|
422
571
|
field = value
|
|
423
572
|
mediaPlayer?.setRate(value)
|
|
424
573
|
}
|
|
425
574
|
|
|
426
|
-
var time: Int = DEFAULT_PLAYER_TIME
|
|
575
|
+
var time: Int = MediaPlayerConstants.DEFAULT_PLAYER_TIME
|
|
427
576
|
|
|
428
|
-
var volume: Int = MAX_PLAYER_VOLUME
|
|
577
|
+
var volume: Int = MediaPlayerConstants.MAX_PLAYER_VOLUME
|
|
429
578
|
set(value) {
|
|
430
579
|
field = value
|
|
431
580
|
|
|
432
|
-
|
|
433
|
-
onEncounteredError(mapOf("error" to "Audio disabled via options"))
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
val newVolume = value.coerceIn(MIN_PLAYER_VOLUME, MAX_PLAYER_VOLUME)
|
|
581
|
+
val newVolume = value.coerceIn(MediaPlayerConstants.MIN_PLAYER_VOLUME, MediaPlayerConstants.MAX_PLAYER_VOLUME)
|
|
437
582
|
MediaPlayerManager.audioFocusManager.oldVolume = newVolume
|
|
438
583
|
|
|
439
584
|
if (!mute) {
|
|
@@ -446,13 +591,9 @@ class LibVlcPlayerView(
|
|
|
446
591
|
set(value) {
|
|
447
592
|
field = value
|
|
448
593
|
|
|
449
|
-
if (options.hasAudioOption()) {
|
|
450
|
-
onEncounteredError(mapOf("error" to "Audio disabled via options"))
|
|
451
|
-
}
|
|
452
|
-
|
|
453
594
|
val newVolume =
|
|
454
595
|
if (value) {
|
|
455
|
-
MIN_PLAYER_VOLUME
|
|
596
|
+
MediaPlayerConstants.MIN_PLAYER_VOLUME
|
|
456
597
|
} else {
|
|
457
598
|
MediaPlayerManager.audioFocusManager.oldVolume
|
|
458
599
|
}
|
|
@@ -476,10 +617,6 @@ class LibVlcPlayerView(
|
|
|
476
617
|
var repeat: Boolean = false
|
|
477
618
|
set(value) {
|
|
478
619
|
field = value
|
|
479
|
-
|
|
480
|
-
if (options.hasRepeatOption()) {
|
|
481
|
-
onEncounteredError(mapOf("error" to "Repeat enabled via options"))
|
|
482
|
-
}
|
|
483
620
|
}
|
|
484
621
|
|
|
485
622
|
var autoplay: Boolean = true
|
|
@@ -601,32 +738,6 @@ class LibVlcPlayerView(
|
|
|
601
738
|
}
|
|
602
739
|
}
|
|
603
740
|
|
|
604
|
-
private fun ArrayList<String>.hasAudioOption(): Boolean {
|
|
605
|
-
val options =
|
|
606
|
-
setOf(
|
|
607
|
-
"--no-audio",
|
|
608
|
-
"-no-audio",
|
|
609
|
-
":no-audio",
|
|
610
|
-
)
|
|
611
|
-
|
|
612
|
-
return this.any { option -> option in options }
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
fun ArrayList<String>.hasRepeatOption(): Boolean {
|
|
616
|
-
val options =
|
|
617
|
-
setOf(
|
|
618
|
-
"--input-repeat=",
|
|
619
|
-
"-input-repeat=",
|
|
620
|
-
":input-repeat=",
|
|
621
|
-
)
|
|
622
|
-
|
|
623
|
-
return this.any { option ->
|
|
624
|
-
options.any { value ->
|
|
625
|
-
option.startsWith(value)
|
|
626
|
-
}
|
|
627
|
-
}
|
|
628
|
-
}
|
|
629
|
-
|
|
630
741
|
private fun ArrayList<String>.hasStartPausedOption(): Boolean {
|
|
631
742
|
val options =
|
|
632
743
|
setOf(
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
package expo.modules.libvlcplayer.constants
|
|
2
|
+
|
|
3
|
+
object MediaPlayerConstants {
|
|
4
|
+
const val DEFAULT_PLAYER_SCALE: Float = 0f
|
|
5
|
+
const val DEFAULT_PLAYER_RATE: Float = 1f
|
|
6
|
+
const val DEFAULT_PLAYER_TIME: Int = 0
|
|
7
|
+
const val MIN_PLAYER_VOLUME: Int = 0
|
|
8
|
+
const val MAX_PLAYER_VOLUME: Int = 100
|
|
9
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
package expo.modules.libvlcplayer
|
|
1
|
+
package expo.modules.libvlcplayer.managers
|
|
2
2
|
|
|
3
3
|
import android.content.Context
|
|
4
4
|
import android.media.AudioAttributes
|
|
@@ -7,6 +7,7 @@ import android.media.AudioManager
|
|
|
7
7
|
import android.os.Build
|
|
8
8
|
import expo.modules.kotlin.AppContext
|
|
9
9
|
import expo.modules.kotlin.exception.Exceptions
|
|
10
|
+
import expo.modules.libvlcplayer.constants.MediaPlayerConstants
|
|
10
11
|
import expo.modules.libvlcplayer.enums.AudioMixingMode
|
|
11
12
|
import kotlinx.coroutines.launch
|
|
12
13
|
import org.videolan.libvlc.MediaPlayer
|
|
@@ -23,23 +24,21 @@ class AudioFocusManager(
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
private val playerViews = MediaPlayerManager.playerViews
|
|
27
|
-
|
|
28
27
|
private var currentFocusRequest: AudioFocusRequest? = null
|
|
29
28
|
|
|
30
29
|
private val anyPlayerRequiresFocus: Boolean
|
|
31
30
|
get() =
|
|
32
|
-
playerViews.toList().any { view ->
|
|
31
|
+
MediaPlayerManager.playerViews.toList().any { view ->
|
|
33
32
|
playerRequiresFocus(view.get()?.mediaPlayer)
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
var currentMixingMode: AudioMixingMode = AudioMixingMode.AUTO
|
|
37
36
|
|
|
38
|
-
var oldVolume: Int = MAX_PLAYER_VOLUME
|
|
37
|
+
var oldVolume: Int = MediaPlayerConstants.MAX_PLAYER_VOLUME
|
|
39
38
|
|
|
40
39
|
private fun playerRequiresFocus(player: MediaPlayer?): Boolean {
|
|
41
40
|
if (player != null) {
|
|
42
|
-
return player.isPlaying() && player.getVolume() > MIN_PLAYER_VOLUME
|
|
41
|
+
return player.isPlaying() && player.getVolume() > MediaPlayerConstants.MIN_PLAYER_VOLUME
|
|
43
42
|
} else {
|
|
44
43
|
return false
|
|
45
44
|
}
|
|
@@ -47,7 +46,7 @@ class AudioFocusManager(
|
|
|
47
46
|
|
|
48
47
|
private fun findAudioMixingMode(): AudioMixingMode {
|
|
49
48
|
val mixingModes =
|
|
50
|
-
playerViews.toList().mapNotNull { playerView ->
|
|
49
|
+
MediaPlayerManager.playerViews.toList().mapNotNull { playerView ->
|
|
51
50
|
playerView
|
|
52
51
|
.get()
|
|
53
52
|
?.takeIf { view ->
|
|
@@ -103,6 +102,7 @@ class AudioFocusManager(
|
|
|
103
102
|
currentFocusRequest = newFocusRequest
|
|
104
103
|
audioManager.requestAudioFocus(newFocusRequest)
|
|
105
104
|
} else {
|
|
105
|
+
@Suppress("DEPRECATION")
|
|
106
106
|
audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC, audioFocusType)
|
|
107
107
|
}
|
|
108
108
|
|
|
@@ -114,6 +114,7 @@ class AudioFocusManager(
|
|
|
114
114
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
115
115
|
audioManager.abandonAudioFocusRequest(it)
|
|
116
116
|
} else {
|
|
117
|
+
@Suppress("DEPRECATION")
|
|
117
118
|
audioManager.abandonAudioFocus(this)
|
|
118
119
|
}
|
|
119
120
|
}
|
|
@@ -131,7 +132,7 @@ class AudioFocusManager(
|
|
|
131
132
|
|
|
132
133
|
private fun pausePlayerIfUnmuted(player: MediaPlayer?) {
|
|
133
134
|
player?.let { mediaPlayer ->
|
|
134
|
-
if (mediaPlayer.getVolume() > MIN_PLAYER_VOLUME) {
|
|
135
|
+
if (mediaPlayer.getVolume() > MediaPlayerConstants.MIN_PLAYER_VOLUME) {
|
|
135
136
|
mediaPlayer.pause()
|
|
136
137
|
}
|
|
137
138
|
}
|
|
@@ -147,7 +148,7 @@ class AudioFocusManager(
|
|
|
147
148
|
|
|
148
149
|
private fun unduckPlayer(player: MediaPlayer?) {
|
|
149
150
|
player?.let { mediaPlayer ->
|
|
150
|
-
if (mediaPlayer.getVolume() > MIN_PLAYER_VOLUME) {
|
|
151
|
+
if (mediaPlayer.getVolume() > MediaPlayerConstants.MIN_PLAYER_VOLUME) {
|
|
151
152
|
mediaPlayer.setVolume(oldVolume)
|
|
152
153
|
}
|
|
153
154
|
}
|
|
@@ -157,7 +158,7 @@ class AudioFocusManager(
|
|
|
157
158
|
when (focusChange) {
|
|
158
159
|
AudioManager.AUDIOFOCUS_LOSS -> {
|
|
159
160
|
appContext.mainQueue.launch {
|
|
160
|
-
playerViews.forEach { view ->
|
|
161
|
+
MediaPlayerManager.playerViews.forEach { view ->
|
|
161
162
|
pausePlayerIfUnmuted(view.get()?.mediaPlayer)
|
|
162
163
|
}
|
|
163
164
|
|
|
@@ -173,7 +174,7 @@ class AudioFocusManager(
|
|
|
173
174
|
}
|
|
174
175
|
|
|
175
176
|
appContext.mainQueue.launch {
|
|
176
|
-
playerViews.forEach { view ->
|
|
177
|
+
MediaPlayerManager.playerViews.forEach { view ->
|
|
177
178
|
pausePlayerIfUnmuted(view.get()?.mediaPlayer)
|
|
178
179
|
}
|
|
179
180
|
|
|
@@ -185,7 +186,7 @@ class AudioFocusManager(
|
|
|
185
186
|
val audioMixingMode = findAudioMixingMode()
|
|
186
187
|
|
|
187
188
|
appContext.mainQueue.launch {
|
|
188
|
-
playerViews.forEach { view ->
|
|
189
|
+
MediaPlayerManager.playerViews.forEach { view ->
|
|
189
190
|
view.get()?.mediaPlayer?.let { player ->
|
|
190
191
|
if (audioMixingMode == AudioMixingMode.DO_NOT_MIX) {
|
|
191
192
|
pausePlayerIfUnmuted(player)
|
|
@@ -199,7 +200,7 @@ class AudioFocusManager(
|
|
|
199
200
|
|
|
200
201
|
AudioManager.AUDIOFOCUS_GAIN -> {
|
|
201
202
|
appContext.mainQueue.launch {
|
|
202
|
-
playerViews.forEach { view ->
|
|
203
|
+
MediaPlayerManager.playerViews.forEach { view ->
|
|
203
204
|
unduckPlayer(view.get()?.mediaPlayer)
|
|
204
205
|
}
|
|
205
206
|
}
|