mirror of
https://github.com/streamyfin/streamyfin.git
synced 2025-08-20 18:37:18 +02:00
Compare commits
3 Commits
refactor-p
...
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."
|
"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": {
|
"experiments": {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import Animated, {
|
|||||||
import Video from "react-native-video";
|
import Video from "react-native-video";
|
||||||
import { Text } from "./common/Text";
|
import { Text } from "./common/Text";
|
||||||
import { Loader } from "./Loader";
|
import { Loader } from "./Loader";
|
||||||
|
import { VLCPlayer, VlCPlayerView } from "react-native-vlc-media-player";
|
||||||
|
|
||||||
export const CurrentlyPlayingBar: React.FC = () => {
|
export const CurrentlyPlayingBar: React.FC = () => {
|
||||||
const segments = useSegments();
|
const segments = useSegments();
|
||||||
@@ -137,68 +138,80 @@ export const CurrentlyPlayingBar: React.FC = () => {
|
|||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
{currentlyPlaying?.url && (
|
{currentlyPlaying?.url && (
|
||||||
<Video
|
// <Video
|
||||||
ref={videoRef}
|
// ref={videoRef}
|
||||||
allowsExternalPlayback
|
// allowsExternalPlayback
|
||||||
style={{ width: "100%", height: "100%" }}
|
// style={{ width: "100%", height: "100%" }}
|
||||||
playWhenInactive={true}
|
// playWhenInactive={true}
|
||||||
playInBackground={true}
|
// playInBackground={true}
|
||||||
showNotificationControls={true}
|
// showNotificationControls={true}
|
||||||
ignoreSilentSwitch="ignore"
|
// ignoreSilentSwitch="ignore"
|
||||||
controls={false}
|
// controls={false}
|
||||||
pictureInPicture={true}
|
// pictureInPicture={true}
|
||||||
poster={
|
// poster={
|
||||||
backdropUrl && currentlyPlaying.item?.Type === "Audio"
|
// backdropUrl && currentlyPlaying.item?.Type === "Audio"
|
||||||
? backdropUrl
|
// ? backdropUrl
|
||||||
: undefined
|
// : undefined
|
||||||
}
|
// }
|
||||||
debug={{
|
// debug={{
|
||||||
enable: true,
|
// enable: true,
|
||||||
thread: true,
|
// thread: true,
|
||||||
}}
|
// }}
|
||||||
paused={!isPlaying}
|
// paused={!isPlaying}
|
||||||
onProgress={(e) => onProgress(e)}
|
// onProgress={(e) => onProgress(e)}
|
||||||
subtitleStyle={{
|
// subtitleStyle={{
|
||||||
fontSize: 16,
|
// 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={{
|
source={{
|
||||||
uri: currentlyPlaying.url,
|
uri: encodeURIComponent(currentlyPlaying.url),
|
||||||
isNetwork: true,
|
|
||||||
startPosition,
|
|
||||||
headers: getAuthHeaders(api),
|
|
||||||
}}
|
}}
|
||||||
onBuffer={(e) =>
|
key={"1"}
|
||||||
e.isBuffering ? console.log("Buffering...") : null
|
autoAspectRatio={true}
|
||||||
}
|
resizeMode="cover"
|
||||||
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>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|||||||
@@ -219,7 +219,6 @@ export const SettingToggles: React.FC = () => {
|
|||||||
<View
|
<View
|
||||||
className={`
|
className={`
|
||||||
flex flex-row items-center space-x-2 justify-between bg-neutral-900 p-4
|
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">
|
<View className="flex flex-col shrink">
|
||||||
|
|||||||
@@ -72,6 +72,7 @@
|
|||||||
"react-native-url-polyfill": "^2.0.0",
|
"react-native-url-polyfill": "^2.0.0",
|
||||||
"react-native-uuid": "^2.0.2",
|
"react-native-uuid": "^2.0.2",
|
||||||
"react-native-video": "^6.4.3",
|
"react-native-video": "^6.4.3",
|
||||||
|
"react-native-vlc-media-player": "^1.0.69",
|
||||||
"react-native-web": "~0.19.10",
|
"react-native-web": "~0.19.10",
|
||||||
"tailwindcss": "3.3.2",
|
"tailwindcss": "3.3.2",
|
||||||
"use-debounce": "^10.0.3",
|
"use-debounce": "^10.0.3",
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export const getStreamUrl = async ({
|
|||||||
headers: {
|
headers: {
|
||||||
Authorization: `MediaBrowser DeviceId="${api.deviceInfo.id}", Token="${api.accessToken}"`,
|
Authorization: `MediaBrowser DeviceId="${api.deviceInfo.id}", Token="${api.accessToken}"`,
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const mediaSource = response.data.MediaSources?.[0] as MediaSourceInfo;
|
const mediaSource = response.data.MediaSources?.[0] as MediaSourceInfo;
|
||||||
@@ -69,7 +69,16 @@ export const getStreamUrl = async ({
|
|||||||
if (mediaSource.SupportsDirectPlay || forceDirectPlay === true) {
|
if (mediaSource.SupportsDirectPlay || forceDirectPlay === true) {
|
||||||
if (item.MediaType === "Video") {
|
if (item.MediaType === "Video") {
|
||||||
console.log("Using direct stream for 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") {
|
} else if (item.MediaType === "Audio") {
|
||||||
console.log("Using direct stream for audio!");
|
console.log("Using direct stream for audio!");
|
||||||
const searchParams = new URLSearchParams({
|
const searchParams = new URLSearchParams({
|
||||||
@@ -87,7 +96,9 @@ export const getStreamUrl = async ({
|
|||||||
EnableRedirection: "true",
|
EnableRedirection: "true",
|
||||||
EnableRemoteMedia: "false",
|
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