html5的audio标签播放FTP服务器语音

弄这个鬼东西折腾了一天半,记录一下:

直接上代码:

    <audio id="player" src="audio/a2.mp3"></audio>
     <div id="musicPlayer" class="musicPlayer">
         <div class="time-volume">
               <div class="timePart">
                  <span class="nowTime">正在连接...</span>
                   <span class="timeLine">/</span>
                   <span class="allTime"></span>
               </div>
               <div class="volumePart">
                    <div class="volumeBtn" onclick="playMuted()" title="切换静音"></div>
                    <div class="volumeSlideBox" onclick="updateVolume(event)" title="30">
                       <div class="volumeSlide"></div>
                    </div>
               </div>
         </div>
         <div class="process" onclick="clickProcess(event)">
              <div class="processSlide"></div>
         </div>
         <div class="control">
              <!--<div id="prevBtn" class="controlBtn" title="上一条通话记录"></div>-->
              <div id="playBtn" class="controlBtn" onclick="playMusic()" title="播放/暂停"></div>
              <!--<div id="nextBtn" class="controlBtn" title="下一条通话记录"></div>-->
         </div>
     </div>

    <div class="zd-panel-control">
        <button type="button" class="btn btn-zd-search" onclick="cancelClose()">确定        </button>&nbsp;
        <button type="button" class="btn btn-zd" onclick="cancelClose()">取消</button>
    </div>
//播放音频
function playMp3(row) {
    if (row.sfjt != 1) {
        $.modal.alertWarning("此通话
        return;
    }
    showBg();
    window.clearInterval(loadTime
    //	console.log(row.lyurl);
    $("#cancelDiv").show();
    $("#hjsj").val(row.hjsj);
    $("#jtsj").val(row.jtsj);
    $("#zjf").val(row.zjf);
    $("#bjf").val(row.bjf);
    $("#thsc").val(row.thsc);
    // $('#player').attr("src", r
    var playUrl = ctx + "qx/phone
    $('#player').attr("src", play
    getMusicTime();
    initVolume();
}
//显示灰色 jQuery 遮罩层
function showBg() {
    var bh = $("body").height();
    var bw = $("body").width();
    $("#fullbg").css({
        height:bh,
        width:bw,
        display:"block"
    });
}
//关闭灰色 jQuery 遮罩
function closeBg() {
    $("#fullbg").hide();
}
//关闭音频和div
function cancelClose() {
    closeBg();
    $.form.reset('formCancel');
    player.pause();
    // player.load();
    $("#cancelDiv").hide();
}

//获得总时长
    function getMusicTime() {
        loadTimer = setInterval(function () {
            if (player.readyState == 4) {
                $('.allTime').text(formateTime(player.duration));
                console.log(player.duration);
                $('.nowTime').text('00:00');
                $('.timeLine').show();
                clearInterval(loadTimer);
                playMusic();
            }
        }, 100);
    }

    // 初始化音量
    function initVolume() {
        player.volume = 0.3;
    }

    //播放/暂停
    function playMusic() {
        if (player.paused) {
            player.play();
            $('#playBtn').addClass('paused');
            //设置定时器
            playTimer = setInterval(updateProgress, 500);
        } else {
            clearInterval(playTimer);
            player.pause();
            $('#playBtn').removeClass('paused');
        }
    }

    //通过点击滑块控制音乐进度
    function clickProcess(event) {
        //计算点击位置的百分比
        var currentValue = event.offsetX / $('.process').width();
        console.log(player.currentTime);
        console.log(player.duration * currentValue);
        // $("#player").attr("currentTime", 1.000000);
        player.currentTime = (player.duration * currentValue).toFixed(6);
        console.log((player.duration * currentValue).toFixed(6));
        console.log(player.currentTime);
        // alert(parseInt((player.duration * currentValue)+""));
        // player.setCurrentTime(parseInt((player.duration * currentValue)+""));
        //播放
        clearInterval(playTimer);
        player.play();
        $('#playBtn').addClass('paused');
        //设置定时器
        playTimer = setInterval(updateProgress, 500);
    }

    //通过滑块控制音量大小
    function updateVolume(event) {
        //得到当前点击的位置
        var currentVolume = (event.offsetX / $('.volumeSlideBox').width()).toFixed(2);
        //设置音量
        player.volume = currentVolume;
        $('.volumeSlide').width(currentVolume * 100 + "%");
        $('.volumeSlideBox').attr('title', currentVolume * 100);
    }

    //静音
    function playMuted() {
        if (player.muted) {
            player.muted = false;
            $('.volumeSlide').width(player.volume * 100 + "%");
            $('.volumeSlideBox').attr('title', player.volume * 100);
            $('.volumeBtn').removeClass('muted');
        } else {
            player.muted = true;
            $('.volumeSlide').width(0);
            $('.volumeSlideBox').attr('title', '静音');
            $('.volumeBtn').addClass('muted');
        }
    }

    // 更新进度条
    function updateProgress() {
        //currentTime 当前播放的秒数
        $('.nowTime').text(formateTime(player.currentTime));
        //duration 当前音乐的总时长,秒数
        var percent = player.currentTime / player.duration * 100 + "%";
        $('.processSlide').width(percent);
        //播放完毕
        if (player.ended) {
            $('.nowTime').text('00:00');
            $('.processSlide').width(0);
            $('#playBtn').removeClass('paused');
        }
    }

    // 将秒数转换为时分秒格式
    function formateTime(time) {
        if (time > 3600) {
            var hour = parseInt(time / 3600);
            var minute = parseInt(time % 3600 / 60);
            var second = parseInt(time % 3600 % 60);
            hour = hour >= 10 ? hour : "0" + hour;
            minute = minute >= 10 ? minute : "0" + minute;
            second = second >= 10 ? second : "0" + second;
            return hour + ":" + minute + ":" + second;
        }
        else {
            var minute = parseInt(time / 60);
            var second = parseInt(time % 60);
            minute = minute >= 10 ? minute : "0" + minute;
            second = second >= 10 ? second : "0" + second;
            return minute + ":" + second;
        }
    }

注意点:

1、如果文件服务器是web服务,则直接在<autio src=web文件地址>,src直接使用文件地址;

2、如果文件服务器为ftp服务器,则需要在src中直接掉后台下载文件的接口即可,当然,文件要以流的方式放在response中。

/**
     * 下载影音文件  (response-header设置不同)
     * @param response 。
     * @param remote 文件全路径
     * @return void
     **/
    public void downloadAudio(HttpServletResponse response, String remote) throws IOException {
        initFtpClient();
        ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
        String fileName = remote.substring(remote.lastIndexOf(FILE_SEPARATOR) + 1);
        InputStream ins = ftpClient.retrieveFileStream(remote);
        if (null == ins) {
            return;
        }
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        byte[] buf = new byte[204800];
        int bufsize = 0;
        while ((bufsize = ins.read(buf, 0, buf.length)) != -1) {
            byteOut.write(buf, 0, bufsize);
        }
        byte[] return_arraybyte = byteOut.toByteArray();
        response.reset();
        //设置响应头
        response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("gb2312"), "ISO8859-1"));
        response.setContentType("application/octet-stream");
        response.addHeader("Accept-Ranges","bytes");
        int length = return_arraybyte.length;
        response.setContentLength(length);
        byteOut.close();
        ins.close();
        ServletOutputStream outputStream = response.getOutputStream();
        BufferedOutputStream toClient = new BufferedOutputStream(outputStream);
        toClient.write(return_arraybyte);
        toClient.flush();
        outputStream.close();
        toClient.close();
    }

这里有几个非常重要的注意点,以上四个responseHeader属性是必须要设置的:

1、Content-Disposition和Content-Type就不多说了,文件肯定要设置的。

2、Accept-Ranges如果不设置,则谷歌浏览器中audio标签中的属性currentTime无法修改,修改后总为0;

3、Content-length如果不设置,当文件时间长度大于30秒时,无法获取audio标签中的属性duration(总时长),会报无穷大。

网上找了一份不错的说明

经验证是和response header有关的。我通过对MP3资源set不同的response header来验证,结果如下

ie
Content-Type 必须,当我设为audio/mpeg时才能播放,设为application/octet-stream不能。
Content-Length必须。和Accept-Ranges无关。

chrome
Content-Type 无关,设为application/octet-stream可以播放。
Content-Length,Accept-Ranges必须都有才可更改 currentTime。

也就是说ie需要response header 有正确的Content-Type,Content-Length。
chrome需要头部有Content-Length和Accept-Ranges。(Firefox没测)

上一篇:使用 HTML5 控制摄像头摄像和拍照并保存图像文件到本地和JSP上传到服务器


下一篇:HTML5——Flex布局