mirror of
https://github.com/imputnet/cobalt.git
synced 2025-07-10 15:28:29 +00:00
Merge branch 'main' into clipboard
This commit is contained in:
commit
e8703982b9
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@imput/cobalt-api",
|
"name": "@imput/cobalt-api",
|
||||||
"description": "save what you love",
|
"description": "save what you love",
|
||||||
"version": "11.2",
|
"version": "11.2.2",
|
||||||
"author": "imput",
|
"author": "imput",
|
||||||
"exports": "./src/cobalt.js",
|
"exports": "./src/cobalt.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@ -26,6 +26,7 @@
|
|||||||
"@datastructures-js/priority-queue": "^6.3.1",
|
"@datastructures-js/priority-queue": "^6.3.1",
|
||||||
"@imput/psl": "^2.0.4",
|
"@imput/psl": "^2.0.4",
|
||||||
"@imput/version-info": "workspace:^",
|
"@imput/version-info": "workspace:^",
|
||||||
|
"@imput/youtubei.js": "^14.0.0",
|
||||||
"content-disposition-header": "0.6.0",
|
"content-disposition-header": "0.6.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^16.0.1",
|
"dotenv": "^16.0.1",
|
||||||
@ -37,9 +38,8 @@
|
|||||||
"mime": "^4.0.4",
|
"mime": "^4.0.4",
|
||||||
"nanoid": "^5.0.9",
|
"nanoid": "^5.0.9",
|
||||||
"set-cookie-parser": "2.6.0",
|
"set-cookie-parser": "2.6.0",
|
||||||
"undici": "^5.19.1",
|
"undici": "^6.21.3",
|
||||||
"url-pattern": "1.0.3",
|
"url-pattern": "1.0.3",
|
||||||
"youtubei.js": "^14.0.0",
|
|
||||||
"zod": "^3.23.8"
|
"zod": "^3.23.8"
|
||||||
},
|
},
|
||||||
"optionalDependencies": {
|
"optionalDependencies": {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Constants } from "youtubei.js";
|
import { Constants } from "@imput/youtubei.js";
|
||||||
import { services } from "../processing/service-config.js";
|
import { services } from "../processing/service-config.js";
|
||||||
import { updateEnv, canonicalEnv, env as currentEnv } from "../config.js";
|
import { updateEnv, canonicalEnv, env as currentEnv } from "../config.js";
|
||||||
|
|
||||||
|
@ -49,5 +49,6 @@ const maps = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const convertLanguageCode = (code) => {
|
export const convertLanguageCode = (code) => {
|
||||||
|
code = code?.split("-")[0]?.split("_")[0] || "";
|
||||||
return maps[code.length]?.[code.toLowerCase()] || null;
|
return maps[code.length]?.[code.toLowerCase()] || null;
|
||||||
}
|
}
|
||||||
|
@ -263,8 +263,9 @@ export default function({
|
|||||||
|
|
||||||
// extractors usually return ISO 639-1 language codes,
|
// extractors usually return ISO 639-1 language codes,
|
||||||
// but video players expect ISO 639-2, so we convert them here
|
// but video players expect ISO 639-2, so we convert them here
|
||||||
if (defaultParams.fileMetadata?.sublanguage?.length === 2) {
|
const sublanguage = defaultParams.fileMetadata?.sublanguage;
|
||||||
const code = convertLanguageCode(defaultParams.fileMetadata.sublanguage);
|
if (sublanguage && sublanguage.length !== 3) {
|
||||||
|
const code = convertLanguageCode(sublanguage);
|
||||||
if (code) {
|
if (code) {
|
||||||
defaultParams.fileMetadata.sublanguage = code;
|
defaultParams.fileMetadata.sublanguage = code;
|
||||||
} else {
|
} else {
|
||||||
|
@ -15,7 +15,46 @@ const resolutionMatch = {
|
|||||||
"426": 240
|
"426": 240
|
||||||
}
|
}
|
||||||
|
|
||||||
const requestApiInfo = (videoId, password) => {
|
const genericHeaders = {
|
||||||
|
Accept: 'application/vnd.vimeo.*+json; version=3.4.10',
|
||||||
|
'User-Agent': 'Vimeo/11.13.0 (com.vimeo; build:250619.102023.0; iOS 18.5.0) Alamofire/5.9.0 VimeoNetworking/5.0.0',
|
||||||
|
Authorization: 'Basic MTMxNzViY2Y0NDE0YTQ5YzhjZTc0YmU0NjVjNDQxYzNkYWVjOWRlOTpHKzRvMmgzVUh4UkxjdU5FRW80cDNDbDhDWGR5dVJLNUJZZ055dHBHTTB4V1VzaG41bEx1a2hiN0NWYWNUcldSSW53dzRUdFRYZlJEZmFoTTArOTBUZkJHS3R4V2llYU04Qnl1bERSWWxUdXRidjNqR2J4SHFpVmtFSUcyRktuQw==',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.9',
|
||||||
|
}
|
||||||
|
|
||||||
|
let bearer = '';
|
||||||
|
|
||||||
|
const getBearer = async (refresh = false) => {
|
||||||
|
if (bearer && !refresh) return bearer;
|
||||||
|
|
||||||
|
const oauthResponse = await fetch(
|
||||||
|
`https://api.vimeo.com/oauth/authorize/client?sizes=216,288,300,360,640,960,1280,1920&cdm_type=fairplay`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({
|
||||||
|
scope: 'public private purchased create edit delete interact upload stats',
|
||||||
|
grant_type: 'client_credentials',
|
||||||
|
// device_identifier is a long ass base64 string of seemingly
|
||||||
|
// random data, but it doesn't seem to be required, so we just omit it lol
|
||||||
|
device_identifier: '',
|
||||||
|
}),
|
||||||
|
headers: {
|
||||||
|
...genericHeaders,
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.then(a => a.json())
|
||||||
|
.catch(() => {});
|
||||||
|
|
||||||
|
if (!oauthResponse || !oauthResponse.access_token) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return bearer = oauthResponse.access_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestApiInfo = (bearerToken, videoId, password) => {
|
||||||
if (password) {
|
if (password) {
|
||||||
videoId += `:${password}`
|
videoId += `:${password}`
|
||||||
}
|
}
|
||||||
@ -24,10 +63,8 @@ const requestApiInfo = (videoId, password) => {
|
|||||||
`https://api.vimeo.com/videos/${videoId}`,
|
`https://api.vimeo.com/videos/${videoId}`,
|
||||||
{
|
{
|
||||||
headers: {
|
headers: {
|
||||||
Accept: 'application/vnd.vimeo.*+json; version=3.4.2',
|
...genericHeaders,
|
||||||
'User-Agent': 'Vimeo/10.19.0 (com.vimeo; build:101900.57.0; iOS 17.5.1) Alamofire/5.9.0 VimeoNetworking/5.0.0',
|
Authorization: `Bearer ${bearerToken}`,
|
||||||
Authorization: 'Basic MTMxNzViY2Y0NDE0YTQ5YzhjZTc0YmU0NjVjNDQxYzNkYWVjOWRlOTpHKzRvMmgzVUh4UkxjdU5FRW80cDNDbDhDWGR5dVJLNUJZZ055dHBHTTB4V1VzaG41bEx1a2hiN0NWYWNUcldSSW53dzRUdFRYZlJEZmFoTTArOTBUZkJHS3R4V2llYU04Qnl1bERSWWxUdXRidjNqR2J4SHFpVmtFSUcyRktuQw==',
|
|
||||||
'Accept-Language': 'en'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -151,9 +188,28 @@ export default async function(obj) {
|
|||||||
if (quality < 240) quality = 240;
|
if (quality < 240) quality = 240;
|
||||||
if (!quality || obj.isAudioOnly) quality = 9000;
|
if (!quality || obj.isAudioOnly) quality = 9000;
|
||||||
|
|
||||||
const info = await requestApiInfo(obj.id, obj.password);
|
const bearerToken = await getBearer();
|
||||||
|
if (!bearerToken) {
|
||||||
|
return { error: "fetch.fail" };
|
||||||
|
}
|
||||||
|
|
||||||
|
let info = await requestApiInfo(bearerToken, obj.id, obj.password);
|
||||||
let response;
|
let response;
|
||||||
|
|
||||||
|
// auth error, try to refresh the token
|
||||||
|
if (info?.error_code === 8003) {
|
||||||
|
const newBearer = await getBearer(true);
|
||||||
|
if (!newBearer) {
|
||||||
|
return { error: "fetch.fail" };
|
||||||
|
}
|
||||||
|
info = await requestApiInfo(newBearer, obj.id, obj.password);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if there's still no info, then return a generic error
|
||||||
|
if (!info || info.error_code) {
|
||||||
|
return { error: "fetch.empty" };
|
||||||
|
}
|
||||||
|
|
||||||
if (obj.isAudioOnly) {
|
if (obj.isAudioOnly) {
|
||||||
response = await getHLS(info.config_url, { ...obj, quality });
|
response = await getHLS(info.config_url, { ...obj, quality });
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import HLS from "hls-parser";
|
import HLS from "hls-parser";
|
||||||
|
|
||||||
import { fetch } from "undici";
|
import { fetch } from "undici";
|
||||||
import { Innertube, Session } from "youtubei.js";
|
import { Innertube, Session } from "@imput/youtubei.js";
|
||||||
|
|
||||||
import { env } from "../../config.js";
|
import { env } from "../../config.js";
|
||||||
import { getCookie } from "../cookie/manager.js";
|
import { getCookie } from "../cookie/manager.js";
|
||||||
|
@ -19,6 +19,9 @@ importers:
|
|||||||
'@imput/version-info':
|
'@imput/version-info':
|
||||||
specifier: workspace:^
|
specifier: workspace:^
|
||||||
version: link:../packages/version-info
|
version: link:../packages/version-info
|
||||||
|
'@imput/youtubei.js':
|
||||||
|
specifier: ^14.0.0
|
||||||
|
version: 14.0.0
|
||||||
content-disposition-header:
|
content-disposition-header:
|
||||||
specifier: 0.6.0
|
specifier: 0.6.0
|
||||||
version: 0.6.0
|
version: 0.6.0
|
||||||
@ -53,14 +56,11 @@ importers:
|
|||||||
specifier: 2.6.0
|
specifier: 2.6.0
|
||||||
version: 2.6.0
|
version: 2.6.0
|
||||||
undici:
|
undici:
|
||||||
specifier: ^5.19.1
|
specifier: ^6.21.3
|
||||||
version: 5.28.4
|
version: 6.21.3
|
||||||
url-pattern:
|
url-pattern:
|
||||||
specifier: 1.0.3
|
specifier: 1.0.3
|
||||||
version: 1.0.3
|
version: 1.0.3
|
||||||
youtubei.js:
|
|
||||||
specifier: ^14.0.0
|
|
||||||
version: 14.0.0
|
|
||||||
zod:
|
zod:
|
||||||
specifier: ^3.23.8
|
specifier: ^3.23.8
|
||||||
version: 3.23.8
|
version: 3.23.8
|
||||||
@ -563,6 +563,9 @@ packages:
|
|||||||
'@imput/psl@2.0.4':
|
'@imput/psl@2.0.4':
|
||||||
resolution: {integrity: sha512-vuy76JX78/DnJegLuJoLpMmw11JTA/9HvlIADg/f8dDVXyxbh0jnObL0q13h+WvlBO4Gk26Pu8sUa7/h0JGQig==}
|
resolution: {integrity: sha512-vuy76JX78/DnJegLuJoLpMmw11JTA/9HvlIADg/f8dDVXyxbh0jnObL0q13h+WvlBO4Gk26Pu8sUa7/h0JGQig==}
|
||||||
|
|
||||||
|
'@imput/youtubei.js@14.0.0':
|
||||||
|
resolution: {integrity: sha512-YvTnh53URPlzsmMzqF/DFHZyR9HrpgoWYHzEOklx5OCkwk1/0F/CrO9gqArXw/1oI6GjaTS2CqBd1CzyFZB07A==}
|
||||||
|
|
||||||
'@isaacs/cliui@8.0.2':
|
'@isaacs/cliui@8.0.2':
|
||||||
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@ -2080,6 +2083,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==}
|
resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==}
|
||||||
engines: {node: '>=14.0'}
|
engines: {node: '>=14.0'}
|
||||||
|
|
||||||
|
undici@6.21.3:
|
||||||
|
resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==}
|
||||||
|
engines: {node: '>=18.17'}
|
||||||
|
|
||||||
unist-util-stringify-position@2.0.3:
|
unist-util-stringify-position@2.0.3:
|
||||||
resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==}
|
resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==}
|
||||||
|
|
||||||
@ -2181,9 +2188,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
youtubei.js@14.0.0:
|
|
||||||
resolution: {integrity: sha512-KAFttOw+9fwwBUvBc1T7KzMNBLczDOuN/dfote8BA9CABxgx8MPgV+vZWlowdDB6DnHjSUYppv+xvJ4VNBLK9A==}
|
|
||||||
|
|
||||||
zimmerframe@1.1.2:
|
zimmerframe@1.1.2:
|
||||||
resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
|
resolution: {integrity: sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w==}
|
||||||
|
|
||||||
@ -2396,7 +2400,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
levn: 0.4.1
|
levn: 0.4.1
|
||||||
|
|
||||||
'@fastify/busboy@2.1.1': {}
|
'@fastify/busboy@2.1.1':
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@fontsource/ibm-plex-mono@5.0.13': {}
|
'@fontsource/ibm-plex-mono@5.0.13': {}
|
||||||
|
|
||||||
@ -2423,6 +2428,13 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
|
|
||||||
|
'@imput/youtubei.js@14.0.0':
|
||||||
|
dependencies:
|
||||||
|
'@bufbuild/protobuf': 2.2.5
|
||||||
|
jintr: 3.3.1
|
||||||
|
tslib: 2.6.3
|
||||||
|
undici: 6.21.3
|
||||||
|
|
||||||
'@isaacs/cliui@8.0.2':
|
'@isaacs/cliui@8.0.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
string-width: 5.1.2
|
string-width: 5.1.2
|
||||||
@ -3960,6 +3972,9 @@ snapshots:
|
|||||||
undici@5.28.4:
|
undici@5.28.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@fastify/busboy': 2.1.1
|
'@fastify/busboy': 2.1.1
|
||||||
|
optional: true
|
||||||
|
|
||||||
|
undici@6.21.3: {}
|
||||||
|
|
||||||
unist-util-stringify-position@2.0.3:
|
unist-util-stringify-position@2.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -4035,13 +4050,6 @@ snapshots:
|
|||||||
|
|
||||||
yocto-queue@0.1.0: {}
|
yocto-queue@0.1.0: {}
|
||||||
|
|
||||||
youtubei.js@14.0.0:
|
|
||||||
dependencies:
|
|
||||||
'@bufbuild/protobuf': 2.2.5
|
|
||||||
jintr: 3.3.1
|
|
||||||
tslib: 2.6.3
|
|
||||||
undici: 5.28.4
|
|
||||||
|
|
||||||
zimmerframe@1.1.2: {}
|
zimmerframe@1.1.2: {}
|
||||||
|
|
||||||
zod@3.23.8: {}
|
zod@3.23.8: {}
|
||||||
|
@ -6,7 +6,7 @@ banner:
|
|||||||
alt: "meowth plush in a forest looking at the rising sun between the trees."
|
alt: "meowth plush in a forest looking at the rising sun between the trees."
|
||||||
---
|
---
|
||||||
|
|
||||||
it's summertime! even though it's been rainy for us lately, the sun is right on the horizon, just like this cobalt update. we improved local processing, added long-awaited features, and improved a ton of other stuff. **downloading from youtube is back, btw**.
|
it's summertime! even though it's been rainy for us lately, the sun is right on the horizon, just like this cobalt update. we improved local processing, added long-awaited features, and improved a ton of other stuff.
|
||||||
|
|
||||||
here's what's new since 11.0:
|
here's what's new since 11.0:
|
||||||
|
|
||||||
@ -31,6 +31,8 @@ downloading from youtube on the main instance is restored! sorry that it took a
|
|||||||
|
|
||||||
hopefully it'll last for a while, but we think downloading from youtube will get significantly more annoying/complex in next few weeks-months. **right now is the best time to download everything you've been putting off**, either with cobalt or other tools.
|
hopefully it'll last for a while, but we think downloading from youtube will get significantly more annoying/complex in next few weeks-months. **right now is the best time to download everything you've been putting off**, either with cobalt or other tools.
|
||||||
|
|
||||||
|
**update**: unfortunately it did not last, youtube is unavailable on the main instance again. we will try one more way soon and update this changelog and post about it on socials accordingly.
|
||||||
|
|
||||||
we're not trying to scare you; it's our educated guess based on what youtube has been doing lately:
|
we're not trying to scare you; it's our educated guess based on what youtube has been doing lately:
|
||||||
- roll out of SABR & related limitations for more clients. SABR is Server ABR, Google's proprietary HLS alternative, controlled by the server.
|
- roll out of SABR & related limitations for more clients. SABR is Server ABR, Google's proprietary HLS alternative, controlled by the server.
|
||||||
- growing potoken enforcement.
|
- growing potoken enforcement.
|
||||||
|
@ -85,6 +85,8 @@
|
|||||||
|
|
||||||
"metadata.filename.preview.video": "Video Title - Video Author",
|
"metadata.filename.preview.video": "Video Title - Video Author",
|
||||||
"metadata.filename.preview.audio": "Audio Title - Audio Author",
|
"metadata.filename.preview.audio": "Audio Title - Audio Author",
|
||||||
|
"filename.preview_desc.video": "video file preview",
|
||||||
|
"filename.preview_desc.audio": "audio file preview",
|
||||||
|
|
||||||
"metadata.file": "file metadata",
|
"metadata.file": "file metadata",
|
||||||
"metadata.disable.title": "disable file metadata",
|
"metadata.disable.title": "disable file metadata",
|
||||||
|
@ -80,6 +80,8 @@
|
|||||||
"video.youtube.hls.title": "предпочитать hls для видео и аудио",
|
"video.youtube.hls.title": "предпочитать hls для видео и аудио",
|
||||||
"metadata.filename.preview.video": "Название Видео - Автор Видео",
|
"metadata.filename.preview.video": "Название Видео - Автор Видео",
|
||||||
"metadata.filename.preview.audio": "Название Аудио - Автор Аудио",
|
"metadata.filename.preview.audio": "Название Аудио - Автор Аудио",
|
||||||
|
"filename.preview_desc.video": "превью видео файла",
|
||||||
|
"filename.preview_desc.audio": "превью аудио файла",
|
||||||
"saving.description": "предпочтительный способ сохранения файла или ссылки с кобальта. если предпочитаемый метод недоступен или что-то пойдёт не так, кобальт спросит тебя как поступить.",
|
"saving.description": "предпочтительный способ сохранения файла или ссылки с кобальта. если предпочитаемый метод недоступен или что-то пойдёт не так, кобальт спросит тебя как поступить.",
|
||||||
"accessibility.transparency.description": "уменьшает прозрачность поверхностей и выключает эффекты размытия. также может улучшить работу интерфейса на менее мощных устройствах.",
|
"accessibility.transparency.description": "уменьшает прозрачность поверхностей и выключает эффекты размытия. также может улучшить работу интерфейса на менее мощных устройствах.",
|
||||||
"accessibility.transparency.title": "уменьшить визуальную прозрачность",
|
"accessibility.transparency.title": "уменьшить визуальную прозрачность",
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@imput/cobalt-web",
|
"name": "@imput/cobalt-web",
|
||||||
"version": "11.2.2",
|
"version": "11.2.3",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -75,7 +75,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="item-text">
|
<div class="item-text">
|
||||||
<div class="preview">{`${videoFilePreview}.${youtubeVideoExt}`}</div>
|
<div class="preview">{`${videoFilePreview}.${youtubeVideoExt}`}</div>
|
||||||
<div class="subtext description">video file preview</div>
|
<div class="subtext description">{$t("settings.filename.preview_desc.video")}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="filename-preview-audio" class="filename-preview-item">
|
<div id="filename-preview-audio" class="filename-preview-item">
|
||||||
@ -84,7 +84,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="item-text">
|
<div class="item-text">
|
||||||
<div class="preview">{`${audioFilePreview}.${audioFormat}`}</div>
|
<div class="preview">{`${audioFilePreview}.${audioFormat}`}</div>
|
||||||
<div class="subtext description">audio file preview</div>
|
<div class="subtext description">{$t("settings.filename.preview_desc.audio")}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user