kiến thức Tổng hợp những addon chất cho Firefox / Chromium

Mình vừa dòm qua mã nguồn thằng ClearURLs này thấy lạm dụng RegEx quá, hiệu năng chắc sẽ không tốt chắc nên dùng cái list của uBlock: https://gist.github.com/iam-py-test/1db25658541945170eaaf191b399fac0
Có thể sẽ gây chậm cho máy yếu, máy mạnh chắc k ảnh hưởng cho lắm. Addon của ClearUrls này có cái chặn được hyberlink nên chặn theo dõi của nhiều web khi nhấn link rất tốt
 
Hình như trang trên chậm hay mạng mình lag không load nổi, chắc để khi nào mạng hết lag sẽ test cơ mà khả năng là được nếu mod lại script này https://greasyfork.org/en/scripts/449581-m3u8视频侦测下载器-自动嗅探 để get link m3u8 rồi chuột phải xổ ra MPV.

Vấn đề hiện tại là script trên nó không cho chuột phải vào link, nên phải phức tạp hóa vấn đề lên chút là click vào 下载(Download) để mở ra tab chứa cái file m3u8 đó rồi ấn vào nút MPV để xổ, tốn thêm vài s cuộc đời. :D

vylXQJ.png


À mà pop ngon nhé, cơ mà phức tạp hơn chút mình sẽ làm hướng dẫn sau :D, video đây: https://gfycat.com/AdoredNaughtyAmericanalligator
e thấy nó cho tải về máy xem thôi, chứ chưa thấy cho e xem online á
 
e thấy nó cho tải về máy xem thôi, chứ chưa thấy cho e xem online á

À, tất nhiên rồi vì của mình đã mod lại script trên cho nó tự pop sang MPV, đây là bản mod mà bạn có thể chuột phải vào phần Download rồi chọn MPV để bật qua xem:


