mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-18 17:18:11 +00:00
213 lines
6.2 KiB
JavaScript
213 lines
6.2 KiB
JavaScript
/**
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
import { Platform } from "react-native";
|
|
import MediaTypes from "../../constants/MediaTypes";
|
|
import { getSubtitleProfiles } from "./subtitles";
|
|
|
|
/**
|
|
* @typedef {"ios" | "android"} PlatformType
|
|
* @typedef {"vlc" | "ksplayer"} PlayerType
|
|
* @typedef {"auto" | "stereo" | "5.1" | "passthrough"} AudioTranscodeModeType
|
|
*
|
|
* @typedef {Object} ProfileOptions
|
|
* @property {PlatformType} [platform] - Target platform
|
|
* @property {PlayerType} [player] - Video player being used
|
|
* @property {AudioTranscodeModeType} [audioMode] - Audio transcoding mode
|
|
*/
|
|
|
|
/**
|
|
* Audio profiles for react-native-track-player based on platform capabilities.
|
|
* iOS uses AVPlayer, Android uses ExoPlayer - each has different codec support.
|
|
*/
|
|
const getAudioDirectPlayProfile = (platform) => {
|
|
if (platform === "ios") {
|
|
// iOS AVPlayer supported formats
|
|
return {
|
|
Type: MediaTypes.Audio,
|
|
Container: "mp3,m4a,aac,flac,alac,wav,aiff,caf",
|
|
AudioCodec: "mp3,aac,alac,flac,opus,pcm",
|
|
};
|
|
}
|
|
|
|
// Android ExoPlayer supported formats
|
|
return {
|
|
Type: MediaTypes.Audio,
|
|
Container: "mp3,m4a,aac,ogg,flac,wav,webm,mka",
|
|
AudioCodec: "mp3,aac,flac,vorbis,opus,pcm",
|
|
};
|
|
};
|
|
|
|
const getAudioCodecProfile = (platform) => {
|
|
if (platform === "ios") {
|
|
// iOS AVPlayer codec constraints
|
|
return {
|
|
Type: MediaTypes.Audio,
|
|
Codec: "aac,ac3,eac3,mp3,flac,alac,opus,pcm",
|
|
};
|
|
}
|
|
|
|
// Android ExoPlayer codec constraints
|
|
return {
|
|
Type: MediaTypes.Audio,
|
|
Codec: "aac,ac3,eac3,mp3,flac,vorbis,opus,pcm",
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Gets the video audio codec configuration based on platform, player, and audio mode.
|
|
*
|
|
* Key insight: VLC handles AC3/EAC3/DTS downmixing fine.
|
|
* Only TrueHD and DTS-HD MA (lossless 7.1) cause issues on mobile devices
|
|
* because VLC's internal downmixing from 7.1 to stereo fails on some Android audio pipelines.
|
|
*
|
|
* @param {PlatformType} platform
|
|
* @param {PlayerType} player
|
|
* @param {AudioTranscodeModeType} audioMode
|
|
* @returns {{ directPlayCodec: string, maxAudioChannels: string }}
|
|
*/
|
|
const getVideoAudioCodecs = (platform, player, audioMode) => {
|
|
// Base codecs that work everywhere
|
|
const baseCodecs = "aac,mp3,flac,opus,vorbis";
|
|
|
|
// Surround codecs that VLC handles well (downmixes properly)
|
|
const surroundCodecs = "ac3,eac3,dts";
|
|
|
|
// Lossless HD codecs that cause issues with VLC's downmixing on mobile
|
|
const losslessHdCodecs = "truehd";
|
|
|
|
// Platform-specific codecs
|
|
const platformCodecs = platform === "ios" ? "alac,wma" : "wma";
|
|
|
|
// Handle explicit user settings first
|
|
switch (audioMode) {
|
|
case "stereo":
|
|
// Force stereo transcoding - only allow basic codecs
|
|
return {
|
|
directPlayCodec: `${baseCodecs},${platformCodecs}`,
|
|
maxAudioChannels: "2",
|
|
};
|
|
|
|
case "5.1":
|
|
// Allow up to 5.1 - include surround codecs but not lossless HD
|
|
return {
|
|
directPlayCodec: `${baseCodecs},${surroundCodecs},${platformCodecs}`,
|
|
maxAudioChannels: "6",
|
|
};
|
|
|
|
case "passthrough":
|
|
// Allow all codecs - for users with external DAC/receiver
|
|
return {
|
|
directPlayCodec: `${baseCodecs},${surroundCodecs},${losslessHdCodecs},${platformCodecs}`,
|
|
maxAudioChannels: "8",
|
|
};
|
|
default:
|
|
// Auto mode: platform and player-specific defaults
|
|
break;
|
|
}
|
|
|
|
// Auto mode logic based on platform and player
|
|
if (player === "ksplayer" && platform === "ios") {
|
|
// KSPlayer on iOS handles all codecs well, including TrueHD
|
|
return {
|
|
directPlayCodec: `${baseCodecs},${surroundCodecs},${losslessHdCodecs},${platformCodecs}`,
|
|
maxAudioChannels: "8",
|
|
};
|
|
}
|
|
|
|
// VLC on Android or iOS - don't include TrueHD (causes 7.1 downmix issues)
|
|
// DTS core is fine, VLC handles it well. Only lossless 7.1 formats are problematic.
|
|
return {
|
|
directPlayCodec: `${baseCodecs},${surroundCodecs},${platformCodecs}`,
|
|
maxAudioChannels: "6",
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Generates a device profile for Jellyfin playback.
|
|
*
|
|
* @param {ProfileOptions} [options] - Profile configuration options
|
|
* @returns {Object} Jellyfin device profile
|
|
*/
|
|
export const generateDeviceProfile = (options = {}) => {
|
|
const platform = options.platform || Platform.OS;
|
|
const player = options.player || "vlc";
|
|
const audioMode = options.audioMode || "auto";
|
|
|
|
const { directPlayCodec, maxAudioChannels } = getVideoAudioCodecs(
|
|
platform,
|
|
player,
|
|
audioMode,
|
|
);
|
|
|
|
const playerName = player === "ksplayer" ? "KSPlayer" : "VLC Player";
|
|
|
|
/**
|
|
* Device profile for Native video player
|
|
*/
|
|
const profile = {
|
|
Name: `1. ${playerName}`,
|
|
MaxStaticBitrate: 999_999_999,
|
|
MaxStreamingBitrate: 999_999_999,
|
|
CodecProfiles: [
|
|
{
|
|
Type: MediaTypes.Video,
|
|
Codec: "h264,mpeg4,divx,xvid,wmv,vc1,vp8,vp9,av1",
|
|
},
|
|
{
|
|
Type: MediaTypes.Video,
|
|
Codec: "hevc,h265",
|
|
Conditions: [
|
|
{
|
|
Condition: "LessThanEqual",
|
|
Property: "VideoLevel",
|
|
Value: "153",
|
|
IsRequired: false,
|
|
},
|
|
{
|
|
Condition: "NotEquals",
|
|
Property: "VideoRangeType",
|
|
Value: "DOVI", //no dolby vision at all
|
|
IsRequired: true,
|
|
},
|
|
],
|
|
},
|
|
getAudioCodecProfile(platform),
|
|
],
|
|
DirectPlayProfiles: [
|
|
{
|
|
Type: MediaTypes.Video,
|
|
Container: "mp4,mkv,avi,mov,flv,ts,m2ts,webm,ogv,3gp,hls",
|
|
VideoCodec:
|
|
"h264,hevc,mpeg4,divx,xvid,wmv,vc1,vp8,vp9,av1,avi,mpeg,mpeg2video",
|
|
AudioCodec: directPlayCodec,
|
|
},
|
|
getAudioDirectPlayProfile(platform),
|
|
],
|
|
TranscodingProfiles: [
|
|
{
|
|
Type: MediaTypes.Video,
|
|
Context: "Streaming",
|
|
Protocol: "hls",
|
|
Container: "ts",
|
|
VideoCodec: "h264, hevc",
|
|
AudioCodec: "aac,mp3,ac3,dts",
|
|
MaxAudioChannels: maxAudioChannels,
|
|
},
|
|
{
|
|
Type: MediaTypes.Audio,
|
|
Context: "Streaming",
|
|
Protocol: "http",
|
|
Container: "mp3",
|
|
AudioCodec: "mp3",
|
|
MaxAudioChannels: "2",
|
|
},
|
|
],
|
|
SubtitleProfiles: getSubtitleProfiles(),
|
|
};
|
|
|
|
return profile;
|
|
};
|