Merge pull request #257 from Alexk2309/fix/pause-video-when-exiting-ios

Made pause video on app exit and added some performance changes for android
This commit is contained in:
Fredrik Burmester
2024-12-07 09:28:08 +01:00
committed by GitHub
4 changed files with 80 additions and 16 deletions

View File

@@ -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;

View File

@@ -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
@@ -32,6 +34,16 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
private var startPosition: Int? = 0
private var isMediaReady: Boolean = false
private var externalTrack: Map<String, String>? = 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()
@@ -48,6 +60,11 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
}
fun setSource(source: Map<String, Any>) {
if (hasSource) {
mediaPlayer?.attachViews(videoLayout, null, false, false)
play()
return
}
val mediaOptions = source["mediaOptions"] as? Map<String, Any> ?: emptyMap()
val autoplay = source["autoplay"] as? Boolean ?: false
val isNetwork = source["isNetwork"] as? Boolean ?: false
@@ -87,6 +104,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...")
@@ -97,15 +115,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) {
@@ -170,6 +191,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()
@@ -187,7 +209,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
}
}
}
@@ -241,7 +265,6 @@ class VlcPlayerView(context: Context, appContext: AppContext) : ExpoView(context
val currentTimeMs = player.time.toInt()
val durationMs = player.media?.duration?.toInt() ?: 0
if (currentTimeMs >= 0 && currentTimeMs < durationMs) {
// Set subtitle URL if available
if (player.isPlaying && !isMediaReady) {

View File

@@ -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

View File

@@ -15,6 +15,8 @@ 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
var hasSource = false
// MARK: - Initialization
@@ -50,8 +52,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() {
@@ -156,6 +158,7 @@ class VlcPlayerView: ExpoView {
self.setSubtitleTrack(subtitleTrackIndex)
self.mediaPlayer?.media = media
hasSource = true
if autoplay {
print("Playing...")
@@ -259,8 +262,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?()
@@ -281,15 +282,11 @@ class VlcPlayerView: ExpoView {
// MARK: - Private Methods
@objc private func applicationWillResignActive() {
if !isPaused {
pause()
}
}
@objc private func applicationWillEnterForeground() {
if !isPaused {
play()
}
@objc private func applicationDidBecomeActive() {
}
private func performStop(completion: (() -> Void)? = nil) {