spritenguyen
Senior Member
ngon r fenBởi do Dark Mode nửa mùa hiện đã lo vụ chuyển đổi màu sắc, nên trong uBlock nên chuyển sang Light là lại thấy ngay:
View attachment 2102847
ngon r fenBởi do Dark Mode nửa mùa hiện đã lo vụ chuyển đổi màu sắc, nên trong uBlock nên chuyển sang Light là lại thấy ngay:
View attachment 2102847
Yên tâm là Dark Mode nửa mùa vẫn còn đang ở giai đoạn tiến hóa, sắp tới mình sẽ nghiên cứu thêm mà đây là cái ảnh đề mô thật ra nó còn sâu lắm, nghĩa là nó còn có thể tự sửa cho trường hợp như Dark Mode, cứ để đây để cùng nghiên cứu @haidangtueba @Chu Cong Canh :ngon r fen
browser.display.background_color.dark | #1C1B22 |
---|
browser.display.foreground_color.dark | #FBFBFE |
---|
browser.active_color.dark | #FF6666 |
---|
browser.anchor_color.dark | #8C8CFF |
---|
browser.visited_color.dark | #FFADFF |
---|
browser.display.use_focus_colors | true |
---|
browser.display.focus_background_color | #117722 |
---|
browser.display.focus_text_color | #ffffff |
---|
browser.display.suppress_canvas_background_image_on_forced_colors | true |
---|
# Whether we should suppress the background-image of the canvas (the root
# frame) if we're in forced colors mode.
#
# This is important because some sites use background-image with a plain color
# and it causes undesirable results in high-contrast mode.
#
# See bug 1614921 for example.
- name: browser.display.suppress_canvas_background_image_on_forced_colors
type: bool
value: true
mirror: always
- name: browser.display.focus_ring_on_anything
type: bool
value: false
mirror: always
- name: browser.display.focus_ring_width
type: uint32_t
value: 1
mirror: always
- name: browser.display.focus_background_color
type: String
value: "#117722"
mirror: never
# Focus ring border style.
# 0 = solid border, 1 = dotted border
- name: browser.display.focus_ring_style
type: uint32_t
value: 1
mirror: always
- name: browser.display.focus_text_color
type: String
value: "#ffffff"
mirror: never
- name: browser.display.foreground_color
type: String
value: "#000000"
mirror: never
- name: browser.display.foreground_color.dark
type: String
value: "#FBFBFE"
mirror: never
Cập nhập Handlers dành cho MPV, hỗ trợ thêm rất nhiều tính năng khi so sánh với phiên bản trước đó, cách sử dụng cũng nhẹ nhàng hơn
Nếu các bạn thấy lỗi báo cho mình bởi mình chưa có test kỹ.
Tính năng:
- Kéo thả link qua bên tay phải để mở qua MPV, kéo qua tay trái để mở qua streamlink, kéo xuống dưới để tải với yt-dlp
- Hỗ trợ thêm streamlink và yt-dlp
- Nhẹ và đơn giản hơn so với code cũ gấp tỉ lần, rất dễ cho việc phát triển thêm từ phía các bạn chứ không chỉ mình
- Có thể tùy ý thêm tính năng nếu các bạn muốn, bởi script này hỗ trợ 8 hướng
Video demo: https://streamable.com/o3sxe1
Cài đặt:
1. Cài đặt tại Greasyfork.org hoặc Từ addon quản lý Userscript như Violent/Fire/Tamplermonkey, tạo script mới rồi paste chỗ này vào, Save.
- V1.0: Bản thử nghiệm đầu tiên
- V1.1: Sửa lỗi M3U8 không cho script kéo link
- V1.2: Không cập nhập gì nhiều, thêm sẵn
Hướng
cho chéo lên phải, chéo lên trái, chéo xuống phải, chéo xuống trái và hướng dẫn cách phát triển thêm tính năng cho script- V1.3: Sửa lỗi kèm với làm theo một số khuyến nghị từ Firemonkey (
@include
thay cho@match
sai chuẩn)- V1.4: Chuyển code sang chuẩn switch case cho đẹp bởi @pTalent
- V1.5: Hỗ trợ tính năng mới (chú ý để có tính năng mới các bạn cập nhập cả
protocol_hook.lua
mới đính kèm):
- Chọn nhiều video bằng cách giữ chuột phải 0.4s sau đó mở hàng loạt qua MPV/Streamlink, tải hàng loạt qua YTDL
- Hỗ trợ Linux, MacOS (sửa lỗi URL bị hỏng của Mac)
- Không còn phải nhập tay thư mục MPV nữa
- Kéo lên để xem playlist dạng stream
- V1.6: Hỗ trợ
mpv://
, sửa lại code cho đúng quy chuẩnJavaScript:// ==UserScript== // @name Handlers Helper // @include *://*/* // @grant none // @version 1.6 // @author - // @description Helper for protocol_hook.lua // @namespace Violentmonkey Scripts // ==/UserScript== var collected_urls = {}; function GM_getParentByTagName(el, tagName) { tagName = tagName.toLowerCase(); if (el.tagName.toLowerCase() == tagName) { return el; } while (el && el.parentNode) { el = el.parentNode; if (el.tagName && el.tagName.toLowerCase() == tagName) { return el; } } return "undefined"; } function attachDrag(elem) { function GM_btoaUrl(url) { return btoa(url).replace(/\//g, "_").replace(/\+/g, "-").replace(/\=/g, ""); } function EA(attr, type) { var url = ''; var subs = ''; var s = ''; console.log(attr, type) if (attr.startsWith('http')) { url = attr; } else if (attr.startsWith('http')) { location.href = attr; return; } if (url == '') { url = location.href; } console.log(collected_urls); if (Object.keys(collected_urls).length > 0) { for (link in collected_urls) { console.log(link, collected_urls[link]); collected_urls[link].style.boxSizing = 'unset'; collected_urls[link].style.border = 'unset'; s += link + ' '; } s = s.trim(' '); console.log(s); //var s = collected_urls.join(" "); } else { var s = url; } collected_urls = {}; var app = 'play'; if (type != 'vid') { var app = type.toLowerCase(); } var bs = GM_btoaUrl(s); var url2 = 'mpv://' + app + '/' + bs + '/' + "?referer=" + GM_btoaUrl(location.href); if (subs != '') { url2 = url2 + '?subs=' + GM_btoaUrl(subs); } //alert(url2); location.href = url2; } // Define the enum-like directory const DirectionEnum = { RIGHT: 6, LEFT: 4, UP: 2, DOWN: 8, UP_LEFT: 1, UP_RIGHT: 3, DOWN_LEFT: 7, DOWN_RIGHT: 9 }; function getDirection(x, y, cx, cy) { /*================= | | | 1↖ 2↑ 3↗ | | | | 4← 5 6→ | | | | 7↙ 8↓ 9↘ | | | |=================*/ let d, t; if ((cx - x) >= -50 && (cx - x) <= 50 && (cy - y) >= -50 && (cy - y) <= 50) { return 5; } // Change (4 == 4) to (8 == 4) to enable 8 directions if (4 == 4) { //4 directions if (Math.abs(cx - x) < Math.abs(cy - y)) { d = cy > y ? "8" : "2"; } else { d = cx > x ? "6" : "4"; } } else { //8 directions t = (cy - y) / (cx - x); if (-0.4142 <= t && t < 0.4142) d = cx > x ? '6' : "4"; else if (2.4142 <= t || t < -2.4142) d = cy > y ? '8' : '2'; else if (0.4142 <= t && t < 2.4142) d = cx > x ? '9' : '1'; else d = cy > y ? '7' : '3'; } return d; } elem.addEventListener('dragstart', function(e) { //console.log(e.target); //console.log(e.target.shadowRoot); /*if (e.target.nodeName != "A") { e.stopPropagation(); e.stopImmediatePropagation(); //e.preventDefault(); }*/ console.log('dragstart'); var x1 = e.clientX; var y1 = e.clientY; var dragend = elem.addEventListener('dragend', function doEA(e) { var x2 = e.clientX; var y2 = e.clientY; var direction = getDirection(x1, y1, x2, y2); //if ((x2 - x1) >= -50 && (x2 - x1) <= 50 && (y2 - y1) >= -50 && (y2 - y1) <= 50) {direction = 5;console.log(5);} //if (e.target.nodeName == "A" && e.target.href.match(/youtube.com|youtu.be|streamable.com/)) { console.log('Direction: ' + direction); console.log(x1, y1, x2, y2, direction); const targetHref = e.target.href || e.target.src; switch (+direction) { case DirectionEnum.RIGHT: console.log('MPV: ' + targetHref); EA(targetHref, 'vid'); break; case DirectionEnum.LEFT: console.log('Streamlink: ' + targetHref); EA(targetHref, 'stream'); break; case DirectionEnum.UP: console.log('Open: ' + targetHref); EA(targetHref, 'list'); break; case DirectionEnum.DOWN: console.log('YTDL: ' + targetHref); EA(targetHref, 'ytdl'); break; case DirectionEnum.UP_LEFT: case DirectionEnum.UP_RIGHT: case DirectionEnum.DOWN_LEFT: case DirectionEnum.DOWN_RIGHT: default: break; } //} console.log(direction); this.removeEventListener('dragend', doEA); }, false); }, false); } var count = 0; var mouseIsDown = false; var held = false; document.addEventListener("mousedown", function (e) { var link = GM_getParentByTagName(e.target, 'A'); if (link.nodeName == 'A') { mouseIsDown = true; document.addEventListener("mouseup", function mouseup(e) { mouseIsDown = false; this.removeEventListener('mouseup', mouseup); }); document.addEventListener("contextmenu", function contextmenu(e) { if (held == true) { held = false; e.preventDefault(); } held = false; this.removeEventListener('contextmenu', contextmenu); }); if (e.button === 2) { setTimeout(function () { if (mouseIsDown) { if (collected_urls[link.href] == undefined) { //var ele = GM_eleTOPele(e.target); //document.body.appendChild(ele); //collected_urls[link.href] = ele; collected_urls[link.href] = e.target; e.target.style.boxSizing = 'border-box'; e.target.style.border = 'solid yellow 4px'; //popup('Added: ' + link.href, e.clientX, e.clientY) } else { //collected_urls[link.href].parentNode.removeChild(collected_urls[link.href]); collected_urls[link.href].style.boxSizing = 'unset'; collected_urls[link.href].style.border = 'unset'; delete collected_urls[link.href]; //e.target.style.boxSizing = 'unset'; //e.target.style.border = 'unset'; } console.log(collected_urls); count = 0; mouseIsDown = false; held = true; } }, 200); } } }); attachDrag(document); var attachedeles = []; document.addEventListener('mouseover', function(e) { if (e.target.shadowRoot) { if (attachedeles.includes(e.target) == false) { console.log(attachedeles); attachedeles.push(e.target); attachDrag(e.target.shadowRoot); } } });
2. Tài fileprotocol_hook.zip
bên dưới vào thẳng folderscripts
của MPV, giải nénExtract Here
.
3. Mở file(bản mới tự nhận ra đường dẫn, không nhận mới cần tự làm)protocol_hook.lua
bằng Notepad rồi tìm dònglocal cwd = 'D:/mpv'
, nếu thư mục chứa MPV của các bạn khác cái này thì tự sửa lại, nhớ dùng/
phân cách các phần đường dẫn để đảm bảo tính tương thích nhiều hệ điều hành, giống của mình bên trên ấy.
3. Phầnhandlers.json
Firefox:
Chú ý: Nếu vị trí của MPV ở chỗ khác thì tự chỉnh nhé.
- Từ Firefox gõ
about:support
- Open Profile Folder
- Mở file
handlers.json
lên, sẽ thấy đoạn kiểu"schemes":{{...}, {...}, {...}}
, thêm, "mpv":{"action":2,"handlers":[{"name":"MPV","path":"D:\\mpv\\mpv.exe"}]
vào cuối cùng của cái đoạn đó, mà sẽ thành như này:"schemes":{{...}, {...}, {...}, "mpv":{"action":2,"handlers":[{"name":"MPV","path":"D:\\mpv\\mpv.exe"}]}
- Ví dụ file của mình (nếu muốn có thể lấy file này luôn):
{"defaultHandlersVersion":{},"mimeTypes":{},"schemes":{"tg":{"action":4}, "mpv":{"action":2,"handlers":[{"name":"MPV","path":"D:\\mpv\\mpv.exe"}]}},"isDownloadsImprovementsAlreadyMigrated":true,"isSVGXMLAlreadyMigrated":true}
- Tắt Firefox
- Save lại rồi khởi động lại Firefox
Thưởng thức thôi.
Cứ tự tạo thôi, nhìn vào cái cây thư mục này rồi cứ thao thao bất tuyệt chỉnh là xong thôiView attachment 2102905View attachment 2102906
bác cho e hỏi vs ạ e có làm theo bác nhưng sao trong mpv của e k có mục scripts ạ
mpv
D:\mpv
mpv.conf
đã tạo theo bài File mpv.conf
khá ổn để bắt đầu sử dụng MPV từ con số 0Tệp .zip không tải đc bác ơi @toi la gay :sosad:Cập nhập Handlers dành cho MPV, hỗ trợ thêm rất nhiều tính năng khi so sánh với phiên bản trước đó, cách sử dụng cũng nhẹ nhàng hơn
Nếu các bạn thấy lỗi báo cho mình bởi mình chưa có test kỹ.
Tính năng:
Thưởng thức thôi.
tải bình thường mà bác ơiTệp .zip không tải đc bác ơi @toi la gay :sosad:
có mà https://voz.vn/t/tong-hop-nhung-addon-chat-cho-firefox-pc-mobile.682181/page-77#post-24558249Còn vụ xem stream hiển thị live comments nữa thím @toi la gay :sosad: ơi
má k biết addon nào nó chặn tải, phải để private mới tải đc, tks báctải bình thường mà bác ơi
Hiện tại lên Handlers rồi mấy cái này sau này làm được dễ dàng hơn nhiều, tại Handlers Helper giờ phân bu rõ ràng là kéo trái là xem stream, giờ mod lại bồi code từCòn vụ xem stream hiển thị live comments nữa thím @toi la gay :sosad: ơi
// ==UserScript==
// @name Handlers Helper
// @include *://*/*
// @grant none
// @version 1.7
// @author -
// @description Helper for protocol_hook.lua
// @namespace Violentmonkey Scripts
// ==/UserScript==
var collected_urls = {};
function GM_getParentByTagName(el, tagName) {
tagName = tagName.toLowerCase();
if (el.tagName.toLowerCase() == tagName) {
return el;
}
while (el && el.parentNode) {
el = el.parentNode;
if (el.tagName && el.tagName.toLowerCase() == tagName) {
return el;
}
}
return "undefined";
}
function attachDrag(elem) {
function GM_btoaUrl(url) {
return btoa(url).replace(/\//g, "_").replace(/\+/g, "-").replace(/\=/g, "");
}
function EA(attr, type) {
var url = '';
var subs = '';
var s = '';
console.log(attr, type)
if (attr.startsWith('http')) {
url = attr;
} else if (attr.startsWith('mpv://')) {
location.href = attr;
return;
}
if (url == '') {
url = location.href;
}
console.log(collected_urls);
if (Object.keys(collected_urls).length > 0) {
for (link in collected_urls) {
console.log(link, collected_urls[link]);
collected_urls[link].style.boxSizing = 'unset';
collected_urls[link].style.border = 'unset';
s += link + ' ';
}
s = s.trim(' ');
console.log(s);
//var s = collected_urls.join(" ");
} else {
var s = url;
}
collected_urls = {};
var app = 'play';
if (type != 'vid') {
var app = type.toLowerCase();
}
var bs = GM_btoaUrl(s);
var url2 = 'mpv://' + app + '/' + bs + '/' + "?referer=" + GM_btoaUrl(location.href);
if (subs != '') {
url2 = url2 + '?subs=' + GM_btoaUrl(subs);
}
//alert(url2);
if (app == 'stream') {
var nurl = new URL(url);
if (nurl.href.indexOf('www.youtube.com/watch') != -1 || nurl.href.indexOf('m.youtube.com/watch') != -1) {
window.open("https://www.youtube.com/live_chat?is_popout=1&v=" + nurl.search.split("v=")[1], "", "fullscreen=no,toolbar=no,titlebar=no,menubar=no,location=no,width=800,height=600")
} else if (nurl.href.match('https://.*?.twitch.tv/.')) {
window.open("https://www.twitch.tv/popout" + nurl.pathname + "/chat?popout=", "", "fullscreen=no,toolbar=no,titlebar=no,menubar=no,location=no,width=800,height=600")
}
}
location.href = url2;
}
// Define the enum-like directory
const DirectionEnum = {
RIGHT: 6,
LEFT: 4,
UP: 2,
DOWN: 8,
UP_LEFT: 1,
UP_RIGHT: 3,
DOWN_LEFT: 7,
DOWN_RIGHT: 9
};
function getDirection(x, y, cx, cy) {
/*=================
| |
| 1↖ 2↑ 3↗ |
| |
| 4← 5 6→ |
| |
| 7↙ 8↓ 9↘ |
| |
|=================*/
let d, t;
if ((cx - x) >= -50 && (cx - x) <= 50 && (cy - y) >= -50 && (cy - y) <= 50) {
return 5;
}
// Change (4 == 4) to (8 == 4) to enable 8 directions
if (4 == 4) { //4 directions
if (Math.abs(cx - x) < Math.abs(cy - y)) {
d = cy > y ? "8" : "2";
} else {
d = cx > x ? "6" : "4";
}
} else { //8 directions
t = (cy - y) / (cx - x);
if (-0.4142 <= t && t < 0.4142) d = cx > x ? '6' : "4";
else if (2.4142 <= t || t < -2.4142) d = cy > y ? '8' : '2';
else if (0.4142 <= t && t < 2.4142) d = cx > x ? '9' : '1';
else d = cy > y ? '7' : '3';
}
return d;
}
elem.addEventListener('dragstart', function(e) {
//console.log(e.target);
//console.log(e.target.shadowRoot);
/*if (e.target.nodeName != "A") {
e.stopPropagation();
e.stopImmediatePropagation();
//e.preventDefault();
}*/
console.log('dragstart');
var x1 = e.clientX;
var y1 = e.clientY;
var dragend = elem.addEventListener('dragend', function doEA(e) {
var x2 = e.clientX;
var y2 = e.clientY;
var direction = getDirection(x1, y1, x2, y2);
//if ((x2 - x1) >= -50 && (x2 - x1) <= 50 && (y2 - y1) >= -50 && (y2 - y1) <= 50) {direction = 5;console.log(5);}
//if (e.target.nodeName == "A" && e.target.href.match(/youtube.com|youtu.be|streamable.com/)) {
console.log('Direction: ' + direction);
console.log(x1, y1, x2, y2, direction);
const targetHref = e.target.href || e.target.src;
switch (+direction) {
case DirectionEnum.RIGHT:
console.log('MPV: ' + targetHref);
EA(targetHref, 'vid');
break;
case DirectionEnum.LEFT:
console.log('Streamlink: ' + targetHref);
EA(targetHref, 'stream');
break;
case DirectionEnum.UP:
console.log('Open: ' + targetHref);
EA(targetHref, 'list');
break;
case DirectionEnum.DOWN:
console.log('YTDL: ' + targetHref);
EA(targetHref, 'ytdl');
break;
case DirectionEnum.UP_LEFT:
case DirectionEnum.UP_RIGHT:
case DirectionEnum.DOWN_LEFT:
case DirectionEnum.DOWN_RIGHT:
default:
break;
}
//}
console.log(direction);
this.removeEventListener('dragend', doEA);
}, false);
}, false);
}
var count = 0;
var mouseIsDown = false;
var held = false;
document.addEventListener("mousedown", function (e) {
var link = GM_getParentByTagName(e.target, 'A');
if (link.nodeName == 'A') {
mouseIsDown = true;
document.addEventListener("mouseup", function mouseup(e) {
mouseIsDown = false;
this.removeEventListener('mouseup', mouseup);
});
document.addEventListener("contextmenu", function contextmenu(e) {
if (held == true) {
held = false;
e.preventDefault();
}
held = false;
this.removeEventListener('contextmenu', contextmenu);
});
if (e.button === 2) {
setTimeout(function () {
if (mouseIsDown) {
if (collected_urls[link.href] == undefined) {
//var ele = GM_eleTOPele(e.target);
//document.body.appendChild(ele);
//collected_urls[link.href] = ele;
collected_urls[link.href] = e.target;
e.target.style.boxSizing = 'border-box';
e.target.style.border = 'solid yellow 4px';
//popup('Added: ' + link.href, e.clientX, e.clientY)
} else {
//collected_urls[link.href].parentNode.removeChild(collected_urls[link.href]);
collected_urls[link.href].style.boxSizing = 'unset';
collected_urls[link.href].style.border = 'unset';
delete collected_urls[link.href];
//e.target.style.boxSizing = 'unset';
//e.target.style.border = 'unset';
}
console.log(collected_urls);
count = 0;
mouseIsDown = false;
held = true;
}
}, 200);
}
}
});
attachDrag(document);
var attachedeles = [];
document.addEventListener('mouseover', function(e) {
if (e.target.shadowRoot) {
if (attachedeles.includes(e.target) == false) {
console.log(attachedeles);
attachedeles.push(e.target);
attachDrag(e.target.shadowRoot);
}
}
});
Cái Dark Mode nửa mùa này không phải tối ưu đâu mà nó mang tính cá nhân hóa, người này thấy đẹp nhưng rất nhiều người khác thấy xấu, sau này cứ làm thành fileBác Gei chắc nên tinh giản các bài hướng dẫn lại, đoạn này bắt đầu tẩu hỏa nhập ma rồi, e theo dõi từ đầu thì có thể làm theo được, nếu pack được thành 1 gói ăn sẵn là oke nhất, có khi góp ý cho Floorp mấy cái tweak của mình cho nó native được luôn
user.js
copy+paste là nhanh nhất, thích trường phái nào thì copy+paste thôi.mpv
để xem youtube thì cài thêm cái này nữa thôi các fencefirefox
nữa, lên mpv
rồi search rồi vứt đấy cho nó tự chạympv --no-video --force-window
là chả khác gì Youtube Music Ânchạympv --no-video --force-window
là chả khác gì Youtube Music
Shift+-
bằng _
gạch dưới tắt video nhanh hơn, còn lặp vĩnh cửu nhạc thì ấn Shift+l
bằng L
lờ to ấy.Chắc tắt mất cái drag preview rồi:mở link youtube bằng mpv bình thường, nhưng mà cái handlers helper khi kéo link thì nó hiện dấu này, không biết fix sao các bác nhỉ
nglayout.enable_drag_images | true |
---|
vẫn bật nglayout.enable_drag_images true bácChắc tắt mất cái drag preview rồi:
nglayout.enable_drag_images true
Thường một số tối ưu sẽ bảo tắt đi, ví dụ như mình nhưng ở thread này mình chưa phổ biến cái này tại nó phế, cái dấutắt triệt bằng CSS được:
View attachment 2103190
Tốt nhất là kệ nó thôi, chả ảnh hưởng gì còn tắt luôn trong Win thử xem, chọn lấy con chuột thường hay con chuột nào giống đang kéo:vẫn bật nglayout.enable_drag_images true bác