mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
Compare commits
3 Commits
renovate/b
...
feat/vlc-p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a29e6a3815 | ||
|
|
92b847a447 | ||
|
|
e7fcf806b3 |
11
app.json
11
app.json
@@ -96,6 +96,17 @@
|
||||
{
|
||||
"motionPermission": "Allow Streamyfin to access your device motion for landscape video watching."
|
||||
}
|
||||
],
|
||||
[
|
||||
"react-native-vlc-media-player",
|
||||
{
|
||||
"ios": {
|
||||
"includeVLCKit": false // should be true if react-native version < 0.61
|
||||
},
|
||||
"android": {
|
||||
"legacyJetifier": false // should be true if react-native version < 0.71
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"experiments": {
|
||||
|
||||
@@ -17,6 +17,7 @@ import Animated, {
|
||||
import Video from "react-native-video";
|
||||
import { Text } from "./common/Text";
|
||||
import { Loader } from "./Loader";
|
||||
import { VLCPlayer, VlCPlayerView } from "react-native-vlc-media-player";
|
||||
|
||||
export const CurrentlyPlayingBar: React.FC = () => {
|
||||
const segments = useSegments();
|
||||
@@ -137,68 +138,80 @@ export const CurrentlyPlayingBar: React.FC = () => {
|
||||
`}
|
||||
>
|
||||
{currentlyPlaying?.url && (
|
||||
<Video
|
||||
ref={videoRef}
|
||||
allowsExternalPlayback
|
||||
style={{ width: "100%", height: "100%" }}
|
||||
playWhenInactive={true}
|
||||
playInBackground={true}
|
||||
showNotificationControls={true}
|
||||
ignoreSilentSwitch="ignore"
|
||||
controls={false}
|
||||
pictureInPicture={true}
|
||||
poster={
|
||||
backdropUrl && currentlyPlaying.item?.Type === "Audio"
|
||||
? backdropUrl
|
||||
: undefined
|
||||
}
|
||||
debug={{
|
||||
enable: true,
|
||||
thread: true,
|
||||
}}
|
||||
paused={!isPlaying}
|
||||
onProgress={(e) => onProgress(e)}
|
||||
subtitleStyle={{
|
||||
fontSize: 16,
|
||||
// <Video
|
||||
// ref={videoRef}
|
||||
// allowsExternalPlayback
|
||||
// style={{ width: "100%", height: "100%" }}
|
||||
// playWhenInactive={true}
|
||||
// playInBackground={true}
|
||||
// showNotificationControls={true}
|
||||
// ignoreSilentSwitch="ignore"
|
||||
// controls={false}
|
||||
// pictureInPicture={true}
|
||||
// poster={
|
||||
// backdropUrl && currentlyPlaying.item?.Type === "Audio"
|
||||
// ? backdropUrl
|
||||
// : undefined
|
||||
// }
|
||||
// debug={{
|
||||
// enable: true,
|
||||
// thread: true,
|
||||
// }}
|
||||
// paused={!isPlaying}
|
||||
// onProgress={(e) => onProgress(e)}
|
||||
// subtitleStyle={{
|
||||
// fontSize: 16,
|
||||
// }}
|
||||
// source={{
|
||||
// uri: currentlyPlaying.url,
|
||||
// isNetwork: true,
|
||||
// startPosition,
|
||||
// headers: getAuthHeaders(api),
|
||||
// }}
|
||||
// onBuffer={(e) =>
|
||||
// e.isBuffering ? console.log("Buffering...") : null
|
||||
// }
|
||||
// onFullscreenPlayerDidDismiss={() => {}}
|
||||
// onFullscreenPlayerDidPresent={() => {}}
|
||||
// onPlaybackStateChanged={(e) => {
|
||||
// if (e.isPlaying) {
|
||||
// setIsPlaying(true);
|
||||
// } else if (e.isSeeking) {
|
||||
// return;
|
||||
// } else {
|
||||
// setIsPlaying(false);
|
||||
// }
|
||||
// }}
|
||||
// progressUpdateInterval={2000}
|
||||
// onError={(e) => {
|
||||
// console.log(e);
|
||||
// writeToLog(
|
||||
// "ERROR",
|
||||
// "Video playback error: " + JSON.stringify(e)
|
||||
// );
|
||||
// Alert.alert("Error", "Cannot play this video file.");
|
||||
// setIsPlaying(false);
|
||||
// // setCurrentlyPlaying(null);
|
||||
// }}
|
||||
// renderLoader={
|
||||
// currentlyPlaying.item?.Type !== "Audio" && (
|
||||
// <View className="flex flex-col items-center justify-center h-full">
|
||||
// <Loader />
|
||||
// </View>
|
||||
// )
|
||||
// }
|
||||
// />
|
||||
<VlCPlayerView
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
}}
|
||||
source={{
|
||||
uri: currentlyPlaying.url,
|
||||
isNetwork: true,
|
||||
startPosition,
|
||||
headers: getAuthHeaders(api),
|
||||
uri: encodeURIComponent(currentlyPlaying.url),
|
||||
}}
|
||||
onBuffer={(e) =>
|
||||
e.isBuffering ? console.log("Buffering...") : null
|
||||
}
|
||||
onFullscreenPlayerDidDismiss={() => {}}
|
||||
onFullscreenPlayerDidPresent={() => {}}
|
||||
onPlaybackStateChanged={(e) => {
|
||||
if (e.isPlaying) {
|
||||
setIsPlaying(true);
|
||||
} else if (e.isSeeking) {
|
||||
return;
|
||||
} else {
|
||||
setIsPlaying(false);
|
||||
}
|
||||
}}
|
||||
progressUpdateInterval={2000}
|
||||
onError={(e) => {
|
||||
console.log(e);
|
||||
writeToLog(
|
||||
"ERROR",
|
||||
"Video playback error: " + JSON.stringify(e)
|
||||
);
|
||||
Alert.alert("Error", "Cannot play this video file.");
|
||||
setIsPlaying(false);
|
||||
// setCurrentlyPlaying(null);
|
||||
}}
|
||||
renderLoader={
|
||||
currentlyPlaying.item?.Type !== "Audio" && (
|
||||
<View className="flex flex-col items-center justify-center h-full">
|
||||
<Loader />
|
||||
</View>
|
||||
)
|
||||
}
|
||||
key={"1"}
|
||||
autoAspectRatio={true}
|
||||
resizeMode="cover"
|
||||
/>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -219,7 +219,6 @@ export const SettingToggles: React.FC = () => {
|
||||
<View
|
||||
className={`
|
||||
flex flex-row items-center space-x-2 justify-between bg-neutral-900 p-4
|
||||
${settings?.forceDirectPlay ? "opacity-50 select-none" : ""}
|
||||
`}
|
||||
>
|
||||
<View className="flex flex-col shrink">
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
"react-native-url-polyfill": "^2.0.0",
|
||||
"react-native-uuid": "^2.0.2",
|
||||
"react-native-video": "^6.4.3",
|
||||
"react-native-vlc-media-player": "^1.0.69",
|
||||
"react-native-web": "~0.19.10",
|
||||
"tailwindcss": "3.3.2",
|
||||
"use-debounce": "^10.0.3",
|
||||
|
||||
@@ -53,7 +53,7 @@ export const getStreamUrl = async ({
|
||||
headers: {
|
||||
Authorization: `MediaBrowser DeviceId="${api.deviceInfo.id}", Token="${api.accessToken}"`,
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
const mediaSource = response.data.MediaSources?.[0] as MediaSourceInfo;
|
||||
@@ -69,7 +69,16 @@ export const getStreamUrl = async ({
|
||||
if (mediaSource.SupportsDirectPlay || forceDirectPlay === true) {
|
||||
if (item.MediaType === "Video") {
|
||||
console.log("Using direct stream for video!");
|
||||
return `${api.basePath}/Videos/${itemId}/stream.mp4?playSessionId=${sessionData.PlaySessionId}&mediaSourceId=${itemId}&static=true`;
|
||||
|
||||
const params = new URLSearchParams({
|
||||
mediaSourceId: itemId,
|
||||
Static: "true",
|
||||
deviceId: api.deviceInfo.id,
|
||||
api_key: api.accessToken,
|
||||
Tag: item.MediaSources?.[0].ETag || "",
|
||||
});
|
||||
|
||||
return `${api.basePath}/Videos/${itemId}/stream.mp4?${params.toString()}`;
|
||||
} else if (item.MediaType === "Audio") {
|
||||
console.log("Using direct stream for audio!");
|
||||
const searchParams = new URLSearchParams({
|
||||
@@ -87,7 +96,9 @@ export const getStreamUrl = async ({
|
||||
EnableRedirection: "true",
|
||||
EnableRemoteMedia: "false",
|
||||
});
|
||||
return `${api.basePath}/Audio/${itemId}/universal?${searchParams.toString()}`;
|
||||
return `${
|
||||
api.basePath
|
||||
}/Audio/${itemId}/universal?${searchParams.toString()}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user