it's all about you and your native language!

- finally cleaned up localisation (now i18n)
- made localisation strings easier to read and understand
- removed static selected language in service modules
- added support for russian language (привет-привет)
- it's now extremely easy to add support for more languages. just copy en folder in i18n and start translating strings. pull requests for adding languages are more than welcome.
This commit is contained in:
wukko 2022-07-17 18:58:51 +06:00
parent 299fe6336b
commit d08af58b11
20 changed files with 139 additions and 62 deletions

View file

@ -17,10 +17,11 @@ cobalt doesn't remux any videos, so you get videos of max quality available (unl
## What still has to be done
- [ ] Quality switching for bilibili and Twitter
- [ ] Clean up the mess that localisation is right now
- [ ] Sort contents of .json files
- [ ] Rename each entry key to be less linked to specific service (entries like youtubeBroke are awful, I'm sorry)
- [ ] Add support for more languages when localisation clean up is done
- [ ] Language picker in settings
- [x] Clean up the mess that localisation is right now
- [x] Sort contents of .json files
- [x] Rename each entry key to be less linked to specific service (entries like youtubeBroke are awful, I'm sorry)
- [x] Add support for more languages when localisation clean up is done
- [ ] Use esmbuild to minify frontend css and js
- [ ] Make switch buttons in settings selectable with keyboard
- [ ] Do something about changelog because the way it is right now is not really great

View file

@ -5,7 +5,7 @@
"maxVideoDuration": 1920000,
"genericUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
"repo": "https://github.com/wukko/cobalt",
"supportedLanguages": ["en"],
"supportedLanguages": ["en", "ru"],
"authorInfo": {
"name": "wukko",
"link": "https://wukko.me/",

View file

@ -1,21 +1,18 @@
{
"generic": "something went wrong and i couldn't get the video. you can try again,",
"generic": "something went wrong and i couldn't get anything for you. you can try again, but if issue persists, please <a class=\"text-backdrop nowrap\" href=\"{repo}\">let me know</a>.",
"notSupported": "it seems like this service is not supported yet or your link is invalid.",
"brokenLink": "{s} is supported, but something is wrong with your link.",
"noURL": "i can't guess what you want to download! please give me a link.",
"tryAgain": "\ncheck the link and try again.",
"letMeKnow": "but if issue persists, please <a class=\"text-backdrop nowrap\" href=\"{repo}\">let me know</a>.",
"fatal": "something went wrong and page couldn't render. if you want me to fix this, please <a href=\"https://wukko.me/contacts\">contact me</a>. it'd be useful if you provided the commit hash ({s}) along with recreation steps. thank you :D",
"brokenLink": "{s} is supported, but something is wrong with your link. maybe you didn't copy it fully?",
"noLink": "i can't guess what you want to download! please give me a link.",
"noRender": "something went wrong and page couldn't render. if you want me to fix this, please <a href=\"https://wukko.me/contacts\">contact me</a>. it'd be useful if you provided the commit hash ({s}) along with recreation steps. thank you :D",
"rateLimit": "you're making way too many requests. calm down and try again in a few minutes.",
"youtubeFetch": "couldn't fetch metadata. check if your link is correct and try again.",
"youtubeLimit": "current length limit is {s} minutes. what you tried to download was longer than that. pick something else to download!",
"youtubeBroke": "something went wrong with info fetching. you can try a different format and resoltuion or just try again later.",
"corruptedVideo": "oddly enough the requested video is corrupted on its origin server. youtube does this sometimes because it's a hot pile of mess.",
"corruptedAudio": "oddly enough the requested audio is corrupted on its origin server. youtube does this sometimes because it's a hot pile of mess.",
"noFetch": "couldn't fetch metadata. check if your link is correct and try again.",
"lengthLimit": "current length limit is {s} minutes. what you tried to download was longer than that. pick something else to download!",
"errorFetch": "something went wrong with info fetching. you can try a different format and resoltuion or just try again later.",
"corruptedStream": "it seems like this download is corrupted. try again or try a different format and resolution.",
"noInternet": "it seems like there's no internet or {appName} api is down. check your connection and try again.",
"liveVideo": "i can't download a live video. wait for stream to finish and try again.",
"nothingToDownload": "it seems like there's nothing to download. try another link!",
"cantConnectToAPI": "i couldn't connect to {s} api. seems like either {s} is down or {appName} server ip got blocked. try again later.",
"noStreamID": "there's no such stream id.",
"nothingToDownload": "it seems like there's nothing to download. try another link!",
"liveVideo": "i can't download a live video. wait for stream to finish and try again.",
"noStreamID": "there's no such streamId.",
"noType": "there's no such expected response type."
}

View file

@ -16,6 +16,7 @@
"qmid": "medium\n",
"qlow": "low\n",
"qlos": "lowest",
"qualityDesc": "all resolutions listed here are max values. if there's no video of preferred quality, closest one gets picked instead.",
"extra": "extra"
"qualityDesc": "if selected resolution isn't available, closest one gets picked instead.",
"extra": "extra",
"audioOnly": "audio only"
}

View file

@ -11,7 +11,7 @@
"donateDm": "&gt;&gt; let me know if currency you want to donate isn't listed",
"clickToCopy": "click to copy",
"iosDownload": "you have to press and hold the download button and then select \"download video\" in appeared popup to save the video. this is required because you have an ios device.",
"normalDownload": "download button opens a new tab with requested video. you can disable this popup in settings.",
"normalDownload": "download button opens a new tab with requested file. you can disable this popup in settings.",
"download": "download",
"copy": "copy url",
"open": "open",

View file

@ -0,0 +1,11 @@
{
"about": "Что за {appName}?",
"settings": "Открыть настройки",
"input": "Вставь ссылку сюда",
"download": "Кнопка скачивания",
"changelog": "Посмотреть последние изменения (на английском)",
"close": "Закрыть окно",
"alwaysVisibleButton": "Всегда оставлять кнопку скачивания на экране",
"downloadPopup": "Спрашивать что делать с загрузками",
"donate": "Пожертвования"
}

18
src/i18n/ru/apiError.json Normal file
View file

@ -0,0 +1,18 @@
{
"generic": "что-то пошло совсем не так и у меня не получилось ничего для тебя достать. ты можешь попробовать ещё раз, но если так и не получится, <a class=\"text-backdrop nowrap\" href=\"{repo}\">напиши об этом</a>.",
"notSupported": "этот сервис ещё не поддерживается или с твоей ссылкой что-то не так.",
"brokenLink": "{s} поддерживается, но с твоей ссылкой что-то не так. может быть ты её не полностью скопировал?",
"noLink": "я не могу угадать что ты хочешь скачать. попробуй в следующий раз вставить ссылку.",
"noRender": "что-то пошло не так и у меня не получилось срендерить страницу. если это что-то критичное, пожалуйста, <a href=\"https://wukko.me/contacts\">напиши мне об этом</a>. приложи хэш текущего коммита ({s}) с действиями для получения ошибки. можно на русском языке. спасибо :)",
"rateLimit": "ты делаешь слишком много запросов. успокойся и попробуй ещё раз через несколько минут.",
"noFetch": "мне не удалось получить информацию о твоей ссылке. проверь её и попробуй ещё раз.",
"lengthLimit": "твоё видео было длиннее чем {s} минуты. это превышает текущий лимит. скачай что-нибудь покороче, а не войну и мир.",
"errorFetch": "что-то пошло не так с получением данных о твоей ссылке. попробуй другой формат и разрешение. если не получится, то попробуй ещё раз чуть позже.",
"corruptedStream": "эта загрузка повреждена. попробуй ещё раз. если не получится, то попробуй другой формат и разрешение.",
"noInternet": "кажется нет подключения к интернету. а возможно лежу я, а не твой интернет. в любом случае, проверь подключение к интернету и попробуй ещё раз.",
"cantConnectToAPI": "не получилось подключится к серверу {s}. {s} либо лежит, либо меня добавили в чёрный список. попробуй ещё раз чуть позже.",
"nothingToDownload": "мне нечего скачать. попробуй другую ссылку!",
"liveVideo": "я не могу скачать прямой эфир. дождись окончания трансляции и попробуй ещё раз.",
"noStreamID": "нет такого streamId.",
"noType": "нет такого формата ответа от сервера."
}

22
src/i18n/ru/settings.json Normal file
View file

@ -0,0 +1,22 @@
{
"appearance": "внешний вид",
"alwaysVisibleButton": "оставлять >> на экране",
"downloadPopupButton": "спрашивать что делать с загрузками",
"format": "формат загрузок",
"formatInfo": "выбирай webm если хочешь максимальное качество. webm обычно лучше чем mp4 в плане качества, но устройства на ios не могут их проигрывать без сторонних приложений. все загрузки \"только аудио\" всегда максимального качества.",
"theme": "тема",
"themeAuto": "авто",
"themeLight": "светлая",
"themeDark": "тёмная",
"misc": "ещё",
"general": "загрузки",
"quality": "качество",
"qmax": "макс",
"qhig": "высокое\n",
"qmid": "среднее\n",
"qlow": "низкое\n",
"qlos": "ужасное",
"qualityDesc": "если выбранное разрешение недоступно, то выбирается ближайшее.",
"extra": "ещё",
"audioOnly": "только аудио"
}

18
src/i18n/ru/strings.json Normal file
View file

@ -0,0 +1,18 @@
{
"input": "вставь ссылку сюда",
"aboutSummary": "{appName} — твой друг при скачивании видео с соц.сетей. никакой рекламы или трекеров. просто вставь ссылку и ты прекрасен.",
"embed": "сохраняй что хочешь без мороки и вторжения в личное пространство",
"supportedServices": "что поддерживается:",
"sourceCode": "&gt;&gt; сообщай о проблемах на github",
"popupBottom": "сделано с <3 ~ wukko",
"noScript": "{appName} использует javascript для обработки ссылок и интерактивного интерфейса. ты должен разрешить использование javascript чтобы пользоваться сайтом. тут нет никаких трекеров или рекламы, обещаю.",
"donationsSub": "сейчас намного сложнее платить за хостинг",
"donations": "я ненавижу крипто, но у меня нет возможности платить любым другим способом.",
"donateDm": "&gt;&gt; если нет подходящей валюты, или же ты из россии, то напиши мне",
"clickToCopy": "нажми чтобы скопировать",
"iosDownload": "так как у тебя устройство на ios, тебе нужно зажать кнопку \"скачать\" и выбрать что-то похожее на \"сохранить в галерею\" в появившемся окне.",
"normalDownload": "кнопка скачивания открывает новое окно с файлом. ты можешь отключить метод сохранения файла в настройках.",
"download": "скачать",
"copy": "скопировать ссылку",
"github": "&gt;&gt; посмотреть предыдущие изменения на github"
}

9
src/i18n/ru/title.json Normal file
View file

@ -0,0 +1,9 @@
{
"about": "что за {appName}?",
"settings": "настройки",
"error": "о нет",
"changelog": "что нового?",
"donate": "поддержи {appName}",
"download": "скачивание",
"pickDownload": "как сохранить?"
}

View file

@ -30,6 +30,6 @@ export async function getJSON(originalURL, ip, lang, format, quality) {
return apiJSON(0, { t: errorUnsupported(lang) } )
}
} catch (e) {
return apiJSON(0, { t: loc(lang, 'apiError', 'generic') + loc(lang, 'apiError', 'letMeKnow') });
return apiJSON(0, { t: loc(lang, 'apiError', 'generic') });
}
}

