Kagane: add support for Tachimanga (#11710)
* Kagane: add support for Tachimanga * cache cert
This commit is contained in:
parent
eec57bbf65
commit
64b3c18350
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'Kagane'
|
extName = 'Kagane'
|
||||||
extClass = '.Kagane'
|
extClass = '.Kagane'
|
||||||
extVersionCode = 11
|
extVersionCode = 12
|
||||||
isNsfw = true
|
isNsfw = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -255,12 +255,16 @@ class Kagane : HttpSource(), ConfigurableSource {
|
|||||||
add("Referer", "$baseUrl/")
|
add("Referer", "$baseUrl/")
|
||||||
}.build()
|
}.build()
|
||||||
|
|
||||||
private fun getCertificate(): String {
|
private fun getCertificate(url: String): String {
|
||||||
return client.newCall(GET("$apiUrl/api/v1/static/bin.bin", apiHeaders)).execute()
|
return client.newCall(GET(url, apiHeaders)).execute()
|
||||||
.body.bytes()
|
.body.bytes()
|
||||||
.toBase64()
|
.toBase64()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val windvineCertificate by lazy { getCertificate("$apiUrl/api/v1/static/bin.bin") }
|
||||||
|
|
||||||
|
private val fairPlayCertificate by lazy { getCertificate("$apiUrl/api/v1/static/crt.crt") }
|
||||||
|
|
||||||
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
||||||
if (chapter.url.count { it == ';' } != 2) throw Exception("Chapter url error, please refresh chapter list.")
|
if (chapter.url.count { it == ';' } != 2) throw Exception("Chapter url error, please refresh chapter list.")
|
||||||
var (seriesId, chapterId, pageCount) = chapter.url.split(";")
|
var (seriesId, chapterId, pageCount) = chapter.url.split(";")
|
||||||
@ -304,6 +308,10 @@ class Kagane : HttpSource(), ConfigurableSource {
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script>
|
<script>
|
||||||
|
function detectDRMSupport() {
|
||||||
|
return "WebKitMediaKeys" in window ? "fairplay" : "MediaKeys" in window && "function" == typeof navigator.requestMediaKeySystemAccess ? "widevine" : null
|
||||||
|
}
|
||||||
|
|
||||||
function base64ToArrayBuffer(base64) {
|
function base64ToArrayBuffer(base64) {
|
||||||
var binaryString = atob(base64);
|
var binaryString = atob(base64);
|
||||||
var bytes = new Uint8Array(binaryString.length);
|
var bytes = new Uint8Array(binaryString.length);
|
||||||
@ -314,21 +322,39 @@ class Kagane : HttpSource(), ConfigurableSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getData() {
|
async function getData() {
|
||||||
const g = base64ToArrayBuffer("${getCertificate()}");
|
let widevine = detectDRMSupport() !== 'fairplay';
|
||||||
let t = await navigator.requestMediaKeySystemAccess("com.widevine.alpha", [{
|
const g = base64ToArrayBuffer(widevine ? "$windvineCertificate" : "$fairPlayCertificate");
|
||||||
|
let t = widevine ? await navigator.requestMediaKeySystemAccess("com.widevine.alpha", [{
|
||||||
initDataTypes: ["cenc"],
|
initDataTypes: ["cenc"],
|
||||||
audioCapabilities: [],
|
audioCapabilities: [],
|
||||||
videoCapabilities: [{
|
videoCapabilities: [{
|
||||||
contentType: 'video/mp4; codecs="avc1.42E01E"'
|
contentType: 'video/mp4; codecs="avc1.42E01E"'
|
||||||
}]
|
}]
|
||||||
|
}]) : await navigator.requestMediaKeySystemAccess("com.apple.fps", [{
|
||||||
|
initDataTypes: ["skd"],
|
||||||
|
audioCapabilities: [{
|
||||||
|
contentType: 'audio/mp4; codecs="mp4a.40.2"'
|
||||||
|
}],
|
||||||
|
videoCapabilities: [{
|
||||||
|
contentType: 'video/mp4; codecs="avc1.42E01E"'
|
||||||
|
}]
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
let e = await t.createMediaKeys();
|
let e = await t.createMediaKeys();
|
||||||
await e.setServerCertificate(g);
|
await e.setServerCertificate(g);
|
||||||
|
let video = widevine ? null : document.createElement("video");
|
||||||
|
if (video) {
|
||||||
|
video.style.display = "none";
|
||||||
|
document.body.appendChild(video);
|
||||||
|
await video.setMediaKeys(e);
|
||||||
|
}
|
||||||
let n = e.createSession();
|
let n = e.createSession();
|
||||||
let i = new Promise((resolve, reject) => {
|
let i = new Promise((resolve, reject) => {
|
||||||
function onMessage(event) {
|
function onMessage(event) {
|
||||||
n.removeEventListener("message", onMessage);
|
n.removeEventListener("message", onMessage);
|
||||||
|
if (video) {
|
||||||
|
document.body.removeChild(video)
|
||||||
|
}
|
||||||
resolve(event.message);
|
resolve(event.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +367,18 @@ class Kagane : HttpSource(), ConfigurableSource {
|
|||||||
n.addEventListener("error", onError);
|
n.addEventListener("error", onError);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (widevine) {
|
||||||
await n.generateRequest("cenc", base64ToArrayBuffer("${getPssh(f).toBase64()}"));
|
await n.generateRequest("cenc", base64ToArrayBuffer("${getPssh(f).toBase64()}"));
|
||||||
|
} else {
|
||||||
|
let oo = base64ToArrayBuffer("${f.toBase64()}")
|
||||||
|
let c = Array.from(new Uint8Array(oo)).map(t => t.toString(16).padStart(2, "0")).join("");
|
||||||
|
let d = JSON.stringify({
|
||||||
|
uri: "skd://" + c,
|
||||||
|
assetId: "$chapterId",
|
||||||
|
});
|
||||||
|
const textEncoder = new TextEncoder();
|
||||||
|
await n.generateRequest("skd", textEncoder.encode(d));
|
||||||
|
}
|
||||||
let o = await i;
|
let o = await i;
|
||||||
let m = new Uint8Array(o);
|
let m = new Uint8Array(o);
|
||||||
let v = btoa(String.fromCharCode(...m));
|
let v = btoa(String.fromCharCode(...m));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user