通过javascript 直接播放amr格式的语言

  前段时间做了个功能(有2、3个月了,突然想起来了,就记录一下),语言播放。一开始觉得很简单~~~

  计划应用的是H5的audio标签,但因为这个标签不支持amr格式的语言,但是手机端传到后台的录音却都是amr格式的,无奈,只好先进行了转码工作。

amr格式语言转mp3格式,在windows服务器上均已通过,百度有很多博客。挺简单。

  但是,最怕的但是,服务器是Linux环境,之前的一切工作全部白瞎了。之后就是各种Linux环境下的尝试了,然并卵,苦逼了一个一个礼拜,按照网上方法一个个尝试,结果过程和人家一样,但是就是无法实现转码功能。

  最后,上天无路,入地无门,换种思路,直接开始学习AudioContext文档,结合网上资料,开始学习利用AudioContext直接播放amr语言文件。

AudioContext 学习:https://developer.mozilla.org/zh-CN/docs/Web/API/AudioContext

直接贴代码

HTML部分(href存amr文件访问路径)

<a class="amrnb"  href="'+obj.fileDownloadUrl+'" download=""></a>

业务代码部分(initAudio方法需要在语言加载完毕后初始化)

/*语音播放控制js代码*/
    function initAudio(){
        setTimeout(function(){
            //var audio = $("audio");
            var audio = $(".amrnb");
            var audioIngI=9999;//正在播放的语音的角标
            for(var i = 0; i < audio.length; i++){
                var dshiqi;
                var second = 2;
                /*var second = audio[i].duration;//获取音频秒数
                if(second <= 60){
                    $(".yuyin-time").eq(i).text(parseInt(second) + "s");
                }else if(second > 60){
                    var m = parseInt(second / 60);
                    var s = parseInt(second % 60);
                    $(".yuyin-time").eq(i).text(m + ":" + s + "s");
                }*/
                (function(i,audioIngI){
                    $($(".yuyin")[i]).live("click", function () {
                        $(".yuyin-play").removeClass("yuyin-playing");//播放完毕去除动画
                        var ctx =  getAudioContext();
                        var state = ctx.state;
                        //alert(audioIngI==i);
                        /*if(audioIngI==i){
                            ctx.close();
                            if(state == "running"){
                                ctx.suspend();
                            }
                            if(state == "suspended"){
                                ctx.resume();
                            }
                            return;
                        }*/
                        if(state == "running"){
                            ctx.close();
                            if(audioIngI==i){
                                gAudioContext = new AudioContext();
                                audioIngI=9999;
                                clearTimeout(dshiqi);
                                return;
                            }
                            gAudioContext = new AudioContext();
                        }
                        fetchBlob($(this).find("a.amrnb")[0].href, function(blob) {
                            audioIngI = i;
                            playAmrBlob(blob);
                            //$(this).find(".yuyin-play").attr("class","yuyin-playing");
                            //$(this).find(".yuyin-play").addClass("yuyin-playing");
                        });
                        $(this).find(".yuyin-play").addClass("yuyin-playing");
                        var time = $(this).find("span").text();
                        dshiqi = setTimeout(function(){
                            $(".yuyin-play").removeClass("yuyin-playing");//播放完毕去除动画
                            audioIngI=9999;
                        },time.substr(0,time.length-1) * 1000);
                        //console.log($(this).find("a.amrnb")[i]);
                        /*for(var j = 0; j < $("audio").length; j++){
                            if(j != i){
                                audio[j].pause();// 这个就是暂停
                                audio[j].currentTime = 0;
                                $($(".yuyin-play")[j]).removeClass("yuyin-playing");
                            }
                        }
                        if(audio[i]!==null){
                            //检测播放是否已暂停.audio.paused 在播放器播放时返回false.
                            if(audio[i].paused){
                                audio[i].play();//audio.play();// 这个就是播放
                                $(this).find(".yuyin-play").addClass("yuyin-playing");
                                clearTimeout(dshiqi);
                            }else{
                                audio[i].pause();// 这个就是暂停
                                audio[i].currentTime = 0;
                                $(this).find(".yuyin-play").removeClass("yuyin-playing");
                                clearTimeout(dshiqi);
                            }
                        }
                        dshiqi = setTimeout(function(){
                            $(".yuyin-play").removeClass("yuyin-playing");//播放完毕去除动画
                        },audio[i].duration * 1000);*/
                    });
                })(i);
            }
        },10);
    }

AudioContext代码支持

/*************************************JS控制语音播放*****************************************/
    /*function E(selector) {
        return document.querySelector(selector);
    }

    $('#sample-amr > button').onclick = function() {
        fetchBlob(E('#sample-amr > a').href, function(blob) {
            playAmrBlob(blob);
        });
    };*/

    var gAudioContext = new AudioContext();
    function getAudioContext() {
        if(!gAudioContext) {
            gAudioContext = new AudioContext();
        }
        return gAudioContext;
    }

    function fetchBlob(url, callback) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.responseType = 'blob';
        xhr.onload = function() {
            callback(this.response);
        };
        xhr.onerror = function() {
            alert('Failed to fetch ' + url);
        };
        xhr.send();
    }

    function readBlob(blob, callback) {
        var reader = new FileReader();
        reader.onload = function(e) {
            var data = new Uint8Array(e.target.result);
            callback(data);
        };
        reader.readAsArrayBuffer(blob);
    }

    function fetchAndReadBlob(url, callback) {
        fetchBlob(url, function(blob) {
            readBlob(blob, callback);
        });
    }

    function playAmrBlob(blob, callback) {
        readBlob(blob, function(data) {
            playAmrArray(data);
        });
    }

    function playAmrArray(array) {
        var samples = AMR.decode(array);
        if(!samples) {
            alert('Failed to decode!');
            return;
        }
        playPcm(samples);
    }

    function playPcm(samples) {
        var ctx = getAudioContext();
        var src = ctx.createBufferSource();
        var buffer = ctx.createBuffer(1, samples.length, 8000);
        if(buffer.copyToChannel) {
            buffer.copyToChannel(samples, 0, 0)
        } else {
            var channelBuffer = buffer.getChannelData(0);
            channelBuffer.set(samples);
        }

        src.buffer = buffer;
        src.connect(ctx.destination);
        src.start();
    }

点击a标签就可以了~~

学然后知不足,教然后知困。知不足,然后能自反也;知困,然后能自强也。

原文地址:https://www.cnblogs.com/Garnett-Boy/p/8252123.html