Skip to content

Instantly share code, notes, and snippets.

@saschanaz
Last active November 20, 2018 03:32
Show Gist options
  • Save saschanaz/a5e00b559da591b1a4bd59361778b9fa to your computer and use it in GitHub Desktop.
Save saschanaz/a5e00b559da591b1a4bd59361778b9fa to your computer and use it in GitHub Desktop.
aniplus-patch.user.js
// ==UserScript==
// @name ANIPLUS HLS fix
// @namespace https://saschanaz.github.io/
// @version 0.2.4
// @description Fix bandwidth to match the actual maximum observed bitrate 95726 kbps
// @author Kagami Sascha Rosylight
// @match http://www.aniplustv.com/tv/program_player_html5.asp?*
// @grant none
// @run-at document-start
// ==/UserScript==
/* jshint esversion: 6 */
"use strict";
(() => {
console.log("Starting ANIPLUS autoSetup fix");
const o = new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const node of Array.from(mutation.addedNodes)) {
if (node.nodeType === 1 && node.id === "aniplusVideo" && node.tagName === "VIDEO") {
console.log("Removing data-setup to prevent videojs autoSetup(), which may cause race condition with ANIPLUS ajax success handler and then HLS error.");
node.removeAttribute("data-setup");
}
}
}
});
o.observe(document.documentElement, { childList: true, subtree: true });
})();
(async () => {
if (!document.createElement("video").canPlayType('application/x-mpegURL')) {
console.log("Skipping ANIPLUS bandwidth fix as this browser doesn't have native HLS support");
return;
}
console.log("Starting ANIPLUS bandwidth fix");
const threshold = 128 * 1024 ** 2;
if (!await tryModification()) {
startMutationObserver();
}
async function tryModification() {
if (!window.aniplusVideo_html5_api) {
return false;
}
return fixVideo(aniplusVideo_html5_api);
}
function startMutationObserver() {
const observer = new MutationObserver(async (mutations) => {
for (const mutation of mutations) {
for (const node of Array.from(mutation.addedNodes)) {
if (node.nodeType === 1 && node.id === "aniplusVideo_html5_api") {
await fixVideo(node);
}
}
}
});
observer.observe(document.documentElement, {
subtree: true,
childList: true
});
return observer;
}
async function fixVideo(video) {
const source = video.getElementsByTagName("source")[0];
if (!source.src.includes("playlist.m3u8")) {
return false;
}
video.src = URL.createObjectURL(await fixPlaylist(source.src));
video.setAttribute("x-aniplus-fix", true);
}
async function fixPlaylist(path) {
const directory = path.match(/^.*\//);
const response = await fetch(path);
const text = await response.text();
console.log(`ANIPLUS HLS original:\n\n${text}`);
const fixed = text
.replace(/BANDWIDTH=([0-9]+)/, ($0, $1) => `BANDWIDTH=${Math.max(+$1, threshold)}`)
.replace("chunklist", `${directory}chunklist`);
console.log(`ANIPLUS HLS fix:\n\n${fixed}`);
return new Blob([fixed], { type: "application/vnd.apple.mpegurl" });
}
})().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment