马黑黑 发表于 2025-2-21 12:24

集成快捷键的单曲音频播放器

<h3>效果</h3>
<div id="showRes" style="margin: 30px; text-align: center;"></div>
<h3>代码</h3>
<div id="hEdiv"><pre id="hEpre">
&lt;style&gt;
        #mboard { width: 420px; height: 40px; background: beige; border-radius: 8px; box-shadow: 2px 2px 4px rgba(0,0,0,.5); display: flex; justify-content: center; align-items: center; gap: 8px; position: relative; }
        #mboard img { width: 26px; cursor: pointer; }
        #mboard img:hover { filter: drop-shadow(1px 1px 1px rgba(0,0,0,.5)); }
        #tMsg1, #tMsg2 { width: 45px; font-size: 13px; text-align: center; }
        #volwrap { position: absolute; width: 60px; height: 40px; right: 45px; display: grid; place-items: center; background: none; }
        #volwrap:hover #volume { display: inline; }
        #btnMute:hover ~ #volwrap &gt; #volume { display: inline; }
        #volume { position: absolute; width: 50px; height: 4px; opacity: .75; display: none; }
        #prog { --track: gray; --prog: red; --prg: 0%; width: 200px; height: 20px; cursor: pointer; background: linear-gradient(to right, var(--prog) var(--prg), var(--track) 0) no-repeat 0% 50%/100% 2px; }
&lt;/style&gt;

&lt;div id="mboard"&gt;
        &lt;img id="btnPlay" src="https://638183.freep.cn/638183/web/icon/play.svg" title="播放/暂停(Alt+X)" alt="" /&gt;
        &lt;span id="tMsg1"&gt;00:00&lt;/span&gt;
        &lt;span id="prog"&gt;&lt;/span&gt;
        &lt;span id="tMsg2"&gt;00:00&lt;/span&gt;
        &lt;img id="btnMute" src="https://638183.freep.cn/638183/web/icon/unmuted.svg" title="静音 (Alt+J)" alt="" /&gt;
        &lt;div id="volwrap"&gt;&lt;input id="volume" type="range" min="0" max="1" step="0.1" value="1" /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&lt;audio id="aud" src="https://music.163.com/song/media/outer/url?id=1321297488" autoplay loop&gt;&lt;/audio&gt;&lt;/p&gt;

&lt;script&gt;
       
var lastVolume = 1, muted = false;

var imgAr = [
        'https://638183.freep.cn/638183/web/icon/play.svg',
        'https://638183.freep.cn/638183/web/icon/pause.svg',
        'https://638183.freep.cn/638183/web/icon/unmuted.svg',
        'https://638183.freep.cn/638183/web/icon/muted.svg',
];

var setVolume = (val) =&gt; Math.min(1, Math.max(0, val));

var setMute = () =&gt; {
        if(lastVolume === 0) return;
        muted = !muted;
        muted ? (aud.volume = 0, btnMute.src = imgAr) : (aud.volume = lastVolume, btnMute.src = imgAr);
};

var s2m = (seconds) =&gt; {
    const secs = Math.floor(seconds || 0);
    return `${String(secs/60|0).padStart(2,'0')}:${String(secs%60).padStart(2,'0')}`;
};

var mState = () =&gt; {
        btnPlay.src = aud.paused ? imgAr : imgAr;
        btnPlay.title = (aud.paused ? '播放' : '暂停') + ' (Alt+X)';
};

document.addEventListener('keydown', e =&gt; {
        if(!e.altKey) return;
        switch (e.keyCode) {
                case 88:
                        btnPlay.click();
                        break;
                case 74:
                        setMute();
                        break;
                case 187: case 107:
                        aud.volume = setVolume(aud.volume + 0.1);
                        lastVolume = aud.volume;
                        break;
                case 189: case 109:
                        aud.volume = setVolume(aud.volume - 0.1);
                        lastVolume = aud.volume;
                        break;
                default:
                        return;
        }
});

aud.onplaying = aud.onpause = () =&gt; mState();

aud.ontimeupdate = () =&gt; {
        prog.style.setProperty('--prg', aud.currentTime/aud.duration*100 +'%');
        tMsg1.innerText = s2m(aud.currentTime);
        tMsg2.innerText = s2m(aud.duration);
};

aud.onvolumechange = () =&gt; {
        btnMute.src = aud.volume === 0 ? imgAr : imgAr;
        volume.value = aud.volume;
}

btnPlay.onclick = () =&gt; aud.paused ? aud.play() : aud.pause();
btnMute.onclick = () =&gt; setMute();
volume.onchange = () =&gt; aud.volume = lastVolume = volume.value;
prog.onclick = (e) =&gt; aud.currentTime = e.offsetX * aud.duration / prog.offsetWidth;
prog.onmousemove = (e) =&gt; prog.title = s2m(e.offsetX * aud.duration / prog.offsetWidth);
volwrap.onmouseover = () =&gt; volwrap.title = '音量 : ' + volume.value + ' (Alt++/-)'

&lt;/script&gt;
</pre></div>

<script type="module">
import hlight from 'https://638183.freep.cn/638183/web/mod/helight.js';
hlight.hl(hEdiv, hEpre);