Code:
// ==UserScript==
// @name         m3u8视频侦测下载器【自动嗅探】
// @name:zh-CN   m3u8视频侦测下载器【自动嗅探】
// @name:zh-TW   m3u8視頻偵測下載器【自動嗅探】
// @name:en      M3U8 Video Detector and Downloader
// @version      1.3.2
// @description  自动检测页面m3u8视频并进行完整下载。检测到m3u8链接后会自动出现在页面右上角位置,点击下载即可跳转到m3u8下载器。
// @description:zh-CN  自动检测页面m3u8视频并进行完整下载。检测到m3u8链接后会自动出现在页面右上角位置,点击下载即可跳转到m3u8下载器。
// @description:zh-TW  自動檢測頁面m3u8視頻並進行完整下載。檢測到m3u8鏈接後會自動出現在頁面右上角位置,點擊下載即可跳轉到m3u8下載器。
// @description:en  Automatically detect the m3u8 video of the page and download it completely. Once detected the m3u8 link, it will appear in the upper right corner of the page. Click download to jump to the m3u8 downloader.
// @icon         https://tools.thatwind.com/favicon.png
// @author       allFull
// @namespace    https://tools.thatwind.com/
// @homepage     https://tools.thatwind.com/tool/m3u8downloader
// @match        *://*/*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/m3u8-parser.min.js
// @connect      *
// @grant        unsafeWindow
// @grant        GM_openInTab
// @grant        GM.openInTab
// @grant        GM_getValue
// @grant        GM.getValue
// @grant        GM_setValue
// @grant        GM.setValue
// @grant        GM_deleteValue
// @grant        GM.deleteValue
// @grant        GM_xmlhttpRequest
// @grant        GM.xmlHttpRequest
// @grant        GM_download
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    const mgmapi = {

        addStyle(s) {
            let style = document.createElement("style");
            style.innerHTML = s;
            document.documentElement.appendChild(style);
        },
        async getValue(name, defaultVal) {
            return await ((typeof GM_getValue === "function") ? GM_getValue : GM.getValue)(name, defaultVal);
        },
        async setValue(name, value) {
            return await ((typeof GM_setValue === "function") ? GM_setValue : GM.setValue)(name, value);
        },
        async deleteValue(name) {
            return await ((typeof GM_deleteValue === "function") ? GM_deleteValue : GM.deleteValue)(name);
        },
        openInTab(url, open_in_background = false) {
            return ((typeof GM_openInTab === "function") ? GM_openInTab : GM.openInTab)(url, open_in_background);
        },
        xmlHttpRequest(details) {
            return ((typeof GM_xmlhttpRequest === "function") ? GM_xmlhttpRequest : GM.xmlHttpRequest)(details);
        },
        download(details) {
            if (typeof GM_download === "function") {
                this.message("下载中,请留意浏览器下载弹窗\nDownloading, pay attention to the browser's download pop-up.", 3000);
                return GM_download(details);
            } else {
                this.openInTab(details.url);
            }
        },
        copyText(text) {
            copyTextToClipboard(text);
            function copyTextToClipboard(text) {
                // 复制文本
                var copyFrom = document.createElement("textarea");
                copyFrom.textContent = text;
                document.body.appendChild(copyFrom);
                copyFrom.select();
                document.execCommand('copy');
                copyFrom.blur();
                document.body.removeChild(copyFrom);
            }
        },
        message(text, disappearTime = 5000) {
            const id = "f8243rd238-gm-message-panel";
            let p = document.querySelector(`#${id}`);
            if (!p) {
                p = document.createElement("div");
                p.id = id;
                p.style = `
                    position: fixed;
                    bottom: 20px;
                    right: 20px;
                    display: flex;
                    flex-direction: column;
                    align-items: end;
                    z-index: 999999999999999;
                `;
                (document.body || document.documentElement).appendChild(p);
            }
            let mdiv = document.createElement("div");
            mdiv.innerText = text;
            mdiv.style = `
                padding: 3px 8px;
                border-radius: 5px;
                background: black;
                box-shadow: #000 1px 2px 5px;
                margin-top: 10px;
                font-size: small;
                color: #fff;
                text-align: right;
            `;
            p.appendChild(mdiv);
            setTimeout(() => {
                p.removeChild(mdiv);
            }, disappearTime);
        }
    };


    if (location.host === "tools.thatwind.com" || location.host === "localhost:3000") {
        mgmapi.addStyle("#userscript-tip{display:none !important;}");

        // 对请求做代理
        const _fetch = unsafeWindow.fetch;
        unsafeWindow.fetch = async function (...args) {
            try {
                let response = await _fetch(...args);
                if (response.status !== 200) throw new Error(response.status);
                return response;
            } catch (e) {
                // 失败请求使用代理
                if (args.length == 1) {
                    console.log(`请求代理:${args[0]}`);
                    return await new Promise((resolve, reject) => {
                        let referer = new URLSearchParams(location.hash.slice(1)).get("referer");
                        let headers = {};
                        if (referer) {
                            referer = new URL(referer);
                            headers = {
                                "origin": referer.origin,
                                "referer": referer.href
                            };
                        }
                        mgmapi.xmlHttpRequest({
                            method: "GET",
                            url: args[0],
                            responseType: 'arraybuffer',
                            headers,
                            onload(r) {
                                resolve({
                                    status: r.status,
                                    headers: new Headers(r.responseHeaders.split("\n").filter(n => n).map(s => s.split(/:\s*/)).reduce((all, [a, b]) => { all[a] = b; return all; }, {})),
                                    async text() {
                                        return r.responseText;
                                    },
                                    async arrayBuffer() {
                                        return r.response;
                                    }
                                });
                            },
                            onerror() {
                                reject(new Error());
                            }
                        });
                    });
                } else {
                    throw e;
                }
            }
        }

        return;
    }


    // iframe 信息交流
    // 目前只用于获取顶部标题
    window.addEventListener("message", async (e) => {
        if (e.data === "3j4t9uj349-gm-get-title") {
            let name = `top-title-${Date.now()}`;
            await mgmapi.setValue(name, document.title);
            e.source.postMessage(`3j4t9uj349-gm-top-title-name:${name}`, "*");
        }
    });

    function getTopTitle() {
        return new Promise(resolve => {
            window.addEventListener("message", async function l(e) {
                if (typeof e.data === "string") {
                    if (e.data.startsWith("3j4t9uj349-gm-top-title-name:")) {
                        let name = e.data.slice("3j4t9uj349-gm-top-title-name:".length);
                        await new Promise(r => setTimeout(r, 5)); // 等5毫秒 确定 setValue 已经写入
                        resolve(await mgmapi.getValue(name));
                        mgmapi.deleteValue(name);
                        window.removeEventListener("message", l);
                    }
                }
            });
            window.top.postMessage("3j4t9uj349-gm-get-title", "*");
        });
    }


    {
        // 请求检测
        // const _fetch = unsafeWindow.fetch;
        // unsafeWindow.fetch = function (...args) {
        //     if (checkUrl(args[0])) doM3U({ url: args[0] });
        //     return _fetch(...args);
        // }

        const _r_text = unsafeWindow.Response.prototype.text;
        unsafeWindow.Response.prototype.text = function () {
            return new Promise((resolve, reject) => {
                _r_text.call(this).then((text) => {
                    resolve(text);
                    if (checkContent(text)) doM3U({ url: this.url, content: text });
                }).catch(reject);
            });
        }

        const _open = unsafeWindow.XMLHttpRequest.prototype.open;
        unsafeWindow.XMLHttpRequest.prototype.open = function (...args) {
            this.addEventListener("load", () => {
                try {
                    let content = this.responseText;
                    if (checkContent(content)) doM3U({ url: args[1], content });
                } catch { }
            });
            // checkUrl(args[1]);
            return _open.apply(this, args);
        }


        function checkUrl(url) {
            url = new URL(url, location.href);
            if (url.pathname.endsWith(".m3u8") || url.pathname.endsWith(".m3u")) {
                // 发现
                return true;
            }
        }

        function checkContent(content) {
            if (content.trim().startsWith("#EXTM3U")) {
                return true;
            }
        }


        // 检查纯视频
        setInterval(doVideos, 1000);

    }

    const rootDiv = document.createElement("div");
    rootDiv.style = `
        position: fixed;
        z-index: 9999999999999999;
        opacity: 0.9;
    `;
    rootDiv.style.display = "none";
    document.documentElement.appendChild(rootDiv);

    const shadowDOM = rootDiv.attachShadow({ mode: 'open' });
    const wrapper = document.createElement("div");
    shadowDOM.appendChild(wrapper);


    // 指示器
    const bar = document.createElement("div");
    bar.style = `
        text-align: right;
    `;
    bar.innerHTML = `
        <span
            class="number-indicator"
            data-number="0"
            style="
                display: inline-flex;
                width: 25px;
                height: 25px;
                background: black;
                padding: 10px;
                border-radius: 100px;
                margin-bottom: 5px;
                cursor: pointer;
            "
        >
            <svg
            style="
                filter: invert(1);
            "
            version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 585.913 585.913" style="enable-background:new 0 0 585.913 585.913;" xml:space="preserve">
                <g>
                    <path d="M11.173,46.2v492.311l346.22,47.402V535.33c0.776,0.058,1.542,0.109,2.329,0.109h177.39
                    c20.75,0,37.627-16.883,37.627-37.627V86.597c0-20.743-16.877-37.628-37.627-37.628h-177.39c-0.781,0-1.553,0.077-2.329,0.124V0
                    L11.173,46.2z M110.382,345.888l-1.37-38.273c-0.416-11.998-0.822-26.514-0.822-41.023l-0.415,0.01
                    c-2.867,12.767-6.678,26.956-10.187,38.567l-10.961,38.211l-15.567-0.582l-9.239-37.598c-2.801-11.269-5.709-24.905-7.725-37.361
                    l-0.25,0.005c-0.503,12.914-0.879,27.657-1.503,39.552L50.84,343.6l-17.385-0.672l5.252-94.208l25.415-0.996l8.499,32.064
                    c2.724,11.224,5.467,23.364,7.428,34.819h0.389c2.503-11.291,5.535-24.221,8.454-35.168l9.643-33.042l27.436-1.071l5.237,101.377
                    L110.382,345.888z M172.479,349.999c-12.569-0.504-23.013-4.272-28.539-8.142l4.504-17.249c3.939,2.226,13.1,6.445,22.373,6.687
                    c12.009,0.32,18.174-5.497,18.174-13.218c0-10.068-9.838-14.683-19.979-14.74l-9.253-0.052v-16.777l8.801-0.066
                    c7.708-0.208,17.646-3.262,17.646-11.905c0-6.121-4.914-10.562-14.635-10.331c-7.95,0.189-16.245,3.914-20.213,6.446l-4.52-16.693
                    c5.693-4.008,17.224-8.11,29.883-8.588c21.457-0.795,33.643,10.407,33.643,24.625c0,11.029-6.197,19.691-18.738,24.161v0.314
                    c12.229,2.216,22.266,11.663,22.266,25.281C213.89,338.188,197.866,351.001,172.479,349.999z M331.104,302.986
                    c0,36.126-19.55,52.541-51.193,51.286c-29.318-1.166-46.019-17.103-46.019-52.044v-61.104l25.711-1.006v64.201
                    c0,19.191,7.562,29.146,21.179,29.502c14.234,0.368,22.189-8.976,22.189-29.26v-66.125l28.122-1.097v65.647H331.104z
                    M359.723,70.476h177.39c8.893,0,16.125,7.236,16.125,16.126v411.22c0,8.888-7.232,16.127-16.125,16.127h-177.39
                    c-0.792,0-1.563-0.116-2.329-0.232V380.782c17.685,14.961,40.504,24.032,65.434,24.032c56.037,0,101.607-45.576,101.607-101.599
                    c0-56.029-45.581-101.603-101.607-101.603c-24.93,0-47.749,9.069-65.434,24.035V70.728
                    C358.159,70.599,358.926,70.476,359.723,70.476z M390.873,364.519V245.241c0-1.07,0.615-2.071,1.586-2.521
                    c0.981-0.483,2.13-0.365,2.981,0.307l93.393,59.623c0.666,0.556,1.065,1.376,1.065,2.215c0,0.841-0.399,1.67-1.065,2.215
                    l-93.397,59.628c-0.509,0.4-1.114,0.61-1.743,0.61l-1.233-0.289C391.488,366.588,390.873,365.585,390.873,364.519z" />
                </g>
            </svg>
        </span>
    `;

    wrapper.appendChild(bar);

    // 样式
    const style = document.createElement("style");

    style.innerHTML = `
        .number-indicator{
            position:relative;
        }

        .number-indicator::after{
            content: attr(data-number);
            position: absolute;
            bottom: 0;
            right: 0;
            color: #40a9ff;
            font-size: 14px;
            font-weight: bold;
            background: #000;
            border-radius: 10px;
            padding: 3px 5px;
        }

        .copy-link:active{
            color: #ccc;
        }

        .download-btn:hover{
            text-decoration: underline;
        }
        .download-btn:active{
            opacity: 0.9;
        }

        .m3u8-item{
            color: white;
            margin-bottom: 5px;
            display: flex;
            flex-direction: row;
            background: black;
            padding: 3px 10px;
            border-radius: 3px;
            font-size: 14px;
            user-select: none;
        }

        [data-shown="false"] {
            opacity: 0.8;
            zoom: 0.8;
        }

        [data-shown="false"]:hover{
            opacity: 1;
        }

        [data-shown="false"] .m3u8-item{
            display: none;
        }

    `;

    wrapper.appendChild(style);




    const barBtn = bar.querySelector(".number-indicator");

    // 关于显隐和移动

    (async function () {

        let shown = await GM_getValue("shown", true);
        wrapper.setAttribute("data-shown", shown);


        let x = await GM_getValue("x", 10);
        let y = await GM_getValue("y", 10);

        x = Math.min(innerWidth - 50, x);
        y = Math.min(innerHeight - 50, y);

        if (x < 0) x = 0;
        if (y < 0) y = 0;

        rootDiv.style.top = `${y}px`;
        rootDiv.style.right = `${x}px`;

        barBtn.addEventListener("mousedown", e => {
            let startX = e.pageX;
            let startY = e.pageY;

            let moved = false;

            let mousemove = e => {
                let offsetX = e.pageX - startX;
                let offsetY = e.pageY - startY;
                if (moved || (Math.abs(offsetX) + Math.abs(offsetY)) > 5) {
                    moved = true;
                    rootDiv.style.top = `${y + offsetY}px`;
                    rootDiv.style.right = `${x - offsetX}px`;
                }
            };
            let mouseup = e => {

                let offsetX = e.pageX - startX;
                let offsetY = e.pageY - startY;

                if (moved) {
                    x -= offsetX;
                    y += offsetY;
                    mgmapi.setValue("x", x);
                    mgmapi.setValue("y", y);
                } else {
                    shown = !shown;
                    mgmapi.setValue("shown", shown);
                    wrapper.setAttribute("data-shown", shown);
                }

                removeEventListener("mousemove", mousemove);
                removeEventListener("mouseup", mouseup);
            }
            addEventListener("mousemove", mousemove);
            addEventListener("mouseup", mouseup);
        });
    })();






    let count = 0;
    let shownUrls = [];


    function doVideos() {
        for (let v of Array.from(document.querySelectorAll("video"))) {
            if (v.duration && v.src && v.src.startsWith("http") && (!shownUrls.includes(v.src))) {
                const src = v.src;

                shownUrls.push(src);
                showVideo({
                    type: "video",
                    url: new URL(src),
                    duration: `${Math.ceil(v.duration * 10 / 60) / 10} mins`,
                    download() {
                        const details = {
                            url: src,
                            name: (() => {
                                let name = new URL(src).pathname.split("/").slice(-1)[0];
                                if (!/\.\w+$/.test(name)) {
                                    if (name.match(/^\s*$/)) name = Date.now();
                                    name = name + ".mp4";
                                }
                                return name;
                            })(),
                            headers: {
                                // referer: location.origin, // 不允许该头
                                origin: location.origin
                            },
                            onerror(e) {
                                mgmapi.openInTab(src);
                            }
                        };
                        mgmapi.download(details);
                    }
                })
            }
        }
    }

    async function doM3U({ url, content }) {

        url = new URL(url);

        if (shownUrls.includes(url.href)) return;

        // 解析 m3u
        content = content || await (await fetch(url)).text();

        const parser = new m3u8Parser.Parser();
        parser.push(content);
        parser.end();
        const manifest = parser.manifest;

        if (manifest.segments) {
            let duration = 0;
            manifest.segments.forEach((segment) => {
                duration += segment.duration;
            });
            manifest.duration = duration;
        }

        showVideo({
            type: "m3u8",
            url,
            duration: manifest.duration ? `${Math.ceil(manifest.duration * 10 / 60) / 10} mins` : manifest.playlists ? `多(Multi)(${manifest.playlists.length})` : "未知(unknown)",
            async download() {
                mgmapi.openInTab(
                    `https://tools.thatwind.com/tool/m3u8downloader#${new URLSearchParams({
                        m3u8: url.href,
                        referer: location.href,
                        filename: (await getTopTitle()) || ""
                    })}`
                );
            }
        })

    }



    async function showVideo({
        type,
        url,
        duration,
        download
    }) {
        let div = document.createElement("div");
        div.className = "m3u8-item";
        div.innerHTML = `
            <span>${type}</span>
            <span
                class="copy-link"
                title="${url}"
                style="
                    max-width: 200px;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                    overflow: hidden;
                    margin-left: 10px;
                "
            >${url.pathname}</span>
            <span 
                style="
                    margin-left: 10px;
                    flex-grow: 1;
                "
            >${duration}</span>
            <span
                class="download-btn"
                style="
                    margin-left: 10px;
                    cursor: pointer;
            ">下载(Download)</span>
        `;
        div.innerHTML += '<a target="_blank" href="' + url.href + '"> MPV</a>';
        div.querySelector(".copy-link").addEventListener("click", () => {
            // 复制链接
            mgmapi.copyText(url.href);
            mgmapi.message("已复制链接 (link copied)", 2000);
        });

        div.querySelector(".download-btn").addEventListener("click", download);

        rootDiv.style.display = "block";

        count++;

        shownUrls.push(url.href);

        bar.querySelector(".number-indicator").setAttribute("data-number", count);

        wrapper.appendChild(div);
    }

})();
 
