From 24320541c70fae7d1441bbd990365907f25967d3 Mon Sep 17 00:00:00 2001 From: Alex Kim Date: Sat, 7 Dec 2024 04:15:16 +1100 Subject: [PATCH 1/6] Made pause video on app exit on IOS --- modules/vlc-player/ios/VlcPlayerView.swift | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/vlc-player/ios/VlcPlayerView.swift b/modules/vlc-player/ios/VlcPlayerView.swift index ce964677..59559dbb 100644 --- a/modules/vlc-player/ios/VlcPlayerView.swift +++ b/modules/vlc-player/ios/VlcPlayerView.swift @@ -15,6 +15,7 @@ class VlcPlayerView: ExpoView { private var isMediaReady: Bool = false private var externalTrack: [String: String]? private var progressTimer: DispatchSourceTimer? + private var isStopping: Bool = false // Define isStopping here // MARK: - Initialization @@ -50,8 +51,8 @@ class VlcPlayerView: ExpoView { self, selector: #selector(applicationWillResignActive), name: UIApplication.willResignActiveNotification, object: nil) NotificationCenter.default.addObserver( - self, selector: #selector(applicationWillEnterForeground), - name: UIApplication.willEnterForegroundNotification, object: nil) + self, selector: #selector(applicationDidBecomeActive), + name: UIApplication.didBecomeActiveNotification, object: nil) } private func setupProgressTimer() { @@ -259,8 +260,6 @@ class VlcPlayerView: ExpoView { print("Track not found for name: \(trackName)") } - private var isStopping: Bool = false - @objc func stop(completion: (() -> Void)? = nil) { guard !isStopping else { completion?() @@ -286,7 +285,7 @@ class VlcPlayerView: ExpoView { } } - @objc private func applicationWillEnterForeground() { + @objc private func applicationDidBecomeActive() { if !isPaused { play() } From 38445c6959199d7e171a2140c74b399927489eb9 Mon Sep 17 00:00:00 2001 From: Alex Kim Date: Sat, 7 Dec 2024 05:41:46 +1100 Subject: [PATCH 2/6] Fixed issue for IOS and android --- app/(auth)/player/direct-player.tsx | 46 +++++++++++++++++++- modules/vlc-player/ios/VlcPlayerModule.swift | 4 +- modules/vlc-player/ios/VlcPlayerView.swift | 10 ++--- 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/app/(auth)/player/direct-player.tsx b/app/(auth)/player/direct-player.tsx index e1c88490..d534809c 100644 --- a/app/(auth)/player/direct-player.tsx +++ b/app/(auth)/player/direct-player.tsx @@ -30,8 +30,20 @@ import { useQuery } from "@tanstack/react-query"; import * as Haptics from "expo-haptics"; import { useFocusEffect, useGlobalSearchParams } from "expo-router"; import { useAtomValue } from "jotai"; -import React, { useCallback, useMemo, useRef, useState } from "react"; -import { Alert, BackHandler, View } from "react-native"; +import React, { + useCallback, + useMemo, + useRef, + useState, + useEffect, +} from "react"; +import { + Alert, + BackHandler, + View, + AppState, + AppStateStatus, +} from "react-native"; import { useSharedValue } from "react-native-reanimated"; import settings from "../(tabs)/(home)/settings"; import { useSettings } from "@/utils/atoms/settings"; @@ -359,6 +371,36 @@ export default function page() { }; }, []) ); + + const [appState, setAppState] = useState(AppState.currentState); + + useEffect(() => { + const handleAppStateChange = (nextAppState: AppStateStatus) => { + if (appState.match(/inactive|background/) && nextAppState === "active") { + console.log("App has come to the foreground!"); + // Handle app coming to the foreground + } else if (nextAppState.match(/inactive|background/)) { + console.log("App has gone to the background!"); + // Handle app going to the background + if (videoRef.current && videoRef.current.pause) { + videoRef.current.pause(); + } + } + setAppState(nextAppState); + }; + + // Use AppState.addEventListener and return a cleanup function + const subscription = AppState.addEventListener( + "change", + handleAppStateChange + ); + + return () => { + // Cleanup the event listener when the component is unmounted + subscription.remove(); + }; + }, [appState]); + // Preselection of audio and subtitle tracks. if (!settings) return null; diff --git a/modules/vlc-player/ios/VlcPlayerModule.swift b/modules/vlc-player/ios/VlcPlayerModule.swift index 64d6cad5..131f4ebf 100644 --- a/modules/vlc-player/ios/VlcPlayerModule.swift +++ b/modules/vlc-player/ios/VlcPlayerModule.swift @@ -5,7 +5,9 @@ public class VlcPlayerModule: Module { Name("VlcPlayer") View(VlcPlayerView.self) { Prop("source") { (view: VlcPlayerView, source: [String: Any]) in - view.setSource(source) + if !view.hasSource { + view.setSource(source) + } } Prop("paused") { (view: VlcPlayerView, paused: Bool) in diff --git a/modules/vlc-player/ios/VlcPlayerView.swift b/modules/vlc-player/ios/VlcPlayerView.swift index 59559dbb..8feec050 100644 --- a/modules/vlc-player/ios/VlcPlayerView.swift +++ b/modules/vlc-player/ios/VlcPlayerView.swift @@ -16,6 +16,7 @@ class VlcPlayerView: ExpoView { private var externalTrack: [String: String]? private var progressTimer: DispatchSourceTimer? private var isStopping: Bool = false // Define isStopping here + var hasSource = false // MARK: - Initialization @@ -157,6 +158,7 @@ class VlcPlayerView: ExpoView { self.setSubtitleTrack(subtitleTrackIndex) self.mediaPlayer?.media = media + hasSource = true if autoplay { print("Playing...") @@ -280,15 +282,11 @@ class VlcPlayerView: ExpoView { // MARK: - Private Methods @objc private func applicationWillResignActive() { - if !isPaused { - pause() - } + } @objc private func applicationDidBecomeActive() { - if !isPaused { - play() - } + } private func performStop(completion: (() -> Void)? = nil) { From 39f86a9eb1b314737a883e147b76b5d073f5769e Mon Sep 17 00:00:00 2001 From: Alex Kim Date: Sat, 7 Dec 2024 06:01:04 +1100 Subject: [PATCH 3/6] Added android fix --- .../src/main/java/expo/modules/vlcplayer/VlcPlayerModule.kt | 4 +++- .../src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerModule.kt b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerModule.kt index 070e13a8..ea73f3d1 100644 --- a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerModule.kt +++ b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerModule.kt @@ -9,7 +9,9 @@ class VlcPlayerModule : Module() { View(VlcPlayerView::class) { Prop("source") { view: VlcPlayerView, source: Map -> - view.setSource(source) + if (!view.hasSource) { + view.setSource(source) + } } Prop("paused") { view: VlcPlayerView, paused: Boolean -> diff --git a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt index 03245207..e99fb1d1 100644 --- a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt +++ b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt @@ -32,6 +32,7 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context private var startPosition: Int? = 0 private var isMediaReady: Boolean = false private var externalTrack: Map? = null + var hasSource: Boolean = false init { setupView() @@ -87,6 +88,7 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context // Log.d("VlcPlayerView", "Debug: Subtitle track index is less than -1, not setting") // } + hasSource = true if (autoplay) { Log.d("VlcPlayerView", "Playing...") From 832a717585d0423ff137c1b0673903e685386e91 Mon Sep 17 00:00:00 2001 From: Alex Kim Date: Sat, 7 Dec 2024 06:35:25 +1100 Subject: [PATCH 4/6] Improve performance of android version --- .../expo/modules/vlcplayer/VlcPlayerView.kt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt index e99fb1d1..30d69b3c 100644 --- a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt +++ b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt @@ -1,6 +1,8 @@ package expo.modules.vlcplayer import android.content.Context +import android.os.Handler +import android.os.Looper import android.util.Log import android.view.ViewGroup import android.widget.FrameLayout @@ -34,6 +36,15 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context private var externalTrack: Map? = null var hasSource: Boolean = false + private val handler = Handler(Looper.getMainLooper()) + private val updateInterval = 1000L // 1 second + private val updateProgressRunnable = object : Runnable { + override fun run() { + updateVideoProgress() + handler.postDelayed(this, updateInterval) + } + } + init { setupView() } @@ -99,15 +110,18 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context fun play() { mediaPlayer?.play() isPaused = false + handler.post(updateProgressRunnable) // Start updating progress } fun pause() { mediaPlayer?.pause() isPaused = true + handler.removeCallbacks(updateProgressRunnable) // Stop updating progress } fun stop() { mediaPlayer?.stop() + handler.removeCallbacks(updateProgressRunnable) // Stop updating progress } fun seekTo(time: Int) { @@ -172,6 +186,7 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context println("onDetachedFromWindow") super.onDetachedFromWindow() mediaPlayer?.stop() + handler.removeCallbacks(updateProgressRunnable) // Stop updating progress media?.release() mediaPlayer?.release() @@ -189,7 +204,9 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context MediaPlayer.Event.Buffering, MediaPlayer.Event.EndReached, MediaPlayer.Event.EncounteredError -> updatePlayerState(event) - MediaPlayer.Event.TimeChanged -> updateVideoProgress() + MediaPlayer.Event.TimeChanged -> { + // Do nothing here, as we are updating progress every 1 second + } } } From ef036cb362f0762de10982cbbba9f80520d7d031 Mon Sep 17 00:00:00 2001 From: Alex Kim Date: Sat, 7 Dec 2024 18:11:41 +1100 Subject: [PATCH 5/6] Fixed for android and added some peformance changes for android --- .../main/java/expo/modules/vlcplayer/VlcPlayerModule.kt | 4 +--- .../src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt | 7 ++++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerModule.kt b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerModule.kt index ea73f3d1..070e13a8 100644 --- a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerModule.kt +++ b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerModule.kt @@ -9,9 +9,7 @@ class VlcPlayerModule : Module() { View(VlcPlayerView::class) { Prop("source") { view: VlcPlayerView, source: Map -> - if (!view.hasSource) { - view.setSource(source) - } + view.setSource(source) } Prop("paused") { view: VlcPlayerView, paused: Boolean -> diff --git a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt index 30d69b3c..0b319905 100644 --- a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt +++ b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt @@ -60,6 +60,11 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context } fun setSource(source: Map) { + if (hasSource) { + mediaPlayer?.attachViews(videoLayout, null, false, false) + play() + return + } val mediaOptions = source["mediaOptions"] as? Map ?: emptyMap() val autoplay = source["autoplay"] as? Boolean ?: false val isNetwork = source["isNetwork"] as? Boolean ?: false @@ -260,7 +265,7 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context val currentTimeMs = player.time.toInt() val durationMs = player.media?.duration?.toInt() ?: 0 - + println("isPlayer Attached: ${videoLayout.isAttachedToWindow}") if (currentTimeMs >= 0 && currentTimeMs < durationMs) { // Set subtitle URL if available if (player.isPlaying && !isMediaReady) { From 0d2b15e5af41d5025dc1ed31e6d9fe949ac89835 Mon Sep 17 00:00:00 2001 From: Alex Kim Date: Sat, 7 Dec 2024 18:17:28 +1100 Subject: [PATCH 6/6] Removed unneccessary print statement --- .../src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt index 0b319905..1770e337 100644 --- a/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt +++ b/modules/vlc-player/android/src/main/java/expo/modules/vlcplayer/VlcPlayerView.kt @@ -265,7 +265,6 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context val currentTimeMs = player.time.toInt() val durationMs = player.media?.duration?.toInt() ?: 0 - println("isPlayer Attached: ${videoLayout.isAttachedToWindow}") if (currentTimeMs >= 0 && currentTimeMs < durationMs) { // Set subtitle URL if available if (player.isPlaying && !isMediaReady) {