expo-libvlc-player 3.3.1 → 3.4.0

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.
@@ -1,7 +1,7 @@
1
1
  apply plugin: "com.android.library"
2
2
 
3
3
  group = "expo.modules.libvlcplayer"
4
- version = "3.3.1"
4
+ version = "3.4.0"
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 "3.3.1"
30
+ versionName "3.4.0"
31
31
  consumerProguardFiles("proguard-rules.pro")
32
32
  }
33
33
  lintOptions {
@@ -0,0 +1,29 @@
1
+ package expo.modules.libvlcplayer
2
+
3
+ import android.app.Activity
4
+ import android.view.WindowManager
5
+ import expo.modules.core.errors.CurrentActivityNotFoundException
6
+ import expo.modules.kotlin.AppContext
7
+
8
+ class KeepAwakeManager(
9
+ private val appContext: AppContext?,
10
+ ) {
11
+ private val currentActivity: Activity
12
+ get() = appContext?.currentActivity ?: throw CurrentActivityNotFoundException()
13
+
14
+ fun activateKeepAwake() {
15
+ currentActivity.let {
16
+ it.runOnUiThread {
17
+ it.window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
18
+ }
19
+ }
20
+ }
21
+
22
+ fun deactivateKeepAwake() {
23
+ currentActivity.let {
24
+ it.runOnUiThread {
25
+ it.window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
26
+ }
27
+ }
28
+ }
29
+ }
@@ -67,10 +67,12 @@ class LibVlcPlayerModule : Module() {
67
67
  }
68
68
 
69
69
  OnActivityEntersForeground {
70
+ MediaPlayerManager.keepAwakeManager.activateKeepAwake()
70
71
  MediaPlayerManager.onModuleForeground()
71
72
  }
72
73
 
73
74
  OnActivityEntersBackground {
75
+ MediaPlayerManager.keepAwakeManager.deactivateKeepAwake()
74
76
  MediaPlayerManager.onModuleBackground()
75
77
  }
76
78
 
@@ -98,18 +98,6 @@ class LibVlcPlayerView(
98
98
  detachPlayer()
99
99
  }
100
100
 
101
- override fun onLayout(
102
- changed: Boolean,
103
- left: Int,
104
- top: Int,
105
- right: Int,
106
- bottom: Int,
107
- ) {
108
- super.onLayout(changed, left, top, right, bottom)
109
-
110
- setContentFit()
111
- }
112
-
113
101
  fun getTextureView(): TextureView? = playerView.findViewById(org.videolan.R.id.texture_video)
114
102
 
115
103
  fun createPlayer() {
@@ -220,10 +208,10 @@ class LibVlcPlayerView(
220
208
  mediaPlayer?.let { player ->
221
209
  val textureView = getTextureView() ?: return
222
210
 
223
- val matrix = Matrix()
224
-
225
211
  val video = player.getCurrentVideoTrack()
226
212
 
213
+ val matrix = Matrix()
214
+
227
215
  if (video != null) {
228
216
  val viewWidth = playerView.width.toFloat()
229
217
  val viewHeight = playerView.height.toFloat()
@@ -380,20 +368,14 @@ class LibVlcPlayerView(
380
368
  set(value) {
381
369
  val old = field
382
370
  field = value
383
-
384
- if (!shouldCreate) {
385
- shouldCreate = value != old
386
- }
371
+ shouldCreate = value != old
387
372
  }
388
373
 
389
374
  var options: ArrayList<String> = ArrayList()
390
375
  set(value) {
391
376
  val old = field
392
377
  field = value
393
-
394
- if (!shouldCreate) {
395
- shouldCreate = value != old
396
- }
378
+ shouldCreate = value != old
397
379
  }
398
380
 
399
381
  var tracks: Tracks? = null
@@ -423,6 +405,10 @@ class LibVlcPlayerView(
423
405
  set(value) {
424
406
  field = value
425
407
  mediaPlayer?.setAspectRatio(value)
408
+
409
+ post {
410
+ setContentFit()
411
+ }
426
412
  }
427
413
 
428
414
  var contentFit: VideoContentFit = VideoContentFit.CONTAIN
@@ -28,12 +28,14 @@ fun LibVlcPlayerView.setMediaPlayerListener() {
28
28
  firstPlay = false
29
29
  }
30
30
 
31
+ MediaPlayerManager.keepAwakeManager.activateKeepAwake()
31
32
  MediaPlayerManager.audioFocusManager.updateAudioFocus()
32
33
  }
33
34
 
34
35
  Event.Paused -> {
35
36
  onPaused(Unit)
36
37
 
38
+ MediaPlayerManager.keepAwakeManager.deactivateKeepAwake()
37
39
  MediaPlayerManager.audioFocusManager.updateAudioFocus()
38
40
  }
39
41
 
@@ -42,6 +44,7 @@ fun LibVlcPlayerView.setMediaPlayerListener() {
42
44
 
43
45
  detachPlayer()
44
46
 
47
+ MediaPlayerManager.keepAwakeManager.deactivateKeepAwake()
45
48
  MediaPlayerManager.audioFocusManager.updateAudioFocus()
46
49
 
47
50
  firstPlay = true
@@ -64,6 +67,7 @@ fun LibVlcPlayerView.setMediaPlayerListener() {
64
67
  val error = mapOf("error" to "Media player encountered an error")
65
68
  onEncounteredError(error)
66
69
 
70
+ MediaPlayerManager.keepAwakeManager.deactivateKeepAwake()
67
71
  MediaPlayerManager.audioFocusManager.updateAudioFocus()
68
72
 
69
73
  firstPlay = true
@@ -5,6 +5,7 @@ import java.lang.ref.WeakReference
5
5
 
6
6
  object MediaPlayerManager {
7
7
  lateinit var audioFocusManager: AudioFocusManager
8
+ lateinit var keepAwakeManager: KeepAwakeManager
8
9
 
9
10
  var playerViews: MutableList<WeakReference<LibVlcPlayerView>> = mutableListOf()
10
11
 
@@ -20,6 +21,10 @@ object MediaPlayerManager {
20
21
  if (!this::audioFocusManager.isInitialized) {
21
22
  audioFocusManager = AudioFocusManager(appContext)
22
23
  }
24
+
25
+ if (!this::keepAwakeManager.isInitialized) {
26
+ keepAwakeManager = KeepAwakeManager(appContext)
27
+ }
23
28
  }
24
29
 
25
30
  fun onModuleDestroy() {
@@ -1 +1 @@
1
- {"version":3,"file":"LibVlcPlayerView.d.ts","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,qBAAqB,EACrB,mBAAmB,EAUpB,MAAM,sBAAsB,CAAC;AAU9B,QAAA,MAAM,gBAAgB,uHAyFrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"LibVlcPlayerView.d.ts","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"AAIA,OAAO,EAEL,qBAAqB,EACrB,mBAAmB,EAUpB,MAAM,sBAAsB,CAAC;AAU9B,QAAA,MAAM,gBAAgB,uHAwFrB,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -63,7 +63,7 @@ const LibVlcPlayerView = forwardRef((props, ref) => {
63
63
  <NativeView {...props} ref={ref} style={[props.style, { height: "100%" }]} source={parseSource(props.source)} slaves={props.slaves?.map((slave) => ({
64
64
  ...slave,
65
65
  source: parseSource(slave.source),
66
- }))} aspectRatio={!props.contentFit ? props.aspectRatio : null} onEncounteredError={onEncounteredError} onDialogDisplay={onDialogDisplay} onTimeChanged={onTimeChanged} onPositionChanged={onPositionChanged} onESAdded={onESAdded} onRecordChanged={onRecordChanged} onSnapshotTaken={onSnapshotTaken} onFirstPlay={onFirstPlay}/>
66
+ }))} onEncounteredError={onEncounteredError} onDialogDisplay={onDialogDisplay} onTimeChanged={onTimeChanged} onPositionChanged={onPositionChanged} onESAdded={onESAdded} onRecordChanged={onRecordChanged} onSnapshotTaken={onSnapshotTaken} onFirstPlay={onFirstPlay}/>
67
67
  </View>);
68
68
  });
69
69
  export default LibVlcPlayerView;
@@ -1 +1 @@
1
- {"version":3,"file":"LibVlcPlayerView.js","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeView } from \"expo\";\nimport { forwardRef, type ComponentType } from \"react\";\nimport { View } from \"react-native\";\n\nimport {\n LibVlcPlayerViewNativeProps,\n LibVlcPlayerViewProps,\n LibVlcPlayerViewRef,\n type Dialog,\n type Error,\n type MediaInfo,\n type MediaTracks,\n type NativeEvent,\n type Position,\n type Recording,\n type Snapshot,\n type Time,\n} from \"./LibVlcPlayer.types\";\nimport { convertAspectRatio } from \"./utils/aspect\";\nimport { parseSource } from \"./utils/assets\";\nimport { convertNativeEvent } from \"./utils/events\";\n\nconst NativeView: ComponentType<LibVlcPlayerViewNativeProps> =\n requireNativeView(\"ExpoLibVlcPlayer\");\n\nlet loggedRenderingChildrenWarning: boolean = false;\n\nconst LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(\n (props, ref) => {\n if (props.children && !loggedRenderingChildrenWarning) {\n console.warn(\n \"The <LibVlcPlayerView> component does not support children. This may lead to inconsistent behaviour or crashes. If you want to render content on top of the LibVlcPlayer, consider using absolute positioning.\",\n );\n loggedRenderingChildrenWarning = true;\n }\n\n const onEncounteredError = (event: NativeEvent<Error>) => {\n if (props.onEncounteredError) {\n const nativeEvent = convertNativeEvent(event);\n props.onEncounteredError(nativeEvent);\n }\n };\n\n const onDialogDisplay = (event: NativeEvent<Dialog>) => {\n if (props.onDialogDisplay) {\n const nativeEvent = convertNativeEvent(event);\n props.onDialogDisplay(nativeEvent);\n }\n };\n\n const onTimeChanged = (event: NativeEvent<Time>) => {\n if (props.onTimeChanged) {\n const nativeEvent = convertNativeEvent(event);\n props.onTimeChanged(nativeEvent);\n }\n };\n\n const onPositionChanged = (event: NativeEvent<Position>) => {\n if (props.onPositionChanged) {\n const nativeEvent = convertNativeEvent(event);\n props.onPositionChanged(nativeEvent);\n }\n };\n\n const onESAdded = (event: NativeEvent<MediaTracks>) => {\n if (props.onESAdded) {\n const nativeEvent = convertNativeEvent(event);\n props.onESAdded(nativeEvent);\n }\n };\n\n const onRecordChanged = (event: NativeEvent<Recording>) => {\n if (props.onRecordChanged) {\n const nativeEvent = convertNativeEvent(event);\n props.onRecordChanged(nativeEvent);\n }\n };\n\n const onSnapshotTaken = (event: NativeEvent<Snapshot>) => {\n if (props.onSnapshotTaken) {\n const nativeEvent = convertNativeEvent(event);\n props.onSnapshotTaken(nativeEvent);\n }\n };\n\n const onFirstPlay = (event: NativeEvent<MediaInfo>) => {\n if (props.onFirstPlay) {\n const nativeEvent = convertNativeEvent(event);\n props.onFirstPlay(nativeEvent);\n }\n };\n\n return (\n <View style={{ aspectRatio: convertAspectRatio(props.aspectRatio) }}>\n <NativeView\n {...props}\n ref={ref}\n style={[props.style, { height: \"100%\" }]}\n source={parseSource(props.source)}\n slaves={props.slaves?.map((slave) => ({\n ...slave,\n source: parseSource(slave.source)!,\n }))}\n aspectRatio={!props.contentFit ? props.aspectRatio : null}\n onEncounteredError={onEncounteredError}\n onDialogDisplay={onDialogDisplay}\n onTimeChanged={onTimeChanged}\n onPositionChanged={onPositionChanged}\n onESAdded={onESAdded}\n onRecordChanged={onRecordChanged}\n onSnapshotTaken={onSnapshotTaken}\n onFirstPlay={onFirstPlay}\n />\n </View>\n );\n },\n);\n\nexport default LibVlcPlayerView;\n"]}
1
+ {"version":3,"file":"LibVlcPlayerView.js","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeView } from \"expo\";\nimport { forwardRef, type ComponentType } from \"react\";\nimport { View } from \"react-native\";\n\nimport {\n LibVlcPlayerViewNativeProps,\n LibVlcPlayerViewProps,\n LibVlcPlayerViewRef,\n type Dialog,\n type Error,\n type MediaInfo,\n type MediaTracks,\n type NativeEvent,\n type Position,\n type Recording,\n type Snapshot,\n type Time,\n} from \"./LibVlcPlayer.types\";\nimport { convertAspectRatio } from \"./utils/aspect\";\nimport { parseSource } from \"./utils/assets\";\nimport { convertNativeEvent } from \"./utils/events\";\n\nconst NativeView: ComponentType<LibVlcPlayerViewNativeProps> =\n requireNativeView(\"ExpoLibVlcPlayer\");\n\nlet loggedRenderingChildrenWarning: boolean = false;\n\nconst LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(\n (props, ref) => {\n if (props.children && !loggedRenderingChildrenWarning) {\n console.warn(\n \"The <LibVlcPlayerView> component does not support children. This may lead to inconsistent behaviour or crashes. If you want to render content on top of the LibVlcPlayer, consider using absolute positioning.\",\n );\n loggedRenderingChildrenWarning = true;\n }\n\n const onEncounteredError = (event: NativeEvent<Error>) => {\n if (props.onEncounteredError) {\n const nativeEvent = convertNativeEvent(event);\n props.onEncounteredError(nativeEvent);\n }\n };\n\n const onDialogDisplay = (event: NativeEvent<Dialog>) => {\n if (props.onDialogDisplay) {\n const nativeEvent = convertNativeEvent(event);\n props.onDialogDisplay(nativeEvent);\n }\n };\n\n const onTimeChanged = (event: NativeEvent<Time>) => {\n if (props.onTimeChanged) {\n const nativeEvent = convertNativeEvent(event);\n props.onTimeChanged(nativeEvent);\n }\n };\n\n const onPositionChanged = (event: NativeEvent<Position>) => {\n if (props.onPositionChanged) {\n const nativeEvent = convertNativeEvent(event);\n props.onPositionChanged(nativeEvent);\n }\n };\n\n const onESAdded = (event: NativeEvent<MediaTracks>) => {\n if (props.onESAdded) {\n const nativeEvent = convertNativeEvent(event);\n props.onESAdded(nativeEvent);\n }\n };\n\n const onRecordChanged = (event: NativeEvent<Recording>) => {\n if (props.onRecordChanged) {\n const nativeEvent = convertNativeEvent(event);\n props.onRecordChanged(nativeEvent);\n }\n };\n\n const onSnapshotTaken = (event: NativeEvent<Snapshot>) => {\n if (props.onSnapshotTaken) {\n const nativeEvent = convertNativeEvent(event);\n props.onSnapshotTaken(nativeEvent);\n }\n };\n\n const onFirstPlay = (event: NativeEvent<MediaInfo>) => {\n if (props.onFirstPlay) {\n const nativeEvent = convertNativeEvent(event);\n props.onFirstPlay(nativeEvent);\n }\n };\n\n return (\n <View style={{ aspectRatio: convertAspectRatio(props.aspectRatio) }}>\n <NativeView\n {...props}\n ref={ref}\n style={[props.style, { height: \"100%\" }]}\n source={parseSource(props.source)}\n slaves={props.slaves?.map((slave) => ({\n ...slave,\n source: parseSource(slave.source)!,\n }))}\n onEncounteredError={onEncounteredError}\n onDialogDisplay={onDialogDisplay}\n onTimeChanged={onTimeChanged}\n onPositionChanged={onPositionChanged}\n onESAdded={onESAdded}\n onRecordChanged={onRecordChanged}\n onSnapshotTaken={onSnapshotTaken}\n onFirstPlay={onFirstPlay}\n />\n </View>\n );\n },\n);\n\nexport default LibVlcPlayerView;\n"]}
@@ -0,0 +1,13 @@
1
+ extension MediaPlayerManager {
2
+ func activateKeepAwake() {
3
+ DispatchQueue.main.async {
4
+ UIApplication.shared.isIdleTimerDisabled = true
5
+ }
6
+ }
7
+
8
+ func deactivateKeepAwake() {
9
+ DispatchQueue.main.async {
10
+ UIApplication.shared.isIdleTimerDisabled = false
11
+ }
12
+ }
13
+ }
@@ -47,10 +47,12 @@ public class LibVlcPlayerModule: Module {
47
47
  }
48
48
 
49
49
  OnAppEntersForeground {
50
+ MediaPlayerManager.shared.activateKeepAwake()
50
51
  MediaPlayerManager.shared.onModuleForeground()
51
52
  }
52
53
 
53
54
  OnAppEntersBackground {
55
+ MediaPlayerManager.shared.deactivateKeepAwake()
54
56
  MediaPlayerManager.shared.onModuleBackground()
55
57
  }
56
58
 
@@ -58,63 +60,93 @@ public class LibVlcPlayerModule: Module {
58
60
  Events(playerEvents)
59
61
 
60
62
  Prop("source") { (view: LibVlcPlayerView, source: String?) in
61
- view.source = source
63
+ if source != view.source {
64
+ view.source = source
65
+ }
62
66
  }
63
67
 
64
68
  Prop("options") { (view: LibVlcPlayerView, options: [String]?) in
65
- view.options = options ?? [String]()
69
+ if options != view.options {
70
+ view.options = options ?? [String]()
71
+ }
66
72
  }
67
73
 
68
74
  Prop("tracks") { (view: LibVlcPlayerView, tracks: Tracks?) in
69
- view.tracks = tracks
75
+ if tracks != view.tracks {
76
+ view.tracks = tracks
77
+ }
70
78
  }
71
79
 
72
80
  Prop("slaves") { (view: LibVlcPlayerView, slaves: [Slave]?) in
73
- view.slaves = slaves ?? [Slave]()
81
+ if slaves != view.slaves {
82
+ view.slaves = slaves ?? [Slave]()
83
+ }
74
84
  }
75
85
 
76
86
  Prop("scale") { (view: LibVlcPlayerView, scale: Float?) in
77
- view.scale = scale ?? defaultPlayerScale
87
+ if scale != view.scale {
88
+ view.scale = scale ?? defaultPlayerScale
89
+ }
78
90
  }
79
91
 
80
92
  Prop("aspectRatio") { (view: LibVlcPlayerView, aspectRatio: String?) in
81
- view.aspectRatio = aspectRatio
93
+ if aspectRatio != view.aspectRatio {
94
+ view.aspectRatio = aspectRatio
95
+ }
82
96
  }
83
97
 
84
98
  Prop("contentFit") { (view: LibVlcPlayerView, contentFit: VideoContentFit?) in
85
- view.contentFit = contentFit ?? .contain
99
+ if contentFit != view.contentFit {
100
+ view.contentFit = contentFit ?? .contain
101
+ }
86
102
  }
87
103
 
88
104
  Prop("rate") { (view: LibVlcPlayerView, rate: Float?) in
89
- view.rate = rate ?? defaultPlayerRate
105
+ if rate != view.rate {
106
+ view.rate = rate ?? defaultPlayerRate
107
+ }
90
108
  }
91
109
 
92
110
  Prop("time") { (view: LibVlcPlayerView, time: Int?) in
93
- view.time = time ?? defaultPlayerTime
111
+ if time != view.time {
112
+ view.time = time ?? defaultPlayerTime
113
+ }
94
114
  }
95
115
 
96
116
  Prop("volume") { (view: LibVlcPlayerView, volume: Int?) in
97
- view.volume = volume ?? maxPlayerVolume
117
+ if volume != view.volume {
118
+ view.volume = volume ?? maxPlayerVolume
119
+ }
98
120
  }
99
121
 
100
122
  Prop("mute") { (view: LibVlcPlayerView, mute: Bool?) in
101
- view.mute = mute ?? false
123
+ if mute != view.mute {
124
+ view.mute = mute ?? false
125
+ }
102
126
  }
103
127
 
104
128
  Prop("audioMixingMode") { (view: LibVlcPlayerView, audioMixingMode: AudioMixingMode?) in
105
- view.audioMixingMode = audioMixingMode ?? .auto
129
+ if audioMixingMode != view.audioMixingMode {
130
+ view.audioMixingMode = audioMixingMode ?? .auto
131
+ }
106
132
  }
107
133
 
108
134
  Prop("playInBackground") { (view: LibVlcPlayerView, playInBackground: Bool?) in
109
- view.playInBackground = playInBackground ?? false
135
+ if playInBackground != view.playInBackground {
136
+ view.playInBackground = playInBackground ?? false
137
+ }
110
138
  }
111
139
 
112
140
  Prop("repeat") { (view: LibVlcPlayerView, shouldRepeat: Bool?) in
113
- view.shouldRepeat = shouldRepeat ?? false
141
+ if shouldRepeat != view.shouldRepeat {
142
+ view.shouldRepeat = shouldRepeat ?? false
143
+ }
114
144
  }
115
145
 
116
146
  Prop("autoplay") { (view: LibVlcPlayerView, autoplay: Bool?) in
117
- view.autoplay = autoplay ?? true
147
+ if autoplay != view.autoplay {
148
+ view.autoplay = autoplay ?? true
149
+ }
118
150
  }
119
151
 
120
152
  OnViewDidUpdateProps { (view: LibVlcPlayerView) in
@@ -49,11 +49,11 @@ class LibVlcPlayerView: ExpoView {
49
49
  required init(appContext: AppContext? = nil) {
50
50
  super.init(appContext: appContext)
51
51
 
52
- playerView.backgroundColor = .black
53
52
  clipsToBounds = true
53
+ playerView.backgroundColor = .black
54
+ addSubview(playerView)
54
55
 
55
56
  MediaPlayerManager.shared.registerPlayerView(self)
56
- addSubview(playerView)
57
57
  }
58
58
 
59
59
  deinit {
@@ -61,12 +61,10 @@ class LibVlcPlayerView: ExpoView {
61
61
  destroyPlayer()
62
62
  }
63
63
 
64
- override func layoutSubviews() {
65
- super.layoutSubviews()
66
-
67
- setContentFit()
68
-
69
- playerView.frame = bounds
64
+ override var bounds: CGRect {
65
+ didSet {
66
+ playerView.frame = bounds
67
+ }
70
68
  }
71
69
 
72
70
  func createPlayer() {
@@ -147,11 +145,12 @@ class LibVlcPlayerView: ExpoView {
147
145
 
148
146
  func setContentFit() {
149
147
  if let player = mediaPlayer {
150
- var transform: CGAffineTransform = .identity
151
-
152
148
  let view = playerView.bounds.size
149
+
153
150
  let video = player.videoSize
154
151
 
152
+ var transform: CGAffineTransform = .identity
153
+
155
154
  if video != .zero {
156
155
  let viewAspect = view.width / view.height
157
156
  let videoAspect = video.width / video.height
@@ -262,8 +261,8 @@ class LibVlcPlayerView: ExpoView {
262
261
  player.scaleFactor = scale
263
262
  }
264
263
 
265
- if let aspectRatio = aspectRatio {
266
- aspectRatio.withCString { cString in
264
+ if let ratio = aspectRatio {
265
+ ratio.withCString { cString in
267
266
  player.videoAspectRatio = UnsafeMutablePointer(mutating: cString)
268
267
  }
269
268
  }
@@ -333,13 +332,17 @@ class LibVlcPlayerView: ExpoView {
333
332
 
334
333
  var aspectRatio: String? {
335
334
  didSet {
336
- if let aspectRatio = aspectRatio {
337
- aspectRatio.withCString { cString in
335
+ if let ratio = aspectRatio {
336
+ ratio.withCString { cString in
338
337
  mediaPlayer?.videoAspectRatio = UnsafeMutablePointer(mutating: cString)
339
338
  }
340
339
  } else {
341
340
  mediaPlayer?.videoAspectRatio = nil
342
341
  }
342
+
343
+ DispatchQueue.main.async {
344
+ self.setContentFit()
345
+ }
343
346
  }
344
347
  }
345
348
 
@@ -23,14 +23,17 @@ extension LibVlcPlayerView: VLCMediaPlayerDelegate {
23
23
  firstPlay = false
24
24
  }
25
25
 
26
+ MediaPlayerManager.shared.activateKeepAwake()
26
27
  MediaPlayerManager.shared.setAppropriateAudioSession()
27
28
  case .paused:
28
29
  onPaused()
29
30
 
31
+ MediaPlayerManager.shared.deactivateKeepAwake()
30
32
  MediaPlayerManager.shared.setAppropriateAudioSession()
31
33
  case .stopped:
32
34
  onStopped()
33
35
 
36
+ MediaPlayerManager.shared.deactivateKeepAwake()
34
37
  MediaPlayerManager.shared.setAppropriateAudioSession()
35
38
 
36
39
  firstPlay = true
@@ -49,6 +52,7 @@ extension LibVlcPlayerView: VLCMediaPlayerDelegate {
49
52
  let error = ["error": "Media player encountered an error"]
50
53
  onEncounteredError(error)
51
54
 
55
+ MediaPlayerManager.shared.deactivateKeepAwake()
52
56
  MediaPlayerManager.shared.setAppropriateAudioSession()
53
57
 
54
58
  firstPlay = true
@@ -1,6 +1,6 @@
1
1
  import ExpoModulesCore
2
2
 
3
- struct Tracks: Record {
3
+ struct Tracks: Record, Equatable {
4
4
  @Field
5
5
  var audio: Int = 0
6
6
 
@@ -9,4 +9,10 @@ struct Tracks: Record {
9
9
 
10
10
  @Field
11
11
  var subtitle: Int = 0
12
+
13
+ static func == (lhs: Tracks, rhs: Tracks) -> Bool {
14
+ lhs.audio == rhs.audio &&
15
+ lhs.video == rhs.video &&
16
+ lhs.subtitle == rhs.subtitle
17
+ }
12
18
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-libvlc-player",
3
- "version": "3.3.1",
3
+ "version": "3.4.0",
4
4
  "description": "LibVLC Player for Expo",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -101,7 +101,6 @@ const LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(
101
101
  ...slave,
102
102
  source: parseSource(slave.source)!,
103
103
  }))}
104
- aspectRatio={!props.contentFit ? props.aspectRatio : null}
105
104
  onEncounteredError={onEncounteredError}
106
105
  onDialogDisplay={onDialogDisplay}
107
106
  onTimeChanged={onTimeChanged}