DavidBuchanan314 / Turbo-Recadmiumator

A remake of truedread/netflix-1080p which auto-patches cadmium-playercore at runtime to enable enhanced playback features. (NOTE: still working in 2024 😎)
MIT License
154 stars 18 forks source link

AVC+Prk mode and DDPlus (Atmos) for Higher Bitrate #5

Open vincent1990 opened 3 months ago

vincent1990 commented 3 months ago

Hi, I really love this extension. It works greats in Chrome for 1080p playback. I just wish it could playback the videos in full bitrate mode, AVC mode, which occasionally has 50% more bitrate compared to AVCHigh.

Here is an extension that successfully does so in Chrome (it only does AVChigh + DDPlud on edge in 1080p mode on most computers). However, If the hardware is compliant, it also outputs 4k in edge):

https://github.com/lkmvip/netflix-4K-DDplus

And the following fork outputs AVC and DDPlus in 1080p mode on Edge but doesn't use prk (the developer has not updated the extension since Netflix introduced prk):

https://github.com/Sparoney/netflix-4K-DDplus

The problem with above extensions is that they need occasional maintenance due to the playercore updates. And this extension, which patches on the fly, is more future proof besides being efficient. So once the above features arrive, this extension will be the perfect one for netflix. Thanks again for all the hard work!

naix07 commented 3 months ago

added the missing profiles under custom_profiles image

Getting 4K @ max bitrate (I think) too image

replace get_profile_list() in cadmium-playercore-shim.js with the one below:

function get_profile_list() {
     custom_profiles = [
        "playready-h264mpl30-dash",
        "playready-h264mpl31-dash",
        "playready-h264mpl40-dash",

        "playready-h264hpl30-dash",
        "playready-h264hpl31-dash",
        "playready-h264hpl40-dash",

        "hevc-main10-L30-dash-cenc",
        "hevc-main10-L31-dash-cenc",
        "hevc-main10-L40-dash-cenc",
        "hevc-main10-L50-dash-cenc",
        "hevc-main10-L51-dash-cenc",

        "hevc-main10-L30-dash-cenc-live",
        "hevc-main10-L31-dash-cenc-live",
        "hevc-main10-L40-dash-cenc-live",
        "hevc-main10-L41-dash-cenc-live",
        "hevc-main10-L50-dash-cenc-live",
        "hevc-main10-L51-dash-cenc-live",

        "hevc-main10-L30-dash-cenc-prk",
        "hevc-main10-L31-dash-cenc-prk",
        "hevc-main10-L40-dash-cenc-prk",
        "hevc-main10-L41-dash-cenc-prk",

        "hevc-main10-L30-dash-cenc-prk-do",
        "hevc-main10-L31-dash-cenc-prk-do",
        "hevc-main10-L40-dash-cenc-prk-do",
        "hevc-main10-L41-dash-cenc-prk-do",
        "hevc-main10-L50-dash-cenc-prk-do",
        "hevc-main10-L51-dash-cenc-prk-do",

        "heaac-2-dash",
        "heaac-2hq-dash",
        "ddplus-2.0-dash",

        "simplesdh",
        "nflx-cmisc",
        "BIF240",
        "BIF320"
    ];

    if (my_config["use_VP9"]) {
        custom_profiles = custom_profiles.concat([
            "vp9-profile0-L30-dash-cenc",
            "vp9-profile0-L31-dash-cenc",
            "vp9-profile0-L40-dash-cenc",
        ]);
    }

    if (my_config["use_5.1"]) {
        custom_profiles.push("heaac-5.1-dash");
        custom_profiles.push("ddplus-5.1-dash");
        custom_profiles.push("ddplus-5.1hq-dash");
        custom_profiles.push("ddplus-atmos-dash");

    }

    return custom_profiles;
}

don't forget to set use_5.1 to true under my_config if you want 5.1 If someone wants to make a proper PR you can take the code above.

DavidBuchanan314 commented 3 months ago

Not 100% sure but I think some of the HEVC/prk profiles will error out if you try to request them on a platform that doesn't actually support 4K, so they'll need to be gated behind some kind of "use_hevc" setting

DavidBuchanan314 commented 3 months ago

Idea: Since we're already doing regex magic with cadmium, it might be possible to extract out all possible profile strings automatically, and create some kind of checkbox interface that lets the user fiddle with which ones to enable/disable

