fix: always use native device profile

This commit is contained in:
Fredrik Burmester
2024-10-15 13:08:03 +02:00
parent 9e5aa16a7d
commit ac9bcbcb9f
6 changed files with 100 additions and 333 deletions

View File

@@ -98,18 +98,10 @@ export const DownloadItem: React.FC<DownloadProps> = ({ item, ...props }) => {
); );
} }
let deviceProfile: any = iosFmp4;
if (settings?.deviceProfile === "Native") {
deviceProfile = native;
} else if (settings?.deviceProfile === "Old") {
deviceProfile = old;
}
const response = await api.axiosInstance.post( const response = await api.axiosInstance.post(
`${api.basePath}/Items/${item.Id}/PlaybackInfo`, `${api.basePath}/Items/${item.Id}/PlaybackInfo`,
{ {
DeviceProfile: deviceProfile, DeviceProfile: native,
UserId: user.Id, UserId: user.Id,
MaxStreamingBitrate: maxBitrate.value, MaxStreamingBitrate: maxBitrate.value,
StartTimeTicks: 0, StartTimeTicks: 0,

View File

@@ -350,63 +350,6 @@ export const SettingToggles: React.FC<Props> = ({ ...props }) => {
/> />
</View> </View>
<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">
<Text className="font-semibold">Device profile</Text>
<Text className="text-xs opacity-50">
A profile used for deciding what audio and video codecs the
device supports.
</Text>
</View>
<DropdownMenu.Root>
<DropdownMenu.Trigger>
<TouchableOpacity className="bg-neutral-800 rounded-lg border-neutral-900 border px-3 py-2 flex flex-row items-center justify-between">
<Text>{settings.deviceProfile}</Text>
</TouchableOpacity>
</DropdownMenu.Trigger>
<DropdownMenu.Content
loop={true}
side="bottom"
align="start"
alignOffset={0}
avoidCollisions={true}
collisionPadding={8}
sideOffset={8}
>
<DropdownMenu.Label>Profiles</DropdownMenu.Label>
<DropdownMenu.Item
key="1"
onSelect={() => {
updateSettings({ deviceProfile: "Expo" });
}}
>
<DropdownMenu.ItemTitle>Expo</DropdownMenu.ItemTitle>
</DropdownMenu.Item>
<DropdownMenu.Item
key="2"
onSelect={() => {
updateSettings({ deviceProfile: "Native" });
}}
>
<DropdownMenu.ItemTitle>Native</DropdownMenu.ItemTitle>
</DropdownMenu.Item>
<DropdownMenu.Item
key="3"
onSelect={() => {
updateSettings({ deviceProfile: "Old" });
}}
>
<DropdownMenu.ItemTitle>Old</DropdownMenu.ItemTitle>
</DropdownMenu.Item>
</DropdownMenu.Content>
</DropdownMenu.Root>
</View>
<View className="flex flex-col"> <View className="flex flex-col">
<View <View
className={` className={`

View File

@@ -94,14 +94,10 @@ export const PlaySettingsProvider: React.FC<{ children: React.ReactNode }> = ({
return null; return null;
} }
let deviceProfile: any = iosFmp4;
if (settings?.deviceProfile === "Native") deviceProfile = native;
if (settings?.deviceProfile === "Old") deviceProfile = old;
try { try {
const data = await getStreamUrl({ const data = await getStreamUrl({
api, api,
deviceProfile, deviceProfile: native,
item: newSettings?.item, item: newSettings?.item,
mediaSourceId: newSettings?.mediaSource?.Id, mediaSourceId: newSettings?.mediaSource?.Id,
startTimeTicks: 0, startTimeTicks: 0,
@@ -127,16 +123,12 @@ export const PlaySettingsProvider: React.FC<{ children: React.ReactNode }> = ({
); );
useEffect(() => { useEffect(() => {
let deviceProfile: any = ios;
if (settings?.deviceProfile === "Native") deviceProfile = native;
if (settings?.deviceProfile === "Old") deviceProfile = old;
const postCaps = async () => { const postCaps = async () => {
if (!api) return; if (!api) return;
await getSessionApi(api).postFullCapabilities({ await getSessionApi(api).postFullCapabilities({
clientCapabilitiesDto: { clientCapabilitiesDto: {
AppStoreUrl: "https://apps.apple.com/us/app/streamyfin/id6593660679", AppStoreUrl: "https://apps.apple.com/us/app/streamyfin/id6593660679",
DeviceProfile: deviceProfile, DeviceProfile: native as any,
IconUrl: IconUrl:
"https://raw.githubusercontent.com/retardgerman/streamyfinweb/refs/heads/redesign/public/assets/images/icon_new_withoutBackground.png", "https://raw.githubusercontent.com/retardgerman/streamyfinweb/refs/heads/redesign/public/assets/images/icon_new_withoutBackground.png",
PlayableMediaTypes: ["Audio", "Video"], PlayableMediaTypes: ["Audio", "Video"],

View File

@@ -16,7 +16,7 @@ export const getStreamUrl = async ({
startTimeTicks = 0, startTimeTicks = 0,
maxStreamingBitrate, maxStreamingBitrate,
sessionData, sessionData,
deviceProfile = iosFmp4, deviceProfile = native,
audioStreamIndex = 0, audioStreamIndex = 0,
subtitleStreamIndex = undefined, subtitleStreamIndex = undefined,
forceDirectPlay = false, forceDirectPlay = false,
@@ -89,7 +89,7 @@ export const getStreamUrl = async ({
{ {
method: "POST", method: "POST",
data: { data: {
deviceProfile: forceDirectPlay ? native : deviceProfile, deviceProfile: native,
userId, userId,
maxStreamingBitrate, maxStreamingBitrate,
startTimeTicks, startTimeTicks,

View File

@@ -31,15 +31,6 @@ export const postCapabilities = async ({
throw new Error("Missing parameters for marking item as not played"); throw new Error("Missing parameters for marking item as not played");
} }
let profile: any = iosFmp4;
if (deviceProfile === "Native") {
profile = native;
}
if (deviceProfile === "Old") {
profile = old;
}
try { try {
const d = api.axiosInstance.post( const d = api.axiosInstance.post(
api.basePath + "/Sessions/Capabilities/Full", api.basePath + "/Sessions/Capabilities/Full",
@@ -57,7 +48,7 @@ export const postCapabilities = async ({
], ],
supportsMediaControl: true, supportsMediaControl: true,
id: sessionId, id: sessionId,
DeviceProfile: profile, DeviceProfile: native,
}, },
{ {
headers: getAuthHeaders(api), headers: getAuthHeaders(api),

View File

@@ -15,280 +15,129 @@ export default {
MusicStreamingTranscodingBitrate: 384000, MusicStreamingTranscodingBitrate: 384000,
CodecProfiles: [ CodecProfiles: [
{ {
Codec: "h264",
Conditions: [
{
Condition: "NotEquals",
IsRequired: false,
Property: "IsAnamorphic",
Value: "true",
},
{
Condition: "EqualsAny",
IsRequired: false,
Property: "VideoProfile",
Value: "high|main|baseline|constrained baseline",
},
{
Condition: "LessThanEqual",
IsRequired: false,
Property: "VideoLevel",
Value: "80",
},
{
Condition: "NotEquals",
IsRequired: false,
Property: "IsInterlaced",
Value: "true",
},
],
Type: MediaTypes.Video, Type: MediaTypes.Video,
Codec: "h264,h265,hevc,mpeg4,divx,xvid,wmv,vc1,vp8,vp9,av1",
}, },
{ {
Codec: "hevc", Type: MediaTypes.Audio,
Conditions: [ Codec: "aac,ac3,eac3,mp3,flac,alac,opus,vorbis,pcm,wma",
{
Condition: "NotEquals",
IsRequired: false,
Property: "IsAnamorphic",
Value: "true",
},
{
Condition: "EqualsAny",
IsRequired: false,
Property: "VideoProfile",
Value: "high|main|main 10",
},
{
Condition: "LessThanEqual",
IsRequired: false,
Property: "VideoLevel",
Value: "175",
},
{
Condition: "NotEquals",
IsRequired: false,
Property: "IsInterlaced",
Value: "true",
},
],
Type: MediaTypes.Video,
}, },
], ],
DirectPlayProfiles: [ DirectPlayProfiles: [
{ {
AudioCodec: "flac,alac,aac,eac3,ac3,opus",
Container: "mp4",
Type: MediaTypes.Video, Type: MediaTypes.Video,
VideoCodec: "hevc,h264,mpeg4", Container: "mp4,mkv,avi,mov,flv,ts,m2ts,webm,ogv,3gp",
VideoCodec: "h264,h265,hevc,mpeg4,divx,xvid,wmv,vc1,vp8,vp9,av1",
AudioCodec: "aac,ac3,eac3,mp3,flac,alac,opus,vorbis,wma",
}, },
{ {
AudioCodec: "flac,alac,aac,eac3,ac3,opus",
Container: "mkv",
Type: MediaTypes.Video,
VideoCodec: "hevc,h264,mpeg4",
},
{
AudioCodec: "alac,aac,ac3",
Container: "m4v",
Type: MediaTypes.Video,
VideoCodec: "h264,mpeg4",
},
{
AudioCodec:
"alac,aac,eac3,ac3,mp3,pcm_s24be,pcm_s24le,pcm_s16be,pcm_s16le",
Container: "mov",
Type: MediaTypes.Video,
VideoCodec: "hevc,h264,mpeg4,mjpeg",
},
{
AttrudioCodec: "aac,eac3,ac3,mp3",
Container: "mpegts",
Type: MediaTypes.Video,
VideoCodec: "h264",
},
{
AttrudioCodec: "aac,amr_nb",
Container: "3gp,3g2",
Type: MediaTypes.Video,
VideoCodec: "h264,mpeg4",
},
{
AttrudioCodec: "pcm_s16le,pcm_mulaw",
Container: "avi",
Type: MediaTypes.Video,
VideoCodec: "mjpeg",
},
{
Container: "mp3",
Type: MediaTypes.Audio,
},
{
Container: "aac",
Type: MediaTypes.Audio,
},
{
AudioCodec: "aac",
Container: "m4a",
Type: MediaTypes.Audio,
},
{
AudioCodec: "aac",
Container: "m4b",
Type: MediaTypes.Audio,
},
{
Container: "flac",
Type: MediaTypes.Audio,
},
{
Container: "alac",
Type: MediaTypes.Audio,
},
{
AudioCodec: "alac",
Container: "m4a",
Type: MediaTypes.Audio,
},
{
AudioCodec: "alac",
Container: "m4b",
Type: MediaTypes.Audio,
},
{
Container: "wav",
Type: MediaTypes.Audio, Type: MediaTypes.Audio,
Container: "mp3,aac,flac,alac,wav,ogg,wma",
AudioCodec: "mp3,aac,flac,alac,opus,vorbis,wma,pcm",
}, },
], ],
TranscodingProfiles: [ TranscodingProfiles: [
{ {
AudioCodec: "flac,alac,aac,eac3,ac3,opus", Type: MediaTypes.Video,
BreakOnNonKeyFrames: true, Context: "Streaming",
Container: "mp4",
Context: "streaming",
MaxAudioChannels: "8",
MinSegments: 2,
Protocol: "hls", Protocol: "hls",
Type: "video",
VideoCodec: "hevc,h264,mpeg4",
},
{
AudioCodec: "aac",
BreakOnNonKeyFrames: true,
Container: "aac",
Context: "Streaming",
MaxAudioChannels: "6",
MinSegments: "2",
Protocol: "hls",
Type: MediaTypes.Audio,
},
{
AudioCodec: "aac",
Container: "aac",
Context: "Streaming",
MaxAudioChannels: "6",
Protocol: "http",
Type: MediaTypes.Audio,
},
{
AudioCodec: "mp3",
Container: "mp3",
Context: "Streaming",
MaxAudioChannels: "6",
Protocol: "http",
Type: MediaTypes.Audio,
},
{
AudioCodec: "wav",
Container: "wav",
Context: "Streaming",
MaxAudioChannels: "6",
Protocol: "http",
Type: MediaTypes.Audio,
},
{
AudioCodec: "mp3",
Container: "mp3",
Context: "Static",
MaxAudioChannels: "6",
Protocol: "http",
Type: MediaTypes.Audio,
},
{
AudioCodec: "aac",
Container: "aac",
Context: "Static",
MaxAudioChannels: "6",
Protocol: "http",
Type: MediaTypes.Audio,
},
{
AudioCodec: "wav",
Container: "wav",
Context: "Static",
MaxAudioChannels: "6",
Protocol: "http",
Type: MediaTypes.Audio,
},
{
AudioCodec: "aac,mp3",
BreakOnNonKeyFrames: true,
Container: "ts", Container: "ts",
Context: "Streaming",
MaxAudioChannels: "6",
MinSegments: "2",
Protocol: "hls",
Type: MediaTypes.Video,
VideoCodec: "h264", VideoCodec: "h264",
AudioCodec: "aac,mp3,ac3",
MaxAudioChannels: "8",
MinSegments: "2",
BreakOnNonKeyFrames: true,
}, },
{ {
AudioCodec: "aac,mp3,ac3,eac3,flac,alac", Type: MediaTypes.Audio,
Container: "mp4", Context: "Streaming",
Context: "Static",
Protocol: "http", Protocol: "http",
Type: MediaTypes.Video, Container: "mp3",
VideoCodec: "h264", AudioCodec: "mp3",
MaxAudioChannels: "2",
}, },
], ],
ResponseProfiles: [ ResponseProfiles: [
{ {
Container: "m4v", Container: "mkv",
MimeType: "video/x-matroska",
Type: MediaTypes.Video,
},
{
Container: "mp4",
MimeType: "video/mp4", MimeType: "video/mp4",
Type: MediaTypes.Video, Type: MediaTypes.Video,
}, },
], ],
SubtitleProfiles: [ SubtitleProfiles: [
{ { Format: "srt", Method: "Embed" },
Format: "srt", { Format: "srt", Method: "External" },
Method: "external", { Format: "srt", Method: "Encode" },
}, { Format: "ass", Method: "Embed" },
{ { Format: "ass", Method: "External" },
Format: "pgssub", { Format: "ass", Method: "Encode" },
Method: "embed", { Format: "ssa", Method: "Embed" },
}, { Format: "ssa", Method: "External" },
{ { Format: "ssa", Method: "Encode" },
Format: "dvdsub", { Format: "sub", Method: "Embed" },
Method: "embed", { Format: "sub", Method: "External" },
}, { Format: "sub", Method: "Encode" },
{ { Format: "vtt", Method: "Embed" },
Format: "dvbsub", { Format: "vtt", Method: "External" },
Method: "embed", { Format: "vtt", Method: "Encode" },
}, { Format: "ttml", Method: "Embed" },
{ { Format: "ttml", Method: "External" },
Format: "xsub", { Format: "ttml", Method: "Encode" },
Method: "embed", { Format: "pgs", Method: "Embed" },
}, { Format: "pgs", Method: "External" },
{ { Format: "pgs", Method: "Encode" },
Format: "vtt", { Format: "dvdsub", Method: "Embed" },
Method: "embed", { Format: "dvdsub", Method: "External" },
}, { Format: "dvdsub", Method: "Encode" },
{ { Format: "dvbsub", Method: "Embed" },
Format: "ttml", { Format: "dvbsub", Method: "External" },
Method: "embed", { Format: "dvbsub", Method: "Encode" },
}, { Format: "xsub", Method: "Embed" },
{ { Format: "xsub", Method: "External" },
Format: "cc_dec", { Format: "xsub", Method: "Encode" },
Method: "embed", { Format: "mov_text", Method: "Embed" },
}, { Format: "mov_text", Method: "External" },
{ Format: "mov_text", Method: "Encode" },
{ Format: "scc", Method: "Embed" },
{ Format: "scc", Method: "External" },
{ Format: "scc", Method: "Encode" },
{ Format: "smi", Method: "Embed" },
{ Format: "smi", Method: "External" },
{ Format: "smi", Method: "Encode" },
{ Format: "teletext", Method: "Embed" },
{ Format: "teletext", Method: "External" },
{ Format: "teletext", Method: "Encode" },
{ Format: "microdvd", Method: "Embed" },
{ Format: "microdvd", Method: "External" },
{ Format: "microdvd", Method: "Encode" },
{ Format: "mpl2", Method: "Embed" },
{ Format: "mpl2", Method: "External" },
{ Format: "mpl2", Method: "Encode" },
{ Format: "pjs", Method: "Embed" },
{ Format: "pjs", Method: "External" },
{ Format: "pjs", Method: "Encode" },
{ Format: "realtext", Method: "Embed" },
{ Format: "realtext", Method: "External" },
{ Format: "realtext", Method: "Encode" },
{ Format: "stl", Method: "Embed" },
{ Format: "stl", Method: "External" },
{ Format: "stl", Method: "Encode" },
{ Format: "subrip", Method: "Embed" },
{ Format: "subrip", Method: "External" },
{ Format: "subrip", Method: "Encode" },
{ Format: "subviewer", Method: "Embed" },
{ Format: "subviewer", Method: "External" },
{ Format: "subviewer", Method: "Encode" },
{ Format: "text", Method: "Embed" },
{ Format: "text", Method: "External" },
{ Format: "text", Method: "Encode" },
{ Format: "vplayer", Method: "Embed" },
{ Format: "vplayer", Method: "External" },
{ Format: "vplayer", Method: "Encode" },
], ],
}; };