var runCodes = (str,target) => {
        let reg = /(<script(.*?)>)(.|\n)*?(<\/script>)/g;
        let js_str, html_str;
        if(str.match(reg) !== null) {
                js_str = str.match(reg);
                html_str = str.replace(js_str, '').trim();
                js_str = js_str.replace(/<[\/]{0,1}script[^>]*>/g,'').trim();
        } else {
                js_str = '';
                html_str = str.trim();
        }
        target.innerHTML = html_str;
        let myfunc = new Function(js_str);
        myfunc();
};

runCodes(hEpre.innerText, showRes);
</script>

马黑黑 发表于 2025-2-21 12:31

界面可以:

一、修改 #mboard 相关属性加以修饰。若主元素宽度改变,应相应修改 #prog 的 width 属性值;

二、按钮图片可以更改,若更改,一是相应改变两个 img 的 src 属性值,二是按顺序改变 js 代码中的 imgAr 存放的图片地址;

三、音量滑杆使用的是 input type 做成,不太好看,可以考虑:一是使用CSS美化,代码量相对较大、兼容性不太保证,二是使用 HTML 标签仿进度条的做法,js 需要多加点代码。

杨帆 发表于 2025-2-21 13:32

创新之作,讲解精彩,谢谢老师无私分享{:4_191:}

梦江南 发表于 2025-2-21 15:43

谢谢老师辛苦!{:4_190:}

红影 发表于 2025-2-21 16:45

黑黑用这样的播放框把前面讲的调整都加进去了呢,真好,可以自己去点播放框里的标识,不用自己去找键盘上的对应键了{:4_199:}

红影 发表于 2025-2-21 16:49

音量调整变成竖直的,放在静音符号上面多好,这样就不会对播放时间有遮挡了{:4_173:}

红影 发表于 2025-2-21 16:51

马黑黑 发表于 2025-2-21 12:31
界面可以:

一、修改 #mboard 相关属性加以修饰。若主元素宽度改变,应相应修改 #prog 的 width 属性值 ...

这滑动杆挺好的,非常明确呢{:4_187:}

马黑黑 发表于 2025-2-21 18:00

红影 发表于 2025-2-21 16:51
这滑动杆挺好的,非常明确呢

这是大致模仿了仿 audio 界面上的样式

马黑黑 发表于 2025-2-21 18:02

红影 发表于 2025-2-21 16:49
音量调整变成竖直的,放在静音符号上面多好,这样就不会对播放时间有遮挡了

这个无关紧要的,调整完了它就会消失。这个做法是原生 audio 标签界面在这个细节上的处理方式,我觉得还是挺好的,就大致模仿了一下。竖着的太突兀。

马黑黑 发表于 2025-2-21 18:05

红影 发表于 2025-2-21 16:45
黑黑用这样的播放框把前面讲的调整都加进去了呢,真好,可以自己去点播放框里的标识,不用自己去找键盘上的 ...

快捷键不是每个人都会习惯,不过快捷键是非常有意义的,这个就是尝试加入了快捷键,同时一改过去没有静音、音量调节的省事做法,都加上了。如果针对多曲播放,还应有前一首、下一首和单曲循环、多曲循环等功能。

马黑黑 发表于 2025-2-21 18:05

杨帆 发表于 2025-2-21 13:32
创新之作,讲解精彩,谢谢老师无私分享

{:4_191:}

马黑黑 发表于 2025-2-21 18:06

梦江南 发表于 2025-2-21 15:43
谢谢老师辛苦!

感谢支持

花飞飞 发表于 2025-2-21 18:43

这一版四键控制更完美啦,可以各种自定义~~
目前看篇幅跟一个贴子差不多。
这以后是不是都会封装起来的呢。。{:4_173:}

花飞飞 发表于 2025-2-21 18:46

这播放器比较经典,看代码真是精工细作,一点点描画出来。。。功能还比之前的更加齐全。。
白老师真帅。。{:4_173:}

马黑黑 发表于 2025-2-21 19:24

花飞飞 发表于 2025-2-21 18:46
这播放器比较经典,看代码真是精工细作,一点点描画出来。。。功能还比之前的更加齐全。。
白老师真帅。。 ...

其实也就是加了快捷键、静音和音量控制

马黑黑 发表于 2025-2-21 19:25

花飞飞 发表于 2025-2-21 18:43
这一版四键控制更完美啦,可以各种自定义~~
目前看篇幅跟一个贴子差不多。
这以后是不是都会封装起来的呢 ...

封装与否还看它成熟里木有,以及有木有必要

亚伦影音工作室 发表于 2025-2-21 21:58

即学习了电脑键盘的作用,又学习代码受益匪浅,向老师学习!

马黑黑 发表于 2025-2-21 22:27

亚伦影音工作室 发表于 2025-2-21 21:58
即学习了电脑键盘的作用,又学习代码受益匪浅,向老师学习!

{:4_191:}

红影 发表于 2025-2-21 22:29

马黑黑 发表于 2025-2-21 18:00
这是大致模仿了仿 audio 界面上的样式

这个播放框的功能十分齐全,厉害了{:4_187:}{:4_199:}

红影 发表于 2025-2-21 22:30

马黑黑 发表于 2025-2-21 18:02
这个无关紧要的,调整完了它就会消失。这个做法是原生 audio 标签界面在这个细节上的处理方式,我觉得还 ...

也是,用完就消失了,而且还设置了透明度,倒也无妨{:4_204:}
页: [1] 2 3 4 5 6
查看完整版本: 集成快捷键的单曲音频播放器