废话不多说直接上代码
- html部分
<div class="audio-wrapper" style="background-color: #fcfcfc;max-width: 670px;height: 90px;border: 1px solid #e0e0e0;">
<audio class="audio" src="https://oss.igandan.com/audio/mp3/2023/08/20/1692528842680.mp3" >
</audio>
<div class="audio-left" style="float: left;text-align: center;width: 22%;height: 100%;">
<img src="https://tmanager.igandan.org/testUeditor/ueditor/themes/default/images/play.png" class="playicon" style="width: 40px;position: relative;top: 25px;margin: 0;display: initial;cursor: pointer;"/>
<!-- <img src="/testUeditor/ueditor/themes/default/images/play.png" class="pauseicon" style="width: 40px;position: relative;top: 25px;margin: 0;display: none;cursor: pointer;"/> -->
</div>
<div class="audio-right" style="margin-right: 5%;float: right;width: 73%;height: 100%;">
<p class="audio-title" style="max-width: 490px; font-size: 15px; height: 35%; margin: 8px 0px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis;">
红尘客栈
</p>
<div class="progress-bar-bg progressBarBg" style="background-color: #d9d9d9;position: relative;height: 2px;cursor: pointer;">
<span class="progressDot" style="width: 12px;height: 12px;border-radius: 50%;-moz-border-radius: 50%;-webkit-border-radius: 50%;background-color: #3e87e8;position: absolute;left: 0;top: -5px;margin-left: 0px;cursor: pointer;"></span>
<div class="progressBar" style="background-color: #649fec;width: 0;height: 2px;"></div>
</div>
<div class="audio-time" style="overflow: hidden;margin-top: -1px;">
<span class="audioCurTime" style="float: left;margin-top:10px;font-size: 12px;color: #969696">00:00</span><span class="audioTotalTime" style="float: right;margin-top:10px;font-size: 12px;color: #969696">02:53</span>
</div>
</div>
</div>
- js部分代码
<script src="//lib.baomitu.com/jquery/3.6.0/jquery.js"></script>
<script>
//设置音乐名字
$('.audio-title')[0].innerHTML=decodeURI(getQueryVariable("audioName"))//$(window.frameElement).attr("audioName");
//设置音乐链接
$(".audio").attr("src",decodeURI(getQueryVariable("audioSrc")))
document.addEventListener('DOMContentLoaded', function () {
// 设置音频文件名显示宽度
var element = document.querySelector('.audio-right');
var maxWidth = window.getComputedStyle(element, null).width;
document.querySelector('.audio-right p').style.maxWidth = maxWidth;
// 可能会有多个音频,逐个初始化音频控制事件
var audios = document.getElementsByTagName('audio');
for (var i = 0; i < audios.length; i++) {
initAudioEvent(i);
}
}, false);
function getQueryVariable(variable){
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
/**
* 初始化音频控制事件
* @param {number} index 索引,表示第几个音频(从0开始)
*/
function initAudioEvent(index) {
var audio = document.getElementsByTagName('audio')[index];
var audioPlayer = document.querySelectorAll(".playicon")[index];//document.getElementById('audioPlayer' + index);
audio.addEventListener("canplay", function(){//监听audio是否加载完毕,如果加载完毕,则读取audio播放时间
document.querySelectorAll(".audioTotalTime")[index].innerText = transTime(audio.duration);
});
// 监听音频播放时间并更新进度条
audio.addEventListener('timeupdate', function () {
updateProgress(audio, index);
}, false);
// 监听播放完成事件
audio.addEventListener('ended', function () {
audioEnded(index);
}, false);
// 点击播放/暂停图片时,控制音乐的播放与暂停
audioPlayer.addEventListener('click', function () {
// 改变播放/暂停图片
if (audio.paused) {
//document.querySelectorAll(".playicon").src = 'http://tmanager.igandan.org/testUeditor/ueditor/themes/default/images/pause.png'
// 暂停其他正在播放的音频
// var audios = document.getElementsByTagName('audio');
// for (var i = 0; i < audios.length; i++) {
// if (i != index && !audios[i].paused) {
// audios[i].pause();
// document.querySelectorAll(".playicon")[i].src = '/testUeditor/ueditor/themes/default/images/play.png';
// }
// }
// 开始播放当前点击的音频
audio.play();
document.querySelectorAll(".playicon")[0].src = 'http://tmanager.igandan.org/testUeditor/ueditor/themes/default/images/play.png';
} else {
audio.pause();
document.querySelectorAll(".playicon")[0].src = '/testUeditor/ueditor/themes/default/images/play.png';
}
}, false);
// 点击进度条跳到指定点播放
// PS:此处不要用click,否则下面的拖动进度点事件有可能在此处触发,此时e.offsetX的值非常小,会导致进度条弹回开始处(简直不能忍!!)
var progressBarBg = document.querySelectorAll(".progressBar")[index];
progressBarBg.addEventListener('mousedown', function (event) {
// 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
if (!audio.paused || audio.currentTime != 0) {
var pgsWidth = parseFloat(window.getComputedStyle(progressBarBg, null).width.replace('px', ''));
var rate = event.offsetX / pgsWidth;
audio.currentTime = audio.duration * rate;
updateProgress(audio, index);
}
}, false);
// 拖动进度点调节进度
dragProgressDotEvent(audio, index);
}
/**
* 鼠标拖动进度点时可以调节进度
* @param {*} audio
* @param {number} index 索引,表示第几个音频(从0开始)
*/
function dragProgressDotEvent(audio, index) {
var dot =document.querySelectorAll(".progressDot")[index];
var position = {
oriOffestLeft: 0, // 移动开始时进度条的点距离进度条的偏移值
oriX: 0, // 移动开始时的x坐标
maxLeft: 0, // 向左最大可拖动距离
maxRight: 0 // 向右最大可拖动距离
};
var flag = false; // 标记是否拖动开始
// 鼠标按下时
dot.addEventListener('mousedown', down, false);
dot.addEventListener('touchstart', down, false);
// 开始拖动
document.addEventListener('mousemove', move, false);
document.addEventListener('touchmove', move, false);
// 拖动结束
document.addEventListener('mouseup', end, false);
document.addEventListener('touchend', end, false);
function down(event) {
if (!audio.paused || audio.currentTime != 0) { // 只有音乐开始播放后才可以调节,已经播放过但暂停了的也可以
flag = true;
position.oriOffestLeft = dot.offsetLeft;
position.oriX = event.touches ? event.touches[0].clientX : event.clientX; // 要同时适配mousedown和touchstart事件
position.maxLeft = position.oriOffestLeft; // 向左最大可拖动距离
position.maxRight =document.querySelectorAll(".progressBarBg")[index].offsetWidth - position.oriOffestLeft; // 向右最大可拖动距离
//document.getElementById('progressBarBg' + index)document
// 禁止默认事件(避免鼠标拖拽进度点的时候选中文字)
if (event && event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
// 禁止事件冒泡
if (event && event.stopPropagation) {
event.stopPropagation();
} else {
window.event.cancelBubble = true;
}
}
}
function move(event) {
if (flag) {
var clientX = event.touches ? event.touches[0].clientX : event.clientX; // 要同时适配mousemove和touchmove事件
var length = clientX - position.oriX;
if (length > position.maxRight) {
length = position.maxRight;
} else if (length < -position.maxLeft) {
length = -position.maxLeft;
}
var progressBarBg =document.querySelectorAll(".progressBarBg")[index];// document.getElementById('progressBarBg' + index);
var pgsWidth = parseFloat(window.getComputedStyle(progressBarBg, null).width.replace('px', ''));
var rate = (position.oriOffestLeft + length) / pgsWidth;
audio.currentTime = audio.duration * rate;
updateProgress(audio, index);
}
}
function end() {
flag = false;
}
}
/**
* 更新进度条与当前播放时间
* @param {object} audio - audio对象
* @param {number} index 索引,表示第几个音频(从0开始)
*/
function updateProgress(audio, index) {
var value = audio.currentTime / audio.duration;
if(value==1){
audio.currentTime=0;
audio.pause();
document.querySelectorAll(".playicon")[0].src = '/testUeditor/ueditor/themes/default/images/play.png';
}
//document.getElementById('progressBar' + index)
document.querySelectorAll(".progressBar")[index].style.width = value * 100 + '%';
//document.getElementById('progressDot' + index)
document.querySelectorAll(".progressDot")[index].style.left = value * 100 + '%';
//document.getElementById('audioCurTime' + index)
document.querySelectorAll(".audioCurTime")[index].innerText = transTime(audio.currentTime);
}
/**
* 播放完成时把进度调回开始的位置
* @param {number} index 索引,表示第几个音频(从0开始)
*/
function audioEnded(index) {
document.getElementById('progressBar' + index).style.width = 0;
document.getElementById('progressDot' + index).style.left = 0;
document.getElementById('audioCurTime' + index).innerText = transTime(0);
document.getElementById('audioPlayer' + index).src = './image/play.png';
// 自动播放下一个音频
var audios = document.getElementsByTagName('audio');
var nextIndex = (index + 1) >= audios.length ? 0 : index + 1;
audios[nextIndex].play();
document.getElementById('audioPlayer' + nextIndex).src = '/testUeditor/ueditor/themes/default/images/pause.png';
}
/**
* 音频播放时间换算
* @param {number} value - 音频当前播放时间,单位秒
*/
function transTime(value) {
var time = "";
var h = parseInt(value / 3600);
value %= 3600;
var m = parseInt(value / 60);
var s = parseInt(value % 60);
if (h > 0) {
time = formatTime(h + ":" + m + ":" + s);
} else {
time = formatTime(m + ":" + s);
}
return time;
}
/**
* 格式化时间显示,补零对齐
* eg:2:4 --> 02:04
* @param {string} value - 形如 h:m:s 的字符串
*/
function formatTime(value) {
var time = "";
var s = value.split(':');
var i = 0;
for (; i < s.length - 1; i++) {
time += s[i].length == 1 ? ("0" + s[i]) : s[i];
time += ":";
}
time += s[i].length == 1 ? ("0" + s[i]) : s[i];
return time;
}
</script>
- css代码
.audio-wrapper {
background-color: #fcfcfc;
margin: 0px auto;
max-width: 670px;
height: 70px;
border-radius: 8px;
border: 1px solid #e0e0e0;
box-shadow: 0 0 5px #ccc;
}
.audio-left {
float: left;
text-align: center;
width: 18%;
height: 100%;
}
.audio-left img {
width: 40px;
position: relative;
top: 15px;
margin: 0;
border-radius: 50%;;
display: initial; /* 解除与app的样式冲突 */
cursor: pointer;
-webkit-tap-highlight-color:transparent;
}
.audio-right {
margin-right: 2%;
float: right;
width: 80%;
height: 100%;
}
.audio-right p {
font-size: 15px;
height: 35%;
margin: 8px 0;
/* 歌曲名称只显示在一行,超出部分显示为省略号 */
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
max-width: 243px; /* 要适配小屏幕手机,所以最大宽度先设小一点,后面js根据屏幕大小重新设置 */
}
.progress-bar-bg {
background-color: #d9d9d9;
position: relative;
height: 2px;
cursor: pointer;
}
.progress-bar {
background-color: #649fec;
width: 0;
height: 2px;
}
.progress-bar-bg span {
content: " ";
width: 10px;
height: 10px;
border-radius: 50%;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
background-color: #3e87e8;
position: absolute;
left: 0;
top: 50%;
margin-top: -5px;
margin-left: -5px;
cursor: pointer;
}
.audio-time {
overflow: hidden;
margin-top: -1px;
}
.audio-length-total {
float: right;
font-size: 12px;
}
.audio-length-current {
float: left;
font-size: 12px;
}
.progressDot{
top: -1px !important;
}