zoukankan      html  css  js  c++  java
  • 通过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标签就可以了~~

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

  • 相关阅读:
    git常用命令及常见问题解析
    如何让一个sprite绕一个点旋转,同时又可以实现指定旋转角度并慢慢停下的效果
    webpack打包,同时将ES6转为ES5,初探
    测试网站接口,nginx篇
    Phaserjs V2的state状态解析及技巧
    Phaserjs怎样用ES6开发游戏
    PIXI屏幕自适应以及强制横屏
    CSS性能优化新属性:will-change
    div,css&table布局有哪些区别
    防止js全局变量污染方法总结
  • 原文地址:https://www.cnblogs.com/Garnett-Boy/p/8252123.html
Copyright © 2011-2022 走看看