added adn de and fr dub support
This commit is contained in:
parent
695c8f95fc
commit
201c9bf045
@ -27,7 +27,6 @@
|
||||
"@types/express": "^4.17.21",
|
||||
"@types/fluent-ffmpeg": "^2.1.24",
|
||||
"@types/node-cron": "^3.0.11",
|
||||
"@types/node-forge": "^1.3.11",
|
||||
"concurrently": "^8.2.2",
|
||||
"dotenv": "^16.4.5",
|
||||
"electron": "^30.1.2",
|
||||
@ -60,7 +59,6 @@
|
||||
"mpd-parser": "^1.3.0",
|
||||
"node-cache": "^5.1.2",
|
||||
"node-cron": "^3.0.3",
|
||||
"node-forge": "^1.3.1",
|
||||
"protobufjs": "^7.3.2",
|
||||
"sequelize": "^6.37.3",
|
||||
"sqlite3": "5.1.6",
|
||||
|
@ -191,28 +191,29 @@
|
||||
</div>
|
||||
<div v-if="selectDub" class="absolute top-full left-0 w-full bg-[#868585] rounded-xl grid grid-cols-12 gap-1 p-1 z-10">
|
||||
<button
|
||||
@click="toggleDub({ locale: 'ja-JP', name: 'JP' })"
|
||||
v-if="ADNselectedShow.languages.find((l) => l === 'vostde') || ADNselectedShow.languages.find((l) => l === 'vostfr')"
|
||||
@click="toggleDubADN({ locale: 'ja-JP', name: 'JP' })"
|
||||
class="flex flex-row items-center justify-center gap-3 py-2 rounded-xl text-sm"
|
||||
:class="selectedDubs.find((i) => i.locale === 'ja-JP') ? 'bg-[#585858]' : 'hover:bg-[#747474]'"
|
||||
>
|
||||
JP
|
||||
</button>
|
||||
<!-- <button
|
||||
v-if="ADNselectedShow.languages.find((l) => l === 'vde')"
|
||||
@click="toggleDub({ locale: 'de-DE', name: 'DE' })"
|
||||
class="flex flex-row items-center justify-center gap-3 py-2 rounded-xl text-sm"
|
||||
:class="selectedDubs.find((i) => i.locale === 'de-DE') ? 'bg-[#585858]' : 'hover:bg-[#747474]'"
|
||||
>
|
||||
DE
|
||||
</button>
|
||||
<button
|
||||
v-if="ADNselectedShow.languages.find((l) => l === 'vf')"
|
||||
@click="toggleDub({ locale: 'fr-FR', name: 'FR' })"
|
||||
class="flex flex-row items-center justify-center gap-3 py-2 rounded-xl text-sm"
|
||||
:class="selectedDubs.find((i) => i.locale === 'fr-FR') ? 'bg-[#585858]' : 'hover:bg-[#747474]'"
|
||||
>
|
||||
FR
|
||||
</button> -->
|
||||
<button
|
||||
v-if="ADNselectedShow.languages.find((l) => l === 'vde')"
|
||||
@click="toggleDubADN({ locale: 'de-DE', name: 'DE' })"
|
||||
class="flex flex-row items-center justify-center gap-3 py-2 rounded-xl text-sm"
|
||||
:class="selectedDubs.find((i) => i.locale === 'de-DE') ? 'bg-[#585858]' : 'hover:bg-[#747474]'"
|
||||
>
|
||||
DE
|
||||
</button>
|
||||
<button
|
||||
v-if="ADNselectedShow.languages.find((l) => l === 'vf')"
|
||||
@click="toggleDubADN({ locale: 'fr-FR', name: 'FR' })"
|
||||
class="flex flex-row items-center justify-center gap-3 py-2 rounded-xl text-sm"
|
||||
:class="selectedDubs.find((i) => i.locale === 'fr-FR') ? 'bg-[#585858]' : 'hover:bg-[#747474]'"
|
||||
>
|
||||
FR
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="service === 'crunchyroll'" class="relative flex flex-col select-none">
|
||||
@ -832,6 +833,12 @@ const toggleDub = (lang: { name: string | undefined; locale: string }) => {
|
||||
}
|
||||
}
|
||||
|
||||
const toggleDubADN = (lang: { name: string | undefined; locale: string }) => {
|
||||
selectedDubs.value = []
|
||||
|
||||
selectedDubs.value.push(lang)
|
||||
}
|
||||
|
||||
const toggleSub = (lang: { name: string | undefined; locale: string }) => {
|
||||
const index = selectedSubs.value.findIndex((i) => i.locale === lang.locale)
|
||||
|
||||
|
@ -50,9 +50,6 @@ importers:
|
||||
node-cron:
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3
|
||||
node-forge:
|
||||
specifier: ^1.3.1
|
||||
version: 1.3.1
|
||||
protobufjs:
|
||||
specifier: ^7.3.2
|
||||
version: 7.3.2
|
||||
@ -93,9 +90,6 @@ importers:
|
||||
'@types/node-cron':
|
||||
specifier: ^3.0.11
|
||||
version: 3.0.11
|
||||
'@types/node-forge':
|
||||
specifier: ^1.3.11
|
||||
version: 1.3.11
|
||||
concurrently:
|
||||
specifier: ^8.2.2
|
||||
version: 8.2.2
|
||||
@ -1391,9 +1385,6 @@ packages:
|
||||
'@types/node-cron@3.0.11':
|
||||
resolution: {integrity: sha512-0ikrnug3/IyneSHqCBeslAhlK2aBfYek1fGo4bP4QnZPmiqSGRK+Oy7ZMisLWkesffJvQ1cqAcBnJC+8+nxIAg==}
|
||||
|
||||
'@types/node-forge@1.3.11':
|
||||
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
|
||||
|
||||
'@types/node@20.14.9':
|
||||
resolution: {integrity: sha512-06OCtnTXtWOZBJlRApleWndH4JsRVs1pDCc8dLSQp+7PpUpX3ePdHyeNSFTeSe7FtKyQkrlPvHwJOW3SLd8Oyg==}
|
||||
|
||||
@ -7655,10 +7646,6 @@ snapshots:
|
||||
|
||||
'@types/node-cron@3.0.11': {}
|
||||
|
||||
'@types/node-forge@1.3.11':
|
||||
dependencies:
|
||||
'@types/node': 20.14.9
|
||||
|
||||
'@types/node@20.14.9':
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
|
@ -4,7 +4,7 @@ import { ADNLink, ADNPlayerConfig } from '../../types/adn'
|
||||
import { messageBox } from '../../../electron/background'
|
||||
import { useFetch } from '../useFetch'
|
||||
import { loggedInCheck } from '../service/service.service'
|
||||
import * as forge from 'node-forge'
|
||||
import crypto from 'crypto'
|
||||
|
||||
export async function adnLogin(user: string, passw: string) {
|
||||
const cachedData:
|
||||
@ -125,7 +125,7 @@ export async function getPlayerConfigADN(id: number, geo: 'de' | 'fr') {
|
||||
|
||||
return data
|
||||
} else {
|
||||
throw new Error('Failed to fetch ADN')
|
||||
throw new Error('Failed to fetch ADN Player config')
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error(e as string)
|
||||
@ -156,7 +156,7 @@ async function getPlayerToken(id: number, geo: 'de' | 'fr') {
|
||||
|
||||
return data
|
||||
} else {
|
||||
throw new Error('Failed to fetch ADN')
|
||||
throw new Error('Failed to fetch ADN Player token')
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error(e as string)
|
||||
@ -167,57 +167,48 @@ function randomHexaString(length: number) {
|
||||
const characters = '0123456789abcdef'
|
||||
let result = ''
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += characters[Math.floor(Math.random() * characters.length)]
|
||||
result += characters.charAt(Math.floor(Math.random() * characters.length))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
async function getPlayerEncryptedToken(id: number, geo: 'de' | 'fr') {
|
||||
const token = await getPlayerToken(id, geo)
|
||||
|
||||
if (!token) return
|
||||
|
||||
const publicKeyPem = `-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbQrCJBRmaXM4gJidDmcpWDssgnumHinCLHAgS4buMtdH7dEGGEUfBofLzoEdt1jqcrCDT6YNhM0aFCqbLOPFtx9cg/X2G/G5bPVu8cuFM0L+ehp8s6izK1kjx3OOPH/kWzvstM5tkqgJkNyNEvHdeJl6KhS+IFEqwvZqgbBpKuwIDAQAB-----END PUBLIC KEY-----`
|
||||
|
||||
var random = CryptoJS.lib.WordArray.random(16).toString(CryptoJS.enc.Hex)
|
||||
|
||||
const data = {
|
||||
k: random,
|
||||
t: String(token.token)
|
||||
}
|
||||
|
||||
const finisheddata = JSON.stringify(data)
|
||||
|
||||
const encryptedData = encryptWithPublicKey(publicKeyPem, finisheddata)
|
||||
|
||||
return { data: encryptedData, random: random }
|
||||
}
|
||||
|
||||
function encryptWithPublicKey(publicKeyPem: string, data: string) {
|
||||
const publicKey = forge.pki.publicKeyFromPem(publicKeyPem)
|
||||
const encryptedData = publicKey.encrypt(data, 'RSA-OAEP', {
|
||||
md: forge.md.sha256.create()
|
||||
})
|
||||
return forge.util.encode64(encryptedData)
|
||||
}
|
||||
|
||||
export async function adnGetPlaylist(animeid: number, geo: 'de' | 'fr') {
|
||||
const token = await getPlayerEncryptedToken(animeid, geo)
|
||||
const player = await getPlayerToken(animeid, geo)
|
||||
|
||||
if (!token) return
|
||||
if (!player) return
|
||||
|
||||
const random = randomHexaString(16)
|
||||
|
||||
const authorization = crypto
|
||||
.publicEncrypt(
|
||||
{
|
||||
key: '-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbQrCJBRmaXM4gJidDmcpWDssg\nnumHinCLHAgS4buMtdH7dEGGEUfBofLzoEdt1jqcrCDT6YNhM0aFCqbLOPFtx9cg\n/X2G/G5bPVu8cuFM0L+ehp8s6izK1kjx3OOPH/kWzvstM5tkqgJkNyNEvHdeJl6\nKhS+IFEqwvZqgbBpKuwIDAQAB\n-----END PUBLIC KEY-----',
|
||||
padding: crypto.constants.RSA_PKCS1_PADDING
|
||||
},
|
||||
Buffer.from(
|
||||
JSON.stringify({
|
||||
k: random,
|
||||
t: player.token
|
||||
}),
|
||||
'utf-8'
|
||||
)
|
||||
)
|
||||
.toString('base64')
|
||||
|
||||
if (!authorization) return
|
||||
|
||||
try {
|
||||
const response = await fetch(`https://gw.api.animationdigitalnetwork.fr/player/video/${animeid}/link`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'x-target-distribution': geo,
|
||||
'X-Player-Token': token.data
|
||||
'X-Player-Token': authorization
|
||||
}
|
||||
})
|
||||
|
||||
if (response.ok) {
|
||||
const data: ADNLink = await JSON.parse(await response.text())
|
||||
return { data: data, secret: token.random }
|
||||
return { data: data, secret: random }
|
||||
} else {
|
||||
const data: { message: string; code: string; statusCode: string } = JSON.parse(await response.text())
|
||||
|
||||
|
@ -422,16 +422,60 @@ export async function downloadADNPlaylist(
|
||||
|
||||
var link: string = ''
|
||||
|
||||
switch (quality) {
|
||||
case 1080:
|
||||
link = playlist.data.links.streaming.vostde.fhd
|
||||
break
|
||||
case 720:
|
||||
link = playlist.data.links.streaming.vostde.hd
|
||||
break
|
||||
case 480:
|
||||
link = playlist.data.links.streaming.vostde.sd
|
||||
break
|
||||
if (dubs.find((i) => i === 'ja-JP') && playlist.data.links.streaming.vostde) {
|
||||
switch (quality) {
|
||||
case 1080:
|
||||
link = playlist.data.links.streaming.vostde.fhd
|
||||
break
|
||||
case 720:
|
||||
link = playlist.data.links.streaming.vostde.hd
|
||||
break
|
||||
case 480:
|
||||
link = playlist.data.links.streaming.vostde.sd
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (dubs.find((i) => i === 'ja-JP') && playlist.data.links.streaming.vostf) {
|
||||
switch (quality) {
|
||||
case 1080:
|
||||
link = playlist.data.links.streaming.vostf.fhd
|
||||
break
|
||||
case 720:
|
||||
link = playlist.data.links.streaming.vostf.hd
|
||||
break
|
||||
case 480:
|
||||
link = playlist.data.links.streaming.vostf.sd
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (dubs.find((i) => i === 'de-DE')) {
|
||||
switch (quality) {
|
||||
case 1080:
|
||||
link = playlist.data.links.streaming.vde.fhd
|
||||
break
|
||||
case 720:
|
||||
link = playlist.data.links.streaming.vde.hd
|
||||
break
|
||||
case 480:
|
||||
link = playlist.data.links.streaming.vde.sd
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (dubs.find((i) => i === 'fr-FR')) {
|
||||
switch (quality) {
|
||||
case 1080:
|
||||
link = playlist.data.links.streaming.vf.fhd
|
||||
break
|
||||
case 720:
|
||||
link = playlist.data.links.streaming.vf.hd
|
||||
break
|
||||
case 480:
|
||||
link = playlist.data.links.streaming.vf.sd
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!link) return
|
||||
|
@ -45,6 +45,27 @@ export interface ADNLink {
|
||||
fhd: string
|
||||
auto: string
|
||||
}
|
||||
vostf: {
|
||||
mobile: string
|
||||
sd: string
|
||||
hd: string
|
||||
fhd: string
|
||||
auto: string
|
||||
}
|
||||
vde: {
|
||||
mobile: string
|
||||
sd: string
|
||||
hd: string
|
||||
fhd: string
|
||||
auto: string
|
||||
}
|
||||
vf: {
|
||||
mobile: string
|
||||
sd: string
|
||||
hd: string
|
||||
fhd: string
|
||||
auto: string
|
||||
}
|
||||
}
|
||||
subtitles: {
|
||||
all: string
|
||||
|
Reference in New Issue
Block a user