mirror of
https://github.com/agregarr/agregarr.git
synced 2026-01-25 03:48:48 -06:00
@@ -473,19 +473,68 @@ export async function buildRenderContext(
|
||||
context.bitDepth = parseInt(String(videoStream.bitDepth), 10);
|
||||
}
|
||||
}
|
||||
// Find audio stream (streamType 2) - prefer first one
|
||||
const audioStream = streams.find((s) => s.streamType === 2);
|
||||
if (audioStream) {
|
||||
// Find all audio streams (streamType 2)
|
||||
const audioStreams = streams.filter((s) => s.streamType === 2);
|
||||
if (audioStreams.length > 0) {
|
||||
// Primary audio stream (first one)
|
||||
const primaryAudio = audioStreams[0];
|
||||
|
||||
// Detailed audio format from displayTitle
|
||||
if (audioStream.displayTitle) {
|
||||
context.audioFormat = audioStream.displayTitle;
|
||||
if (primaryAudio.displayTitle) {
|
||||
context.audioFormat = primaryAudio.displayTitle;
|
||||
}
|
||||
// Audio channel layout
|
||||
if (audioStream.audioChannelLayout) {
|
||||
context.audioChannelLayout = audioStream.audioChannelLayout;
|
||||
if (primaryAudio.audioChannelLayout) {
|
||||
context.audioChannelLayout = primaryAudio.audioChannelLayout;
|
||||
}
|
||||
if (audioStream.channels) {
|
||||
context.audioChannels = audioStream.channels;
|
||||
if (primaryAudio.channels) {
|
||||
context.audioChannels = primaryAudio.channels;
|
||||
}
|
||||
|
||||
// Primary audio language
|
||||
if (primaryAudio.language) {
|
||||
context.audioLanguage = primaryAudio.language;
|
||||
}
|
||||
if (primaryAudio.languageCode) {
|
||||
context.audioLanguageCode = primaryAudio.languageCode;
|
||||
}
|
||||
|
||||
// Collect all audio track languages (unique values only)
|
||||
const allAudioLanguages = audioStreams
|
||||
.map((s) => s.language)
|
||||
.filter((lang): lang is string => !!lang);
|
||||
const allAudioLanguageCodes = audioStreams
|
||||
.map((s) => s.languageCode)
|
||||
.filter((code): code is string => !!code);
|
||||
|
||||
if (allAudioLanguages.length > 0) {
|
||||
context.audioLanguages = [...new Set(allAudioLanguages)];
|
||||
}
|
||||
if (allAudioLanguageCodes.length > 0) {
|
||||
context.audioLanguageCodes = [...new Set(allAudioLanguageCodes)];
|
||||
}
|
||||
}
|
||||
|
||||
// Find all subtitle streams (streamType 3)
|
||||
const subtitleStreams = streams.filter((s) => s.streamType === 3);
|
||||
context.hasSubtitles = subtitleStreams.length > 0;
|
||||
|
||||
if (subtitleStreams.length > 0) {
|
||||
// Collect all subtitle languages (unique values only)
|
||||
const allSubtitleLanguages = subtitleStreams
|
||||
.map((s) => s.language)
|
||||
.filter((lang): lang is string => !!lang);
|
||||
const allSubtitleLanguageCodes = subtitleStreams
|
||||
.map((s) => s.languageCode)
|
||||
.filter((code): code is string => !!code);
|
||||
|
||||
if (allSubtitleLanguages.length > 0) {
|
||||
context.subtitleLanguages = [...new Set(allSubtitleLanguages)];
|
||||
}
|
||||
if (allSubtitleLanguageCodes.length > 0) {
|
||||
context.subtitleLanguageCodes = [
|
||||
...new Set(allSubtitleLanguageCodes),
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,6 +377,17 @@ export interface OverlayRenderContext {
|
||||
audioChannelLayout?: string; // '5.1', '7.1', 'atmos'
|
||||
audioFormat?: string; // Full display title (e.g., 'English (Dolby TrueHD Atmos 7.1)')
|
||||
|
||||
// Audio language info
|
||||
audioLanguage?: string; // Primary audio track language name (e.g., 'English', 'German')
|
||||
audioLanguageCode?: string; // Primary audio track language code (e.g., 'en', 'de')
|
||||
audioLanguages?: string[]; // Array of all audio track languages
|
||||
audioLanguageCodes?: string[]; // Array of all audio track language codes
|
||||
|
||||
// Subtitle info
|
||||
subtitleLanguages?: string[]; // Array of all subtitle languages
|
||||
subtitleLanguageCodes?: string[]; // Array of all subtitle language codes
|
||||
hasSubtitles?: boolean; // Whether any subtitle tracks are present
|
||||
|
||||
// File info
|
||||
container?: string; // 'mkv', 'mp4'
|
||||
bitrate?: number; // In kbps
|
||||
|
||||
@@ -106,6 +106,7 @@ const BOOLEAN_FIELDS = [
|
||||
'dolbyVision',
|
||||
'isImdbTop250',
|
||||
'rtCertifiedFresh',
|
||||
'hasSubtitles',
|
||||
];
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -375,6 +375,7 @@ export const OverlayLayerPanel: React.FC<OverlayLayerPanelProps> = ({
|
||||
...AVAILABLE_VARIABLES.metadata,
|
||||
...AVAILABLE_VARIABLES.video,
|
||||
...AVAILABLE_VARIABLES.audio,
|
||||
...AVAILABLE_VARIABLES.language,
|
||||
...AVAILABLE_VARIABLES.file,
|
||||
...AVAILABLE_VARIABLES.playback,
|
||||
...AVAILABLE_VARIABLES['coming-soon'],
|
||||
@@ -1129,6 +1130,13 @@ export const OverlayLayerPanel: React.FC<OverlayLayerPanelProps> = ({
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
<optgroup label="Language">
|
||||
{AVAILABLE_VARIABLES.language.map((v) => (
|
||||
<option key={v.field} value={v.field}>
|
||||
{v.label}
|
||||
</option>
|
||||
))}
|
||||
</optgroup>
|
||||
<optgroup label="File Info">
|
||||
{AVAILABLE_VARIABLES.file.map((v) => (
|
||||
<option key={v.field} value={v.field}>
|
||||
|
||||
@@ -150,6 +150,7 @@ export const VariableElement: React.FC<VariableElementComponentProps> = ({
|
||||
...AVAILABLE_VARIABLES.metadata,
|
||||
...AVAILABLE_VARIABLES.video,
|
||||
...AVAILABLE_VARIABLES.audio,
|
||||
...AVAILABLE_VARIABLES.language,
|
||||
...AVAILABLE_VARIABLES.file,
|
||||
...AVAILABLE_VARIABLES.playback,
|
||||
...AVAILABLE_VARIABLES['coming-soon'],
|
||||
|
||||
@@ -194,6 +194,17 @@ export interface OverlayRenderContext {
|
||||
audioChannelLayout?: string; // '5.1', '7.1', 'atmos'
|
||||
audioFormat?: string; // Full display title (e.g., 'English (Dolby TrueHD Atmos 7.1)')
|
||||
|
||||
// Audio language info
|
||||
audioLanguage?: string; // Primary audio track language name (e.g., 'English', 'German')
|
||||
audioLanguageCode?: string; // Primary audio track language code (e.g., 'en', 'de')
|
||||
audioLanguages?: string[]; // Array of all audio track languages
|
||||
audioLanguageCodes?: string[]; // Array of all audio track language codes
|
||||
|
||||
// Subtitle info
|
||||
subtitleLanguages?: string[]; // Array of all subtitle languages
|
||||
subtitleLanguageCodes?: string[]; // Array of all subtitle language codes
|
||||
hasSubtitles?: boolean; // Whether any subtitle tracks are present
|
||||
|
||||
// File info
|
||||
container?: string; // 'mkv', 'mp4'
|
||||
bitrate?: number; // In kbps
|
||||
@@ -311,6 +322,39 @@ export const AVAILABLE_VARIABLES = {
|
||||
{ field: 'audioChannels', label: 'Audio Channels', example: '8' },
|
||||
{ field: 'audioChannelLayout', label: 'Channel Layout', example: '7.1' },
|
||||
],
|
||||
language: [
|
||||
{
|
||||
field: 'audioLanguage',
|
||||
label: 'Audio Language (Primary)',
|
||||
example: 'English',
|
||||
},
|
||||
{
|
||||
field: 'audioLanguageCode',
|
||||
label: 'Audio Language Code (Primary)',
|
||||
example: 'en',
|
||||
},
|
||||
{
|
||||
field: 'audioLanguages',
|
||||
label: 'Audio Languages (All)',
|
||||
example: 'English, German',
|
||||
},
|
||||
{
|
||||
field: 'audioLanguageCodes',
|
||||
label: 'Audio Language Codes (All)',
|
||||
example: 'en, de',
|
||||
},
|
||||
{
|
||||
field: 'subtitleLanguages',
|
||||
label: 'Subtitle Languages',
|
||||
example: 'English, German, French',
|
||||
},
|
||||
{
|
||||
field: 'subtitleLanguageCodes',
|
||||
label: 'Subtitle Language Codes',
|
||||
example: 'en, de, fr',
|
||||
},
|
||||
{ field: 'hasSubtitles', label: 'Has Subtitles', example: 'true' },
|
||||
],
|
||||
file: [
|
||||
{ field: 'container', label: 'Container', example: 'mkv' },
|
||||
{ field: 'bitrate', label: 'Bitrate (kbps)', example: '15000' },
|
||||
@@ -438,6 +482,37 @@ export const CONDITION_FIELD_CATEGORIES = {
|
||||
{ field: 'audioCodec', label: 'Audio Codec', example: 'truehd' },
|
||||
{ field: 'audioChannels', label: 'Audio Channels', example: '8' },
|
||||
{ field: 'audioChannelLayout', label: 'Channel Layout', example: '7.1' },
|
||||
{
|
||||
field: 'audioLanguage',
|
||||
label: 'Audio Language (Primary)',
|
||||
example: 'English',
|
||||
},
|
||||
{
|
||||
field: 'audioLanguageCode',
|
||||
label: 'Audio Language Code (Primary)',
|
||||
example: 'en',
|
||||
},
|
||||
{
|
||||
field: 'audioLanguages',
|
||||
label: 'Audio Languages (All)',
|
||||
example: 'English, German',
|
||||
},
|
||||
{
|
||||
field: 'audioLanguageCodes',
|
||||
label: 'Audio Language Codes (All)',
|
||||
example: 'en, de',
|
||||
},
|
||||
{
|
||||
field: 'subtitleLanguages',
|
||||
label: 'Subtitle Languages',
|
||||
example: 'English, German, French',
|
||||
},
|
||||
{
|
||||
field: 'subtitleLanguageCodes',
|
||||
label: 'Subtitle Language Codes',
|
||||
example: 'en, de, fr',
|
||||
},
|
||||
{ field: 'hasSubtitles', label: 'Has Subtitles', example: 'true' },
|
||||
{ field: 'container', label: 'Container', example: 'mkv' },
|
||||
{ field: 'bitrate', label: 'Bitrate (kbps)', example: '15000' },
|
||||
{ field: 'fileSize', label: 'File Size (bytes)', example: '4500000000' },
|
||||
@@ -588,6 +663,13 @@ export const SAMPLE_PREVIEW_CONTEXTS: {
|
||||
audioCodec: 'truehd',
|
||||
audioChannels: 8,
|
||||
audioChannelLayout: '7.1',
|
||||
audioLanguage: 'English',
|
||||
audioLanguageCode: 'en',
|
||||
audioLanguages: ['English', 'German'],
|
||||
audioLanguageCodes: ['en', 'de'],
|
||||
subtitleLanguages: ['English', 'German', 'French'],
|
||||
subtitleLanguageCodes: ['en', 'de', 'fr'],
|
||||
hasSubtitles: true,
|
||||
container: 'mkv',
|
||||
bitrate: 15000,
|
||||
fileSize: 4500000000,
|
||||
@@ -636,6 +718,13 @@ export const SAMPLE_PREVIEW_CONTEXTS: {
|
||||
audioCodec: 'dts',
|
||||
audioChannels: 6,
|
||||
audioChannelLayout: '5.1',
|
||||
audioLanguage: 'English',
|
||||
audioLanguageCode: 'en',
|
||||
audioLanguages: ['English'],
|
||||
audioLanguageCodes: ['en'],
|
||||
subtitleLanguages: ['English', 'Spanish'],
|
||||
subtitleLanguageCodes: ['en', 'es'],
|
||||
hasSubtitles: true,
|
||||
container: 'mkv',
|
||||
bitrate: 8000,
|
||||
fileSize: 3000000000,
|
||||
|
||||
Reference in New Issue
Block a user