View file

@ -34,7 +34,7 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
lang: lang
});
return (!r.error) ? apiJSON(2, {
type: "render", urls: r.urls,
type: "render", urls: r.urls, lang: lang,
service: host, ip: ip,
filename: r.filename,
salt: process.env.streamSalt, time: r.time
@ -73,7 +73,7 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
let r = await reddit({
sub: patternMatch["sub"],
id: patternMatch["id"],
title: patternMatch["title"]
title: patternMatch["title"], lang: lang,
});
return (!r.error) ? apiJSON(2, {
type: "render", urls: r.urls,

View file

@ -17,7 +17,7 @@ let enabledServices = Object.keys(s).filter((p) => {
let donate = ``
for (let i in donations) {
donate += `<div class="subtitle">${i} (${loc("en", 'desc', 'clickToCopy').trim()})</div><div id="don-${i}" class="text-to-copy" onClick="copy('don-${i}')">${donations[i]}</div>`
donate += `<div class="subtitle">${i} (REPLACEME)</div><div id="don-${i}" class="text-to-copy" onClick="copy('don-${i}')">${donations[i]}</div>`
}
let com = getCommitInfo();
@ -34,10 +34,10 @@ export default function(obj) {
<meta property="og:url" content="${process.env.selfURL}" />
<meta property="og:title" content="${appName}" />
<meta property="og:description" content="${loc(obj.lang, 'desc', 'embed')}" />
<meta property="og:description" content="${loc(obj.lang, 'strings', 'embed')}" />
<meta property="og:image" content="${process.env.selfURL}icons/generic.png" />
<meta name="title" content="${appName}" />
<meta name="description" content="${loc(obj.lang, 'desc', 'embed')}" />
<meta name="description" content="${loc(obj.lang, 'strings', 'embed')}" />
<meta name="theme-color" content="#000000" />
<meta name="twitter:card" content="summary" />
@ -50,7 +50,7 @@ export default function(obj) {
<link rel="stylesheet" href="cobalt.css" />
<link rel="stylesheet" href="fonts/notosansmono/notosansmono.css" />
<noscript><div style="margin: 2rem;">${loc(obj.lang, 'desc', 'noScript')}</div></noscript>
<noscript><div style="margin: 2rem;">${loc(obj.lang, 'strings', 'noScript')}</div></noscript>
</head>
<body id="cobalt-body">
<div id="popup-download" class="popup center box" style="visibility: hidden;">
@ -62,11 +62,11 @@ export default function(obj) {
<div id="theme-switcher" class="switch-container small-padding">
<div class="subtitle">${loc(obj.lang, 'title', 'pickDownload')}</div>
<div class="switches">
<a id="pd-download" class="switch full space-right" target="_blank"">${loc(obj.lang, 'desc', 'download')}</a>
<div id="pd-copy" class="switch full">${loc(obj.lang, 'desc', 'copy')}</div>
<a id="pd-download" class="switch full space-right" target="_blank"">${loc(obj.lang, 'strings', 'download')}</a>
<div id="pd-copy" class="switch full">${loc(obj.lang, 'strings', 'copy')}</div>
</div>
</div>
<div id="desc" class="explanation about-padding">${isIOS ? loc(obj.lang, 'desc', 'iosDownload') : loc(obj.lang, 'desc', 'normalDownload')}</div>
<div id="desc" class="explanation about-padding">${isIOS ? loc(obj.lang, 'strings', 'iosDownload') : loc(obj.lang, 'strings', 'normalDownload')}</div>
</div>
</div>
<div id="popup-about" class="popup center box" style="visibility: hidden;">
@ -75,12 +75,12 @@ export default function(obj) {
<div id="title" class="popup-title">${loc(obj.lang, 'title', 'about')}</div>
</div>
<div id="content" class="popup-content with-footer">
<div id="desc" class="popup-desc about-padding">${loc(obj.lang, 'desc', 'aboutSummary')}</div>
<div id="desc" class="popup-desc about-padding">${loc(obj.lang, 'desc', 'supportedServices')} ${enabledServices}.</div>
<div id="desc" class="popup-desc"><a class="text-backdrop" href="${repo}">${loc(obj.lang, 'desc', 'sourceCode')}</a></div>
<div id="desc" class="popup-desc about-padding">${loc(obj.lang, 'strings', 'aboutSummary')}</div>
<div id="desc" class="popup-desc about-padding">${loc(obj.lang, 'strings', 'supportedServices')} ${enabledServices}.</div>
<div id="desc" class="popup-desc"><a class="text-backdrop" href="${repo}">${loc(obj.lang, 'strings', 'sourceCode')}</a></div>
</div>
<div id="popup-footer" class="popup-footer">
<a id="popup-bottom" class="popup-footer-content" href="${authorInfo.link}">${loc(obj.lang, 'desc', 'popupBottom')}</a>
<a id="popup-bottom" class="popup-footer-content" href="${authorInfo.link}">${loc(obj.lang, 'strings', 'popupBottom')}</a>
</div>
</div>
<div id="popup-changelog" class="popup center box" style="visibility: hidden;">
@ -91,19 +91,19 @@ export default function(obj) {
</div>
<div id="content" class="popup-content">
<div id="desc" class="popup-desc about-padding">${com[1]}</div>
<div id="desc" class="popup-desc"><a class="text-backdrop" href="${repo}/commits">${loc(obj.lang, 'desc', 'github')}</a></div>
<div id="desc" class="popup-desc"><a class="text-backdrop" href="${repo}/commits">${loc(obj.lang, 'strings', 'github')}</a></div>
</div>
</div>
<div id="popup-donate" class="popup scrollable center box" style="visibility: hidden;">
<div id="popup-header" class="popup-header">
<button id="close" class="button mono" onclick="popup('donate', 0)" aria-label="${loc(obj.lang, 'accessibility', 'close')}">x</button>
<div id="title" class="popup-title">${loc(obj.lang, 'title', 'donate')}</div>
<div id="desc" class="little-subtitle">${loc(obj.lang, 'desc', 'donationsSub')}</div>
<div id="desc" class="little-subtitle">${loc(obj.lang, 'strings', 'donationsSub')}</div>
</div>
<div id="content" class="popup-content">
${donate}
<div id="desc" class="explanation about-padding">${loc(obj.lang, 'desc', 'donations')}</div>
<div id="desc" class="popup-desc"><a class="text-backdrop" href="${authorInfo.contact}">${loc(obj.lang, 'desc', 'donateDm')}</a></div>
${donate.replace(/REPLACEME/g, loc(obj.lang, 'strings', 'clickToCopy').trim())}
<div id="desc" class="explanation about-padding">${loc(obj.lang, 'strings', 'donations')}</div>
<div id="desc" class="popup-desc"><a class="text-backdrop" href="${authorInfo.contact}">${loc(obj.lang, 'strings', 'donateDm')}</a></div>
</div>
</div>
<div id="popup-settings" class="popup scrollable center box" style="visibility: hidden;">
@ -159,7 +159,7 @@ export default function(obj) {
<div class="switches">
<div id="youtubeFormat-mp4" class="switch full" onclick="changeSwitcher('youtubeFormat', 'mp4', 1)">mp4</div>
<div id="youtubeFormat-webm" class="switch" onclick="changeSwitcher('youtubeFormat', 'webm', 1)">webm</div>
<div id="youtubeFormat-audio" class="switch full" onclick="changeSwitcher('youtubeFormat', 'audio', 1)">audio only</div>
<div id="youtubeFormat-audio" class="switch full" onclick="changeSwitcher('youtubeFormat', 'audio', 1)">${loc(obj.lang, 'settings', 'audioOnly')}</div>
</div>
<div class="explanation">${loc(obj.lang, 'settings', 'formatInfo')}</div>
</div>
@ -180,7 +180,7 @@ export default function(obj) {
<div id="cobalt-main-box" class="center box" style="visibility: hidden;">
<div id="logo-area">${appName}</div>
<div id="download-area" class="mobile-center">
<input id="url-input-area" class="mono" type="text" autocorrect="off" maxlength="110" autocapitalize="off" placeholder="${loc(obj.lang, 'desc', 'input')}" aria-label="${loc(obj.lang, 'accessibility', 'input')}" oninput="button()">
<input id="url-input-area" class="mono" type="text" autocorrect="off" maxlength="110" autocapitalize="off" placeholder="${loc(obj.lang, 'strings', 'input')}" aria-label="${loc(obj.lang, 'accessibility', 'input')}" oninput="button()">
<input id="download-button" class="mono dontRead" onclick="download(document.getElementById('url-input-area').value)" type="submit" value="" disabled=true aria-label="${loc(obj.lang, 'accessibility', 'download')}">
</div>
</div>
@ -197,6 +197,6 @@ export default function(obj) {
<script type="text/javascript" src="cobalt.js"></script>
</html>`;
} catch (err) {
return `${loc('en', 'apiError', 'fatal', obj.hash)}`;
return `${loc('en', 'apiError', 'noRender', obj.hash)}`;
}
}

View file

@ -8,7 +8,7 @@ export default async function(obj) {
headers: { "user-agent": genericUserAgent }
});
html.on('error', (err) => {
return { error: loc('en', 'apiError', 'youtubeFetch') };
return { error: loc(obj.lang, 'apiError', 'cantConnectToAPI', 'bilibili') };
});
html = html.body;
if (html.includes('<script>window.__playinfo__=') && html.includes('"video_codecid"')) {
@ -22,13 +22,13 @@ export default async function(obj) {
}).sort((a, b) => Number(b.bandwidth) - Number(a.bandwidth));
return { urls: [video[0]["baseUrl"], audio[0]["baseUrl"]], time: streamData.data.timelength, filename: `bilibili_${obj.id}_${video[0]["width"]}x${video[0]["height"]}.mp4` };
} else {
return { error: loc('en', 'apiError', 'youtubeLimit', maxVideoDuration / 60000) };
return { error: loc(obj.lang, 'apiError', 'lengthLimit', maxVideoDuration / 60000) };
}
} else {
return { error: loc('en', 'apiError', 'youtubeFetch') };
return { error: loc(obj.lang, 'apiError', 'nothingToDownload') };
}
} catch (e) {
return { error: loc('en', 'apiError', 'youtubeFetch') };
return { error: loc(obj.lang, 'apiError', 'noFetch') };
}
}

View file

@ -9,9 +9,9 @@ export default async function(obj) {
if ("reddit_video" in data["secure_media"] && data["secure_media"]["reddit_video"]["duration"] * 1000 < maxVideoDuration) {
return { urls: [data["secure_media"]["reddit_video"]["fallback_url"].split('?')[0], `${data["secure_media"]["reddit_video"]["fallback_url"].split('_')[0]}_audio.mp4`], filename: `reddit_${data["secure_media"]["reddit_video"]["fallback_url"].split('/')[3]}.mp4` };
} else {
return { error: loc('en', 'apiError', 'nothingToDownload') };
return { error: loc(obj.lang, 'apiError', 'nothingToDownload') };
}
} catch (err) {
return { error: loc("en", "apiError", "nothingToDownload") };
return { error: loc(obj.lang, 'apiError', 'noFetch') };
}
}

View file

@ -52,6 +52,6 @@ export default async function (obj) {
}
} else return parsbod;
} catch (err) {
return { error: loc("en", "apiError", "youtubeBroke") };
return { error: loc("en", "apiError", "errorFetch") };
}
}

View file

@ -30,18 +30,18 @@ export default async function(obj) {
if (selectedQuality in js["player"]["params"][0]) {
return { url: js["player"]["params"][0][selectedQuality].replace(`type=${maxQuality}`, `type=${services.vk.quality_match[userQuality]}`), filename: `vk_${js["player"]["params"][0][selectedQuality].split("id=")[1]}_${attr['width']}x${attr['height']}.mp4` };
} else {
return { error: loc('en', 'apiError', 'nothingToDownload') };
return { error: loc(obj.lang, 'apiError', 'nothingToDownload') };
}
} else {
return { error: loc('en', 'apiError', 'youtubeLimit', maxVideoDuration / 60000) };
return { error: loc(obj.lang, 'apiError', 'lengthLimit', maxVideoDuration / 60000) };
}
} else {
return { error: loc('en', 'apiError', 'liveVideo') };
return { error: loc(obj.lang, 'apiError', 'liveVideo') };
}
} else {
return { error: loc('en', 'apiError', 'nothingToDownload') };
return { error: loc(obj.lang, 'apiError', 'nothingToDownload') };
}
} catch (err) {
return { error: loc('en', 'apiError', 'youtubeFetch') };
return { error: loc(obj.lang, 'apiError', 'errorFetch') };
}
}

View file

@ -48,7 +48,7 @@ export default async function (obj) {
filename: `youtube_${obj.id}_${videoMatch[0]["width"]}x${videoMatch[0]["height"]}.${obj.format}` };
}
} else {
return { error: loc('en', 'apiError', 'youtubeBroke') };
return { error: loc('en', 'apiError', 'errorFetch') };
}
} else if (!obj.isAudioOnly) {
return { type: "render", urls: [video[0]["url"], audio[0]["url"]], time: video[0]["approxDurationMs"],
@ -56,10 +56,10 @@ export default async function (obj) {
} else if (audio.length > 0) {
return { type: "render", isAudioOnly: true, urls: [audio[0]["url"]], filename: `youtube_${obj.id}_${audio[0]["audioBitrate"]}kbps.opus` };
} else {
return { error: loc('en', 'apiError', 'youtubeBroke') };
return { error: loc('en', 'apiError', 'errorFetch') };
}
} else {
return { error: loc('en', 'apiError', 'youtubeLimit', maxVideoDuration / 60000) };
return { error: loc('en', 'apiError', 'lengthLimit', maxVideoDuration / 60000) };
}
} else {
return { error: loc('en', 'apiError', 'liveVideo') };

View file

@ -68,7 +68,7 @@ export async function streamLiveRender(streamInfo, res) {
ffmpegProcess.kill();
});
} else {
res.status(400).json({ status: "error", text: loc('en', 'apiError', 'corruptedVideo') });
res.status(400).json({ status: "error", text: loc('en', 'apiError', 'corruptedStream') });
}
} catch (e) {
internalError(res);

View file

@ -4,8 +4,8 @@ export function internalError(res) {
res.status(501).json({ status: "error", text: "Internal Server Error" });
}
export function errorUnsupported(lang) {
return loc(lang, 'apiError', 'notSupported') + loc(lang, 'apiError', 'letMeKnow');
return loc(lang, 'apiError', 'notSupported');
}
export function genericError(lang, host) {
return loc(lang, 'apiError', 'brokenLink', host) + loc(lang, 'apiError', 'letMeKnow');
return loc(lang, 'apiError', 'brokenLink', host);
}