mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-07 12:30:12 +02:00
add OS transcoding extension
This commit is contained in:
@@ -11,6 +11,80 @@ const userParameters = z.object({
|
||||
username: z.string(),
|
||||
});
|
||||
|
||||
const transcodeDecisionParameters = z.object({
|
||||
mediaId: z.string(),
|
||||
mediaType: z.enum(['song', 'podcast']),
|
||||
});
|
||||
|
||||
const getTranscodeStreamParameters = z.object({
|
||||
mediaId: z.string(),
|
||||
mediaType: z.enum(['song', 'podcast']),
|
||||
offset: z.number().optional(),
|
||||
transcodeParams: z.string(),
|
||||
});
|
||||
|
||||
const codecProfileLimitation = z.object({
|
||||
comparison: z.string(),
|
||||
name: z.string(),
|
||||
required: z.boolean().optional(),
|
||||
values: z.array(z.string()),
|
||||
});
|
||||
|
||||
const directPlayProfile = z.object({
|
||||
audioCodecs: z.array(z.string()),
|
||||
containers: z.array(z.string()),
|
||||
maxAudioChannels: z.number().optional(),
|
||||
protocols: z.array(z.string()),
|
||||
});
|
||||
|
||||
const transcodingProfile = z.object({
|
||||
audioCodec: z.string(),
|
||||
container: z.string(),
|
||||
maxAudioChannels: z.number().optional(),
|
||||
protocol: z.string(),
|
||||
});
|
||||
|
||||
const codecProfile = z.object({
|
||||
limitations: z.array(codecProfileLimitation).optional(),
|
||||
name: z.string(),
|
||||
type: z.string(),
|
||||
});
|
||||
|
||||
const transcodeDecisionRequestBody = z.object({
|
||||
codecProfiles: z.array(codecProfile).optional(),
|
||||
directPlayProfiles: z.array(directPlayProfile).optional(),
|
||||
maxAudioBitrate: z.number().optional(),
|
||||
maxTranscodingAudioBitrate: z.number().optional(),
|
||||
name: z.string(),
|
||||
platform: z.string(),
|
||||
transcodingProfiles: z.array(transcodingProfile).optional(),
|
||||
});
|
||||
|
||||
const streamDetails = z.object({
|
||||
audioBitdepth: z.number().optional(),
|
||||
audioBitrate: z.number().optional(),
|
||||
audioChannels: z.number().optional(),
|
||||
audioProfile: z.string().optional(),
|
||||
audioSamplerate: z.number().optional(),
|
||||
codec: z.string().optional(),
|
||||
container: z.string().optional(),
|
||||
protocol: z.string().optional(),
|
||||
});
|
||||
|
||||
const transcodeDecision = z.object({
|
||||
canDirectPlay: z.boolean(),
|
||||
canTranscode: z.boolean(),
|
||||
errorReason: z.string().optional(),
|
||||
sourceStream: streamDetails.optional(),
|
||||
transcodeParams: z.string().optional(),
|
||||
transcodeReason: z.array(z.string()).optional(),
|
||||
transcodeStream: streamDetails.optional(),
|
||||
});
|
||||
|
||||
const getTranscodeDecision = z.object({
|
||||
transcodeDecision,
|
||||
});
|
||||
|
||||
const user = z.object({
|
||||
user: z.object({
|
||||
adminRole: z.boolean(),
|
||||
@@ -382,6 +456,7 @@ export enum SubsonicExtensions {
|
||||
INDEX_BASED_QUEUE = 'indexBasedQueue',
|
||||
SONG_LYRICS = 'songLyrics',
|
||||
TRANSCODE_OFFSET = 'transcodeOffset',
|
||||
TRANSCODING = 'transcoding',
|
||||
}
|
||||
|
||||
const updatePlaylistParameters = z.object({
|
||||
@@ -718,6 +793,9 @@ const getInternetRadioStations = z.object({
|
||||
});
|
||||
|
||||
export const ssType = {
|
||||
_body: {
|
||||
getTranscodeDecision: transcodeDecisionRequestBody,
|
||||
},
|
||||
_parameters: {
|
||||
albumInfo: albumInfoParameters,
|
||||
albumList: albumListParameters,
|
||||
@@ -741,6 +819,8 @@ export const ssType = {
|
||||
getSong: getSongParameters,
|
||||
getSongsByGenre: getSongsByGenreParameters,
|
||||
getStarred: getStarredParameters,
|
||||
getTranscodeDecision: transcodeDecisionParameters,
|
||||
getTranscodeStream: getTranscodeStreamParameters,
|
||||
randomSongList: randomSongListParameters,
|
||||
removeFavorite: removeFavoriteParameters,
|
||||
savePlayQueueByIndex: savePlayQueueByIndexParameters,
|
||||
@@ -786,6 +866,7 @@ export const ssType = {
|
||||
getSong,
|
||||
getSongsByGenre,
|
||||
getStarred,
|
||||
getTranscodeDecision,
|
||||
internetRadioStation,
|
||||
musicFolderList,
|
||||
ping,
|
||||
|
||||
@@ -410,16 +410,18 @@ export type Song = {
|
||||
userRating: null | number;
|
||||
};
|
||||
|
||||
type ApiContext = {
|
||||
pathReplace?: string;
|
||||
pathReplaceWith?: string;
|
||||
};
|
||||
|
||||
type BaseEndpointArgs = {
|
||||
apiClientProps: {
|
||||
server?: null | ServerListItemWithCredential;
|
||||
serverId: string;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
context?: {
|
||||
pathReplace?: string;
|
||||
pathReplaceWith?: string;
|
||||
};
|
||||
context?: ApiContext;
|
||||
};
|
||||
|
||||
type GenreListSortMap = {
|
||||
@@ -1416,11 +1418,10 @@ export type ControllerEndpoint = {
|
||||
getSongDetail: (args: SongDetailArgs) => Promise<SongDetailResponse>;
|
||||
getSongList: (args: SongListArgs) => Promise<SongListResponse>;
|
||||
getSongListCount: (args: SongListCountArgs) => Promise<number>;
|
||||
getStreamUrl: (args: StreamArgs) => string;
|
||||
getStreamUrl: (args: StreamArgs) => Promise<string>;
|
||||
getStructuredLyrics?: (args: StructuredLyricsArgs) => Promise<StructuredLyric[]>;
|
||||
getTagList?: (args: TagListArgs) => Promise<TagListResponse>;
|
||||
getTopSongs: (args: TopSongListArgs) => Promise<TopSongListResponse>;
|
||||
// getArtistInfo?: (args: any) => void;
|
||||
getUserInfo: (args: UserInfoArgs) => Promise<UserInfoResponse>;
|
||||
getUserList?: (args: UserListArgs) => Promise<UserListResponse>;
|
||||
movePlaylistItem?: (args: MoveItemArgs) => Promise<void>;
|
||||
@@ -1563,7 +1564,7 @@ export type InternalControllerEndpoint = {
|
||||
getSongDetail: (args: ReplaceApiClientProps<SongDetailArgs>) => Promise<SongDetailResponse>;
|
||||
getSongList: (args: ReplaceApiClientProps<SongListArgs>) => Promise<SongListResponse>;
|
||||
getSongListCount: (args: ReplaceApiClientProps<SongListCountArgs>) => Promise<number>;
|
||||
getStreamUrl: (args: ReplaceApiClientProps<StreamArgs>) => string;
|
||||
getStreamUrl: (args: ReplaceApiClientProps<StreamArgs>) => Promise<string>;
|
||||
getStructuredLyrics?: (
|
||||
args: ReplaceApiClientProps<StructuredLyricsArgs>,
|
||||
) => Promise<StructuredLyric[]>;
|
||||
@@ -1667,6 +1668,9 @@ export type StreamQuery = {
|
||||
bitrate?: number;
|
||||
format?: string;
|
||||
id: string;
|
||||
mediaType?: 'podcast' | 'song';
|
||||
offset?: number;
|
||||
skipAutoTranscode?: boolean;
|
||||
transcode: boolean;
|
||||
};
|
||||
|
||||
@@ -1711,6 +1715,50 @@ export type TagListResponse = {
|
||||
tags?: Tag[];
|
||||
};
|
||||
|
||||
export type TranscodeDecisionArgs = BaseEndpointArgs & {
|
||||
body?: TranscodeDecisionRequestBody;
|
||||
query: TranscodeDecisionQuery;
|
||||
};
|
||||
|
||||
export type TranscodeDecisionQuery = {
|
||||
id: string;
|
||||
type: 'song';
|
||||
};
|
||||
|
||||
export type TranscodeDecisionRequestBody = {
|
||||
codecProfiles?: Array<{
|
||||
limitations?: Array<{
|
||||
comparison: string;
|
||||
name: string;
|
||||
required?: boolean;
|
||||
values: string[];
|
||||
}>;
|
||||
name: string;
|
||||
type: string;
|
||||
}>;
|
||||
directPlayProfiles?: Array<{
|
||||
audioCodecs: string[];
|
||||
containers: string[];
|
||||
maxAudioChannels?: number;
|
||||
protocols: string[];
|
||||
}>;
|
||||
maxAudioBitrate?: number;
|
||||
maxTranscodingAudioBitrate?: number;
|
||||
name: string;
|
||||
platform: string;
|
||||
transcodingProfiles?: Array<{
|
||||
audioCodec: string;
|
||||
container: string;
|
||||
maxAudioChannels?: number;
|
||||
protocol: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
export type TranscodeDecisionResponse = {
|
||||
decision: 'direct' | 'transcode';
|
||||
transcodeParams?: string;
|
||||
};
|
||||
|
||||
export type UserInfoArgs = BaseEndpointArgs & { query: UserInfoQuery };
|
||||
|
||||
export type UserInfoQuery = {
|
||||
@@ -1730,8 +1778,5 @@ type BaseEndpointArgsWithServer = {
|
||||
serverId: string;
|
||||
signal?: AbortSignal;
|
||||
};
|
||||
context?: {
|
||||
pathReplace?: string;
|
||||
pathReplaceWith?: string;
|
||||
};
|
||||
context?: ApiContext;
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@ export enum ServerFeature {
|
||||
LYRICS_SINGLE_STRUCTURED = 'lyricsSingleStructured',
|
||||
MUSIC_FOLDER_MULTISELECT = 'musicFolderMultiselect',
|
||||
OS_FORM_POST = 'osFormPost',
|
||||
OS_TRANSCODE_DECISION = 'osTranscodeDecision',
|
||||
PLAYLISTS_SMART = 'playlistsSmart',
|
||||
PUBLIC_PLAYLIST = 'publicPlaylist',
|
||||
SERVER_PLAY_QUEUE = 'serverPlayQueue',
|
||||
|
||||
Reference in New Issue
Block a user