e thấy nó cho tải về máy xem thôi, chứ chưa thấy cho e xem online á

Ngoài ra phải thêm --title=NoTitle vào MPV trong External Application vì cái URL của Facebook video nó dài quá gây treo MPV (nhược điểm là nếu dùng --title=NoTitle thì sau này khi xem video sẽ không có tên video mà sẽ bị chèn tên thành NoTitle), lỗi này nếu report lên Github của MPV fix toàn thể thì tốt, bạn nên tạo một nút mới tên là MPV NOYTDL để dùng cho trường hợp này:


MPV NOYTDL
--no-ytdl --title=NoTitle [HREF]

Video thành công nhé: https://gfycat.com/BronzeIgnorantDragon
 
Ngoài ra phải thêm --title=NoTitle vào MPV trong External Application vì cái URL của Facebook video nó dài quá gây treo MPV (nhược điểm là nếu dùng --title=NoTitle thì sau này khi xem video sẽ không có tên video mà sẽ bị chèn tên thành NoTitle), lỗi này nếu report lên Github của MPV fix toàn thể thì tốt, bạn nên tạo một nút mới tên là MPV NOYTDL để dùng cho trường hợp này:


MPV NOYTDL
--no-ytdl --title=NoTitle [HREF]

Video thành công nhé: https://gfycat.com/BronzeIgnorantDragon
ngon quá
cám ơn nha :big_smile:
1676950947159.png
 

Chắc phải lên Github tụi MPV báo lỗi này thôi chứ bất tiện lắm, lẽ ra không cần thêm --title=NoTitle nhưng mà lại phải thêm mới buồn, bọn MPV này phần mềm chất lượng ngon nhưng dính lỗi ngu vê ka lờ :beat_brick:

Nếu có thể bạn hay bất kỳ bạn nào rành dùng Github và trình báo lỗi Github có thể vào đây báo lỗi cho họ nhé, mình không giỏi báo lỗi cho lắm nên mở toàn bị lờ đi: https://github.com/mpv-player/mpv/issues

Lệnh ví dụ:
Code:
mpv --title=NoTitle --no-ytdl "https://scontent-sin6-2.xx.fbcdn.net/v/t39.25447-2/10000000_150747141158559_2304511369673619337_n.mp4?_nc_cat=108&vs=b4d50b4455f0e7b7&_nc_vs=HBksFQAYJEdJQ1dtQUNmdHN5Tkdva0FBSW0zUG9MaFJQc2ZibWRqQUFBRhUAAsgBABUAGCRHSUNXbUFBYTloV1h5UmtEQU1xcWNIU01FdDhhYnJGcUFBQUYVAgLIAQBLB4gScHJvZ3Jlc3NpdmVfcmVjaXBlATENc3Vic2FtcGxlX2ZwcwAQdm1hZl9lbmFibGVfbnN1YgAgbWVhc3VyZV9vcmlnaW5hbF9yZXNvbHV0aW9uX3NzaW0AKGNvbXB1dGVfc3NpbV9vbmx5X2F0X29yaWdpbmFsX3Jlc29sdXRpb24AHXVzZV9sYW5jem9zX2Zvcl92cW1fdXBzY2FsaW5nABFkaXNhYmxlX3Bvc3RfcHZxcwAVACUAHAAAJsjdreOe84MUFZBOKAJDMxgLdnRzX3ByZXZpZXccF0CWL6wIMSbpGDRkYXNoX2k0bGl0ZWJhc2ljX3Bhc3N0aHJvdWdoYWxpZ25lZF9ocTJfZnJhZ18yX3ZpZGVvEgAYGHZpZGVvcy52dHMuY2FsbGJhY2sucHJvZDgSVklERU9fVklFV19SRVFVRVNUGw6IFW9lbV90YXJnZXRfZW5jb2RlX3RhZwZvZXBfaGQTb2VtX3JlcXVlc3RfdGltZV9tcwEwDG9lbV9jZmdfcnVsZQd1bm11dGVkE29lbV9yb2lfcmVhY2hfY291bnQBMBFvZW1faXNfZXhwZXJpbWVudAARb2VtX3JvaV91c2VyX3RpZXIDdWdjHm9lbV9yb2lfcHJlZGljdGVkX3dhdGNoX3RpbWVfcwEwFm9lbV9yb2lfcmVjaXBlX2JlbmVmaXQFMC4wMDAlb2VtX3JvaV9zdGF0aWNfYmVuZWZpdF9jb3N0X2V2YWx1YXRvcgtwcm9ncmVzc2l2ZQxvZW1fdmlkZW9faWQQMTgyNDc5NzA4MTIzOTMzOBJvZW1fdmlkZW9fYXNzZXRfaWQQNTQxNzg0MTQwODMyMDM3MhVvZW1fdmlkZW9fcmVzb3VyY2VfaWQQNTYzODA3NjQxOTY1MTQyOBxvZW1fc291cmNlX3ZpZGVvX2VuY29kaW5nX2lkDzkxODUxMzQ4OTMyOTI2MA52dHNfcmVxdWVzdF9pZA8yZWU5N2Q0ZTBlYjU0MmUlAhwcHBXw5hcbAVUAAhsBVQACHBUCAAAAFoC6twMAJY4CGwiIAXMENTE4OAJjZAoyMDIzLTAyLTAyA3JjYgEwA2FwcAZ1cGxvYWQCY3QZQ09OVEFJTkVEX1BPU1RfQVRUQUNITUVOVBNvcmlnaW5hbF9kdXJhdGlvbl9zCDE0MjAuMDc1AWYCYWQCdHMVcHJvZ3Jlc3NpdmVfZW5jb2RpbmdzAA%3D%3D&ccb=1-7&_nc_sid=41a7d5&_nc_ohc=L_dzb8dbQwcAX8wwXSo&_nc_ht=scontent-sin6-2.xx&edm=APRAPSkEAAAA&oh=00_AfCY25yJxLCTq0lZ1bttybDBFV_-7qbGg7ZZoE3s_1nEig&oe=63F82C10&_nc_rid=897881643295126" -v

