mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-03-18 23:36:22 +00:00
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:
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user