added better decryption error handeling and updated endpoint

This commit is contained in:
stratuma 2024-05-29 13:23:22 +02:00
parent 448c206101
commit 7640c2ea89
2 changed files with 88 additions and 16 deletions

View File

@ -710,11 +710,38 @@ export async function downloadCrunchyrollPlaylist(
if (playlist.mediaGroups.AUDIO.audio.main.playlists[0].contentProtection) { if (playlist.mediaGroups.AUDIO.audio.main.playlists[0].contentProtection) {
if (!playlist.mediaGroups.AUDIO.audio.main.playlists[0].contentProtection['com.widevine.alpha'].pssh) { if (!playlist.mediaGroups.AUDIO.audio.main.playlists[0].contentProtection['com.widevine.alpha'].pssh) {
console.log('No PSSH found, exiting.') console.log('No PSSH found, exiting.')
messageBox(
'error',
['Cancel'],
2,
'Encryption Detect error',
'Encryption Detect error',
'Audio file is decrypted, but it looks like not with widevine. Stopping Download. Contact Developer'
)
server.logger.log({
level: 'error',
message: `Audio file is decrypted, but it looks like not with widevine in Download ${downloadID}`,
error: 'No PSSH found',
timestamp: new Date().toISOString(),
section: 'crunchyrollDownloadProcessAudioDecryption'
})
return return
} }
pssh = Uint8ArrayToBase64(playlist.mediaGroups.AUDIO.audio.main.playlists[0].contentProtection['com.widevine.alpha'].pssh) pssh = Uint8ArrayToBase64(playlist.mediaGroups.AUDIO.audio.main.playlists[0].contentProtection['com.widevine.alpha'].pssh)
keys = await getDRMKeys(pssh, assetId[1], list.account_id) keys = await getDRMKeys(pssh, assetId[1], list.account_id)
if (!keys) {
await updatePlaylistByID(downloadID, 'failed')
server.logger.log({
level: 'error',
message: `No decryption keys, failing Download ${downloadID}`,
error: 'No decryption keys',
timestamp: new Date().toISOString(),
section: 'crunchyrollDownloadProcessAudioDecryption'
})
throw Error(`No decryption keys, failing Download ${downloadID}`)
}
} }
if ( if (
@ -925,6 +952,18 @@ export async function downloadCrunchyrollPlaylist(
pssh = Uint8ArrayToBase64(hq.contentProtection['com.widevine.alpha'].pssh) pssh = Uint8ArrayToBase64(hq.contentProtection['com.widevine.alpha'].pssh)
keys = await getDRMKeys(pssh, assetId[1], play.account_id) keys = await getDRMKeys(pssh, assetId[1], play.account_id)
if (!keys) {
await updatePlaylistByID(downloadID, 'failed')
server.logger.log({
level: 'error',
message: `No decryption keys, failing Download ${downloadID}`,
error: 'No decryption keys',
timestamp: new Date().toISOString(),
section: 'crunchyrollDownloadProcessVideoDecryption'
})
throw Error(`No decryption keys, failing Download ${downloadID}`)
}
} }
if ((hq.contentProtection && !drmL3blob && !drmL3key) || (hq.contentProtection && !drmL3blob) || (hq.contentProtection && !drmL3key)) { if ((hq.contentProtection && !drmL3blob && !drmL3key) || (hq.contentProtection && !drmL3blob) || (hq.contentProtection && !drmL3key)) {

View File

@ -1,9 +1,22 @@
import { Session } from '../modules/license' import { Session } from '../modules/license'
import { readFileSync } from 'fs' import { readFileSync } from 'fs'
import { getWVKPath } from './widevine' import { getWVKPath } from './widevine'
import { messageBox } from '../../electron/background'
import { server } from '../api'
export async function getDRMKeys(pssh: string, assetID: string, userID: string) { export async function getDRMKeys(pssh: string, assetID: string, userID: string) {
const auth = await getWVKey(assetID, userID) const auth = await getWVKey(assetID, userID)
if (!auth) {
server.logger.log({
level: 'error',
message: 'WVKey missing, aborting',
timestamp: new Date().toISOString(),
section: 'drmAuthCrunchyrollStatus'
})
return
}
const depssh = Buffer.from(pssh, 'base64') const depssh = Buffer.from(pssh, 'base64')
const keys = await getWVKPath() const keys = await getWVKPath()
@ -14,6 +27,7 @@ export async function getDRMKeys(pssh: string, assetID: string, userID: string)
if (!keys.client) return if (!keys.client) return
try {
const privateKey = readFileSync(keys.key) const privateKey = readFileSync(keys.key)
const identifierBlob = readFileSync(keys.client) const identifierBlob = readFileSync(keys.client)
@ -31,6 +45,18 @@ export async function getDRMKeys(pssh: string, assetID: string, userID: string)
if (response.ok) { if (response.ok) {
const json = JSON.parse(await response.text()) const json = JSON.parse(await response.text())
return session.parseLicense(Buffer.from(json['license'], 'base64')) as { kid: string; key: string }[] return session.parseLicense(Buffer.from(json['license'], 'base64')) as { kid: string; key: string }[]
} else {
throw Error(await response.text())
}
} catch (e) {
messageBox('error', ['Cancel'], 2, 'Error while getting video/audio decryption keys', 'Error while getting video/audio decryption keys', String(e))
server.logger.log({
level: 'error',
message: 'Error while getting video/audio decryption keys',
error: String(e),
timestamp: new Date().toISOString(),
section: 'drmVideoAudioKeyCrunchyrollFetch'
})
} }
} }
@ -43,7 +69,7 @@ export async function getWVKey(assetID: string, userID: string) {
} }
try { try {
const response = await fetch(`https://pl.crunchyroll.com/drm/v1/auth`, { const response = await fetch(`https://beta-api.crunchyroll.com/drm/v1/auth`, {
method: 'POST', method: 'POST',
body: JSON.stringify(body) body: JSON.stringify(body)
}) })
@ -59,7 +85,14 @@ export async function getWVKey(assetID: string, userID: string) {
throw new Error(await response.text()) throw new Error(await response.text())
} }
} catch (e) { } catch (e) {
throw new Error(e as string) messageBox('error', ['Cancel'], 2, 'Failed to Fetch Decryption token', 'Failed to Fetch Decryption token', String(e))
server.logger.log({
level: 'error',
message: 'Failed to Fetch Decryption token',
error: String(e),
timestamp: new Date().toISOString(),
section: 'drmAuthCrunchyrollFetch'
})
} }
} }