js 实现网页内容语音朗读功能

案列演示地址

/*!
 * TtsAudioUtils v1.0
 * author dengmengxin
 * date 2019-09-5
 *
 * @example
 * ```
 * // 初始化语音合成配置
 * // 百度语音合成接口参数 请参考https://ai.baidu.com/docs#/TTS-API/0bda9a98
 * ttsAudioUtils.initTts({
 *     tok: 'access token',
 *     spd: 6,
 *     pit: 4,
 *     vol: 15,
 *     per: 0,
 *     lan: "zh"
 * });
 * // 获取文本数组
 * ttsAudioUtils.obtainTextArrayFunction = function () {
 *     var textArray = [];
 *     textArray.push("语音合成由百度语音技术提供");
 *     return textArray;
 * }
 * ```
 */
var ttsAudioUtils = {
    stopped: true,
    paused: true,
    playing: false,
    param: {},
    audioArray: [],
    audio: new Audio(),
    obtainTextArrayFunction: null,// 获取要合成播放的文本数组,由于不定性网页内容,需要在外部实现
    onPlayCallback: null,// 播放回调
    onPauseCallback: null,// 暂停播放回调
    onStopCallback: null,// 停止播放回调
    onAudioErrorCallback: null,// 音频错误回调
    onPlayCompleteCallback: null, // 播放完成回调
    /**
     * 初始化
     * @param {Object} param 合成参数
     */
    initTts: function (param) {
        ttsAudioUtils.param = param;
        ttsAudioUtils.param['ctp'] = 1;
        ttsAudioUtils.param['cuid'] = ttsAudioUtils._getDeviceOs();
    },
    /**
     * 播放
     */
    play: function () {
        if (ttsAudioUtils.playing) {
            return;
        }
        var textArray = ttsAudioUtils.isFunction(ttsAudioUtils.obtainTextArrayFunction) ? ttsAudioUtils.obtainTextArrayFunction() : [];
        if (textArray < 1) {
            console.log('没有要播放的文本');
            return false;
        }
        if (ttsAudioUtils.stopped) {
            ttsAudioUtils._speak(textArray);
            ttsAudioUtils.stopped = false;
        }
        ttsAudioUtils.isFunction(ttsAudioUtils.onPlayCallback) && ttsAudioUtils.onPlayCallback();
        ttsAudioUtils.audio.play();
        ttsAudioUtils.paused = false;
        ttsAudioUtils.playing = true;
    },
    /**
     * 暂停播放
     */
    pause: function () {
        ttsAudioUtils.isFunction(ttsAudioUtils.onPauseCallback) && ttsAudioUtils.onPauseCallback();
        ttsAudioUtils.audio.pause();
        ttsAudioUtils.paused = true;
        ttsAudioUtils.playing = false;
    },
    /**
     * 停止播放
     */
    stop: function () {
        ttsAudioUtils.isFunction(ttsAudioUtils.onStopCallback) && ttsAudioUtils.onStopCallback();
        ttsAudioUtils.audio.pause();
        ttsAudioUtils.audio.removeEventListener('ended', ttsAudioUtils._playEndedHandler, false);
        ttsAudioUtils.audio.removeEventListener('error', ttsAudioUtils._playErrorHandler, false);
        ttsAudioUtils.stopped = true;
        ttsAudioUtils.paused = true;
        ttsAudioUtils.playing = false;
    },
    /**
     * 准备重读
     */
    prepareReread: function () {
        ttsAudioUtils.audio.pause();
        ttsAudioUtils.audio.removeEventListener('ended', ttsAudioUtils._playEndedHandler, false);
        ttsAudioUtils.audio.removeEventListener('error', ttsAudioUtils._playErrorHandler, false);
        ttsAudioUtils.stopped = true;
        ttsAudioUtils.play();
    },
    /**
     * 内部播放结束回调
     */
    _playEndedHandler: function () {
        if (ttsAudioUtils.audioArray.length > 0) {
            ttsAudioUtils.audio.src = ttsAudioUtils.audioArray.pop();
            ttsAudioUtils.audio.play();
        } else {
            // 播放完成
            ttsAudioUtils.isFunction(ttsAudioUtils.onPlayCompleteCallback) && ttsAudioUtils.onPlayCompleteCallback();
            ttsAudioUtils.stop();
        }
    },
    /**
     * 内部播放错误回调
     */
    _playErrorHandler: function () {
        // 错误状态  
        // Media.error; //null:正常  
        // Media.error.code; //1.用户终止 2.网络错误 3.解码错误 4.URL无效
        ttsAudioUtils.playing = false;
        ttsAudioUtils.stop();
        ttsAudioUtils.isFunction(ttsAudioUtils.onAudioErrorCallback) && ttsAudioUtils.onAudioErrorCallback(ttsAudioUtils.audio);
        // console.log('合成语音播放出错,错误码:' + ttsAudioUtils.audio.error.code + ',链接:' + ttsAudioUtils.audio.currentSrc);
    },
    /**
     * 内部核心文本处理
     * @param {any[]} textArray 字符串文本数组
     */
    _speak: function (textArray) {
        if (ttsAudioUtils.param) {
            if (textArray < 1) {
                return false;
            }

            // 处理参数
            var urlParameter = [];
            for (var k in ttsAudioUtils.param) {
                urlParameter.push(k + '=' + ttsAudioUtils.param[k]);
            }

            ttsAudioUtils.audioArray = [];
            for (var i = 0; i < textArray.length; i++) {
                var address = 'http://tsn.baidu.com/text2audio?tex=' + encodeURIComponent(textArray[i]) + '&' + urlParameter.join('&');
                ttsAudioUtils.audioArray.unshift(address);

                //var address = 'http://tsn.baidu.com/text2audio?tex=' + encodeURIComponent(textArray[i]) + '&lan=zh&ctp=1&cuid=' + cuid + '&per=' + per + '&spd=' + spd + '&pit=' + pit + '&tok=' + tok;
                //ttsAudioUtils.audioArray.unshift(address);
            }
            ttsAudioUtils.audio.preload = true;
            ttsAudioUtils.audio.controls = true;
            ttsAudioUtils.audio.src = ttsAudioUtils.audioArray.pop();
            ttsAudioUtils.audio.addEventListener('ended', ttsAudioUtils._playEndedHandler, false);
            ttsAudioUtils.audio.addEventListener('error', ttsAudioUtils._playErrorHandler, false);
            ttsAudioUtils.audio.loop = false;
            console.log('语音合成中,请稍后...');
            return true;
        } else {
            return false;
        }
    },
    /**
     * 内部获取设备系统
     */
    _getDeviceOs: function () {
        var sUserAgent = navigator.userAgent;
        var isWin = (navigator.platform == "Win32") || (navigator.platform == "Windows");
        var isMac = (navigator.platform == "Mac68K") || (navigator.platform == "MacPPC") || (navigator.platform == "Macintosh") || (navigator.platform == "MacIntel");
        if (isMac)
            return "Mac";
        var isUnix = (navigator.platform == "X11") && !isWin && !isMac;
        if (isUnix)
            return "Unix";
        var isLinux = (String(navigator.platform).indexOf("Linux") > -1);
        if (isLinux)
            return "Linux";
        if (isWin) {
            var isWin2K = sUserAgent.indexOf("Windows NT 5.0") > -1 || sUserAgent.indexOf("Windows 2000") > -1;
            if (isWin2K)
                return "Win2000";
            var isWinXP = sUserAgent.indexOf("Windows NT 5.1") > -1 || sUserAgent.indexOf("Windows XP") > -1;
            if (isWinXP)
                return "WinXP";
            var isWin2003 = sUserAgent.indexOf("Windows NT 5.2") > -1 || sUserAgent.indexOf("Windows 2003") > -1;
            if (isWin2003)
                return "Win2003";
            var isWinVista = sUserAgent.indexOf("Windows NT 6.0") > -1 || sUserAgent.indexOf("Windows Vista") > -1;
            if (isWinVista)
                return "WinVista";
            var isWin7 = sUserAgent.indexOf("Windows NT 6.1") > -1 || sUserAgent.indexOf("Windows 7") > -1;
            if (isWin7)
                return "Win7";
        }
        return "other";
    },
    // 判断是否是函数
    isFunction: function (obj) {
        if (Object.prototype.toString.call(obj) === '[object Function]') {
            return true;
        }
        return false;
    },
    /**
     * 判断字符是否为空的方法
     * @param {String} obj - 字符串
     */
    isEmpty: function (obj) {
        if (typeof obj == "undefined" || obj == null || obj == "") {
            return true;
        } else {
            return false;
        }
    }
};

 

你可能感兴趣的:(HTML,Javascript,Android)