lynda.com 字幕翻译

使用搜狗网页翻译接口将 lynda.com 的字幕译为中文

目前为 2019-02-20 提交的版本。查看 最新版本

// ==UserScript==
// @name         lynda.com 字幕翻译

// @description  使用搜狗网页翻译接口将 lynda.com 的字幕译为中文

// @namespace    https://github.com/journey-ad
// @version      0.1.2
// @author       journey-ad
// @match        *://www.lynda.com/*
// @license      MIT
// @run-at       document-end
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function () {
    "use strict"; // 监听历史记录变化,实现自动翻译每节课程

    (function (history) {
        var pushState = history.pushState;

        history.pushState = function (state) {
            if (typeof history.onpushstate == "function") {
                history.onpushstate({
                    state: state
                });
            }

            console.log("章节切换");
            unsafeWindow.transTimer = window.setInterval(transText, 1000); // 用定时器检查待翻译文本是否已准备好

            return pushState.apply(history, arguments);
        };
    })(unsafeWindow.history);

    function transText() {
        try {
            if (mejs.players.mep_0.selectedTrack) {
                // 待翻译文本已准备好
                unsafeWindow.clearInterval(unsafeWindow.transTimer); // 清除定时器

                console.log("字幕文本可用");
                var s = "",
                    r = "",
                    arr = [],
                    num = 0,
                    count = 0,
                    subtitle = mejs.players.mep_0.selectedTrack.entries.text,
                    subtitleTrans = [];

                subtitle.forEach(function (e) { // 去除每条字幕的换行符并按行排列
                    s += e.replace(/\r?\n|\r/g, "") + "\n";
                });
                // console.log(s);

                num = translate(s, function (data, index) { // 调用翻译方法并处理回调
                    count++;
                    arr[index] = data; // 按分块原始下标放回结果数组

                    if (count >= num) { // 所有翻译文本已取回
                        r = arr.join("");
                        subtitleTrans = r.split("\n");

                        subtitle.forEach(function (e, i) {
                            subtitle[i] = subtitleTrans[i] + "\n" + e.replace(/\r?\n|\r/g, ""); // 翻译文本填回原处
                        });
                        // console.log(r.split('\n'));

                        console.log(r);
                        console.log("翻译完成");
                    }
                });
            }
        } catch (error) {

        }
    }

    function translate(str, callback) {
        var KEY = "b33bf8c58706155663d1ad5dba4192dc"; // 硬编码于搜狗网页翻译js

        var textArr = [],
            count = 1;

        if (str.length > 5000) {
            //大于5000字符分块翻译
            var strArr = str.split("\n"),
                i = 0;
            strArr.forEach(function (v) {
                textArr[i] = textArr[i] || "";

                if ((textArr[i] + v).length > (i + 1) * 5000) { // 若加上此行后长度超出5000字符则分块
                    i++;
                    textArr[i] = "";
                }

                textArr[i] += v + "\n";

            });
            count = i + 1; // 记录块的数量

        } else {
            textArr[0] = str;
        }

        var data = {
            from: "auto",
            to: "zh-CHS",
            client: "pc",
            fr: "browser_pc",
            text: null,
            pid: "sogou-dict-vr",
            useDetect: "on",
            useDetectResult: "on",
            oxford: "on",
            isReturnSugg: "on",
            needQc: 1,
            s: null
        };

        textArr.forEach(function (text, index) {
            // 遍历每块分别进行翻译
            data.text = text;
            data.s = md5("autozh-CHS".concat(text).concat(KEY)); // 签名算法

            GM_xmlhttpRequest({
                method: "POST",
                url: "https://fanyi.sogou.com/reventondc/translateV1",
                headers: {
                    accept: "application/json",
                    "content-type": "application/x-www-form-urlencoded; charset=UTF-8"
                },
                data: serialize(data),
                onload: function onload(response) {
                    var result = JSON.parse(response.responseText);
                    // console.log(result);

                    callback(result.data.translate.dit + "\n", index); // 执行回调,在回调中拼接
                }
            });
        });

        return count; // 返回分块数量
    }

    function serialize(obj) {
        return Object.keys(obj)
            .map(function (k) {
                return (
                    encodeURIComponent(k) +
                    "=" +
                    encodeURIComponent(obj[k]).replace("%20", "+")
                );
            })
            .join("&");
    }

    function md5(str) {
        var k = [],
            i = 0;

        for (i = 0; i < 64;) {
            k[i] = 0 | (Math.abs(Math.sin(++i)) * 4294967296);
        }

        var b,
            c,
            d,
            j,
            x = [],
            str2 = unescape(encodeURI(str)),
            a = str2.length,
            h = [(b = 1732584193), (c = -271733879), ~b, ~c];

        for (i = 0; i <= a;) {
            x[i >> 2] |= (str2.charCodeAt(i) || 128) << (8 * (i++ % 4));
        }

        x[(str = ((a + 8) >> 6) * 16 + 14)] = a * 8;
        i = 0;

        for (; i < str; i += 16) {
            a = h;
            j = 0;

            for (; j < 64;) {
                a = [
                    (d = a[3]),
                    (b = a[1] | 0) +
                    (((d =
                                a[0] + [
                                    (b & (c = a[2])) | (~b & d),
                                    (d & b) | (~d & c),
                                    b ^ c ^ d,
                                    c ^ (b | ~d)
                                ][(a = j >> 4)] +
                                (k[j] +
                                    (x[([j, 5 * j + 1, 3 * j + 5, 7 * j][a] % 16) + i] | 0))) <<
                            (a = [7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21][
                                4 * a + (j++ % 4)
                            ])) |
                        (d >>> (32 - a))),
                    b,
                    c
                ];
            }

            for (j = 4; j;) {
                h[--j] = h[j] + a[j];
            }
        }

        str = "";

        for (; j < 32;) {
            str += ((h[j >> 3] >> ((1 ^ (j++ & 7)) * 4)) & 15).toString(16);
        }

        return str;
    }
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址