diff --git a/mobile/patches/expo-video+2.0.6.patch b/mobile/patches/expo-video+2.0.6.patch index 2f9338a..9acc6fb 100644 --- a/mobile/patches/expo-video+2.0.6.patch +++ b/mobile/patches/expo-video+2.0.6.patch @@ -1,3 +1,40 @@ +diff --git a/node_modules/expo-video/android/src/main/java/expo/modules/video/AudioFocusManager.kt b/node_modules/expo-video/android/src/main/java/expo/modules/video/AudioFocusManager.kt +index aa911b1..671bf05 100644 +--- a/node_modules/expo-video/android/src/main/java/expo/modules/video/AudioFocusManager.kt ++++ b/node_modules/expo-video/android/src/main/java/expo/modules/video/AudioFocusManager.kt +@@ -21,7 +21,9 @@ class AudioFocusManager(private val appContext: AppContext) : AudioManager.OnAud + } + } + +- private var players: MutableList> = mutableListOf() ++ // CopyOnWriteArrayList z tego samego powodu co listeners w VideoPlayer: register/unregister ++ // przychodza z watku JS i sprzatajacego, a forEach po liscie idzie na glownym (Goon, GOON-7A). ++ private val players = java.util.concurrent.CopyOnWriteArrayList>() + private var currentFocusRequest: AudioFocusRequest? = null + private var currentMixingMode: AudioMixingMode = AudioMixingMode.MIX_WITH_OTHERS + private val anyPlayerRequiresFocus: Boolean +@@ -89,8 +91,10 @@ class AudioFocusManager(private val appContext: AppContext) : AudioManager.OnAud + } + + fun registerPlayer(player: VideoPlayer) { +- players.find { it.get() == player } ?: run { +- players.add(WeakReference(player)) ++ synchronized(players) { ++ players.find { it.get() == player } ?: run { ++ players.add(WeakReference(player)) ++ } + } + player.addListener(this) + updateAudioFocus() +@@ -98,7 +102,7 @@ class AudioFocusManager(private val appContext: AppContext) : AudioManager.OnAud + + fun unregisterPlayer(player: VideoPlayer) { + player.removeListener(this) +- players.removeAll { it.get() == player } ++ players.removeIf { it.get() == player } + updateAudioFocus() + } + diff --git a/node_modules/expo-video/android/src/main/java/expo/modules/video/playbackService/ExpoVideoPlaybackService.kt b/node_modules/expo-video/android/src/main/java/expo/modules/video/playbackService/ExpoVideoPlaybackService.kt index cd798cf..8cb6dfb 100644 --- a/node_modules/expo-video/android/src/main/java/expo/modules/video/playbackService/ExpoVideoPlaybackService.kt @@ -34,3 +71,40 @@ index cd798cf..8cb6dfb 100644 } private fun hidePlayerNotification(player: ExoPlayer) { +diff --git a/node_modules/expo-video/android/src/main/java/expo/modules/video/player/VideoPlayer.kt b/node_modules/expo-video/android/src/main/java/expo/modules/video/player/VideoPlayer.kt +index ec7accf..dd365e3 100644 +--- a/node_modules/expo-video/android/src/main/java/expo/modules/video/player/VideoPlayer.kt ++++ b/node_modules/expo-video/android/src/main/java/expo/modules/video/player/VideoPlayer.kt +@@ -44,7 +44,11 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou + private var renderersFactory = DefaultRenderersFactory(context) + .forceEnableMediaCodecAsynchronousQueueing() + .setEnableDecoderFallback(true) +- private var listeners: MutableList> = mutableListOf() ++ // CopyOnWriteArrayList, nie ArrayList: close() (watek JS albo sprzatajacy obiekty) wypisuje ++ // stad AudioFocusManager, a glowny watek w tym samym czasie rozsyla zdarzenie po prepare() ++ // i iteruje liste -> ConcurrentModificationException (Goon 0.4.2, Sentry GOON-7A, Edge ++ // tworzy i zwalnia odtwarzacze przy kazdym przewinieciu). Iteracja idzie po migawce. ++ private val listeners = java.util.concurrent.CopyOnWriteArrayList>() + val loadControl: VideoPlayerLoadControl = VideoPlayerLoadControl.Builder().build() + val subtitles: VideoPlayerSubtitles = VideoPlayerSubtitles(this) + val trackSelector = DefaultTrackSelector(context) +@@ -320,13 +324,16 @@ class VideoPlayer(val context: Context, appContext: AppContext, source: VideoSou + } + + fun addListener(videoPlayerListener: VideoPlayerListener) { +- if (listeners.all { it.get() != videoPlayerListener }) { +- listeners.add(WeakReference(videoPlayerListener)) ++ synchronized(listeners) { ++ if (listeners.all { it.get() != videoPlayerListener }) { ++ listeners.add(WeakReference(videoPlayerListener)) ++ } + } + } + + fun removeListener(videoPlayerListener: VideoPlayerListener) { +- listeners.removeAll { it.get() == videoPlayerListener } ++ // removeIf listy (atomowe), nie kotlinowe removeAll { }, ktore usuwa po indeksach. ++ listeners.removeIf { it.get() == videoPlayerListener } + } + + private fun sendEvent(event: PlayerEvent) {