vincent1990 commented 3 months ago

Prk with avc main that works on non-4k devices can be achieved with following profiles:

    "h264mpl30-dash-playready-prk-qc",
"h264mpl31-dash-playready-prk-qc",
"h264mpl40-dash-playready-prk-qc",

The above will unlock 1080p video at higher bitrate

Phoenomenal commented 3 months ago

I modified cadmium a bit purely for Edge. But there was some trouble with audio. I disabled : ddplus-5.1hq-dash cause non atmos 5.1 wont load with that (and now with only ddplus-5.1-dash all videos load but have 192 kbps ddplus instead of 640). Second is some titles (tv series Rookie for example) still use he-aac codec unless i disable it in cadmium, But don't know why it affects Atmos bitrate which go down from 768 to 448 if i disable he-aac completely. So now its a switch to me with either use ddplus 5.1 (192 kbps) + sometimes revert to he-aac (192 kbps) and atmos 768 kbps. Or fully ddplus on all titles and atmos with 448 kbps. And also without ddplus-5.1hq profile which should be using up to 640 kbps bitrate instead of 192 (but titles wont playing with this profile enabled) If someone can use this cadmium and upgrade it would apreciate the help !
to enable he-aac or ddplushq just delete 2 slashes : image

Cadmium full code :

var my_config = { "use_VP9": false, "use_5.1": true, "set_max_bitrate": true, "use_heaac-5.1": false, }