@boscofz: Lỗi này có vẻ khó chịu trong quá trình sử dụng ? Bạn có tạo cái issue trên Github của họ báo lỗi được chứ ?
Thật ra mình có ý tưởng sửa lỗi này mà không cần phía dev hỗ trợ, đó là tạo một plugin kiểm tra độ dài tên tiêu đề của MPV, nếu dài quá thì chuyển qua NoTitle là ngon thôi, để tí viết thử :D
 
Mình có sửa lại code của thím @toi la gay :sosad: 1 tí để cho giao diện nó đồng bộ với thằng script nên ai thích thì có thể lấy dùng nha

Code:
// ==UserScript==
// @name         m3u8视频侦测下载器【自动嗅探】 1
// @name:zh-CN   m3u8视频侦测下载器【自动嗅探】 1
// @name:zh-TW   m3u8視頻偵測下載器【自動嗅探】 1
// @name:en      M3U8 Video Detector and Downloader 1
// @version      1.3.2
// @description  自动检测页面m3u8视频并进行完整下载。检测到m3u8链接后会自动出现在页面右上角位置,点击下载即可跳转到m3u8下载器。
// @description:zh-CN  自动检测页面m3u8视频并进行完整下载。检测到m3u8链接后会自动出现在页面右上角位置,点击下载即可跳转到m3u8下载器。
// @description:zh-TW  自動檢測頁面m3u8視頻並進行完整下載。檢測到m3u8鏈接後會自動出現在頁面右上角位置,點擊下載即可跳轉到m3u8下載器。
// @description:en  Automatically detect the m3u8 video of the page and download it completely. Once detected the m3u8 link, it will appear in the upper right corner of the page. Click download to jump to the m3u8 downloader.
// @icon         https://tools.thatwind.com/favicon.png
// @author       allFull
// @namespace    https://tools.thatwind.com/
// @homepage     https://tools.thatwind.com/tool/m3u8downloader
// @match        *://*/*
// @require      https://cdn.jsdelivr.net/npm/[email protected]/dist/m3u8-parser.min.js
// @connect      *
// @grant        unsafeWindow
// @grant        GM_openInTab
// @grant        GM.openInTab
// @grant        GM_getValue
// @grant        GM.getValue
// @grant        GM_setValue
// @grant        GM.setValue
// @grant        GM_deleteValue
// @grant        GM.deleteValue
// @grant        GM_xmlhttpRequest
// @grant        GM.xmlHttpRequest
// @grant        GM_download
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    const mgmapi = {

        addStyle(s) {
            let style = document.createElement("style");
            style.innerHTML = s;
            document.documentElement.appendChild(style);
        },
        async getValue(name, defaultVal) {
            return await ((typeof GM_getValue === "function") ? GM_getValue : GM.getValue)(name, defaultVal);
        },
        async setValue(name, value) {
            return await ((typeof GM_setValue === "function") ? GM_setValue : GM.setValue)(name, value);
        },
        async deleteValue(name) {
            return await ((typeof GM_deleteValue === "function") ? GM_deleteValue : GM.deleteValue)(name);
        },
        openInTab(url, open_in_background = false) {
            return ((typeof GM_openInTab === "function") ? GM_openInTab : GM.openInTab)(url, open_in_background);
        },
        xmlHttpRequest(details) {
            return ((typeof GM_xmlhttpRequest === "function") ? GM_xmlhttpRequest : GM.xmlHttpRequest)(details);
        },
        download(details) {
            if (typeof GM_download === "function") {
                this.message("下载中,请留意浏览器下载弹窗\nDownloading, pay attention to the browser's download pop-up.", 3000);
                return GM_download(details);
            } else {
                this.openInTab(details.url);
            }
        },
        copyText(text) {
            copyTextToClipboard(text);
            function copyTextToClipboard(text) {
                // 复制文本
                var copyFrom = document.createElement("textarea");
                copyFrom.textContent = text;
                document.body.appendChild(copyFrom);
                copyFrom.select();
                document.execCommand('copy');
                copyFrom.blur();
                document.body.removeChild(copyFrom);
            }
        },
        message(text, disappearTime = 5000) {
            const id = "f8243rd238-gm-message-panel";
            let p = document.querySelector(`#${id}`);
            if (!p) {
                p = document.createElement("div");
                p.id = id;
                p.style = `
                    position: fixed;
                    bottom: 20px;
                    right: 20px;
                    display: flex;
                    flex-direction: column;
                    align-items: end;
                    z-index: 999999999999999;
                `;
                (document.body || document.documentElement).appendChild(p);
            }
            let mdiv = document.createElement("div");
            mdiv.innerText = text;
            mdiv.style = `
                padding: 3px 8px;
                border-radius: 5px;
                background: black;
                box-shadow: #000 1px 2px 5px;
                margin-top: 10px;
                font-size: small;
                color: #fff;
                text-align: right;
            `;
            p.appendChild(mdiv);
            setTimeout(() => {
                p.removeChild(mdiv);
            }, disappearTime);
        }
    };


    if (location.host === "tools.thatwind.com" || location.host === "localhost:3000") {
        mgmapi.addStyle("#userscript-tip{display:none !important;}");

        // 对请求做代理
        const _fetch = unsafeWindow.fetch;
        unsafeWindow.fetch = async function (...args) {
            try {
                let response = await _fetch(...args);
                if (response.status !== 200) throw new Error(response.status);
                return response;
            } catch (e) {
                // 失败请求使用代理
                if (args.length == 1) {
                    console.log(`请求代理:${args[0]}`);
                    return await new Promise((resolve, reject) => {
                        let referer = new URLSearchParams(location.hash.slice(1)).get("referer");
                        let headers = {};
                        if (referer) {
                            referer = new URL(referer);
                            headers = {
                                "origin": referer.origin,
                                "referer": referer.href
                            };
                        }
                        mgmapi.xmlHttpRequest({
                            method: "GET",
                            url: args[0],
                            responseType: 'arraybuffer',
                            headers,
                            onload(r) {
                                resolve({
                                    status: r.status,
                                    headers: new Headers(r.responseHeaders.split("\n").filter(n => n).map(s => s.split(/:\s*/)).reduce((all, [a, b]) => { all[a] = b; return all; }, {})),
                                    async text() {
                                        return r.responseText;
                                    },
                                    async arrayBuffer() {
                                        return r.response;
                                    }
                                });
                            },
                            onerror() {
                                reject(new Error());
                            }
                        });
                    });
                } else {
                    throw e;
                }
            }
        }

        return;
    }


    // iframe 信息交流
    // 目前只用于获取顶部标题
    window.addEventListener("message", async (e) => {
        if (e.data === "3j4t9uj349-gm-get-title") {
            let name = `top-title-${Date.now()}`;
            await mgmapi.setValue(name, document.title);
            e.source.postMessage(`3j4t9uj349-gm-top-title-name:${name}`, "*");
        }
    });

    function getTopTitle() {
        return new Promise(resolve => {
            window.addEventListener("message", async function l(e) {
                if (typeof e.data === "string") {
                    if (e.data.startsWith("3j4t9uj349-gm-top-title-name:")) {
                        let name = e.data.slice("3j4t9uj349-gm-top-title-name:".length);
                        await new Promise(r => setTimeout(r, 5)); // 等5毫秒 确定 setValue 已经写入
                        resolve(await mgmapi.getValue(name));
                        mgmapi.deleteValue(name);
                        window.removeEventListener("message", l);
                    }
                }
            });
            window.top.postMessage("3j4t9uj349-gm-get-title", "*");
        });
    }


    {
        // 请求检测
        // const _fetch = unsafeWindow.fetch;
        // unsafeWindow.fetch = function (...args) {
        //     if (checkUrl(args[0])) doM3U({ url: args[0] });
        //     return _fetch(...args);
        // }

        const _r_text = unsafeWindow.Response.prototype.text;
        unsafeWindow.Response.prototype.text = function () {
            return new Promise((resolve, reject) => {
                _r_text.call(this).then((text) => {
                    resolve(text);
                    if (checkContent(text)) doM3U({ url: this.url, content: text });
                }).catch(reject);
            });
        }

        const _open = unsafeWindow.XMLHttpRequest.prototype.open;
        unsafeWindow.XMLHttpRequest.prototype.open = function (...args) {
            this.addEventListener("load", () => {
                try {
                    let content = this.responseText;
                    if (checkContent(content)) doM3U({ url: args[1], content });
                } catch { }
            });
            // checkUrl(args[1]);
            return _open.apply(this, args);
        }


        function checkUrl(url) {
            url = new URL(url, location.href);
            if (url.pathname.endsWith(".m3u8") || url.pathname.endsWith(".m3u")) {
                // 发现
                return true;
            }
        }

        function checkContent(content) {
            if (content.trim().startsWith("#EXTM3U")) {
                return true;
            }
        }


        // 检查纯视频
        setInterval(doVideos, 1000);

    }

    const rootDiv = document.createElement("div");
    rootDiv.style = `
        position: fixed;
        z-index: 9999999999999999;
        opacity: 0.9;
    `;
    rootDiv.style.display = "none";
    document.documentElement.appendChild(rootDiv);

    const shadowDOM = rootDiv.attachShadow({ mode: 'open' });
    const wrapper = document.createElement("div");
    shadowDOM.appendChild(wrapper);


    // 指示器
    const bar = document.createElement("div");
    bar.style = `
        text-align: right;
    `;
    bar.innerHTML = `
        <span
            class="number-indicator"
            data-number="0"
            style="
                display: inline-flex;
                width: 25px;
                height: 25px;
                background: black;
                padding: 10px;
                border-radius: 100px;
                margin-bottom: 5px;
                cursor: pointer;
            "
        >
            <svg
            style="
                filter: invert(1);
            "
            version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 585.913 585.913" style="enable-background:new 0 0 585.913 585.913;" xml:space="preserve">
                <g>
                    <path d="M11.173,46.2v492.311l346.22,47.402V535.33c0.776,0.058,1.542,0.109,2.329,0.109h177.39
                    c20.75,0,37.627-16.883,37.627-37.627V86.597c0-20.743-16.877-37.628-37.627-37.628h-177.39c-0.781,0-1.553,0.077-2.329,0.124V0
                    L11.173,46.2z M110.382,345.888l-1.37-38.273c-0.416-11.998-0.822-26.514-0.822-41.023l-0.415,0.01
                    c-2.867,12.767-6.678,26.956-10.187,38.567l-10.961,38.211l-15.567-0.582l-9.239-37.598c-2.801-11.269-5.709-24.905-7.725-37.361
                    l-0.25,0.005c-0.503,12.914-0.879,27.657-1.503,39.552L50.84,343.6l-17.385-0.672l5.252-94.208l25.415-0.996l8.499,32.064
                    c2.724,11.224,5.467,23.364,7.428,34.819h0.389c2.503-11.291,5.535-24.221,8.454-35.168l9.643-33.042l27.436-1.071l5.237,101.377
                    L110.382,345.888z M172.479,349.999c-12.569-0.504-23.013-4.272-28.539-8.142l4.504-17.249c3.939,2.226,13.1,6.445,22.373,6.687
                    c12.009,0.32,18.174-5.497,18.174-13.218c0-10.068-9.838-14.683-19.979-14.74l-9.253-0.052v-16.777l8.801-0.066
                    c7.708-0.208,17.646-3.262,17.646-11.905c0-6.121-4.914-10.562-14.635-10.331c-7.95,0.189-16.245,3.914-20.213,6.446l-4.52-16.693
                    c5.693-4.008,17.224-8.11,29.883-8.588c21.457-0.795,33.643,10.407,33.643,24.625c0,11.029-6.197,19.691-18.738,24.161v0.314
                    c12.229,2.216,22.266,11.663,22.266,25.281C213.89,338.188,197.866,351.001,172.479,349.999z M331.104,302.986
                    c0,36.126-19.55,52.541-51.193,51.286c-29.318-1.166-46.019-17.103-46.019-52.044v-61.104l25.711-1.006v64.201
                    c0,19.191,7.562,29.146,21.179,29.502c14.234,0.368,22.189-8.976,22.189-29.26v-66.125l28.122-1.097v65.647H331.104z
                    M359.723,70.476h177.39c8.893,0,16.125,7.236,16.125,16.126v411.22c0,8.888-7.232,16.127-16.125,16.127h-177.39
                    c-0.792,0-1.563-0.116-2.329-0.232V380.782c17.685,14.961,40.504,24.032,65.434,24.032c56.037,0,101.607-45.576,101.607-101.599
                    c0-56.029-45.581-101.603-101.607-101.603c-24.93,0-47.749,9.069-65.434,24.035V70.728
                    C358.159,70.599,358.926,70.476,359.723,70.476z M390.873,364.519V245.241c0-1.07,0.615-2.071,1.586-2.521
                    c0.981-0.483,2.13-0.365,2.981,0.307l93.393,59.623c0.666,0.556,1.065,1.376,1.065,2.215c0,0.841-0.399,1.67-1.065,2.215
                    l-93.397,59.628c-0.509,0.4-1.114,0.61-1.743,0.61l-1.233-0.289C391.488,366.588,390.873,365.585,390.873,364.519z" />
                </g>
            </svg>
        </span>
    `;

    wrapper.appendChild(bar);

    // 样式
    const style = document.createElement("style");

    style.innerHTML = `
        .number-indicator{
            position:relative;
        }

        .number-indicator::after{
            content: attr(data-number);
            position: absolute;
            bottom: 0;
            right: 0;
            color: #40a9ff;
            font-size: 14px;
            font-weight: bold;
            background: #000;
            border-radius: 10px;
            padding: 3px 5px;
        }

        .copy-link:active{
            color: #ccc;
        }

        .download-btn:hover{
            text-decoration: underline;
        }
        .download-btn:active{
            opacity: 0.9;
        }

        .mpv:link{
            text-decoration: none;
        }

        .mpv:hover{
            text-decoration: underline;
        }

        .m3u8-item{
            color: white;
            margin-bottom: 5px;
            display: flex;
            flex-direction: row;
            background: black;
            padding: 3px 10px;
            border-radius: 3px;
            font-size: 14px;
            user-select: none;
        }

        [data-shown="false"] {
            opacity: 0.8;
            zoom: 0.8;
        }

        [data-shown="false"]:hover{
            opacity: 1;
        }

        [data-shown="false"] .m3u8-item{
            display: none;
        }

    `;

    wrapper.appendChild(style);




    const barBtn = bar.querySelector(".number-indicator");

    // 关于显隐和移动

    (async function () {

        let shown = await GM_getValue("shown", true);
        wrapper.setAttribute("data-shown", shown);


        let x = await GM_getValue("x", 10);
        let y = await GM_getValue("y", 10);

        x = Math.min(innerWidth - 50, x);
        y = Math.min(innerHeight - 50, y);

        if (x < 0) x = 0;
        if (y < 0) y = 0;

        rootDiv.style.top = `${y}px`;
        rootDiv.style.right = `${x}px`;

        barBtn.addEventListener("mousedown", e => {
            let startX = e.pageX;
            let startY = e.pageY;

            let moved = false;

            let mousemove = e => {
                let offsetX = e.pageX - startX;
                let offsetY = e.pageY - startY;
                if (moved || (Math.abs(offsetX) + Math.abs(offsetY)) > 5) {
                    moved = true;
                    rootDiv.style.top = `${y + offsetY}px`;
                    rootDiv.style.right = `${x - offsetX}px`;
                }
            };
            let mouseup = e => {

                let offsetX = e.pageX - startX;
                let offsetY = e.pageY - startY;

                if (moved) {
                    x -= offsetX;
                    y += offsetY;
                    mgmapi.setValue("x", x);
                    mgmapi.setValue("y", y);
                } else {
                    shown = !shown;
                    mgmapi.setValue("shown", shown);
                    wrapper.setAttribute("data-shown", shown);
                }

                removeEventListener("mousemove", mousemove);
                removeEventListener("mouseup", mouseup);
            }
            addEventListener("mousemove", mousemove);
            addEventListener("mouseup", mouseup);
        });
    })();






    let count = 0;
    let shownUrls = [];


    function doVideos() {
        for (let v of Array.from(document.querySelectorAll("video"))) {
            if (v.duration && v.src && v.src.startsWith("http") && (!shownUrls.includes(v.src))) {
                const src = v.src;

                shownUrls.push(src);
                showVideo({
                    type: "video",
                    url: new URL(src),
                    duration: `${Math.ceil(v.duration * 10 / 60) / 10} mins`,
                    download() {
                        const details = {
                            url: src,
                            name: (() => {
                                let name = new URL(src).pathname.split("/").slice(-1)[0];
                                if (!/\.\w+$/.test(name)) {
                                    if (name.match(/^\s*$/)) name = Date.now();
                                    name = name + ".mp4";
                                }
                                return name;
                            })(),
                            headers: {
                                // referer: location.origin, // 不允许该头
                                origin: location.origin
                            },
                            onerror(e) {
                                mgmapi.openInTab(src);
                            }
                        };
                        mgmapi.download(details);
                    }
                })
            }
        }
    }

    async function doM3U({ url, content }) {

        url = new URL(url);

        if (shownUrls.includes(url.href)) return;

        // 解析 m3u
        content = content || await (await fetch(url)).text();

        const parser = new m3u8Parser.Parser();
        parser.push(content);
        parser.end();
        const manifest = parser.manifest;

        if (manifest.segments) {
            let duration = 0;
            manifest.segments.forEach((segment) => {
                duration += segment.duration;
            });
            manifest.duration = duration;
        }

        showVideo({
            type: "m3u8",
            url,
            duration: manifest.duration ? `${Math.ceil(manifest.duration * 10 / 60) / 10} mins` : manifest.playlists ? `多(Multi)(${manifest.playlists.length})` : "未知(unknown)",
            async download() {
                mgmapi.openInTab(
                    `https://tools.thatwind.com/tool/m3u8downloader#${new URLSearchParams({
                        m3u8: url.href,
                        referer: location.href,
                        filename: (await getTopTitle()) || ""
                    })}`
                );
            }
        })

    }



    async function showVideo({
        type,
        url,
        duration,
        download
    }) {
        let div = document.createElement("div");
        div.className = "m3u8-item";
        div.innerHTML = `
            <span>${type}</span>
            <span
                class="copy-link"
                title="${url}"
                style="
                    max-width: 200px;
                    text-overflow: ellipsis;
                    white-space: nowrap;
                    overflow: hidden;
                    margin-left: 10px;
                "
            >${url.pathname}</span>
            <span
                style="
                    margin-left: 10px;
                    flex-grow: 1;
                "
            >${duration}</span>
            <span
                class="download-btn"
                style="
                    margin-left: 10px;
                    cursor: pointer;
            ">Download</span>
        `;
        div.innerHTML += '<a  class="mpv" target="_blank" href="' + url.href + '" style=" color: white; margin-left: 10px; cursor:pointer; "> MPV</a>';

        div.querySelector(".copy-link").addEventListener("click", () => {
            // 复制链接
            mgmapi.copyText(url.href);
            mgmapi.message("已复制链接 (link copied)", 2000);
        });

        div.querySelector(".download-btn").addEventListener("click", download);

        rootDiv.style.display = "block";

        count++;

        shownUrls.push(url.href);

        bar.querySelector(".number-indicator").setAttribute("data-number", count);

        wrapper.appendChild(div);
    }

})();
chrome_Bwgtd2osJi.png



