弄这个鬼东西折腾了一天半,记录一下:
直接上代码:
<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>
<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没测)