function repr(obj) { // can you tell I'm a python programmer? return JSON.stringify(obj); }

function do_patch(desc, needle, replacement) { var match = cadmium_src.match(needle); if (!match) { alert("Failed to find patch: " + repr(desc)); } else { cadmium_src = cadmium_src.replace(needle, replacement); console.log("[+] Patched: " + repr(desc)); if (match[0].length < 200) { // avoid spamming the console console.log(repr(match[0]) + " -> " + repr(replacement)); } } }

/ We need to do a synchronous request because we need to eval the response before the body of this script finishes executing / var request = new XMLHttpRequest(); var cadmium_url = document.getElementById("player-core-js").src; request.open("GET", cadmium_url + "?no_filter", false); // synchronous request.send(null);

var cadmium_src = request.responseText;

function get_profile_list() { custom_profiles = [

            "playready-h264mpl30-dash",
    "playready-h264mpl31-dash",
    "playready-h264mpl40-dash",

            "h264mpl30-dash-playready-prk-qc",
        "h264mpl31-dash-playready-prk-qc",
        "h264mpl40-dash-playready-prk-qc",

    "hevc-main10-L30-dash-cenc",
    "hevc-main10-L31-dash-cenc",
    "hevc-main10-L40-dash-cenc",
    "hevc-main10-L50-dash-cenc",
    "hevc-main10-L51-dash-cenc",

    "hevc-main10-L30-dash-cenc-live",
    "hevc-main10-L31-dash-cenc-live",
    "hevc-main10-L40-dash-cenc-live",
    "hevc-main10-L41-dash-cenc-live",
    "hevc-main10-L50-dash-cenc-live",
    "hevc-main10-L51-dash-cenc-live",

    "hevc-main10-L30-dash-cenc-prk",
    "hevc-main10-L31-dash-cenc-prk",
    "hevc-main10-L40-dash-cenc-prk",
    "hevc-main10-L41-dash-cenc-prk",

    "hevc-main10-L30-dash-cenc-prk-do",
    "hevc-main10-L31-dash-cenc-prk-do",
    "hevc-main10-L40-dash-cenc-prk-do",
    "hevc-main10-L41-dash-cenc-prk-do",
    "hevc-main10-L50-dash-cenc-prk-do",
    "hevc-main10-L51-dash-cenc-prk-do",

            "hevc-hdr-main10-L30-dash-cenc-prk",
            "hevc-hdr-main10-L31-dash-cenc-prk",
            "hevc-hdr-main10-L40-dash-cenc-prk",
            "hevc-hdr-main10-L41-dash-cenc-prk",
            "hevc-hdr-main10-L50-dash-cenc-prk",
            "hevc-hdr-main10-L51-dash-cenc-prk",
            "hevc-hdr-main10-L30-dash-cenc-prk-do",
            "hevc-hdr-main10-L31-dash-cenc-prk-do",
            "hevc-hdr-main10-L40-dash-cenc-prk-do",
            "hevc-hdr-main10-L41-dash-cenc-prk-do",
            "hevc-hdr-main10-L50-dash-cenc-prk-do",
            "hevc-hdr-main10-L51-dash-cenc-prk-do",
            "hevc-hdr-main10-L30-dash-cenc-live",
            "hevc-hdr-main10-L31-dash-cenc-live",
            "hevc-hdr-main10-L40-dash-cenc-live",
            "hevc-hdr-main10-L41-dash-cenc-live",
            "hevc-hdr-main10-L50-dash-cenc-live",
            "hevc-hdr-main10-L51-dash-cenc-live",

    "ddplus-2.0-dash",

    "simplesdh",
    "nflx-cmisc",
    "BIF240",
    "BIF320"
];

if (my_config["use_VP9"]) {
    custom_profiles = custom_profiles.concat([
        "vp9-profile0-L30-dash-cenc",
        "vp9-profile0-L31-dash-cenc",
        "vp9-profile0-L40-dash-cenc",
    ]);
}

if (my_config["use_5.1"]) {
    custom_profiles.push("ddplus-5.1-dash");
            //custom_profiles.push("heaac-5.1-dash");
    //custom_profiles.push("ddplus-5.1hq-dash");
    custom_profiles.push("ddplus-atmos-dash");

}

if (my_config["use_heaac-5.1"]) {
    custom_profiles.push("heaac-5.1-dash");
}

return custom_profiles;

}

do_patch( "Hello world", /(.*)/, "console.log('Hello, I am code which has been injected into playercore!'); $1" );

do_patch( "Custom profiles", /(viewableId:.,profiles:).,/, "$1 get_profile_list()," );

do_patch( "Custom profile group", /(name:"default",profiles:)./, "$1 get_profile_list()" );

do_patch( "Re-enable Ctrl+Shift+Alt+S menu", /this.......\s\&\&\sthis.toggle();/, "this.toggle();");

// run our patched copy of playercore eval(cadmium_src);

/ netflix_max_bitrate.js /

/ eslint-disable no-undef / let getElementByXPath = function (xpath) { return document.evaluate( xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue; };

let fn = function () { const VIDEO_SELECT = getElementByXPath("//div[text()='Video Bitrate']") || getElementByXPath("//div[text()='Video Bitrate / VMAF']"); const AUDIO_SELECT = getElementByXPath("//div[text()='Audio Bitrate']"); const BUTTON = getElementByXPath("//button[text()='Override']");

const videoPlayer = netflix.appContext.state.playerApp.getAPI().videoPlayer;
if(!videoPlayer) {
    console.log("API Not Loading!");
    return false;
}
const player = videoPlayer.getVideoPlayerBySessionId(videoPlayer.getAllPlayerSessionIds()[0]);
if(!player) {
    console.log("Video Not Loading!");
    return false;
}
if(!player.isPlaying()) {
    console.log("Video Not Playing!");
    return false;
}

window.dispatchEvent(new KeyboardEvent('keydown', {
    keyCode: 66,
    ctrlKey: true,
    altKey: true,
    shiftKey: true,
}));

if (!(VIDEO_SELECT && AUDIO_SELECT && BUTTON)){
    return false;
}

[VIDEO_SELECT, AUDIO_SELECT].forEach(function (el) {
    let parent = el.parentElement;

    let options = parent.querySelectorAll('select > option');

    for (var i = 0; i < options.length - 1; i++) {
        options[i].removeAttribute('selected');
    }

    options[options.length - 1].setAttribute('selected', 'selected');
});

console.log("Video Playing!");
BUTTON.click();

return true;

};

let run = function () { fn() || setTimeout(run, 100)
};

const WATCH_REGEXP = /netflix.com\/watch\/.*/;

let oldLocation;

if (window.globalOptions === undefined) { try { window.globalOptions = JSON.parse(document.getElementById("netflix-intl-settings").innerText); } catch(e) { console.error("Could not load settings:", e); } } if(window.globalOptions.setMaxBitrate ) { console.log("netflix_max_bitrate.js enabled"); //setInterval(test, 500); setInterval(function () {

    let newLocation = window.location.toString();

    if (newLocation !== oldLocation) {
        oldLocation = newLocation;
        WATCH_REGEXP.test(newLocation) && run();
    }

}, 500); }