Cứ post issue rồi lấy ví dụ như thím đưa hả ta @toi la gay :sosad: Vậy có gì để e post thử xem
 
Mình có sửa lại code của thím @toi la gay :sosad: 1 tí để cho giao diện nó đồng bộ với thằng script nên ai thích thì có thể lấy dùng nha

chrome_Bwgtd2osJi.png


Cứ post issue rồi lấy ví dụ như thím đưa hả ta @toi la gay :sosad: Vậy có gì để e post thử xem

Ngon rồi, để mình dùng luôn, mình toàn code kiểu nông dân ra sản phẩm nên cũng không chú ý tới giao diện :love:

Còn issue Gituhb thì theo mình nghĩ cứ gửi họ hai cái lệnh:

Cái này sẽ gây đơ MPV (do không có --title=NoTitle):
Code:
mpv --no-ytdl "https://scontent-sin6-2.xx.fbcdn.net/v/t39.25447-2/10000000_150747141158559_2304511369673619337_n.mp4?_nc_cat=108&vs=b4d50b4455f0e7b7&_nc_vs=HBksFQAYJEdJQ1dtQUNmdHN5Tkdva0FBSW0zUG9MaFJQc2ZibWRqQUFBRhUAAsgBABUAGCRHSUNXbUFBYTloV1h5UmtEQU1xcWNIU01FdDhhYnJGcUFBQUYVAgLIAQBLB4gScHJvZ3Jlc3NpdmVfcmVjaXBlATENc3Vic2FtcGxlX2ZwcwAQdm1hZl9lbmFibGVfbnN1YgAgbWVhc3VyZV9vcmlnaW5hbF9yZXNvbHV0aW9uX3NzaW0AKGNvbXB1dGVfc3NpbV9vbmx5X2F0X29yaWdpbmFsX3Jlc29sdXRpb24AHXVzZV9sYW5jem9zX2Zvcl92cW1fdXBzY2FsaW5nABFkaXNhYmxlX3Bvc3RfcHZxcwAVACUAHAAAJsjdreOe84MUFZBOKAJDMxgLdnRzX3ByZXZpZXccF0CWL6wIMSbpGDRkYXNoX2k0bGl0ZWJhc2ljX3Bhc3N0aHJvdWdoYWxpZ25lZF9ocTJfZnJhZ18yX3ZpZGVvEgAYGHZpZGVvcy52dHMuY2FsbGJhY2sucHJvZDgSVklERU9fVklFV19SRVFVRVNUGw6IFW9lbV90YXJnZXRfZW5jb2RlX3RhZwZvZXBfaGQTb2VtX3JlcXVlc3RfdGltZV9tcwEwDG9lbV9jZmdfcnVsZQd1bm11dGVkE29lbV9yb2lfcmVhY2hfY291bnQBMBFvZW1faXNfZXhwZXJpbWVudAARb2VtX3JvaV91c2VyX3RpZXIDdWdjHm9lbV9yb2lfcHJlZGljdGVkX3dhdGNoX3RpbWVfcwEwFm9lbV9yb2lfcmVjaXBlX2JlbmVmaXQFMC4wMDAlb2VtX3JvaV9zdGF0aWNfYmVuZWZpdF9jb3N0X2V2YWx1YXRvcgtwcm9ncmVzc2l2ZQxvZW1fdmlkZW9faWQQMTgyNDc5NzA4MTIzOTMzOBJvZW1fdmlkZW9fYXNzZXRfaWQQNTQxNzg0MTQwODMyMDM3MhVvZW1fdmlkZW9fcmVzb3VyY2VfaWQQNTYzODA3NjQxOTY1MTQyOBxvZW1fc291cmNlX3ZpZGVvX2VuY29kaW5nX2lkDzkxODUxMzQ4OTMyOTI2MA52dHNfcmVxdWVzdF9pZA8yZWU5N2Q0ZTBlYjU0MmUlAhwcHBXw5hcbAVUAAhsBVQACHBUCAAAAFoC6twMAJY4CGwiIAXMENTE4OAJjZAoyMDIzLTAyLTAyA3JjYgEwA2FwcAZ1cGxvYWQCY3QZQ09OVEFJTkVEX1BPU1RfQVRUQUNITUVOVBNvcmlnaW5hbF9kdXJhdGlvbl9zCDE0MjAuMDc1AWYCYWQCdHMVcHJvZ3Jlc3NpdmVfZW5jb2RpbmdzAA%3D%3D&ccb=1-7&_nc_sid=41a7d5&_nc_ohc=L_dzb8dbQwcAX8wwXSo&_nc_ht=scontent-sin6-2.xx&edm=APRAPSkEAAAA&oh=00_AfCY25yJxLCTq0lZ1bttybDBFV_-7qbGg7ZZoE3s_1nEig&oe=63F82C10&_nc_rid=897881643295126" -v

