expo-libvlc-player 4.0.3 → 4.0.5

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.
@@ -122,7 +122,7 @@ class LibVlcPlayerModule : Module() {
122
122
  }
123
123
 
124
124
  OnViewDidUpdateProps { view: LibVlcPlayerView ->
125
- view.createPlayer()
125
+ view.initPlayer()
126
126
  }
127
127
 
128
128
  OnViewDestroys { view: LibVlcPlayerView ->
@@ -50,13 +50,12 @@ class LibVlcPlayerView(
50
50
 
51
51
  var libVLC: LibVLC? = null
52
52
  var mediaPlayer: MediaPlayer? = null
53
- private var media: Media? = null
53
+ var media: Media? = null
54
54
  var vlcDialog: VLCDialog? = null
55
55
 
56
56
  var mediaLength: Long? = null
57
-
58
- private var shouldCreate: Boolean = true
59
- var firstPlay: Boolean = false
57
+ var firstPlay: Boolean = true
58
+ private var shouldInit: Boolean = true
60
59
 
61
60
  val onBuffering by EventDispatcher<Unit>()
62
61
  val onPlaying by EventDispatcher<Unit>()
@@ -104,18 +103,21 @@ class LibVlcPlayerView(
104
103
 
105
104
  fun getTextureView(): TextureView? = playerView.findViewById(org.videolan.R.id.texture_video)
106
105
 
107
- fun createPlayer() {
108
- if (!shouldCreate) {
109
- return
110
- }
111
-
112
- destroyPlayer()
106
+ fun initPlayer() {
107
+ if (shouldInit) {
108
+ destroyPlayer()
113
109
 
114
- val source = source ?: return
110
+ if (source != null) {
111
+ createPlayer()
112
+ }
113
+ }
114
+ }
115
115
 
116
+ fun createPlayer() {
116
117
  libVLC = LibVLC(context, options)
117
118
  setDialogCallbacks(libVLC!!)
118
- mediaPlayer = MediaPlayer(libVLC)
119
+
120
+ mediaPlayer = MediaPlayer(libVLC!!)
119
121
  setPlayerListener(mediaPlayer!!)
120
122
 
121
123
  try {
@@ -125,16 +127,16 @@ class LibVlcPlayerView(
125
127
  return
126
128
  }
127
129
 
128
- media = Media(libVLC, Uri.parse(source))
129
- mediaPlayer!!.setMedia(media)
130
+ media = Media(libVLC!!, Uri.parse(source!!))
131
+ mediaPlayer!!.setMedia(media!!)
130
132
  media!!.release()
131
133
 
132
134
  if (autoplay) {
133
135
  mediaPlayer!!.play()
134
136
  }
135
137
 
136
- shouldCreate = false
137
138
  firstPlay = true
139
+ shouldInit = false
138
140
  }
139
141
 
140
142
  fun attachPlayer() {
@@ -164,7 +166,6 @@ class LibVlcPlayerView(
164
166
  mediaPlayer?.release()
165
167
  mediaPlayer = null
166
168
  media = null
167
- vlcDialog = null
168
169
  removeAllViews()
169
170
  }
170
171
 
@@ -371,13 +372,13 @@ class LibVlcPlayerView(
371
372
  var source: String? = null
372
373
  set(value) {
373
374
  field = value
374
- shouldCreate = true
375
+ shouldInit = true
375
376
  }
376
377
 
377
378
  var options: MutableList<String> = mutableListOf()
378
379
  set(value) {
379
380
  field = value
380
- shouldCreate = true
381
+ shouldInit = true
381
382
  }
382
383
 
383
384
  var tracks: Tracks? = null
@@ -36,6 +36,66 @@ class AudioFocusManager(
36
36
 
37
37
  var oldVolume: Int = MediaPlayerConstants.MAX_PLAYER_VOLUME
38
38
 
39
+ override fun onAudioFocusChange(focusChange: Int) {
40
+ when (focusChange) {
41
+ AudioManager.AUDIOFOCUS_LOSS -> {
42
+ appContext.mainQueue.launch {
43
+ MediaPlayerManager.playerViews.forEach { view ->
44
+ pausePlayerIfUnmuted(view.mediaPlayer)
45
+ }
46
+
47
+ currentFocusRequest = null
48
+ }
49
+ }
50
+
51
+ AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
52
+ val audioMixingMode = findAudioMixingMode()
53
+
54
+ if (audioMixingMode == AudioMixingMode.MIX_WITH_OTHERS) {
55
+ return
56
+ }
57
+
58
+ appContext.mainQueue.launch {
59
+ MediaPlayerManager.playerViews.forEach { view ->
60
+ pausePlayerIfUnmuted(view.mediaPlayer)
61
+ }
62
+
63
+ currentFocusRequest = null
64
+ }
65
+ }
66
+
67
+ AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
68
+ val audioMixingMode = findAudioMixingMode()
69
+
70
+ appContext.mainQueue.launch {
71
+ MediaPlayerManager.playerViews.forEach { view ->
72
+ if (audioMixingMode == AudioMixingMode.DO_NOT_MIX) {
73
+ pausePlayerIfUnmuted(view.mediaPlayer)
74
+ } else {
75
+ duckPlayer(view.mediaPlayer)
76
+ }
77
+ }
78
+ }
79
+ }
80
+
81
+ AudioManager.AUDIOFOCUS_GAIN -> {
82
+ appContext.mainQueue.launch {
83
+ MediaPlayerManager.playerViews.forEach { view ->
84
+ unduckPlayer(view.mediaPlayer)
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ fun updateAudioFocus() {
92
+ if (anyPlayerRequiresFocus || findAudioMixingMode() != currentMixingMode) {
93
+ requestAudioFocus()
94
+ } else {
95
+ abandonAudioFocus()
96
+ }
97
+ }
98
+
39
99
  private fun playerRequiresFocus(player: MediaPlayer?): Boolean {
40
100
  if (player != null) {
41
101
  return player.isPlaying() && player.getVolume() > MediaPlayerConstants.MIN_PLAYER_VOLUME
@@ -118,14 +178,6 @@ class AudioFocusManager(
118
178
  currentFocusRequest = null
119
179
  }
120
180
 
121
- fun updateAudioFocus() {
122
- if (anyPlayerRequiresFocus || findAudioMixingMode() != currentMixingMode) {
123
- requestAudioFocus()
124
- } else {
125
- abandonAudioFocus()
126
- }
127
- }
128
-
129
181
  private fun pausePlayerIfUnmuted(player: MediaPlayer?) {
130
182
  player?.let { mediaPlayer ->
131
183
  if (mediaPlayer.getVolume() > MediaPlayerConstants.MIN_PLAYER_VOLUME) {
@@ -149,56 +201,4 @@ class AudioFocusManager(
149
201
  }
150
202
  }
151
203
  }
152
-
153
- override fun onAudioFocusChange(focusChange: Int) {
154
- when (focusChange) {
155
- AudioManager.AUDIOFOCUS_LOSS -> {
156
- appContext.mainQueue.launch {
157
- MediaPlayerManager.playerViews.forEach { view ->
158
- pausePlayerIfUnmuted(view.mediaPlayer)
159
- }
160
-
161
- currentFocusRequest = null
162
- }
163
- }
164
-
165
- AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
166
- val audioMixingMode = findAudioMixingMode()
167
-
168
- if (audioMixingMode == AudioMixingMode.MIX_WITH_OTHERS) {
169
- return
170
- }
171
-
172
- appContext.mainQueue.launch {
173
- MediaPlayerManager.playerViews.forEach { view ->
174
- pausePlayerIfUnmuted(view.mediaPlayer)
175
- }
176
-
177
- currentFocusRequest = null
178
- }
179
- }
180
-
181
- AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK -> {
182
- val audioMixingMode = findAudioMixingMode()
183
-
184
- appContext.mainQueue.launch {
185
- MediaPlayerManager.playerViews.forEach { view ->
186
- if (audioMixingMode == AudioMixingMode.DO_NOT_MIX) {
187
- pausePlayerIfUnmuted(view.mediaPlayer)
188
- } else {
189
- duckPlayer(view.mediaPlayer)
190
- }
191
- }
192
- }
193
- }
194
-
195
- AudioManager.AUDIOFOCUS_GAIN -> {
196
- appContext.mainQueue.launch {
197
- MediaPlayerManager.playerViews.forEach { view ->
198
- unduckPlayer(view.mediaPlayer)
199
- }
200
- }
201
- }
202
- }
203
- }
204
204
  }
@@ -7,9 +7,9 @@ import { convertNativeEvent } from "./utils/events";
7
7
  const NativeView = requireNativeView("ExpoLibVlcPlayer");
8
8
  const RENDERING_CHILDREN_WARNING = "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.";
9
9
  let loggedRenderingChildrenWarning = false;
10
- const DEFAULT_ASPECT_RATIO = 16 / 9;
10
+ const FALLBACK_RATIO = 16 / 9;
11
11
  const LibVlcPlayerView = forwardRef((props, ref) => {
12
- const fallbackRatio = useRef(DEFAULT_ASPECT_RATIO);
12
+ const defaultRatio = useRef(FALLBACK_RATIO);
13
13
  if (props.children && !loggedRenderingChildrenWarning) {
14
14
  console.warn(RENDERING_CHILDREN_WARNING);
15
15
  loggedRenderingChildrenWarning = true;
@@ -58,13 +58,14 @@ const LibVlcPlayerView = forwardRef((props, ref) => {
58
58
  };
59
59
  const onFirstPlay = (event) => {
60
60
  const nativeEvent = convertNativeEvent(event);
61
+ const mediaRatio = nativeEvent.width / nativeEvent.height;
61
62
  if (props.onFirstPlay) {
62
63
  props.onFirstPlay(nativeEvent);
63
64
  }
64
- fallbackRatio.current =
65
- nativeEvent.width / nativeEvent.height || DEFAULT_ASPECT_RATIO;
65
+ defaultRatio.current = mediaRatio || FALLBACK_RATIO;
66
66
  };
67
- const aspectRatio = props.aspectRatio === "auto" ? fallbackRatio.current : props.aspectRatio;
67
+ const propRatio = props.aspectRatio;
68
+ const aspectRatio = propRatio === "auto" ? defaultRatio.current : propRatio;
68
69
  const nativeRatio = convertAspectRatio(aspectRatio);
69
70
  return (<View style={{ aspectRatio: nativeRatio }}>
70
71
  <NativeView {...props} ref={ref} style={[props.style, { height: "100%" }]} source={parseSource(props.source)} slaves={props.slaves?.map((slave) => ({
@@ -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, useRef, 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 type VideoAspectRatio,\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\nconst RENDERING_CHILDREN_WARNING =\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\nlet loggedRenderingChildrenWarning: boolean = false;\n\nconst DEFAULT_ASPECT_RATIO = 16 / 9;\n\nconst LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(\n (props, ref) => {\n const fallbackRatio = useRef<VideoAspectRatio>(DEFAULT_ASPECT_RATIO);\n\n if (props.children && !loggedRenderingChildrenWarning) {\n console.warn(RENDERING_CHILDREN_WARNING);\n loggedRenderingChildrenWarning = true;\n }\n\n const onEncounteredError = (event: NativeEvent<Error>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onEncounteredError) {\n props.onEncounteredError(nativeEvent);\n }\n };\n\n const onDialogDisplay = (event: NativeEvent<Dialog>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onDialogDisplay) {\n props.onDialogDisplay(nativeEvent);\n }\n };\n\n const onTimeChanged = (event: NativeEvent<Time>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onTimeChanged) {\n props.onTimeChanged(nativeEvent);\n }\n };\n\n const onPositionChanged = (event: NativeEvent<Position>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onPositionChanged) {\n props.onPositionChanged(nativeEvent);\n }\n };\n\n const onESAdded = (event: NativeEvent<MediaTracks>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onESAdded) {\n props.onESAdded(nativeEvent);\n }\n };\n\n const onRecordChanged = (event: NativeEvent<Recording>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onRecordChanged) {\n props.onRecordChanged(nativeEvent);\n }\n };\n\n const onSnapshotTaken = (event: NativeEvent<Snapshot>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onSnapshotTaken) {\n props.onSnapshotTaken(nativeEvent);\n }\n };\n\n const onFirstPlay = (event: NativeEvent<MediaInfo>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onFirstPlay) {\n props.onFirstPlay(nativeEvent);\n }\n\n fallbackRatio.current =\n nativeEvent.width / nativeEvent.height || DEFAULT_ASPECT_RATIO;\n };\n\n const aspectRatio =\n props.aspectRatio === \"auto\" ? fallbackRatio.current : props.aspectRatio;\n const nativeRatio = convertAspectRatio(aspectRatio);\n\n return (\n <View style={{ aspectRatio: nativeRatio }}>\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"]}
1
+ {"version":3,"file":"LibVlcPlayerView.js","sourceRoot":"","sources":["../src/LibVlcPlayerView.tsx"],"names":[],"mappings":"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","sourcesContent":["import { requireNativeView } from \"expo\";\nimport { forwardRef, useRef, 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 type VideoAspectRatio,\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\nconst RENDERING_CHILDREN_WARNING =\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\nlet loggedRenderingChildrenWarning: boolean = false;\n\nconst FALLBACK_RATIO = 16 / 9;\n\nconst LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(\n (props, ref) => {\n const defaultRatio = useRef<VideoAspectRatio>(FALLBACK_RATIO);\n\n if (props.children && !loggedRenderingChildrenWarning) {\n console.warn(RENDERING_CHILDREN_WARNING);\n loggedRenderingChildrenWarning = true;\n }\n\n const onEncounteredError = (event: NativeEvent<Error>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onEncounteredError) {\n props.onEncounteredError(nativeEvent);\n }\n };\n\n const onDialogDisplay = (event: NativeEvent<Dialog>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onDialogDisplay) {\n props.onDialogDisplay(nativeEvent);\n }\n };\n\n const onTimeChanged = (event: NativeEvent<Time>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onTimeChanged) {\n props.onTimeChanged(nativeEvent);\n }\n };\n\n const onPositionChanged = (event: NativeEvent<Position>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onPositionChanged) {\n props.onPositionChanged(nativeEvent);\n }\n };\n\n const onESAdded = (event: NativeEvent<MediaTracks>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onESAdded) {\n props.onESAdded(nativeEvent);\n }\n };\n\n const onRecordChanged = (event: NativeEvent<Recording>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onRecordChanged) {\n props.onRecordChanged(nativeEvent);\n }\n };\n\n const onSnapshotTaken = (event: NativeEvent<Snapshot>) => {\n const nativeEvent = convertNativeEvent(event);\n\n if (props.onSnapshotTaken) {\n props.onSnapshotTaken(nativeEvent);\n }\n };\n\n const onFirstPlay = (event: NativeEvent<MediaInfo>) => {\n const nativeEvent = convertNativeEvent(event);\n const mediaRatio = nativeEvent.width / nativeEvent.height;\n\n if (props.onFirstPlay) {\n props.onFirstPlay(nativeEvent);\n }\n\n defaultRatio.current = mediaRatio || FALLBACK_RATIO;\n };\n\n const propRatio = props.aspectRatio;\n const aspectRatio = propRatio === \"auto\" ? defaultRatio.current : propRatio;\n const nativeRatio = convertAspectRatio(aspectRatio);\n\n return (\n <View style={{ aspectRatio: nativeRatio }}>\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"]}
@@ -128,7 +128,7 @@ public class LibVlcPlayerModule: Module {
128
128
  }
129
129
 
130
130
  OnViewDidUpdateProps { (view: LibVlcPlayerView) in
131
- view.createPlayer()
131
+ view.initPlayer()
132
132
  }
133
133
 
134
134
  AsyncFunction("play") { (view: LibVlcPlayerView) in
@@ -16,10 +16,9 @@ class LibVlcPlayerView: ExpoView {
16
16
  var vlcDialogRef: NSValue?
17
17
 
18
18
  var mediaLength: Int32?
19
- private var oldVolume: Int = MediaPlayerConstants.maxPlayerVolume
20
-
21
- private var shouldCreate: Bool = true
22
- var firstPlay: Bool = false
19
+ var oldVolume: Int = MediaPlayerConstants.maxPlayerVolume
20
+ var firstPlay: Bool = true
21
+ private var shouldInit: Bool = true
23
22
 
24
23
  let onBuffering = EventDispatcher()
25
24
  let onPlaying = EventDispatcher()
@@ -60,15 +59,17 @@ class LibVlcPlayerView: ExpoView {
60
59
  }
61
60
  }
62
61
 
63
- func createPlayer() {
64
- if !shouldCreate {
65
- return
66
- }
67
-
68
- destroyPlayer()
62
+ func initPlayer() {
63
+ if shouldInit {
64
+ destroyPlayer()
69
65
 
70
- guard let source else { return }
66
+ if source != nil {
67
+ createPlayer()
68
+ }
69
+ }
70
+ }
71
71
 
72
+ func createPlayer() {
72
73
  mediaPlayer = VLCMediaPlayer(options: options)
73
74
  mediaPlayer!.drawable = playerView
74
75
  mediaPlayer!.delegate = self
@@ -77,7 +78,7 @@ class LibVlcPlayerView: ExpoView {
77
78
  vlcDialog = VLCDialogProvider(library: library, customUI: dialogCustomUI)
78
79
  vlcDialog!.customRenderer = self
79
80
 
80
- guard let url = URL(string: source) else {
81
+ guard let url = URL(string: source!) else {
81
82
  onEncounteredError(["error": "Invalid source, media could not be set"])
82
83
  return
83
84
  }
@@ -88,8 +89,8 @@ class LibVlcPlayerView: ExpoView {
88
89
  mediaPlayer!.play()
89
90
  }
90
91
 
91
- shouldCreate = false
92
92
  firstPlay = true
93
+ shouldInit = false
93
94
  }
94
95
 
95
96
  func destroyPlayer() {
@@ -99,7 +100,6 @@ class LibVlcPlayerView: ExpoView {
99
100
  mediaPlayer = nil
100
101
  vlcDialog?.customRenderer = nil
101
102
  vlcDialog = nil
102
- vlcDialogRef = nil
103
103
  }
104
104
 
105
105
  func setPlayerTracks() {
@@ -278,13 +278,13 @@ class LibVlcPlayerView: ExpoView {
278
278
 
279
279
  var source: String? {
280
280
  didSet {
281
- shouldCreate = true
281
+ shouldInit = true
282
282
  }
283
283
  }
284
284
 
285
285
  var options: [String] = .init() {
286
286
  didSet {
287
- shouldCreate = true
287
+ shouldInit = true
288
288
  }
289
289
  }
290
290
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-libvlc-player",
3
- "version": "4.0.3",
3
+ "version": "4.0.5",
4
4
  "description": "LibVLC Player for Expo",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -29,11 +29,11 @@ const RENDERING_CHILDREN_WARNING =
29
29
 
30
30
  let loggedRenderingChildrenWarning: boolean = false;
31
31
 
32
- const DEFAULT_ASPECT_RATIO = 16 / 9;
32
+ const FALLBACK_RATIO = 16 / 9;
33
33
 
34
34
  const LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(
35
35
  (props, ref) => {
36
- const fallbackRatio = useRef<VideoAspectRatio>(DEFAULT_ASPECT_RATIO);
36
+ const defaultRatio = useRef<VideoAspectRatio>(FALLBACK_RATIO);
37
37
 
38
38
  if (props.children && !loggedRenderingChildrenWarning) {
39
39
  console.warn(RENDERING_CHILDREN_WARNING);
@@ -98,17 +98,17 @@ const LibVlcPlayerView = forwardRef<LibVlcPlayerViewRef, LibVlcPlayerViewProps>(
98
98
 
99
99
  const onFirstPlay = (event: NativeEvent<MediaInfo>) => {
100
100
  const nativeEvent = convertNativeEvent(event);
101
+ const mediaRatio = nativeEvent.width / nativeEvent.height;
101
102
 
102
103
  if (props.onFirstPlay) {
103
104
  props.onFirstPlay(nativeEvent);
104
105
  }
105
106
 
106
- fallbackRatio.current =
107
- nativeEvent.width / nativeEvent.height || DEFAULT_ASPECT_RATIO;
107
+ defaultRatio.current = mediaRatio || FALLBACK_RATIO;
108
108
  };
109
109
 
110
- const aspectRatio =
111
- props.aspectRatio === "auto" ? fallbackRatio.current : props.aspectRatio;
110
+ const propRatio = props.aspectRatio;
111
+ const aspectRatio = propRatio === "auto" ? defaultRatio.current : propRatio;
112
112
  const nativeRatio = convertAspectRatio(aspectRatio);
113
113
 
114
114
  return (