-
-
Save akku1139/8a098c004ead96c74a70a235b8926b66 to your computer and use it in GitHub Desktop.
| // ==UserScript== | |
| // @name enhanced-h264ify | |
| // @namespace Violentmonkey Scripts | |
| // @version 0.1 | |
| // @description enhanced-h264ify for user script. | |
| // @author akku | |
| // @match *://*.youtube.com/* | |
| // @match *://*.youtube-nocookie.com/* | |
| // @match *://*.youtu.be/* | |
| // @grant none | |
| // @run-at document-start | |
| // ==/UserScript== | |
| /** | |
| * The MIT License (MIT) | |
| * | |
| * Copyright (c) 2024 akku | |
| * Copyright (c) 2019 alextrv | |
| * Copyright (c) 2015 erkserkserks | |
| * | |
| * Permission is hereby granted, free of charge, to any person obtaining a copy | |
| * of this software and associated documentation files (the "Software"), to deal | |
| * in the Software without restriction, including without limitation the rights | |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| * copies of the Software, and to permit persons to whom the Software is | |
| * furnished to do so, subject to the following conditions: | |
| * | |
| * The above copyright notice and this permission notice shall be included in all | |
| * copies or substantial portions of the Software. | |
| * | |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |
| * SOFTWARE. | |
| */ | |
| const config = { | |
| 'block_60fps': true, | |
| 'block_h264': false, | |
| 'block_vp8': true, | |
| 'block_vp9': true, | |
| 'block_av1': true, | |
| 'disable_LN': true, | |
| }; | |
| function inject () { | |
| override(); | |
| function override() { | |
| // Override video element canPlayType() function | |
| var videoElem = document.createElement('video'); | |
| var origCanPlayType = videoElem.canPlayType.bind(videoElem); | |
| videoElem.__proto__.canPlayType = makeModifiedTypeChecker(origCanPlayType); | |
| // Override media source extension isTypeSupported() function | |
| var mse = window.MediaSource; | |
| // Check for MSE support before use | |
| if (mse === undefined) return; | |
| var origIsTypeSupported = mse.isTypeSupported.bind(mse); | |
| mse.isTypeSupported = makeModifiedTypeChecker(origIsTypeSupported); | |
| } | |
| // return a custom MIME type checker that can defer to the original function | |
| function makeModifiedTypeChecker(origChecker) { | |
| // Check if a video type is allowed | |
| return function (type) { | |
| if (type === undefined) return ''; | |
| var disallowed_types = []; | |
| if (config['block_h264']) { | |
| disallowed_types.push('avc'); | |
| } | |
| if (config['block_vp8']) { | |
| disallowed_types.push('vp8'); | |
| } | |
| if (config['block_vp9']) { | |
| disallowed_types.push('vp9', 'vp09'); | |
| } | |
| if (config['block_av1']) { | |
| disallowed_types.push('av01'); | |
| } | |
| // If video type is in disallowed_types, say we don't support them | |
| for (var i = 0; i < disallowed_types.length; i++) { | |
| if (type.indexOf(disallowed_types[i]) !== -1) return ''; | |
| } | |
| if (config['block_60fps']) { | |
| var match = /framerate=(\d+)/.exec(type); | |
| if (match && match[1] > 30) return ''; | |
| } | |
| // Otherwise, ask the browser | |
| return origChecker(type); | |
| }; | |
| } | |
| } | |
| function useActualVolumeLevel() { | |
| if (!config['disable_LN']) { | |
| return; | |
| } | |
| var video = document.querySelector('video'); | |
| var observerConfig = {attributes: true}; | |
| var onVolumeChange = function(mutationList) { | |
| var attr = 'aria-valuenow'; | |
| for (var mutation of mutationList) { | |
| if (mutation.attributeName == attr) { | |
| // Get current volume level from player's attribute | |
| // and set the actual volume | |
| video.volume = mutation.target.attributes[attr].value / 100; | |
| } | |
| } | |
| } | |
| var volumePanel = document.querySelector('.ytp-volume-panel'); | |
| if (volumePanel) { | |
| var observer = new MutationObserver(onVolumeChange); | |
| observer.observe(volumePanel, observerConfig); | |
| } | |
| } | |
| inject(); | |
| document.onreadystatechange = useActualVolumeLevel; |
it does not work because you are using a strict equality check between the boolean value true and the string "true". also everything in the config is set to true by default, so even if that problem wasn't there no video would play.
to fix this you can simply replace the makeModifiedTypeChecker and useActualVolumeLevel functions with these versions
function makeModifiedTypeChecker(origChecker) {
// Check if a video type is allowed
return function (type) {
if (type === undefined) return '';
var disallowed_types = [];
if (config['block_h264']) {
disallowed_types.push('avc');
}
if (config['block_vp8']) {
disallowed_types.push('vp8');
}
if (config['block_vp9']) {
disallowed_types.push('vp9', 'vp09');
}
if (config['block_av1']) {
disallowed_types.push('av01');
}
// If video type is in disallowed_types, say we don't support them
for (var i = 0; i < disallowed_types.length; i++) {
if (type.indexOf(disallowed_types[i]) !== -1) return '';
}
if (config['block_60fps']) {
var match = /framerate=(\d+)/.exec(type);
if (match && match[1] > 30) return '';
}
// Otherwise, ask the browser
return origChecker(type);
};
}
function useActualVolumeLevel() {
if (!config['disable_LN']) {
return;
}
var video = document.querySelector('video');
var observerConfig = {attributes: true};
var onVolumeChange = function(mutationList) {
var attr = 'aria-valuenow';
for (var mutation of mutationList) {
if (mutation.attributeName == attr) {
// Get current volume level from player's attribute
// and set the actual volume
video.volume = mutation.target.attributes[attr].value / 100;
}
}
}
var volumePanel = document.querySelector('.ytp-volume-panel');
if (volumePanel) {
var observer = new MutationObserver(onVolumeChange);
observer.observe(volumePanel, observerConfig);
}
}please forgive my indentation this was cancer to type out on mobile
also might i add, since this is a userscript, the injection section is not necessary.
it is trivial to replace this
var injectScript = document.createElement('script');
// Use textContent instead of src to run inject() synchronously
injectScript.textContent = inject.toString() + "inject();";
injectScript.onload = function() {
// Remove <script> node after injectScript runs.
this.parentNode.removeChild(this);
};
(document.head || document.documentElement).appendChild(injectScript);
document.onreadystatechange = function() {
if (document.readyState == 'interactive') {
var script = document.createElement('script');
script.text = useActualVolumeLevel.toString() + "useActualVolumeLevel();";
document.body.appendChild(script);
}
}with this
inject(); // we're already running at document-start
document.onreadystatechange = useActualVolumeLevel;hope this helps anyone who stumbles across this
no ai was used in the creation of this comment
ohno!
thank you
but I don't use this script now...
yeah i thought so, it's been more than 2 years now. but after applying the modifications I documented it works perfectly. what do you use now?
i bought dGPU,
before: Intel HD Graphics 4400, 4600
now: Radeon RX 6700 XT
it also supports VP9,
so no longer need h246ify
Trying display: wayland
vainfo: VA-API version: 1.22 (libva 2.22.0)
vainfo: Driver version: Mesa Gallium driver 25.3.1-arch1.3 for AMD Radeon RX 6700 XT (radeonsi, navi22, LLVM 21.1.6, DRM 3.64, 6.18.1-2-cachyos)
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
VAProfileHEVCMain10 : VAEntrypointVLD
VAProfileHEVCMain10 : VAEntrypointEncSlice
VAProfileJPEGBaseline : VAEntrypointVLD
VAProfileVP9Profile0 : VAEntrypointVLD
VAProfileVP9Profile2 : VAEntrypointVLD
VAProfileAV1Profile0 : VAEntrypointVLD
VAProfileNone : VAEntrypointVideoProc
(Intel HD Graphics 4600)
Trying display: wayland
error: failed to resolve wl_drm_interface(): /usr/lib/libEGL_mesa.so.0: undefined symbol: wl_drm_interface
vainfo: VA-API version: 1.22 (libva 2.22.0)
vainfo: Driver version: Intel i965 driver for Intel(R) Haswell Desktop - 2.4.1
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Simple : VAEntrypointEncSlice
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264MultiviewHigh : VAEntrypointVLD
VAProfileH264MultiviewHigh : VAEntrypointEncSlice
VAProfileH264StereoHigh : VAEntrypointVLD
VAProfileH264StereoHigh : VAEntrypointEncSlice
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileNone : VAEntrypointVideoProc
VAProfileJPEGBaseline : VAEntrypointVLD
i guess that's one way to solve the problem. even though this cpu supports vp9 I'm using h264 for better battery life (it's an sd678).
good,
i'll update the code after test your fix


Not working