Show audio language names for videos

show_audio_lang
aandrew-me 3 weeks ago
parent b812d0cec5
commit 167142a7d0

@ -1293,11 +1293,11 @@ input[type="range"]::-webkit-slider-thumb:hover {
}
.video-grid-extended {
grid-template-columns: 85px 65px 60px 1fr auto;
grid-template-columns: 85px 65px 60px 1fr 120px;
}
.video-grid-compact {
grid-template-columns: 85px 65px 1fr auto;
grid-template-columns: 85px 65px 1fr 120px;
}
.audio-grid {
@ -1340,25 +1340,41 @@ input[type="range"]::-webkit-slider-thumb:hover {
color: var(--text);
}
.audio-indicator {
.audio-indicator,
.audio-placeholder {
width: 120px;
box-sizing: border-box;
display: inline-flex;
align-items: center;
gap: 4px;
justify-content: flex-start;
gap: 6px;
border-radius: 8px;
}
.audio-indicator {
font-size: 11px;
padding: 2px 6px;
border-radius: 4px;
background-color: transparent;
padding: 2px 4px;
color: #10b981;
font-weight: 500;
background-color: #29974513;
}
.audio-indicator svg {
width: 20px;
height: 20px;
width: 18px;
height: 18px;
flex-shrink: 0;
fill: currentColor;
}
.audio-placeholder {
width: 53px;
.audio-indicator .lang-text {
font-size: 12px;
color: var(--text);
opacity: 0.9;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Resolution */
.ss-option .main-text {
color: var(--text) !important;

@ -3,7 +3,14 @@ const {default: YTDlpWrap} = require("yt-dlp-wrap-plus");
const {constants} = require("fs/promises");
const {homedir, platform} = require("os");
const {join} = require("path");
const {mkdirSync, accessSync, promises, existsSync, cpSync, copyFileSync} = require("fs");
const {
mkdirSync,
accessSync,
promises,
existsSync,
cpSync,
copyFileSync,
} = require("fs");
const {execSync, spawn} = require("child_process");
const CONSTANTS = {
@ -564,7 +571,6 @@ class YtDownloaderApp {
const ffmpegName = isWin ? "ffmpeg.exe" : "ffmpeg";
const targetFfmpegFile = join(targetDir, "bin", ffmpegName);
// Check if the folder has already been copied
if (!existsSync(targetFfmpegFile)) {
if (existsSync(bundledDir)) {
@ -684,7 +690,6 @@ class YtDownloaderApp {
return `${exeName}:${targetNodeFile}`;
}
return "";
}
@ -1500,6 +1505,25 @@ class YtDownloaderApp {
const speakerIconSvg = `<svg viewBox="0 0 24 24"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/></svg>`;
// Convert en -> English
const langFormatter = new Intl.DisplayNames(
[navigator.language || "en"],
{type: "language"},
);
const getLanguageName = (code) => {
if (!code) return "";
try {
// Split cases like "en-US"
const baseCode = code.split("-")[0];
const name = langFormatter.of(baseCode);
return name
? name.charAt(0).toUpperCase() + name.slice(1)
: code;
} catch (e) {
return code;
}
};
// Find the ideal match height boundary
formats.forEach((f) => {
if (
@ -1571,10 +1595,19 @@ class YtDownloaderApp {
const quality = `${format.height || "???"}p${format.fps === 60 ? "60" : ""}`;
const vcodecText = format.vcodec?.split(".")[0] || "";
const audioMarkup =
format.acodec !== "none"
? `<div class="audio-indicator">${speakerIconSvg}</div>`
: `<div class="audio-placeholder"></div>`;
let audioMarkup = `<div class="audio-placeholder"></div>`;
if (format.acodec !== "none") {
const langName = getLanguageName(format.language);
const langSpan = langName
? `<span class="lang-text">${langName}</span>`
: "";
audioMarkup = `
<div class="audio-indicator">
${speakerIconSvg}
${langSpan}
</div>
`;
}
const codecHtml = showMoreFormats
? `<span class="codec-text">${vcodecText}</span>`
@ -1589,14 +1622,14 @@ class YtDownloaderApp {
: `${quality} ${format.ext} ${displaySize}`;
const htmlContent = `
<div class="modern-option-row ${gridClass}">
<span class="main-text">${quality}</span>
<span class="badge badge-format">${format.ext}</span>
${codecHtml}
<span class="size-text">${displaySize}</span>
${audioMarkup}
</div>
`;
<div class="modern-option-row ${gridClass}">
<span class="main-text">${quality}</span>
<span class="badge badge-format">${format.ext}</span>
${codecHtml}
<span class="size-text">${displaySize}</span>
${audioMarkup}
</div>
`;
videoOptions.push({
text: optionTextFallback,
@ -1613,17 +1646,22 @@ class YtDownloaderApp {
if (!showMoreFormats && format.ext === "webm") return;
const audioExt = format.ext === "webm" ? "opus" : format.ext;
const langName = getLanguageName(format.language);
const displayLang = langName ? ` [${langName}]` : "";
const formatNote =
i18n.__(format.format_note) || i18n.__("unknownQuality");
(i18n.__(format.format_note) || i18n.__("unknownQuality")) +
displayLang;
// HTML for Audio Grid
const htmlContent = `
<div class="modern-option-row audio-grid">
<span class="main-text">${formatNote}</span>
<span class="badge badge-format">${audioExt}</span>
<span class="size-text">${displaySize}</span>
</div>
`;
<div class="modern-option-row audio-grid">
<span class="main-text">${formatNote}</span>
<span class="badge badge-format">${audioExt}</span>
<span class="size-text">${displaySize}</span>
</div>
`;
audioOptions.push({
text: `${formatNote} ${audioExt} ${displaySize}`,
@ -1703,10 +1741,10 @@ class YtDownloaderApp {
text: noAudioTxt,
value: "none|none",
html: `
<div class="modern-option-row audio-grid">
<span class="main-text">${noAudioTxt}</span>
</div>
`,
<div class="modern-option-row audio-grid">
<span class="main-text">${noAudioTxt}</span>
</div>
`,
});
mountSlimSelect(audioForVideoSelectEl, audioForVideoOptions);

Loading…
Cancel
Save