Cái này ok:
Code:
mpv --title=NoTitle --no-ytdl "https://scontent-sin6-2.xx.fbcdn.net/v/t39.25447-2/10000000_150747141158559_2304511369673619337_n.mp4?_nc_cat=108&vs=b4d50b4455f0e7b7&_nc_vs=HBksFQAYJEdJQ1dtQUNmdHN5Tkdva0FBSW0zUG9MaFJQc2ZibWRqQUFBRhUAAsgBABUAGCRHSUNXbUFBYTloV1h5UmtEQU1xcWNIU01FdDhhYnJGcUFBQUYVAgLIAQBLB4gScHJvZ3Jlc3NpdmVfcmVjaXBlATENc3Vic2FtcGxlX2ZwcwAQdm1hZl9lbmFibGVfbnN1YgAgbWVhc3VyZV9vcmlnaW5hbF9yZXNvbHV0aW9uX3NzaW0AKGNvbXB1dGVfc3NpbV9vbmx5X2F0X29yaWdpbmFsX3Jlc29sdXRpb24AHXVzZV9sYW5jem9zX2Zvcl92cW1fdXBzY2FsaW5nABFkaXNhYmxlX3Bvc3RfcHZxcwAVACUAHAAAJsjdreOe84MUFZBOKAJDMxgLdnRzX3ByZXZpZXccF0CWL6wIMSbpGDRkYXNoX2k0bGl0ZWJhc2ljX3Bhc3N0aHJvdWdoYWxpZ25lZF9ocTJfZnJhZ18yX3ZpZGVvEgAYGHZpZGVvcy52dHMuY2FsbGJhY2sucHJvZDgSVklERU9fVklFV19SRVFVRVNUGw6IFW9lbV90YXJnZXRfZW5jb2RlX3RhZwZvZXBfaGQTb2VtX3JlcXVlc3RfdGltZV9tcwEwDG9lbV9jZmdfcnVsZQd1bm11dGVkE29lbV9yb2lfcmVhY2hfY291bnQBMBFvZW1faXNfZXhwZXJpbWVudAARb2VtX3JvaV91c2VyX3RpZXIDdWdjHm9lbV9yb2lfcHJlZGljdGVkX3dhdGNoX3RpbWVfcwEwFm9lbV9yb2lfcmVjaXBlX2JlbmVmaXQFMC4wMDAlb2VtX3JvaV9zdGF0aWNfYmVuZWZpdF9jb3N0X2V2YWx1YXRvcgtwcm9ncmVzc2l2ZQxvZW1fdmlkZW9faWQQMTgyNDc5NzA4MTIzOTMzOBJvZW1fdmlkZW9fYXNzZXRfaWQQNTQxNzg0MTQwODMyMDM3MhVvZW1fdmlkZW9fcmVzb3VyY2VfaWQQNTYzODA3NjQxOTY1MTQyOBxvZW1fc291cmNlX3ZpZGVvX2VuY29kaW5nX2lkDzkxODUxMzQ4OTMyOTI2MA52dHNfcmVxdWVzdF9pZA8yZWU5N2Q0ZTBlYjU0MmUlAhwcHBXw5hcbAVUAAhsBVQACHBUCAAAAFoC6twMAJY4CGwiIAXMENTE4OAJjZAoyMDIzLTAyLTAyA3JjYgEwA2FwcAZ1cGxvYWQCY3QZQ09OVEFJTkVEX1BPU1RfQVRUQUNITUVOVBNvcmlnaW5hbF9kdXJhdGlvbl9zCDE0MjAuMDc1AWYCYWQCdHMVcHJvZ3Jlc3NpdmVfZW5jb2RpbmdzAA%3D%3D&ccb=1-7&_nc_sid=41a7d5&_nc_ohc=L_dzb8dbQwcAX8wwXSo&_nc_ht=scontent-sin6-2.xx&edm=APRAPSkEAAAA&oh=00_AfCY25yJxLCTq0lZ1bttybDBFV_-7qbGg7ZZoE3s_1nEig&oe=63F82C10&_nc_rid=897881643295126" -v

