Even more 10.9 fixes, including a patch for broken syncplay
This commit is contained in:
parent
c13b69cb04
commit
d6b84ce2cc
@ -103,7 +103,7 @@ export default JadefinIntegrity("Jadefin", import.meta.url, () => window["Jadefi
|
|||||||
try {
|
try {
|
||||||
return this.webpackLoad?.(id);
|
return this.webpackLoad?.(id);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.log.w(`Failed to load webpack module ${id}`);
|
this.log.e(`Failed to load webpack module ${id}`);
|
||||||
this.log.dir(e);
|
this.log.dir(e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -242,21 +242,21 @@ export default JadefinIntegrity("Jadefin", import.meta.url, () => window["Jadefi
|
|||||||
* @param {(e: any) => any} cb
|
* @param {(e: any) => any} cb
|
||||||
*/
|
*/
|
||||||
findWebpackRawLoad(cb) {
|
findWebpackRawLoad(cb) {
|
||||||
return Object.keys(this.webpackModuleFuncs).map(id => this.webpackTryLoad?.(id)).filter(e => e && cb(e));
|
return JadefinUtils.filterMap(Object.keys(this.webpackModuleFuncs).map(id => this.webpackTryLoad?.(id)), e => e && cb(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {(e: any) => any} cb
|
* @param {(e: any) => any} cb
|
||||||
*/
|
*/
|
||||||
findWebpackModules(cb) {
|
findWebpackModules(cb) {
|
||||||
return Object.keys(this.webpackModuleFuncs).map(id => this.webpackTryLoad?.(id)?.default).filter(e => e && cb(e));
|
return JadefinUtils.filterMap(Object.keys(this.webpackModuleFuncs).map(id => this.webpackTryLoad?.(id)?.default), e => e && cb(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {(e: any) => any} cb
|
* @param {(e: any) => any} cb
|
||||||
*/
|
*/
|
||||||
findWebpackFunctions(cb) {
|
findWebpackFunctions(cb) {
|
||||||
return Object.keys(this.webpackModuleFuncs).map(id => this.webpackTryLoad?.(id)).filter(e => e && e instanceof Function && cb(e));
|
return JadefinUtils.filterMap(Object.keys(this.webpackModuleFuncs).map(id => this.webpackTryLoad?.(id)), e => e && e instanceof Function && cb(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
import JadefinIntegrity from "./JadefinIntegrity.js";
|
import JadefinIntegrity from "./JadefinIntegrity.js";
|
||||||
|
|
||||||
|
import JadefinUtils from "./JadefinUtils.js";
|
||||||
|
|
||||||
export default JadefinIntegrity("JadefinModules", import.meta.url, () => window["JadefinModules"] = new (class JadefinModules {
|
export default JadefinIntegrity("JadefinModules", import.meta.url, () => window["JadefinModules"] = new (class JadefinModules {
|
||||||
/** @type {{[id: string]: any}} */
|
/** @type {{[id: string]: any}} */
|
||||||
_ = {};
|
_ = {};
|
||||||
@ -95,7 +97,7 @@ export default JadefinIntegrity("JadefinModules", import.meta.url, () => window[
|
|||||||
// toast
|
// toast
|
||||||
/** @return {(text: string) => void} */
|
/** @return {(text: string) => void} */
|
||||||
get toast() {
|
get toast() {
|
||||||
return this._.toast ??= this.Jadefin.findWebpackRawLoad(e => (e.A?.toString().indexOf(`toast"),t.textContent=`) || -1) != -1)[0]?.A;
|
return this._.toast ??= this.Jadefin.findWebpackRawLoad(e => JadefinUtils.findDeep(e, 1, (_, o) => o.toString().indexOf(`toast"),t.textContent=`) != -1))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// plugins/syncPlay/core/index
|
// plugins/syncPlay/core/index
|
||||||
@ -108,7 +110,7 @@ export default JadefinIntegrity("JadefinModules", import.meta.url, () => window[
|
|||||||
}}
|
}}
|
||||||
*/
|
*/
|
||||||
get syncPlay() {
|
get syncPlay() {
|
||||||
return this._.syncPlay ??= this.Jadefin.findWebpackModules(e => e.Manager?.isSyncPlayEnabled)[0];
|
return this._.syncPlay ??= this.Jadefin.findWebpackModules(e => e.Manager?.isSyncPlayEnabled && 1)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// inputManager
|
// inputManager
|
||||||
@ -123,7 +125,7 @@ export default JadefinIntegrity("JadefinModules", import.meta.url, () => window[
|
|||||||
}}
|
}}
|
||||||
*/
|
*/
|
||||||
get inputManager() {
|
get inputManager() {
|
||||||
return this._.inputManager ??= this.Jadefin.findWebpackModules(e => e.handleCommand && e.notify && e.idleTime)[0];
|
return this._.inputManager ??= this.Jadefin.findWebpackModules(e => e.handleCommand && e.notify && e.idleTime && 1)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// playbackManager
|
// playbackManager
|
||||||
@ -131,7 +133,7 @@ export default JadefinIntegrity("JadefinModules", import.meta.url, () => window[
|
|||||||
@return {any}
|
@return {any}
|
||||||
*/
|
*/
|
||||||
get playbackManager() {
|
get playbackManager() {
|
||||||
return this._.playbackManager ??= this.Jadefin.findWebpackRawLoad(e => e.f?.canHandleOffsetOnCurrentSubtitle)[0]?.f;
|
return this._.playbackManager ??= this.Jadefin.findWebpackRawLoad(e => JadefinUtils.findDeep(e, 1, (_, o) => o.canHandleOffsetOnCurrentSubtitle))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// plugins/htmlVideoPlayer/plugin.js
|
// plugins/htmlVideoPlayer/plugin.js
|
||||||
@ -139,7 +141,7 @@ export default JadefinIntegrity("JadefinModules", import.meta.url, () => window[
|
|||||||
@return {any}
|
@return {any}
|
||||||
*/
|
*/
|
||||||
get htmlVideoPlayer() {
|
get htmlVideoPlayer() {
|
||||||
return this._.htmlVideoPlayer ??= this.Jadefin.findWebpackModules(e => e.getDeviceProfileInternal)[0];
|
return this._.htmlVideoPlayer ??= this.Jadefin.findWebpackModules(e => e.getDeviceProfileInternal && 1)[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// taskbutton
|
// taskbutton
|
||||||
@ -156,7 +158,7 @@ export default JadefinIntegrity("JadefinModules", import.meta.url, () => window[
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
get taskButton() {
|
get taskButton() {
|
||||||
return this._.taskButton ??= this.Jadefin.findWebpackRawLoad(e => (e.A?.toString().indexOf(`sendMessage("ScheduledTasksInfoStart","1000,1000")`) || -1) != -1)[0]?.A;
|
return this._.taskButton ??= this.Jadefin.findWebpackRawLoad(e => JadefinUtils.findDeep(e, 1, (_, o) => o.toString().indexOf(`sendMessage("ScheduledTasksInfoStart","1000,1000")`) != -1))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// browser
|
// browser
|
||||||
@ -202,7 +204,7 @@ export default JadefinIntegrity("JadefinModules", import.meta.url, () => window[
|
|||||||
}}
|
}}
|
||||||
*/
|
*/
|
||||||
get browser() {
|
get browser() {
|
||||||
return this._.browser ??= this.Jadefin.findWebpackRawLoad(e => typeof(e.A) == "object" && "supportsCssAnimation" in e.A && "version" in e.A)[0]?.A;
|
return this._.browser ??= this.Jadefin.findWebpackRawLoad(e => JadefinUtils.findDeep(e, 1, (_, o) => "supportsCssAnimation" in o && "version" in o))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// datetime
|
// datetime
|
||||||
@ -220,7 +222,7 @@ export default JadefinIntegrity("JadefinModules", import.meta.url, () => window[
|
|||||||
}}
|
}}
|
||||||
*/
|
*/
|
||||||
get datetime() {
|
get datetime() {
|
||||||
return this._.datetime ??= this.Jadefin.findWebpackRawLoad(e => e.Ay?.getDisplayRunningTime)[0]?.Ay;
|
return this._.datetime ??= this.Jadefin.findWebpackRawLoad(e => JadefinUtils.findDeep(e, 1, (_, o) => o.getDisplayRunningTime))[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
// events
|
// events
|
||||||
@ -232,7 +234,7 @@ export default JadefinIntegrity("JadefinModules", import.meta.url, () => window[
|
|||||||
}}
|
}}
|
||||||
*/
|
*/
|
||||||
get Events() {
|
get Events() {
|
||||||
return this._.events ??= this.Jadefin.findWebpackRawLoad(e => e.Events?.on && e.Events?.off && e.Events?.trigger)[0]?.Events;
|
return this._.events ??= this.Jadefin.findWebpackRawLoad(e => e.Events?.on && e.Events?.off && e.Events?.trigger && 1)[0]?.Events;
|
||||||
}
|
}
|
||||||
|
|
||||||
})());
|
})());
|
||||||
|
@ -90,4 +90,66 @@ export default JadefinIntegrity("JadefinUtils", import.meta.url, () => window["J
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{ [x: string]: any; }} obj
|
||||||
|
* @param {number} levels
|
||||||
|
* @param {(level: number, v: any, k: string, obj: any) => any} cond
|
||||||
|
* @param {(level: number, v: any, k: string, obj: any) => void} [cb]
|
||||||
|
*/
|
||||||
|
findDeep(obj, levels, cond, cb) {
|
||||||
|
if (levels <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof(parent) == "object") {
|
||||||
|
for (const k in obj) {
|
||||||
|
let v;
|
||||||
|
try {
|
||||||
|
v = obj[k];
|
||||||
|
} catch {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let rv;
|
||||||
|
try {
|
||||||
|
rv = cond(levels, v, k, obj);
|
||||||
|
} catch {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cond(levels, v, k, obj)) {
|
||||||
|
cb?.(levels, v, k, obj);
|
||||||
|
|
||||||
|
if (levels > 1) {
|
||||||
|
return this.findDeep(obj, levels - 1, cond, cb);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any[]} arr
|
||||||
|
* @param {(value: any, [index]: any, [array]: any) => any} cb
|
||||||
|
*/
|
||||||
|
filterMap(arr, cb) {
|
||||||
|
return arr.reduce((res, value, index, array) => {
|
||||||
|
const rv = cb(value, index, array);
|
||||||
|
|
||||||
|
if (rv) {
|
||||||
|
if (typeof(rv) == "object" || typeof(rv) == "function") {
|
||||||
|
res.push(rv);
|
||||||
|
} else {
|
||||||
|
res.push(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
})());
|
})());
|
||||||
|
@ -5,5 +5,7 @@
|
|||||||
"VersionCheck.js",
|
"VersionCheck.js",
|
||||||
"Screenshot.js",
|
"Screenshot.js",
|
||||||
"InputEater.js",
|
"InputEater.js",
|
||||||
"Transcript.js"
|
"Transcript.js",
|
||||||
|
"PatchForceHLSJS.js",
|
||||||
|
"PatchFixSyncPlay.js"
|
||||||
]
|
]
|
@ -214,7 +214,7 @@ export default JadefinIntegrity("InputEater", import.meta.url, () => new (class
|
|||||||
}
|
}
|
||||||
|
|
||||||
initHookMediaSessionHandlers() {
|
initHookMediaSessionHandlers() {
|
||||||
const owner = Jadefin.findWebpackRawLoad(e => e?.f?.nextTrack && e?.f?.fastForward)[0].f;
|
const owner = Jadefin.findWebpackRawLoad(e => JadefinUtils.findDeep(e, 1, (_, o) => o.nextTrack && o.fastForward));
|
||||||
|
|
||||||
if (!owner || !("mediaSession" in navigator)) {
|
if (!owner || !("mediaSession" in navigator)) {
|
||||||
this.log.e("Couldn't hook media session handlers");
|
this.log.e("Couldn't hook media session handlers");
|
||||||
|
78
mods/PatchFixSyncPlay.js
Normal file
78
mods/PatchFixSyncPlay.js
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
//@ts-check
|
||||||
|
|
||||||
|
import JadefinIntegrity from '../JadefinIntegrity.js';
|
||||||
|
|
||||||
|
import Jadefin from "../Jadefin.js";
|
||||||
|
import JadefinMod from "../JadefinMod.js";
|
||||||
|
import JadefinModules from "../JadefinModules.js";
|
||||||
|
import JadefinUtils from "../JadefinUtils.js";
|
||||||
|
|
||||||
|
// Mainly spawned from https://github.com/jellyfin/jellyfin-web/issues/5485
|
||||||
|
export default JadefinIntegrity("PatchFixSyncPlay", import.meta.url, () => new (class PatchFixSyncPlay extends JadefinMod {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this._scheduleMightSkip = 0;
|
||||||
|
this._scheduleSkip = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
async init(name, url) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
await super.init(name, url);
|
||||||
|
|
||||||
|
await JadefinUtils.waitUntil(() => JadefinModules.syncPlay);
|
||||||
|
|
||||||
|
const queueCore = JadefinModules.syncPlay.Manager.queueCore;
|
||||||
|
|
||||||
|
const startPlayback = this._startPlayback = queueCore.startPlayback.bind(queueCore);
|
||||||
|
queueCore.startPlayback = function(apiClient) {
|
||||||
|
// scheduleReadyRequestOnPlaybackStart must occur BEFORE playerWrapper.localPlay
|
||||||
|
if (this.manager.isFollowingGroupPlayback() && !this.isPlaylistEmpty()) {
|
||||||
|
this.scheduleReadyRequestOnPlaybackStart(apiClient, "startPlayback");
|
||||||
|
self._scheduleMightSkip++;
|
||||||
|
self.hookPlayerWrapper(this.manager.getPlayerWrapper());
|
||||||
|
}
|
||||||
|
|
||||||
|
return startPlayback(apiClient);
|
||||||
|
};
|
||||||
|
|
||||||
|
const scheduleReadyRequestOnPlaybackStart = this._scheduleReadyRequestOnPlaybackStart = queueCore.scheduleReadyRequestOnPlaybackStart.bind(queueCore);
|
||||||
|
queueCore.scheduleReadyRequestOnPlaybackStart = function(apiClient, origin) {
|
||||||
|
if (origin == "startPlayback" && self._scheduleSkip > 0) {
|
||||||
|
self._scheduleSkip--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scheduleReadyRequestOnPlaybackStart(apiClient, origin);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {any} playerWrapper
|
||||||
|
*/
|
||||||
|
hookPlayerWrapper(playerWrapper) {
|
||||||
|
if (playerWrapper._PatchFixSyncPlay_localPlay) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const localPlay = playerWrapper._PatchFixSyncPlay_localPlay = playerWrapper.localPlay.bind(playerWrapper);
|
||||||
|
playerWrapper.localPlay = (options) => {
|
||||||
|
const skip = this._scheduleMightSkip > 0;
|
||||||
|
if (skip) {
|
||||||
|
this._scheduleMightSkip--;
|
||||||
|
this._scheduleSkip++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rv = localPlay(options);
|
||||||
|
|
||||||
|
rv.catch(() => {
|
||||||
|
if (skip) {
|
||||||
|
this._scheduleSkip--;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
})());
|
@ -1,10 +1,11 @@
|
|||||||
//@ts-check
|
//@ts-check
|
||||||
|
|
||||||
import JadefinIntegrity from '../../JadefinIntegrity.js';
|
import JadefinIntegrity from '../JadefinIntegrity.js';
|
||||||
|
|
||||||
import Jadefin from "../../Jadefin.js";
|
import Jadefin from "../Jadefin.js";
|
||||||
import JadefinMod from "../../JadefinMod.js";
|
import JadefinMod from "../JadefinMod.js";
|
||||||
import JadefinModules from "../../JadefinModules.js";
|
import JadefinModules from "../JadefinModules.js";
|
||||||
|
import JadefinUtils from "../JadefinUtils.js";
|
||||||
|
|
||||||
// Mainly spawned from https://github.com/jellyfin/jellyfin-android/issues/1031
|
// Mainly spawned from https://github.com/jellyfin/jellyfin-android/issues/1031
|
||||||
export default JadefinIntegrity("PatchAndroidHLSJS", import.meta.url, () => new (class PatchAndroidHLSJS extends JadefinMod {
|
export default JadefinIntegrity("PatchAndroidHLSJS", import.meta.url, () => new (class PatchAndroidHLSJS extends JadefinMod {
|
||||||
@ -25,12 +26,20 @@ export default JadefinIntegrity("PatchAndroidHLSJS", import.meta.url, () => new
|
|||||||
async init(name, url) {
|
async init(name, url) {
|
||||||
await super.init(name, url);
|
await super.init(name, url);
|
||||||
|
|
||||||
const htmlMediaHelper = this.htmlMediaPlayer = Jadefin.findWebpackRawLoad(e => (e.JQ?.toString().indexOf("x-mpegURL") || -1) != -1)[0];
|
let enableHlsJsPlayerKey = [];
|
||||||
this._enableHlsJsPlayer = htmlMediaHelper.JQ.bind(htmlMediaHelper);
|
const htmlMediaHelper = this.htmlMediaPlayer = Jadefin.findWebpackRawLoad(
|
||||||
|
e => JadefinUtils.findDeep(
|
||||||
|
e,
|
||||||
|
1,
|
||||||
|
(i, o) => o.toString().indexOf(`.canPlayType("application/vnd.apple.mpegURL").replace(/no/,"")`) != -1,
|
||||||
|
(i, v, k) => enableHlsJsPlayerKey.push(k)
|
||||||
|
) && 1
|
||||||
|
)[0];
|
||||||
|
this._enableHlsJsPlayer = htmlMediaHelper[enableHlsJsPlayerKey[0]].bind(htmlMediaHelper);
|
||||||
|
|
||||||
Object.defineProperty(htmlMediaHelper, "JQ", { get: () => this.enableHlsJsPlayer });
|
Object.defineProperty(htmlMediaHelper, enableHlsJsPlayerKey[0], { get: () => this.enableHlsJsPlayer });
|
||||||
|
|
||||||
const ExtrasMenu = /** @type {import("../ExtrasMenu.js").default} */ (Jadefin.getMod("ExtrasMenu"));
|
const ExtrasMenu = /** @type {import("./ExtrasMenu.js").default} */ (Jadefin.getMod("ExtrasMenu"));
|
||||||
|
|
||||||
ExtrasMenu.items.push({
|
ExtrasMenu.items.push({
|
||||||
name: "Enable HLS.js",
|
name: "Enable HLS.js",
|
@ -620,6 +620,8 @@ export default JadefinIntegrity("Transcript", import.meta.url, () => new (class
|
|||||||
return el;
|
return el;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
line.el?.classList.toggle("active", false);
|
||||||
|
|
||||||
line.el["_data_subLine"] = line;
|
line.el["_data_subLine"] = line;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
"Screenshot.js",
|
"Screenshot.js",
|
||||||
"InputEater.js",
|
"InputEater.js",
|
||||||
"Transcript.js",
|
"Transcript.js",
|
||||||
|
"PatchForceHLSJS.js",
|
||||||
|
"PatchFixSyncPlay.js",
|
||||||
|
|
||||||
"jade/Shortcuts.js",
|
"jade/Shortcuts.js"
|
||||||
"jade/PatchForceHLSJS.js"
|
|
||||||
]
|
]
|
Loading…
Reference in New Issue
Block a user