fix(overlays): add language and subtitle variables

fix #389
This commit is contained in:
Tom Wheeler
2026-01-21 12:02:35 +13:00
parent 1aff792f9e
commit ea2e468dfb
6 changed files with 168 additions and 9 deletions

View File

@@ -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),
];
}
}
}

View File

@@ -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

View File

@@ -106,6 +106,7 @@ const BOOLEAN_FIELDS = [
'dolbyVision',
'isImdbTop250',
'rtCertifiedFresh',
'hasSubtitles',
];
// ============================================================================

View File

@@ -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}>

View File

@@ -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'],

View File

@@ -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,