Hiện tại vụ plugin sửa lỗi mình vẫn chưa code được do chưa tìm ra code ví dụ.
 
Ngon rồi, để mình dùng luôn, mình toàn code kiểu nông dân ra sản phẩm nên cũng không chú ý tới giao diện :love:

Còn issue Gituhb thì theo mình nghĩ cứ gửi họ hai cái lệnh:

Cái này sẽ gây đơ MPV (do không có --title=NoTitle):
Code:
mpv --no-ytdl "https://scontent-sin6-2.xx.fbcdn.net/v/t39.25447-2/10000000_150747141158559_2304511369673619337_n.mp4?_nc_cat=108&vs=b4d50b4455f0e7b7&_nc_vs=HBksFQAYJEdJQ1dtQUNmdHN5Tkdva0FBSW0zUG9MaFJQc2ZibWRqQUFBRhUAAsgBABUAGCRHSUNXbUFBYTloV1h5UmtEQU1xcWNIU01FdDhhYnJGcUFBQUYVAgLIAQBLB4gScHJvZ3Jlc3NpdmVfcmVjaXBlATENc3Vic2FtcGxlX2ZwcwAQdm1hZl9lbmFibGVfbnN1YgAgbWVhc3VyZV9vcmlnaW5hbF9yZXNvbHV0aW9uX3NzaW0AKGNvbXB1dGVfc3NpbV9vbmx5X2F0X29yaWdpbmFsX3Jlc29sdXRpb24AHXVzZV9sYW5jem9zX2Zvcl92cW1fdXBzY2FsaW5nABFkaXNhYmxlX3Bvc3RfcHZxcwAVACUAHAAAJsjdreOe84MUFZBOKAJDMxgLdnRzX3ByZXZpZXccF0CWL6wIMSbpGDRkYXNoX2k0bGl0ZWJhc2ljX3Bhc3N0aHJvdWdoYWxpZ25lZF9ocTJfZnJhZ18yX3ZpZGVvEgAYGHZpZGVvcy52dHMuY2FsbGJhY2sucHJvZDgSVklERU9fVklFV19SRVFVRVNUGw6IFW9lbV90YXJnZXRfZW5jb2RlX3RhZwZvZXBfaGQTb2VtX3JlcXVlc3RfdGltZV9tcwEwDG9lbV9jZmdfcnVsZQd1bm11dGVkE29lbV9yb2lfcmVhY2hfY291bnQBMBFvZW1faXNfZXhwZXJpbWVudAARb2VtX3JvaV91c2VyX3RpZXIDdWdjHm9lbV9yb2lfcHJlZGljdGVkX3dhdGNoX3RpbWVfcwEwFm9lbV9yb2lfcmVjaXBlX2JlbmVmaXQFMC4wMDAlb2VtX3JvaV9zdGF0aWNfYmVuZWZpdF9jb3N0X2V2YWx1YXRvcgtwcm9ncmVzc2l2ZQxvZW1fdmlkZW9faWQQMTgyNDc5NzA4MTIzOTMzOBJvZW1fdmlkZW9fYXNzZXRfaWQQNTQxNzg0MTQwODMyMDM3MhVvZW1fdmlkZW9fcmVzb3VyY2VfaWQQNTYzODA3NjQxOTY1MTQyOBxvZW1fc291cmNlX3ZpZGVvX2VuY29kaW5nX2lkDzkxODUxMzQ4OTMyOTI2MA52dHNfcmVxdWVzdF9pZA8yZWU5N2Q0ZTBlYjU0MmUlAhwcHBXw5hcbAVUAAhsBVQACHBUCAAAAFoC6twMAJY4CGwiIAXMENTE4OAJjZAoyMDIzLTAyLTAyA3JjYgEwA2FwcAZ1cGxvYWQCY3QZQ09OVEFJTkVEX1BPU1RfQVRUQUNITUVOVBNvcmlnaW5hbF9kdXJhdGlvbl9zCDE0MjAuMDc1AWYCYWQCdHMVcHJvZ3Jlc3NpdmVfZW5jb2RpbmdzAA%3D%3D&ccb=1-7&_nc_sid=41a7d5&_nc_ohc=L_dzb8dbQwcAX8wwXSo&_nc_ht=scontent-sin6-2.xx&edm=APRAPSkEAAAA&oh=00_AfCY25yJxLCTq0lZ1bttybDBFV_-7qbGg7ZZoE3s_1nEig&oe=63F82C10&_nc_rid=897881643295126" -v

