expo-libvlc-player 0.1.39 → 0.1.40
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/AudioFocusManager.kt +12 -14
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerModule.kt +6 -6
- package/android/src/main/java/expo/modules/libvlcplayer/LibVlcPlayerView.kt +62 -44
- package/android/src/main/java/expo/modules/libvlcplayer/MediaPlayerManager.kt +2 -2
- package/ios/LibVlcPlayerModule.swift +13 -13
- package/ios/LibVlcPlayerView.swift +92 -78
- package/package.json +1 -1
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 = '0.1.
|
|
4
|
+
version = '0.1.39'
|
|
5
5
|
|
|
6
6
|
def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
|
|
7
7
|
apply from: expoModulesCorePlugin
|
|
@@ -27,7 +27,7 @@ android {
|
|
|
27
27
|
namespace "expo.modules.libvlcplayer"
|
|
28
28
|
defaultConfig {
|
|
29
29
|
versionCode 1
|
|
30
|
-
versionName "0.1.
|
|
30
|
+
versionName "0.1.39"
|
|
31
31
|
consumerProguardFiles("proguard-rules.pro")
|
|
32
32
|
}
|
|
33
33
|
lintOptions {
|
|
@@ -10,11 +10,9 @@ import expo.modules.kotlin.exception.CodedException
|
|
|
10
10
|
import expo.modules.libvlcplayer.enums.AudioMixingMode
|
|
11
11
|
import kotlinx.coroutines.launch
|
|
12
12
|
import org.videolan.libvlc.MediaPlayer
|
|
13
|
-
import java.lang.ref.WeakReference
|
|
14
13
|
|
|
15
14
|
class AudioFocusManager(
|
|
16
15
|
private val appContext: AppContext,
|
|
17
|
-
private var playerViews: MutableList<WeakReference<LibVlcPlayerView>>,
|
|
18
16
|
) : AudioManager.OnAudioFocusChangeListener {
|
|
19
17
|
private val audioManager by lazy {
|
|
20
18
|
appContext.reactContext?.getSystemService(Context.AUDIO_SERVICE) as? AudioManager ?: run {
|
|
@@ -25,8 +23,8 @@ class AudioFocusManager(
|
|
|
25
23
|
private var currentFocusRequest: AudioFocusRequest? = null
|
|
26
24
|
private val anyPlayerRequiresFocus: Boolean
|
|
27
25
|
get() =
|
|
28
|
-
playerViews.toList().any {
|
|
29
|
-
|
|
26
|
+
MediaPlayerManager.playerViews.toList().any { playerView ->
|
|
27
|
+
playerView.get()?.let { view ->
|
|
30
28
|
playerRequiresFocus(view.mediaPlayer)
|
|
31
29
|
} ?: false
|
|
32
30
|
}
|
|
@@ -38,7 +36,7 @@ class AudioFocusManager(
|
|
|
38
36
|
|
|
39
37
|
private fun findAudioMixingMode(): AudioMixingMode {
|
|
40
38
|
val mixingModes =
|
|
41
|
-
playerViews.toList().mapNotNull { view ->
|
|
39
|
+
MediaPlayerManager.playerViews.toList().mapNotNull { view ->
|
|
42
40
|
view.get()?.takeIf { it.mediaPlayer?.isPlaying() == true }?.audioMixingMode
|
|
43
41
|
}
|
|
44
42
|
|
|
@@ -118,7 +116,7 @@ class AudioFocusManager(
|
|
|
118
116
|
when (focusChange) {
|
|
119
117
|
AudioManager.AUDIOFOCUS_LOSS -> {
|
|
120
118
|
appContext.mainQueue.launch {
|
|
121
|
-
playerViews.forEach { view ->
|
|
119
|
+
MediaPlayerManager.playerViews.forEach { view ->
|
|
122
120
|
pausePlayerIfUnmuted(view.get()?.mediaPlayer)
|
|
123
121
|
}
|
|
124
122
|
|
|
@@ -134,7 +132,7 @@ class AudioFocusManager(
|
|
|
134
132
|
}
|
|
135
133
|
|
|
136
134
|
appContext.mainQueue.launch {
|
|
137
|
-
playerViews.forEach { view ->
|
|
135
|
+
MediaPlayerManager.playerViews.forEach { view ->
|
|
138
136
|
pausePlayerIfUnmuted(view.get()?.mediaPlayer)
|
|
139
137
|
}
|
|
140
138
|
|
|
@@ -146,8 +144,8 @@ class AudioFocusManager(
|
|
|
146
144
|
val audioMixingMode = findAudioMixingMode()
|
|
147
145
|
|
|
148
146
|
appContext.mainQueue.launch {
|
|
149
|
-
playerViews.forEach {
|
|
150
|
-
|
|
147
|
+
MediaPlayerManager.playerViews.forEach { playerView ->
|
|
148
|
+
playerView.get()?.let { view ->
|
|
151
149
|
view.mediaPlayer?.let { player ->
|
|
152
150
|
if (audioMixingMode == AudioMixingMode.DO_NOT_MIX) {
|
|
153
151
|
pausePlayerIfUnmuted(player)
|
|
@@ -164,8 +162,8 @@ class AudioFocusManager(
|
|
|
164
162
|
|
|
165
163
|
AudioManager.AUDIOFOCUS_GAIN -> {
|
|
166
164
|
appContext.mainQueue.launch {
|
|
167
|
-
playerViews.forEach {
|
|
168
|
-
|
|
165
|
+
MediaPlayerManager.playerViews.forEach { playerView ->
|
|
166
|
+
playerView.get()?.let { view ->
|
|
169
167
|
view.mediaPlayer?.let { player ->
|
|
170
168
|
if (player.getVolume() > MIN_PLAYER_VOLUME) {
|
|
171
169
|
player.setVolume(view.userVolume)
|
|
@@ -179,9 +177,9 @@ class AudioFocusManager(
|
|
|
179
177
|
}
|
|
180
178
|
|
|
181
179
|
private fun pausePlayerIfUnmuted(player: MediaPlayer?) {
|
|
182
|
-
player?.let {
|
|
183
|
-
if (
|
|
184
|
-
|
|
180
|
+
player?.let { mPlayer ->
|
|
181
|
+
if (mPlayer.getVolume() > MIN_PLAYER_VOLUME) {
|
|
182
|
+
mPlayer.pause()
|
|
185
183
|
}
|
|
186
184
|
}
|
|
187
185
|
}
|
|
@@ -61,15 +61,15 @@ class LibVlcPlayerModule : Module() {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
Prop("volume") { view: LibVlcPlayerView, volume: Int? ->
|
|
64
|
-
view.
|
|
64
|
+
view.volume = volume ?: MAX_PLAYER_VOLUME
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
Prop("mute") { view: LibVlcPlayerView, mute: Boolean? ->
|
|
68
|
-
view.
|
|
68
|
+
view.mute = mute ?: false
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
Prop("rate") { view: LibVlcPlayerView, rate: Float? ->
|
|
72
|
-
view.
|
|
72
|
+
view.rate = rate ?: DEFAULT_PLAYER_RATE
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
Prop("time") { view: LibVlcPlayerView, time: Int? ->
|
|
@@ -77,11 +77,11 @@ class LibVlcPlayerModule : Module() {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
Prop("repeat") { view: LibVlcPlayerView, repeat: Boolean? ->
|
|
80
|
-
view.
|
|
80
|
+
view.repeat = repeat ?: false
|
|
81
81
|
}
|
|
82
82
|
|
|
83
83
|
Prop("aspectRatio") { view: LibVlcPlayerView, aspectRatio: String? ->
|
|
84
|
-
view.
|
|
84
|
+
view.aspectRatio = aspectRatio
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
Prop("audioMixingMode") { view: LibVlcPlayerView, audioMixingMode: AudioMixingMode? ->
|
|
@@ -93,7 +93,7 @@ class LibVlcPlayerModule : Module() {
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
Prop("autoplay") { view: LibVlcPlayerView, autoplay: Boolean? ->
|
|
96
|
-
view.
|
|
96
|
+
view.autoplay = autoplay ?: true
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
OnViewDestroys { view: LibVlcPlayerView ->
|
|
@@ -17,6 +17,7 @@ import java.util.UUID
|
|
|
17
17
|
|
|
18
18
|
const val DEFAULT_PLAYER_RATE: Float = 1f
|
|
19
19
|
const val DEFAULT_PLAYER_TIME: Int = 0
|
|
20
|
+
|
|
20
21
|
const val MIN_PLAYER_VOLUME: Int = 0
|
|
21
22
|
const val MAX_PLAYER_VOLUME: Int = 100
|
|
22
23
|
const val PLAYER_VOLUME_STEP: Int = 10
|
|
@@ -37,9 +38,6 @@ class LibVlcPlayerView(
|
|
|
37
38
|
internal var media: Media? = null
|
|
38
39
|
private var shouldCreate: Boolean = false
|
|
39
40
|
|
|
40
|
-
internal var repeat: Boolean = false
|
|
41
|
-
private var autoplay: Boolean = true
|
|
42
|
-
|
|
43
41
|
internal var videoLength: Long = 0L
|
|
44
42
|
internal var userVolume: Int = MAX_PLAYER_VOLUME
|
|
45
43
|
|
|
@@ -81,6 +79,22 @@ class LibVlcPlayerView(
|
|
|
81
79
|
|
|
82
80
|
addPlayerSlaves()
|
|
83
81
|
|
|
82
|
+
if (volume != MAX_PLAYER_VOLUME) {
|
|
83
|
+
mediaPlayer!!.setVolume(volume)
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (mute) {
|
|
87
|
+
mediaPlayer!!.setVolume(MIN_PLAYER_VOLUME)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (rate != DEFAULT_PLAYER_RATE) {
|
|
91
|
+
mediaPlayer!!.setRate(rate)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (aspectRatio != null) {
|
|
95
|
+
mediaPlayer!!.setAspectRatio(aspectRatio)
|
|
96
|
+
}
|
|
97
|
+
|
|
84
98
|
if (autoplay) {
|
|
85
99
|
mediaPlayer!!.play()
|
|
86
100
|
}
|
|
@@ -99,7 +113,6 @@ class LibVlcPlayerView(
|
|
|
99
113
|
set(value) {
|
|
100
114
|
val old = field
|
|
101
115
|
field = value
|
|
102
|
-
|
|
103
116
|
shouldCreate = value != old
|
|
104
117
|
}
|
|
105
118
|
|
|
@@ -107,7 +120,6 @@ class LibVlcPlayerView(
|
|
|
107
120
|
set(value) {
|
|
108
121
|
val old = field
|
|
109
122
|
field = value
|
|
110
|
-
|
|
111
123
|
shouldCreate = value != old
|
|
112
124
|
}
|
|
113
125
|
|
|
@@ -171,57 +183,65 @@ class LibVlcPlayerView(
|
|
|
171
183
|
setPlayerTracks()
|
|
172
184
|
}
|
|
173
185
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
186
|
+
var volume: Int = MAX_PLAYER_VOLUME
|
|
187
|
+
set(value) {
|
|
188
|
+
if (options.hasAudioOption()) {
|
|
189
|
+
val error = mapOf("error" to "Audio disabled via options")
|
|
190
|
+
onEncounteredError(error)
|
|
191
|
+
}
|
|
179
192
|
|
|
180
|
-
|
|
181
|
-
userVolume = newVolume
|
|
193
|
+
field = value
|
|
182
194
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
195
|
+
val volume = value.coerceIn(MIN_PLAYER_VOLUME, MAX_PLAYER_VOLUME)
|
|
196
|
+
userVolume = volume
|
|
186
197
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
val error = mapOf("error" to "Audio disabled via options")
|
|
190
|
-
onEncounteredError(error)
|
|
198
|
+
mediaPlayer?.setVolume(volume)
|
|
199
|
+
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
191
200
|
}
|
|
192
201
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
202
|
+
var mute: Boolean = false
|
|
203
|
+
set(value) {
|
|
204
|
+
if (options.hasAudioOption()) {
|
|
205
|
+
val error = mapOf("error" to "Audio disabled via options")
|
|
206
|
+
onEncounteredError(error)
|
|
198
207
|
}
|
|
199
208
|
|
|
200
|
-
|
|
201
|
-
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
202
|
-
}
|
|
209
|
+
field = value
|
|
203
210
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
211
|
+
val newVolume =
|
|
212
|
+
if (!value) {
|
|
213
|
+
userVolume.coerceIn(PLAYER_VOLUME_STEP, MAX_PLAYER_VOLUME)
|
|
214
|
+
} else {
|
|
215
|
+
MIN_PLAYER_VOLUME
|
|
216
|
+
}
|
|
207
217
|
|
|
208
|
-
|
|
218
|
+
mediaPlayer?.setVolume(newVolume)
|
|
219
|
+
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
var rate: Float = DEFAULT_PLAYER_RATE
|
|
209
223
|
set(value) {
|
|
210
224
|
field = value
|
|
225
|
+
mediaPlayer?.setRate(value)
|
|
211
226
|
}
|
|
212
227
|
|
|
213
|
-
|
|
214
|
-
if (options.hasRepeatOption()) {
|
|
215
|
-
val error = mapOf("error" to "Repeat enabled via options")
|
|
216
|
-
onEncounteredError(error)
|
|
217
|
-
}
|
|
228
|
+
var time: Int = DEFAULT_PLAYER_TIME
|
|
218
229
|
|
|
219
|
-
|
|
220
|
-
|
|
230
|
+
var repeat: Boolean = false
|
|
231
|
+
set(value) {
|
|
232
|
+
if (options.hasRepeatOption()) {
|
|
233
|
+
val error = mapOf("error" to "Repeat enabled via options")
|
|
234
|
+
onEncounteredError(error)
|
|
235
|
+
}
|
|
221
236
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
237
|
+
field = value
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
var aspectRatio: String? = null
|
|
241
|
+
set(value) {
|
|
242
|
+
field = value
|
|
243
|
+
mediaPlayer?.setAspectRatio(value)
|
|
244
|
+
}
|
|
225
245
|
|
|
226
246
|
var audioMixingMode: AudioMixingMode = AudioMixingMode.AUTO
|
|
227
247
|
set(value) {
|
|
@@ -235,9 +255,7 @@ class LibVlcPlayerView(
|
|
|
235
255
|
MediaPlayerManager.audioFocusManager.updateAudioFocus()
|
|
236
256
|
}
|
|
237
257
|
|
|
238
|
-
|
|
239
|
-
this.autoplay = autoplay
|
|
240
|
-
}
|
|
258
|
+
var autoplay: Boolean = true
|
|
241
259
|
|
|
242
260
|
fun play() {
|
|
243
261
|
mediaPlayer?.play()
|
|
@@ -5,7 +5,7 @@ import expo.modules.kotlin.exception.Exceptions
|
|
|
5
5
|
import java.lang.ref.WeakReference
|
|
6
6
|
|
|
7
7
|
object MediaPlayerManager {
|
|
8
|
-
|
|
8
|
+
internal var playerViews: MutableList<WeakReference<LibVlcPlayerView>> = mutableListOf()
|
|
9
9
|
|
|
10
10
|
lateinit var audioFocusManager: AudioFocusManager
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ object MediaPlayerManager {
|
|
|
13
13
|
val context = appContext.reactContext ?: throw Exceptions.ReactContextLost()
|
|
14
14
|
|
|
15
15
|
if (!this::audioFocusManager.isInitialized) {
|
|
16
|
-
audioFocusManager = AudioFocusManager(appContext
|
|
16
|
+
audioFocusManager = AudioFocusManager(appContext)
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
@@ -34,55 +34,55 @@ public class LibVlcPlayerModule: Module {
|
|
|
34
34
|
Events(playerEvents)
|
|
35
35
|
|
|
36
36
|
Prop("uri") { (view: LibVlcPlayerView, uri: String) in
|
|
37
|
-
view.
|
|
37
|
+
view.uri = uri
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
Prop("options") { (view: LibVlcPlayerView, options: [String]?) in
|
|
41
|
-
view.
|
|
41
|
+
view.options = options ?? [String]()
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
Prop("slaves") { (view: LibVlcPlayerView, slaves: [[String: Any]]?) in
|
|
45
|
-
view.
|
|
45
|
+
view.slaves = slaves
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
Prop("tracks") { (view: LibVlcPlayerView, tracks: [String: Any]?) in
|
|
49
|
-
view.
|
|
49
|
+
view.tracks = tracks
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
Prop("volume") { (view: LibVlcPlayerView, volume: Int?) in
|
|
53
|
-
view.
|
|
53
|
+
view.volume = volume ?? maxPlayerVolume
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
Prop("mute") { (view: LibVlcPlayerView, mute: Bool?) in
|
|
57
|
-
view.
|
|
57
|
+
view.mute = mute ?? false
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
Prop("rate") { (view: LibVlcPlayerView, rate: Float?) in
|
|
61
|
-
view.
|
|
61
|
+
view.rate = rate ?? defaultPlayerRate
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
Prop("time") { (view: LibVlcPlayerView, time: Int?) in
|
|
65
|
-
view.
|
|
65
|
+
view.time = time ?? defaultPlayerTime
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
Prop("repeat") { (view: LibVlcPlayerView, shouldRepeat: Bool?) in
|
|
69
|
-
view.
|
|
69
|
+
view.shouldRepeat = shouldRepeat ?? false
|
|
70
70
|
}
|
|
71
71
|
|
|
72
72
|
Prop("aspectRatio") { (view: LibVlcPlayerView, aspectRatio: String?) in
|
|
73
|
-
view.
|
|
73
|
+
view.aspectRatio = aspectRatio
|
|
74
74
|
}
|
|
75
75
|
|
|
76
76
|
Prop("audioMixingMode") { (view: LibVlcPlayerView, audioMixingMode: AudioMixingMode?) in
|
|
77
|
-
view.
|
|
77
|
+
view.audioMixingMode = audioMixingMode ?? .auto
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
Prop("playInBackground") { (view: LibVlcPlayerView, playInBackground: Bool?) in
|
|
81
|
-
view.
|
|
81
|
+
view.playInBackground = playInBackground ?? false
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
Prop("autoplay") { (view: LibVlcPlayerView, autoplay: Bool?) in
|
|
85
|
-
view.
|
|
85
|
+
view.autoplay = autoplay ?? true
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
OnViewDidUpdateProps { (view: LibVlcPlayerView) in
|
|
@@ -4,6 +4,7 @@ import UIKit
|
|
|
4
4
|
|
|
5
5
|
let defaultPlayerRate: Float = 1.0
|
|
6
6
|
let defaultPlayerTime: Int = 0
|
|
7
|
+
|
|
7
8
|
let minPlayerVolume: Int = 0
|
|
8
9
|
let maxPlayerVolume: Int = 100
|
|
9
10
|
let playerVolumeStep: Int = 10
|
|
@@ -12,19 +13,8 @@ class LibVlcPlayerView: ExpoView {
|
|
|
12
13
|
private let playerView = UIView()
|
|
13
14
|
|
|
14
15
|
var mediaPlayer: VLCMediaPlayer?
|
|
15
|
-
|
|
16
16
|
private var shouldCreate: Bool = false
|
|
17
17
|
|
|
18
|
-
private var uri: String = ""
|
|
19
|
-
var options: [String] = .init()
|
|
20
|
-
private var slaves: [[String: Any]]?
|
|
21
|
-
private var tracks: [String: Any]?
|
|
22
|
-
var time: Int = defaultPlayerTime
|
|
23
|
-
var shouldRepeat: Bool = false
|
|
24
|
-
var audioMixingMode: AudioMixingMode = .auto
|
|
25
|
-
var playInBackground: Bool = false
|
|
26
|
-
private var autoplay: Bool = true
|
|
27
|
-
|
|
28
18
|
var videoLength: Int32 = 0
|
|
29
19
|
private var userVolume: Int = maxPlayerVolume
|
|
30
20
|
|
|
@@ -73,6 +63,24 @@ class LibVlcPlayerView: ExpoView {
|
|
|
73
63
|
|
|
74
64
|
addPlayerSlaves()
|
|
75
65
|
|
|
66
|
+
if volume != maxPlayerVolume {
|
|
67
|
+
mediaPlayer!.volume = Int32(volume)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
if mute {
|
|
71
|
+
mediaPlayer!.volume = Int32(minPlayerVolume)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if rate != defaultPlayerRate {
|
|
75
|
+
mediaPlayer!.rate = rate
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if aspectRatio != nil {
|
|
79
|
+
aspectRatio.withCString { cString in
|
|
80
|
+
mediaPlayer!.videoAspectRatio = UnsafeMutablePointer(mutating: cString)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
76
84
|
if autoplay {
|
|
77
85
|
mediaPlayer!.play()
|
|
78
86
|
}
|
|
@@ -86,18 +94,16 @@ class LibVlcPlayerView: ExpoView {
|
|
|
86
94
|
mediaPlayer = nil
|
|
87
95
|
}
|
|
88
96
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
shouldCreate = uri != old
|
|
97
|
+
var uri: String = "" {
|
|
98
|
+
didSet {
|
|
99
|
+
shouldCreate = uri != oldValue
|
|
100
|
+
}
|
|
94
101
|
}
|
|
95
102
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
shouldCreate = options != old
|
|
103
|
+
var options: [String] = .init() {
|
|
104
|
+
didSet {
|
|
105
|
+
shouldCreate = options != oldValue
|
|
106
|
+
}
|
|
101
107
|
}
|
|
102
108
|
|
|
103
109
|
func addPlayerSlave(_ slave: [String: Any]) {
|
|
@@ -124,9 +130,10 @@ class LibVlcPlayerView: ExpoView {
|
|
|
124
130
|
slaves?.filter { ($0["type"] as? String) == "audio" }.forEach { addPlayerSlave($0) }
|
|
125
131
|
}
|
|
126
132
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
133
|
+
var slaves: [[String: Any]]? {
|
|
134
|
+
didSet {
|
|
135
|
+
addPlayerSlaves()
|
|
136
|
+
}
|
|
130
137
|
}
|
|
131
138
|
|
|
132
139
|
func setPlayerTracks() {
|
|
@@ -141,86 +148,93 @@ class LibVlcPlayerView: ExpoView {
|
|
|
141
148
|
player.currentVideoSubTitleIndex = Int32(videoSubTitleIndex)
|
|
142
149
|
}
|
|
143
150
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
151
|
+
var tracks: [String: Any]? {
|
|
152
|
+
didSet {
|
|
153
|
+
if options.hasAudioTrackOption() {
|
|
154
|
+
let error = ["error": "Audio track selected via options"]
|
|
155
|
+
onEncounteredError(error)
|
|
156
|
+
}
|
|
149
157
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
158
|
+
if options.hasSubtitleTrackOption() {
|
|
159
|
+
let error = ["error": "Subtitle track selected via options"]
|
|
160
|
+
onEncounteredError(error)
|
|
161
|
+
}
|
|
154
162
|
|
|
155
|
-
|
|
156
|
-
|
|
163
|
+
setPlayerTracks()
|
|
164
|
+
}
|
|
157
165
|
}
|
|
158
166
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
167
|
+
var volume: Int = maxPlayerVolume {
|
|
168
|
+
didSet {
|
|
169
|
+
if options.hasAudioOption() {
|
|
170
|
+
let error = ["error": "Audio disabled via options"]
|
|
171
|
+
onEncounteredError(error)
|
|
172
|
+
}
|
|
164
173
|
|
|
165
|
-
|
|
166
|
-
|
|
174
|
+
let newVolume = max(minPlayerVolume, min(maxPlayerVolume, volume))
|
|
175
|
+
userVolume = newVolume
|
|
167
176
|
|
|
168
|
-
|
|
169
|
-
|
|
177
|
+
mediaPlayer?.audio?.volume = Int32(newVolume)
|
|
178
|
+
MediaPlayerManager.shared.setAppropriateAudioSessionOrWarn()
|
|
179
|
+
}
|
|
170
180
|
}
|
|
171
181
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
182
|
+
var mute: Bool = false {
|
|
183
|
+
didSet {
|
|
184
|
+
if options.hasAudioOption() {
|
|
185
|
+
let error = ["error": "Audio disabled via options"]
|
|
186
|
+
onEncounteredError(error)
|
|
187
|
+
}
|
|
177
188
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
189
|
+
let newVolume = !mute ?
|
|
190
|
+
max(playerVolumeStep, min(maxPlayerVolume, userVolume)) :
|
|
191
|
+
minPlayerVolume
|
|
181
192
|
|
|
182
|
-
|
|
183
|
-
|
|
193
|
+
mediaPlayer?.audio?.volume = Int32(newVolume)
|
|
194
|
+
MediaPlayerManager.shared.setAppropriateAudioSessionOrWarn()
|
|
195
|
+
}
|
|
184
196
|
}
|
|
185
197
|
|
|
186
|
-
|
|
187
|
-
|
|
198
|
+
var rate: Float = defaultPlayerRate {
|
|
199
|
+
didSet {
|
|
200
|
+
mediaPlayer?.rate = rate
|
|
201
|
+
}
|
|
188
202
|
}
|
|
189
203
|
|
|
190
|
-
|
|
191
|
-
self.time = time
|
|
192
|
-
}
|
|
204
|
+
var time: Int = defaultPlayerTime
|
|
193
205
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
206
|
+
var shouldRepeat: Bool = false {
|
|
207
|
+
didSet {
|
|
208
|
+
if options.hasRepeatOption() {
|
|
209
|
+
let error = ["error": "Repeat enabled via options"]
|
|
210
|
+
onEncounteredError(error)
|
|
211
|
+
}
|
|
198
212
|
}
|
|
199
|
-
|
|
200
|
-
self.shouldRepeat = shouldRepeat
|
|
201
213
|
}
|
|
202
214
|
|
|
203
|
-
|
|
204
|
-
|
|
215
|
+
var aspectRatio: String? {
|
|
216
|
+
didSet {
|
|
217
|
+
guard let aspectRatio = aspectRatio else { return }
|
|
205
218
|
|
|
206
|
-
|
|
207
|
-
|
|
219
|
+
aspectRatio.withCString { cString in
|
|
220
|
+
mediaPlayer?.videoAspectRatio = UnsafeMutablePointer(mutating: cString)
|
|
221
|
+
}
|
|
208
222
|
}
|
|
209
223
|
}
|
|
210
224
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
225
|
+
var audioMixingMode: AudioMixingMode = .auto {
|
|
226
|
+
didSet {
|
|
227
|
+
MediaPlayerManager.shared.setAppropriateAudioSessionOrWarn()
|
|
228
|
+
}
|
|
214
229
|
}
|
|
215
230
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
231
|
+
var playInBackground: Bool = false {
|
|
232
|
+
didSet {
|
|
233
|
+
MediaPlayerManager.shared.setAppropriateAudioSessionOrWarn()
|
|
234
|
+
}
|
|
219
235
|
}
|
|
220
236
|
|
|
221
|
-
|
|
222
|
-
self.autoplay = autoplay
|
|
223
|
-
}
|
|
237
|
+
var autoplay: Bool = true
|
|
224
238
|
|
|
225
239
|
func play() {
|
|
226
240
|
mediaPlayer?.play()
|