added hardsub and dub subtitle download
This commit is contained in:
parent
33899b4d42
commit
e74c822f49
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex flex-row bg-[#111111] h-16" style="-webkit-app-region: drag">
|
<div class="fixed w-full flex flex-row bg-[#111111] h-16 z-10" style="-webkit-app-region: drag">
|
||||||
<div class="w-full flex gap-10 flex-row items-center justify-center px-">
|
<div class="w-full flex gap-10 flex-row items-center justify-center px-">
|
||||||
<button @click="openAddAnime" class="px-6 py-0.5 border-2 border-[#ce6104] rounded-xl" style="-webkit-app-region: no-drag">
|
<button @click="openAddAnime" class="px-6 py-0.5 border-2 border-[#ce6104] rounded-xl" style="-webkit-app-region: no-drag">
|
||||||
<Icon name="ph:plus-bold" class="h-7 w-7 text-[#ce6104]" />
|
<Icon name="ph:plus-bold" class="h-7 w-7 text-[#ce6104]" />
|
||||||
@ -56,7 +56,7 @@ async function openAddAnime() {
|
|||||||
title: "Add Anime",
|
title: "Add Anime",
|
||||||
url: isProduction ? 'http://localhost:8079/addanime' : 'http://localhost:3000/addanime',
|
url: isProduction ? 'http://localhost:8079/addanime' : 'http://localhost:3000/addanime',
|
||||||
width: 700,
|
width: 700,
|
||||||
height: 400,
|
height: 450,
|
||||||
backgroundColor: "#111111"
|
backgroundColor: "#111111"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -165,12 +165,34 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="relative flex flex-col">
|
||||||
|
<select v-model="hardsub" name="episode" class="bg-[#5c5b5b] focus:outline-none px-3 py-2 rounded-xl text-sm text-center cursor-pointer">
|
||||||
|
<option
|
||||||
|
:value="false"
|
||||||
|
class="text-sm text-slate-200"
|
||||||
|
>Hardsub: false</option
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
:value="true"
|
||||||
|
class="text-sm text-slate-200"
|
||||||
|
>Hardsub: true</option
|
||||||
|
>
|
||||||
|
</select>
|
||||||
|
<div
|
||||||
|
class="absolute w-full h-9 bg-[#afadad] rounded-xl transition-all flex flex-row items-center justify-center gap-1 text-black"
|
||||||
|
:class="isFetchingEpisodes ? 'opacity-100' : 'opacity-0 pointer-events-none'"
|
||||||
|
>
|
||||||
|
<Icon name="mdi:loading" class="h-6 w-6 animate-spin" />
|
||||||
|
<div class="text-sm">Loading</div></div
|
||||||
|
>
|
||||||
|
</div>
|
||||||
<!-- {{ CRselectedShow?.Subs.map(s=> { return locales.find(l => l.locale === s)?.name }) }}
|
<!-- {{ CRselectedShow?.Subs.map(s=> { return locales.find(l => l.locale === s)?.name }) }}
|
||||||
{{ CRselectedShow?.Dubs.map(s=> { return locales.find(l => l.locale === s)?.name }) }} -->
|
{{ CRselectedShow?.Dubs.map(s=> { return locales.find(l => l.locale === s)?.name }) }} -->
|
||||||
<div class="relative flex flex-col mt-auto">
|
<div class="relative flex flex-col mt-auto">
|
||||||
<button @click="addToPlaylist" class="relative py-3 border-2 rounded-xl flex flex-row items-center justify-center">
|
<button @click="addToPlaylist" class="relative py-3 border-2 rounded-xl flex flex-row items-center justify-center">
|
||||||
<div class="flex flex-row items-center justify-center transition-all" :class="isFetchingSeasons ? 'opacity-0' : 'opacity-100'">
|
<div class="flex flex-row items-center justify-center transition-all" :class="isFetchingSeasons ? 'opacity-0' : 'opacity-100'">
|
||||||
<div class="text-xl">Add to Queue</div>
|
<div class="text-xl">Add to Download</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute flex flex-row items-center justify-center gap-1 transition-all" :class="isFetchingSeasons ? 'opacity-100' : 'opacity-0'">
|
<div class="absolute flex flex-row items-center justify-center gap-1 transition-all" :class="isFetchingSeasons ? 'opacity-100' : 'opacity-0'">
|
||||||
<Icon name="mdi:loading" class="h-6 w-6 animate-spin" />
|
<Icon name="mdi:loading" class="h-6 w-6 animate-spin" />
|
||||||
@ -236,6 +258,7 @@ const episodes = ref<CrunchyEpisodes>()
|
|||||||
const selectedSeason = ref<CrunchySeason>()
|
const selectedSeason = ref<CrunchySeason>()
|
||||||
const selectedStartEpisode = ref<CrunchyEpisode>()
|
const selectedStartEpisode = ref<CrunchyEpisode>()
|
||||||
const selectedEndEpisode = ref<CrunchyEpisode>()
|
const selectedEndEpisode = ref<CrunchyEpisode>()
|
||||||
|
const hardsub = ref<boolean>(false)
|
||||||
|
|
||||||
const isFetchingSeasons = ref<number>(0)
|
const isFetchingSeasons = ref<number>(0)
|
||||||
const isFetchingEpisodes = ref<number>(0)
|
const isFetchingEpisodes = ref<number>(0)
|
||||||
@ -402,7 +425,8 @@ const addToPlaylist = async () => {
|
|||||||
episodes: [selectedStartEpisode.value],
|
episodes: [selectedStartEpisode.value],
|
||||||
dubs: selectedDubs.value,
|
dubs: selectedDubs.value,
|
||||||
subs: selectedSubs.value,
|
subs: selectedSubs.value,
|
||||||
dir: path.value
|
dir: path.value,
|
||||||
|
hardsub: hardsub.value
|
||||||
}
|
}
|
||||||
|
|
||||||
const { error } = await useFetch('http://localhost:8080/api/crunchyroll/playlist', {
|
const { error } = await useFetch('http://localhost:8080/api/crunchyroll/playlist', {
|
||||||
|
@ -39,7 +39,7 @@ const openAddAnime = () => {
|
|||||||
title: "Add Anime",
|
title: "Add Anime",
|
||||||
url: isProduction ? 'http://localhost:8079/addanime' : 'http://localhost:3000/addanime',
|
url: isProduction ? 'http://localhost:8079/addanime' : 'http://localhost:3000/addanime',
|
||||||
width: 700,
|
width: 700,
|
||||||
height: 400,
|
height: 450,
|
||||||
backgroundColor: "#111111"
|
backgroundColor: "#111111"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -68,13 +68,13 @@ const getPlaylist = async () => {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
playlist.value = data.value.reverse()
|
playlist.value = data.value
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getPlaylist()
|
getPlaylist()
|
||||||
|
|
||||||
setInterval(getPlaylist, 1000)
|
setInterval(getPlaylist, 2000)
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -43,7 +43,8 @@ interface PlaylistCreateAttributes {
|
|||||||
media: CrunchyEpisode
|
media: CrunchyEpisode
|
||||||
dub: Array<string>
|
dub: Array<string>
|
||||||
sub: Array<string>
|
sub: Array<string>
|
||||||
dir: string
|
dir: string,
|
||||||
|
hardsub: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Account: ModelDefined<AccountAttributes, AccountCreateAttributes> = sequelize.define('Accounts', {
|
const Account: ModelDefined<AccountAttributes, AccountCreateAttributes> = sequelize.define('Accounts', {
|
||||||
@ -103,6 +104,10 @@ const Playlist: ModelDefined<PlaylistAttributes, PlaylistCreateAttributes> = seq
|
|||||||
allowNull: false,
|
allowNull: false,
|
||||||
type: DataTypes.STRING
|
type: DataTypes.STRING
|
||||||
},
|
},
|
||||||
|
hardsub: {
|
||||||
|
allowNull: false,
|
||||||
|
type: DataTypes.BOOLEAN
|
||||||
|
},
|
||||||
partsdownloaded: {
|
partsdownloaded: {
|
||||||
allowNull: true,
|
allowNull: true,
|
||||||
type: DataTypes.BOOLEAN,
|
type: DataTypes.BOOLEAN,
|
||||||
|
@ -66,7 +66,8 @@ export async function addPlaylistController(
|
|||||||
episodes: CrunchyEpisodes
|
episodes: CrunchyEpisodes
|
||||||
dubs: Array<string>
|
dubs: Array<string>
|
||||||
subs: Array<string>
|
subs: Array<string>
|
||||||
dir: string
|
dir: string,
|
||||||
|
hardsub: boolean
|
||||||
}
|
}
|
||||||
}>,
|
}>,
|
||||||
reply: FastifyReply
|
reply: FastifyReply
|
||||||
@ -75,7 +76,7 @@ export async function addPlaylistController(
|
|||||||
const body = request.body;
|
const body = request.body;
|
||||||
|
|
||||||
for (const e of body.episodes) {
|
for (const e of body.episodes) {
|
||||||
await addEpisodeToPlaylist(e, body.subs, body.dubs, body.dir)
|
await addEpisodeToPlaylist(e, body.subs, body.dubs, body.dir, body.hardsub)
|
||||||
}
|
}
|
||||||
|
|
||||||
return reply.code(201).send()
|
return reply.code(201).send()
|
||||||
@ -88,6 +89,6 @@ export async function getPlaylistController(
|
|||||||
|
|
||||||
const playlist = await getPlaylist()
|
const playlist = await getPlaylist()
|
||||||
|
|
||||||
return reply.code(200).send(playlist)
|
return reply.code(200).send(playlist.reverse())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,8 @@ const crErrors = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
export async function crunchyLogin(user: string, passw: string) {
|
export async function crunchyLogin(user: string, passw: string) {
|
||||||
const cachedData: {
|
const cachedData:
|
||||||
|
| {
|
||||||
access_token: string
|
access_token: string
|
||||||
refresh_token: string
|
refresh_token: string
|
||||||
expires_in: number
|
expires_in: number
|
||||||
@ -31,7 +32,8 @@ export async function crunchyLogin(user: string, passw: string) {
|
|||||||
country: string
|
country: string
|
||||||
account_id: string
|
account_id: string
|
||||||
profile_id: string
|
profile_id: string
|
||||||
} | undefined = server.CacheController.get('crtoken')
|
}
|
||||||
|
| undefined = server.CacheController.get('crtoken')
|
||||||
|
|
||||||
if (!cachedData) {
|
if (!cachedData) {
|
||||||
var { data, error } = await crunchyLoginFetch(user, passw)
|
var { data, error } = await crunchyLoginFetch(user, passw)
|
||||||
@ -129,12 +131,13 @@ export async function safeLoginData(user: string, password: string, service: str
|
|||||||
return login?.get()
|
return login?.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function addEpisodeToPlaylist(e: CrunchyEpisode, s: Array<string>, d: Array<string>, dir: string) {
|
export async function addEpisodeToPlaylist(e: CrunchyEpisode, s: Array<string>, d: Array<string>, dir: string, hardsub: boolean) {
|
||||||
const episode = await Playlist.create({
|
const episode = await Playlist.create({
|
||||||
media: e,
|
media: e,
|
||||||
sub: s,
|
sub: s,
|
||||||
dub: d,
|
dub: d,
|
||||||
dir: dir
|
dir: dir,
|
||||||
|
hardsub: hardsub
|
||||||
})
|
})
|
||||||
|
|
||||||
return episode.get()
|
return episode.get()
|
||||||
@ -154,8 +157,22 @@ export async function updatePlaylistToDownloadPartsByID(id: number, parts: numbe
|
|||||||
await Playlist.update({ partsleft: parts }, { where: { id: id } })
|
await Playlist.update({ partsleft: parts }, { where: { id: id } })
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updatePlaylistToDownloadedPartsByID(id: number, parts: number) {
|
let updateTimeout: NodeJS.Timeout | null = null
|
||||||
|
let cooldown = false
|
||||||
|
|
||||||
|
export async function updatePlaylistToDownloadedPartsByID(id: number, parts: number, lenght: number) {
|
||||||
|
if (cooldown && parts !== lenght) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
cooldown = true
|
||||||
|
|
||||||
await Playlist.update({ partsdownloaded: parts }, { where: { id: id } })
|
await Playlist.update({ partsdownloaded: parts }, { where: { id: id } })
|
||||||
|
|
||||||
|
updateTimeout = setTimeout(function () {
|
||||||
|
cooldown = false
|
||||||
|
updateTimeout = null
|
||||||
|
}, 2000)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function checkPlaylists() {
|
async function checkPlaylists() {
|
||||||
@ -163,11 +180,17 @@ async function checkPlaylists() {
|
|||||||
|
|
||||||
for (const e of episodes) {
|
for (const e of episodes) {
|
||||||
await updatePlaylistByID(e.dataValues.id, 'preparing')
|
await updatePlaylistByID(e.dataValues.id, 'preparing')
|
||||||
await downloadPlaylist(e.dataValues.media.id, (e as any).dataValues.dub.map((s: { locale: any })=> s.locale), (e as any).dataValues.sub.map((s: { locale: any })=> s.locale), e.dataValues.hardsub, e.dataValues.id)
|
await downloadPlaylist(
|
||||||
|
e.dataValues.media.id,
|
||||||
|
(e as any).dataValues.dub.map((s: { locale: any }) => s.locale),
|
||||||
|
(e as any).dataValues.sub.map((s: { locale: any }) => s.locale),
|
||||||
|
e.dataValues.hardsub,
|
||||||
|
e.dataValues.id
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cron.schedule('* * * * * *', () => {
|
cron.schedule('*/2 * * * * *', () => {
|
||||||
checkPlaylists()
|
checkPlaylists()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -268,7 +291,10 @@ export async function downloadPlaylist(e: string, dubs: Array<string>, subs: Arr
|
|||||||
console.log(dubs)
|
console.log(dubs)
|
||||||
console.log(subs)
|
console.log(subs)
|
||||||
|
|
||||||
if (!playlist) return
|
if (!playlist) {
|
||||||
|
console.log('Playlist not found')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (playlist.audioLocale !== subs[0]) {
|
if (playlist.audioLocale !== subs[0]) {
|
||||||
const found = playlist.versions.find((v) => v.audio_locale === 'ja-JP')
|
const found = playlist.versions.find((v) => v.audio_locale === 'ja-JP')
|
||||||
@ -277,7 +303,10 @@ export async function downloadPlaylist(e: string, dubs: Array<string>, subs: Arr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!playlist) return
|
if (!playlist) {
|
||||||
|
console.log('Exact Playlist not found')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
const subFolder = await createFolder()
|
const subFolder = await createFolder()
|
||||||
|
|
||||||
@ -297,12 +326,29 @@ export async function downloadPlaylist(e: string, dubs: Array<string>, subs: Arr
|
|||||||
format: string
|
format: string
|
||||||
language: string
|
language: string
|
||||||
url: string
|
url: string
|
||||||
|
isDub: boolean
|
||||||
}> = []
|
}> = []
|
||||||
|
|
||||||
for (const s of subs) {
|
for (const s of subs) {
|
||||||
const found = playlist.subtitles.find((sub) => sub.language === s)
|
var subPlaylist
|
||||||
|
|
||||||
|
if (playlist.audioLocale !== 'ja-JP') {
|
||||||
|
const foundStream = playlist.versions.find((v) => v.audio_locale === 'ja-JP')
|
||||||
|
if (foundStream) {
|
||||||
|
subPlaylist = await crunchyGetPlaylist(foundStream.guid)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
subPlaylist = playlist
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!subPlaylist) {
|
||||||
|
console.log('Subtitle Playlist not found')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const found = subPlaylist.subtitles.find((sub) => sub.language === s)
|
||||||
if (found) {
|
if (found) {
|
||||||
subDownloadList.push(found)
|
subDownloadList.push({ ...found, isDub: false })
|
||||||
console.log(`Subtitle ${s}.ass found, adding to download`)
|
console.log(`Subtitle ${s}.ass found, adding to download`)
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Subtitle ${s}.ass not found, skipping`)
|
console.warn(`Subtitle ${s}.ass not found, skipping`)
|
||||||
@ -312,6 +358,15 @@ export async function downloadPlaylist(e: string, dubs: Array<string>, subs: Arr
|
|||||||
for (const d of dubs) {
|
for (const d of dubs) {
|
||||||
const found = playlist.versions.find((p) => p.audio_locale === d)
|
const found = playlist.versions.find((p) => p.audio_locale === d)
|
||||||
if (found) {
|
if (found) {
|
||||||
|
const list = await crunchyGetPlaylist(found.guid)
|
||||||
|
if (list) {
|
||||||
|
const foundSub = list.subtitles.find((sub) => sub.language === d)
|
||||||
|
if (foundSub) {
|
||||||
|
subDownloadList.push({ ...foundSub, isDub: true })
|
||||||
|
} else {
|
||||||
|
console.log(`No Dub Sub Found for ${d}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
dubDownloadList.push(found)
|
dubDownloadList.push(found)
|
||||||
console.log(`Audio ${d}.aac found, adding to download`)
|
console.log(`Audio ${d}.aac found, adding to download`)
|
||||||
} else {
|
} else {
|
||||||
@ -388,21 +443,19 @@ export async function downloadPlaylist(e: string, dubs: Array<string>, subs: Arr
|
|||||||
|
|
||||||
var mdp = await crunchyGetPlaylistMPD(play.url)
|
var mdp = await crunchyGetPlaylistMPD(play.url)
|
||||||
|
|
||||||
if (hardsub) {
|
// if (hardsub) {
|
||||||
const findjpplaylist = playlist.versions.find((p) => p.audio_locale === 'ja-JP')?.guid
|
// const hardsuburl = play.hardSubs.find(h=> h.hlang === subs[0])?.url
|
||||||
|
|
||||||
if (!findjpplaylist) return
|
// if (!hardsuburl) {
|
||||||
|
// console.error('No Hardsub stream found')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
const hsplaylist = await crunchyGetPlaylist(findjpplaylist)
|
// mdp = await crunchyGetPlaylistMPD(hardsuburl)
|
||||||
|
// console.error('Hardsub stream found')
|
||||||
if (!hsplaylist) return
|
// } else {
|
||||||
|
// console.error('Hardsub is false')
|
||||||
const hsurl = hsplaylist.hardSubs.find((h) => h.hlang === subs[0])
|
// }
|
||||||
|
|
||||||
if (hsurl) {
|
|
||||||
mdp = await crunchyGetPlaylistMPD(hsurl.url)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mdp) return
|
if (!mdp) return
|
||||||
|
|
||||||
@ -424,7 +477,7 @@ export async function downloadPlaylist(e: string, dubs: Array<string>, subs: Arr
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
await updatePlaylistByID(downloadID, "downloading")
|
await updatePlaylistByID(downloadID, 'downloading')
|
||||||
|
|
||||||
await updatePlaylistToDownloadPartsByID(downloadID, p.length)
|
await updatePlaylistToDownloadPartsByID(downloadID, p.length)
|
||||||
|
|
||||||
@ -437,14 +490,14 @@ export async function downloadPlaylist(e: string, dubs: Array<string>, subs: Arr
|
|||||||
|
|
||||||
if (!audios) return
|
if (!audios) return
|
||||||
|
|
||||||
await updatePlaylistByID(downloadID, "merging")
|
await updatePlaylistByID(downloadID, 'merging')
|
||||||
|
|
||||||
await mergeFile(file as string, audios, subss, String(playlist.assetId))
|
await mergeFile(file as string, audios, subss, String(playlist.assetId))
|
||||||
|
|
||||||
await deleteFolder(subFolder)
|
await deleteFolder(subFolder)
|
||||||
await deleteFolder(audioFolder)
|
await deleteFolder(audioFolder)
|
||||||
|
|
||||||
await updatePlaylistByID(downloadID, "completed")
|
await updatePlaylistByID(downloadID, 'completed')
|
||||||
|
|
||||||
return playlist
|
return playlist
|
||||||
}
|
}
|
||||||
@ -486,7 +539,7 @@ async function downloadParts(parts: { filename: string; url: string }[], downloa
|
|||||||
const path = await createFolder()
|
const path = await createFolder()
|
||||||
|
|
||||||
for (const [index, part] of parts.entries()) {
|
for (const [index, part] of parts.entries()) {
|
||||||
let success = false;
|
let success = false
|
||||||
while (!success) {
|
while (!success) {
|
||||||
try {
|
try {
|
||||||
const stream = fs.createWriteStream(`${path}/${part.filename}`)
|
const stream = fs.createWriteStream(`${path}/${part.filename}`)
|
||||||
@ -494,12 +547,12 @@ async function downloadParts(parts: { filename: string; url: string }[], downloa
|
|||||||
await finished(Readable.fromWeb(body as any).pipe(stream))
|
await finished(Readable.fromWeb(body as any).pipe(stream))
|
||||||
console.log(`Fragment ${index + 1} downloaded`)
|
console.log(`Fragment ${index + 1} downloaded`)
|
||||||
partsdownloaded++
|
partsdownloaded++
|
||||||
updatePlaylistToDownloadedPartsByID(downloadID, partsdownloaded)
|
updatePlaylistToDownloadedPartsByID(downloadID, partsdownloaded, parts.length)
|
||||||
success = true;
|
success = true
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Error occurred during download of fragment ${index + 1}:`, error);
|
console.error(`Error occurred during download of fragment ${index + 1}:`, error)
|
||||||
console.log(`Retrying download of fragment ${index + 1}...`);
|
console.log(`Retrying download of fragment ${index + 1}...`)
|
||||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
await new Promise((resolve) => setTimeout(resolve, 5000))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -512,10 +565,11 @@ async function downloadSub(
|
|||||||
format: string
|
format: string
|
||||||
language: string
|
language: string
|
||||||
url: string
|
url: string
|
||||||
|
isDub: boolean
|
||||||
},
|
},
|
||||||
dir: string
|
dir: string
|
||||||
) {
|
) {
|
||||||
const path = `${dir}/${sub.language}.${sub.format}`
|
const path = `${dir}/${sub.language}${sub.isDub ? `-FORCED` : ''}.${sub.format}`
|
||||||
|
|
||||||
const stream = fs.createWriteStream(path)
|
const stream = fs.createWriteStream(path)
|
||||||
const response = await fetch(sub.url)
|
const response = await fetch(sub.url)
|
||||||
@ -666,7 +720,7 @@ async function mergeFile(video: string, audios: Array<string>, subs: Array<strin
|
|||||||
var output = Ffmpeg()
|
var output = Ffmpeg()
|
||||||
var ffindex = 1
|
var ffindex = 1
|
||||||
output.addInput(video)
|
output.addInput(video)
|
||||||
var options = ['-c copy', '-map 0']
|
var options = ['-map_metadata -1', '-c copy', '-metadata:s:v:0 VARIANT_BITRATE=0', '-map 0']
|
||||||
|
|
||||||
for (const [index, a] of audios.entries()) {
|
for (const [index, a] of audios.entries()) {
|
||||||
output.addInput(a)
|
output.addInput(a)
|
||||||
@ -681,23 +735,33 @@ async function mergeFile(video: string, audios: Array<string>, subs: Array<strin
|
|||||||
|
|
||||||
ffindex++
|
ffindex++
|
||||||
|
|
||||||
// Somehow not working
|
options.push(
|
||||||
// options.push(
|
`-metadata:s:a:${index} title=${
|
||||||
// `-metadata:s:a:${index} language="${
|
locales.find((l) => l.locale === a.split('/')[1].split('.aac')[0])
|
||||||
// locales.find(
|
? locales.find((l) => l.locale === a.split('/')[1].split('.aac')[0])?.title
|
||||||
// (l) => l.locale === a.split("/")[1].split(".aac")[0]
|
: a.split('/')[1].split('.aac')[0]
|
||||||
// ) ? locales.find(
|
}`
|
||||||
// (l) => l.locale === a.split("/")[1].split(".aac")[0]
|
)
|
||||||
// )?.title : a.split("/")[1].split(".aac")[0]
|
|
||||||
// }"`
|
options.push(`-metadata:s:a:${index} VARIANT_BITRATE=0`)
|
||||||
// );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options.push(`-disposition:a:0 default`)
|
||||||
|
|
||||||
if (subs) {
|
if (subs) {
|
||||||
for (const [index, s] of subs.entries()) {
|
for (const [index, s] of subs.entries()) {
|
||||||
output.addInput(s)
|
output.addInput(s)
|
||||||
options.push(`-map ${ffindex}:s`)
|
options.push(`-map ${ffindex}:s`)
|
||||||
|
|
||||||
|
if (s.includes('-FORCED')) {
|
||||||
|
options.push(
|
||||||
|
`-metadata:s:s:${index} language=${
|
||||||
|
locales.find((l) => l.locale === s.split('/')[1].split('-FORCED.ass')[0])
|
||||||
|
? locales.find((l) => l.locale === s.split('/')[1].split('-FORCED.ass')[0])?.iso
|
||||||
|
: s.split('/')[1].split('-FORCED.ass')[0]
|
||||||
|
}`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
options.push(
|
options.push(
|
||||||
`-metadata:s:s:${index} language=${
|
`-metadata:s:s:${index} language=${
|
||||||
locales.find((l) => l.locale === s.split('/')[1].split('.ass')[0])
|
locales.find((l) => l.locale === s.split('/')[1].split('.ass')[0])
|
||||||
@ -705,9 +769,29 @@ async function mergeFile(video: string, audios: Array<string>, subs: Array<strin
|
|||||||
: s.split('/')[1].split('.ass')[0]
|
: s.split('/')[1].split('.ass')[0]
|
||||||
}`
|
}`
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.includes('-FORCED')) {
|
||||||
|
options.push(
|
||||||
|
`-metadata:s:s:${index} title=${
|
||||||
|
locales.find((l) => l.locale === s.split('/')[1].split('-FORCED.ass')[0])
|
||||||
|
? locales.find((l) => l.locale === s.split('/')[1].split('-FORCED.ass')[0])?.title
|
||||||
|
: s.split('/')[1].split('-FORCED.ass')[0]
|
||||||
|
}[FORCED]`
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
options.push(
|
||||||
|
`-metadata:s:s:${index} title=${
|
||||||
|
locales.find((l) => l.locale === s.split('/')[1].split('.ass')[0])
|
||||||
|
? locales.find((l) => l.locale === s.split('/')[1].split('.ass')[0])?.title
|
||||||
|
: s.split('/')[1].split('.ass')[0]
|
||||||
|
}`
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
ffindex++
|
ffindex++
|
||||||
}
|
}
|
||||||
|
options.push(`-disposition:s:0 default`)
|
||||||
}
|
}
|
||||||
|
|
||||||
output
|
output
|
||||||
|
Reference in New Issue
Block a user