shamelessly copy transcoding config from NavidromeUI

This commit is contained in:
jeffvli
2026-03-31 20:41:36 -07:00
parent 7d34511039
commit ee33720fcd
2 changed files with 97 additions and 50 deletions
@@ -8,6 +8,10 @@ import md5 from 'md5';
import { z } from 'zod';
import { contract, ssApiClient } from '/@/renderer/api/subsonic/subsonic-api';
import {
getDefaultTranscodingProfiles,
getDirectPlayProfiles,
} from '/@/renderer/features/player/components/audio-players';
import { randomString } from '/@/renderer/utils';
import { logFn } from '/@/renderer/utils/logger';
import { getServerUrl } from '/@/renderer/utils/normalize-server-url';
@@ -88,44 +92,44 @@ const ALBUM_LIST_SORT_MAPPING: Record<AlbumListSort, AlbumListSortType | undefin
const MAX_SUBSONIC_ITEMS = 500;
const SUBSONIC_FAST_BATCH_SIZE = MAX_SUBSONIC_ITEMS * 10;
const TRANSCODE_DIRECT_PLAY_PROFILES = [
{
audioCodecs: ['mp3'],
containers: ['mp3'],
maxAudioChannels: 2,
protocols: ['http'],
},
{
audioCodecs: ['aac'],
containers: ['m4a', 'mp4'],
maxAudioChannels: 2,
protocols: ['http'],
},
{
audioCodecs: ['vorbis'],
containers: ['ogg'],
maxAudioChannels: 2,
protocols: ['http'],
},
{
audioCodecs: ['opus'],
containers: ['ogg', 'webm'],
maxAudioChannels: 2,
protocols: ['http'],
},
{
audioCodecs: ['pcm'],
containers: ['wav'],
maxAudioChannels: 2,
protocols: ['http'],
},
{
audioCodecs: ['flac'],
containers: ['flac'],
maxAudioChannels: 2,
protocols: ['http'],
},
];
// const TRANSCODE_DIRECT_PLAY_PROFILES = [
// {
// audioCodecs: ['mp3'],
// containers: ['mp3'],
// maxAudioChannels: 2,
// protocols: ['http'],
// },
// {
// audioCodecs: ['aac'],
// containers: ['m4a', 'mp4'],
// maxAudioChannels: 2,
// protocols: ['http'],
// },
// {
// audioCodecs: ['vorbis'],
// containers: ['ogg'],
// maxAudioChannels: 2,
// protocols: ['http'],
// },
// {
// audioCodecs: ['opus'],
// containers: ['ogg', 'webm'],
// maxAudioChannels: 2,
// protocols: ['http'],
// },
// {
// audioCodecs: ['pcm'],
// containers: ['wav'],
// maxAudioChannels: 2,
// protocols: ['http'],
// },
// {
// audioCodecs: ['flac'],
// containers: ['flac'],
// maxAudioChannels: 2,
// protocols: ['http'],
// },
// ];
// const TRANSCODE_UNSUPPORTED_DIRECT_PLAY_PROFILES = [
// {
@@ -1971,25 +1975,17 @@ export const SubsonicController: InternalControllerEndpoint = {
if (hasFeature(server, ServerFeature.OS_TRANSCODE_DECISION)) {
const maxTranscodingAudioBitrate = 0;
const transcodingProfiles = format?.split(',').map((f) => {
const trimmedFormat = f.trim();
return {
audioCodec: trimmedFormat,
container: trimmedFormat,
maxAudioChannels: 2,
protocol: 'http',
};
});
const directPlayProfiles = getDirectPlayProfiles();
const transcodingProfiles = getDefaultTranscodingProfiles();
const transcodeDecision = await ssApiClient(apiClientProps).getTranscodeDecision({
body: {
codecProfiles: [],
directPlayProfiles: TRANSCODE_DIRECT_PLAY_PROFILES,
directPlayProfiles,
maxAudioBitrate: 0,
maxTranscodingAudioBitrate,
name: 'Feishin',
platform: 'Web',
platform: navigator.userAgent,
transcodingProfiles,
},
query: {
@@ -37,6 +37,52 @@ import { toast } from '/@/shared/components/toast/toast';
import { LibraryItem } from '/@/shared/types/domain-types';
import { PlayerType } from '/@/shared/types/types';
const CODEC_PROBES = [
{ codec: 'mp3', container: 'mp3', mime: 'audio/mpeg' },
{ codec: 'aac', container: 'mp4', mime: 'audio/mp4; codecs="mp4a.40.2"' },
{ codec: 'opus', container: 'ogg', mime: 'audio/ogg; codecs="opus"' },
{ codec: 'vorbis', container: 'ogg', mime: 'audio/ogg; codecs="vorbis"' },
{ codec: 'flac', container: 'flac', mime: 'audio/flac' },
{ codec: 'wav', container: 'wav', mime: 'audio/wav' },
{ codec: 'alac', container: 'mp4', mime: 'audio/mp4; codecs="alac"' },
];
const DEFAULT_TRANSCODING_PROFILES = [
{ audioCodec: 'opus', container: 'ogg', protocol: 'http' },
{ audioCodec: 'mp3', container: 'mp3', protocol: 'http' },
];
const DIRECT_PLAY_PROFILES: {
audioCodecs: string[];
containers: string[];
protocols: string[];
}[] = [];
export function getDefaultTranscodingProfiles() {
return DEFAULT_TRANSCODING_PROFILES;
}
export function getDirectPlayProfiles() {
return DIRECT_PLAY_PROFILES;
}
// Shamelessly taken from NavidromeUI
function detectBrowserProfile() {
const audio = new Audio();
for (const { codec, container, mime } of CODEC_PROBES) {
if (audio.canPlayType(mime) === 'probably') {
DIRECT_PLAY_PROFILES.push({
audioCodecs: [codec],
containers: [container],
protocols: ['http'],
});
}
}
return DIRECT_PLAY_PROFILES;
}
export const AudioPlayers = () => {
const playbackType = usePlaybackType();
const serverId = useCurrentServerId();
@@ -49,6 +95,11 @@ export const AudioPlayers = () => {
} = usePlaybackSettings();
const { setWebAudio, webAudio: audioContext } = useWebAudio();
useEffect(() => {
console.log('getDirectPlayProfiles');
detectBrowserProfile();
}, []);
return (
<>
<SleepTimerHook />