Cái này ok:
Code:
mpv --title=NoTitle --no-ytdl "https://scontent-sin6-2.xx.fbcdn.net/v/t39.25447-2/10000000_150747141158559_2304511369673619337_n.mp4?_nc_cat=108&vs=b4d50b4455f0e7b7&_nc_vs=HBksFQAYJEdJQ1dtQUNmdHN5Tkdva0FBSW0zUG9MaFJQc2ZibWRqQUFBRhUAAsgBABUAGCRHSUNXbUFBYTloV1h5UmtEQU1xcWNIU01FdDhhYnJGcUFBQUYVAgLIAQBLB4gScHJvZ3Jlc3NpdmVfcmVjaXBlATENc3Vic2FtcGxlX2ZwcwAQdm1hZl9lbmFibGVfbnN1YgAgbWVhc3VyZV9vcmlnaW5hbF9yZXNvbHV0aW9uX3NzaW0AKGNvbXB1dGVfc3NpbV9vbmx5X2F0X29yaWdpbmFsX3Jlc29sdXRpb24AHXVzZV9sYW5jem9zX2Zvcl92cW1fdXBzY2FsaW5nABFkaXNhYmxlX3Bvc3RfcHZxcwAVACUAHAAAJsjdreOe84MUFZBOKAJDMxgLdnRzX3ByZXZpZXccF0CWL6wIMSbpGDRkYXNoX2k0bGl0ZWJhc2ljX3Bhc3N0aHJvdWdoYWxpZ25lZF9ocTJfZnJhZ18yX3ZpZGVvEgAYGHZpZGVvcy52dHMuY2FsbGJhY2sucHJvZDgSVklERU9fVklFV19SRVFVRVNUGw6IFW9lbV90YXJnZXRfZW5jb2RlX3RhZwZvZXBfaGQTb2VtX3JlcXVlc3RfdGltZV9tcwEwDG9lbV9jZmdfcnVsZQd1bm11dGVkE29lbV9yb2lfcmVhY2hfY291bnQBMBFvZW1faXNfZXhwZXJpbWVudAARb2VtX3JvaV91c2VyX3RpZXIDdWdjHm9lbV9yb2lfcHJlZGljdGVkX3dhdGNoX3RpbWVfcwEwFm9lbV9yb2lfcmVjaXBlX2JlbmVmaXQFMC4wMDAlb2VtX3JvaV9zdGF0aWNfYmVuZWZpdF9jb3N0X2V2YWx1YXRvcgtwcm9ncmVzc2l2ZQxvZW1fdmlkZW9faWQQMTgyNDc5NzA4MTIzOTMzOBJvZW1fdmlkZW9fYXNzZXRfaWQQNTQxNzg0MTQwODMyMDM3MhVvZW1fdmlkZW9fcmVzb3VyY2VfaWQQNTYzODA3NjQxOTY1MTQyOBxvZW1fc291cmNlX3ZpZGVvX2VuY29kaW5nX2lkDzkxODUxMzQ4OTMyOTI2MA52dHNfcmVxdWVzdF9pZA8yZWU5N2Q0ZTBlYjU0MmUlAhwcHBXw5hcbAVUAAhsBVQACHBUCAAAAFoC6twMAJY4CGwiIAXMENTE4OAJjZAoyMDIzLTAyLTAyA3JjYgEwA2FwcAZ1cGxvYWQCY3QZQ09OVEFJTkVEX1BPU1RfQVRUQUNITUVOVBNvcmlnaW5hbF9kdXJhdGlvbl9zCDE0MjAuMDc1AWYCYWQCdHMVcHJvZ3Jlc3NpdmVfZW5jb2RpbmdzAA%3D%3D&ccb=1-7&_nc_sid=41a7d5&_nc_ohc=L_dzb8dbQwcAX8wwXSo&_nc_ht=scontent-sin6-2.xx&edm=APRAPSkEAAAA&oh=00_AfCY25yJxLCTq0lZ1bttybDBFV_-7qbGg7ZZoE3s_1nEig&oe=63F82C10&_nc_rid=897881643295126" -v

Hiện tại vụ plugin sửa lỗi mình vẫn chưa code được do chưa tìm ra code ví dụ.
Em vừa mới post rồi https://github.com/mpv-player/mpv/issues/11343 hi vọng có ai dòm ngó :D
 
Em vừa mới post rồi https://github.com/mpv-player/mpv/issues/11343 hi vọng có ai dòm ngó :D

Nhìn chung là mình đã viết xong plugin sửa lỗi title dài cho MPV, copy vào thư mục scripts trong portable_config là chiến mọi thể loại URL dài :D, code rất đơn giản không gây mất tương thích, không mất title khi mở video tự động sử dụng title như Youtube/Nicovideo/Twitch, link tải bên dưới.

Video demo (dù URL dài nhưng không cần --title=NoTitle vẫn chiến): https://gfycat.com/NippyHighFugu

Mã nguồn file longtitlepatcher.lua, update V4, nên dùng phần trong đoạn CODE này vì sẽ được cập nhập khi cần thiết, tạo một file tên longtitlepatcher.lua trong thư mục scripts rồi copy tất bên dưới vào:
Code:
-- Fix MPV VeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitle's Hang
local function media_title(name, val)
    local filename = mp.get_property('path', '')
    local mediatitle = mp.get_property("media-title", "")
    --mp.msg.info(mediatitle)
    --mp.msg.info(string.len(mediatitle))
    --mp.msg.info(filename)
    --mp.msg.info(string.len(filename))
    --if mediatitle == "" then mp.set_property("force-media-title", "NoTitle") end
    if string.len(mediatitle) >= 200 then mp.set_property("force-media-title", "NoTitle") end
    if string.len(filename) >= 200 then mp.set_property("force-media-title", "NoTitle") end
end

mp.observe_property("media-title", "string", media_title)
--mp.observe_property("force-media-title", "string", media_title)

P/s: Đã update lên #1 cho tiện truy xuất sau này: https://voz.vn/t/tong-hop-nhung-addon-chat-cho-firefox-pc-mobile.682181/
 

Attachments

  • longtitlepatcher.zip
    398 bytes · Views: 95
Last edited:
Nhìn chung là mình đã viết xong plugin sửa lỗi title dài cho MPV, copy vào thư mục scripts trong portable_config là chiến mọi thể loại URL dài :D, code rất đơn giản không gây mất tương thích, không mất title khi mở video tự động sử dụng title như Youtube/Nicovideo/Twitch, link tải bên dưới.

Video demo (dù URL dài nhưng không cần --title=NoTitle vẫn chiến): https://gfycat.com/NippyHighFugu

Mã nguồn file longtitlepatcher.lua, update V3:
Code:
-- Fix MPV VeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitle's Hang
local function media_title(name, val)
    local filename = mp.get_property('path', '')
    local mediatitle = mp.get_property("media-title", "")
    mp.msg.info(mediatitle)
    mp.msg.info(string.len(mediatitle))
    mp.msg.info(filename)
    mp.msg.info(string.len(filename))
    --if mediatitle == "" then mp.set_property("force-media-title", "NoTitle") end
    if string.len(mediatitle) >= 200 then mp.set_property("force-media-title", "NoTitle") end
    if string.len(filename) >= 200 then mp.set_property("force-media-title", "NoTitle") end
end

mp.observe_property("media-title", "string", media_title)
--mp.observe_property("force-media-title", "string", media_title)

P/s: Đã update lên #1 cho tiện truy xuất sau này: https://voz.vn/t/tong-hop-nhung-addon-chat-cho-firefox-pc-mobile.682181/
Ngon xài cái này không chỉ xài chung 1 nút với MPV mà còn chỉnh được độ dài của title :p
 
Ngon xài cái này không chỉ xài chung 1 nút với MPV mà còn chỉnh được độ dài của title :p

Giờ ngon đến mức xem cả Nicovideo nhẹ nhàng đằm thắm :D

Video: https://gfycat.com/AccurateBelatedChipmunk

Nhìn chung là xử lý được tầm 90% thể loại trang, trừ mấy trang dùng .html giả làm file .ts thì khó, nói chung mình chưa thử vì tụi này hiếm, lại chỉ có ở mấy trang Việt Nam nên chưa có ví dụ thực tế để test. Nếu mà bạn nào kiếm được thì cứ ném lên mình test thử, cơ mà hiện tại cũng hài lòng với những gì mình đang có rồi. :D
 
Last edited:
Nói chung thì cứ dùng và tìm hiểu, mình đưa một ví dụ và một người có thể qua mặt được cái tính năng phát hiện Sandbox của một phần mềm bằng cách sử dụng tính năng Hide Host Process của Sandboxie, đây là một phần mềm nhiều tùy chỉnh, nên thường là mọi thứ đều có thể linh hoạt: https://github.com/sandboxie-plus/Sandboxie/issues/115 -> Kết quả: https://github.com/sandboxie-plus/Sandboxie/issues/115#issuecomment-1081120394

Ngoài ra tự biên dịch lại Sandboxie để đổi tên file các file quan trọng của Sandboxi thường là sẽ qua được.

Mình chơi nhiều game trong Sandbox đấy (cho bớt rác vào hệ thống, ngoài ra game flash dạng .swf nhiều rác lại không bảo mật, chơi trong Sandbox cho lành), đa phần là đều cho qua nhẹ nhàng, các game online thì nghiêm hơn mà mình không chơi game online nên chắc là vậy. Cái mà Sandboxie và tất cả phần mềm Sandbox đều làm là nhúng file DLL vào ứng dụng được chạy và chuyển hướng, hạn chế quyền hạn, quét lệnh từ các ứng dụng để ép ứng dụng phải nằm trong Sandbox, hành vì này giống y hệt như các phần mềm mà nhiều người dùng để "hack" game đó, nên tất nhiên là thường sẽ bị block.

Vãi, mới tìm được cái hàng mới này để ẩn Sandboxie, khi rảnh test thử: https://github.com/VeroFess/SbieHide
Nguồn: https://github.com/sandboxie-plus/Sandboxie/issues/2310#issuecomment-1324543963

Do Tung Của viết mà Tung Của rất giỏi khoản này nên có thể hy vọng đó.
Nếu mở file winrar trong sanbox
Rồi mo tiếp file exe Trong file winrar thì sanbox nó có cách ly luôn exe ko thím??
Hay phải giải nén ra mới mở exe trong sanbox???
 
Back
Top