php怎么做一个音乐播放器,实现一个HTML5音乐播放器的实例

确立项目结构,开始编码:

因为使用webpack,所以我们直接将css打包至js内,以便作为插件供用户使用:

require('./skPlayer.scss');

抽离公共方法,在播放器中有很多可能需要抽离的公共方法如:点击播放进度条和音量进度条时需要计算鼠标距离进度条左端的距离以进行进度跳转,时间从duratin中获取到的以秒为单位的时间转换成标准时间格式等等:

1211a3b82ed2c3b3f2b8c22e37fb3ec7.gif

2d32a294060a5ac4ecde51ed13943744.gif

const Util = {

leftDistance: (el) => {

let left = el.offsetLeft;

let scrollLeft;while (el.offsetParent) {

el = el.offsetParent;

left += el.offsetLeft;

}

scrollLeft = document.body.scrollLeft + document.documentElement.scrollLeft;return left - scrollLeft;

},

timeFormat: (time) => {

let tempMin = parseInt(time / 60);

let tempSec = parseInt(time % 60);

let curMin = tempMin < 10 ? ('0' + tempMin) : tempMin;

let curSec = tempSec < 10 ? ('0' + tempSec) : tempSec;return curMin + ':' + curSec;

},

percentFormat: (percent) => {return (percent * 100).toFixed(2) + '%';

},

ajax: (option) => {

option.beforeSend && option.beforeSend();

let xhr = new XMLHttpRequest();

xhr.onreadystatechange = () => {if(xhr.readyState === 4){if(xhr.status >= 200 && xhr.status < 300){

option.success && option.success(xhr.responseText);

}else{

option.fail && option.fail(xhr.status);

}

}

};

xhr.open('GET',option.url);

xhr.send(null);

}

};View Code

由于设计之初,考虑到播放器的独特性,设计为只能存在一个实例,设置了一个全局变量以判断当前是否存在实例:

let instance = false;

在使用ES6的情况下,我们将主逻辑放在构造函数内部,将通用性强和API放在公共函数内部:

797ce1d326bc25420e05c2a398d9c459.gif

d7df31de39c730c0256f3aff83f67878.gif

class skPlayer {

constructor(option){

}

template(){

}

init(){

}

bind(){

}

prev(){

}

next(){

}

switchMusic(index){

}

play(){

}

pause(){

}

toggle(){

}

toggleList(){

}

toggleMute(){

}

switchMode(){

}

destroy(){

}

}View Code

实例判断,如果存在返回无原型的空对象,因为ES6构造函数内默认返回带原型的实例:

if(instance){

console.error('SKPlayer只能存在一个实例!');return Object.create(null);

}else{

instance = true;

}

初始化配置项,默认配置与用户配置合并:

const defaultOption = {

...

};this.option = Object.assign({},defaultOption,option);

将常用属性绑定在实例上:

this.root = this.option.element;this.type = this.option.music.type;this.music = this.option.music.source;this.isMobile = /mobile/i.test(window.navigator.userAgent);

一些公共的API内部this指向在默认情况下指向实例,但是为了减少代码量,将操作界面上的功能与API调用一套代码,在绑定事件的时候this指向会改变,所以通过bind的方式绑定this,当然也可以在绑定事件的时候使用箭头函数:

this.toggle = this.toggle.bind(this);this.toggleList = this.toggleList.bind(this);this.toggleMute = this.toggleMute.bind(this);this.switchMode = this.switchMode.bind(this);

接下来,我们就使用ES6字符串模板开始生成HTML,插入到页面中:

this.root.innerHTML = this.template();

接下来初始化,初始化过程中将常用DOM节点绑定,初始化配置项,初始化操作界面:

this.init();

635962e1554f6611175aeac4fb33b7b6.gif

e75df6b4cedd60709090a5663dabaa69.gif

init(){this.dom = {

cover: this.root.querySelector('.skPlayer-cover'),

playbutton: this.root.querySelector('.skPlayer-play-btn'),

name: this.root.querySelector('.skPlayer-name'),

author: this.root.querySelector('.skPlayer-author'),

timeline_total: this.root.querySelector('.skPlayer-percent'),

timeline_loaded: this.root.querySelector('.skPlayer-line-loading'),

timeline_played: this.root.querySelector('.skPlayer-percent .skPlayer-line'),

timetext_total: this.root.querySelector('.skPlayer-total'),

timetext_played: this.root.querySelector('.skPlayer-cur'),

volumebutton: this.root.querySelector('.skPlayer-icon'),

volumeline_total: this.root.querySelector('.skPlayer-volume .skPlayer-percent'),

volumeline_value: this.root.querySelector('.skPlayer-volume .skPlayer-line'),

switchbutton: this.root.querySelector('.skPlayer-list-switch'),

modebutton: this.root.querySelector('.skPlayer-mode'),

musiclist: this.root.querySelector('.skPlayer-list'),

musicitem: this.root.querySelectorAll('.skPlayer-list li')

};this.audio = this.root.querySelector('.skPlayer-source');if(this.option.listshow){this.root.className = 'skPlayer-list-on';

}if(this.option.mode === 'singleloop'){this.audio.loop = true;

}this.dom.musicitem[0].className = 'skPlayer-curMusic';

}View Code

事件绑定,主要绑定audio的事件以及操作面板的事件:

this.bind();

9f714f42b386a0b407e7faec38ce5734.gif

4d82a2a88ec7cf2353d94c27cb0038aa.gif

bind(){this.updateLine = () => {

let percent = this.audio.buffered.length ? (this.audio.buffered.end(this.audio.buffered.length - 1) / this.audio.duration) : 0;this.dom.timeline_loaded.style.width = Util.percentFormat(percent);

};// this.audio.addEventListener('load', (e) => {// if(this.option.autoplay && this.isMobile){// this.play();// }// });this.audio.addEventListener('durationchange', (e) => {this.dom.timetext_total.innerHTML = Util.timeFormat(this.audio.duration);this.updateLine();

});this.audio.addEventListener('progress', (e) => {this.updateLine();

});this.audio.addEventListener('canplay', (e) => {if(this.option.autoplay && !this.isMobile){this.play();

}

});this.audio.addEventListener('timeupdate', (e) => {

let percent = this.audio.currentTime / this.audio.duration;this.dom.timeline_played.style.width = Util.percentFormat(percent);this.dom.timetext_played.innerHTML = Util.timeFormat(this.audio.currentTime);

});//this.audio.addEventListener('seeked', (e) => {// this.play();//});this.audio.addEventListener('ended', (e) => {this.next();

});this.dom.playbutton.addEventListener('click', this.toggle);this.dom.switchbutton.addEventListener('click', this.toggleList);if(!this.isMobile){this.dom.volumebutton.addEventListener('click', this.toggleMute);

}this.dom.modebutton.addEventListener('click', this.switchMode);this.dom.musiclist.addEventListener('click', (e) => {

let target,index,curIndex;if(e.target.tagName.toUpperCase() === 'LI'){

target = e.target;

}else{

target = e.target.parentElement;

}

index = parseInt(target.getAttribute('data-index'));

curIndex = parseInt(this.dom.musiclist.querySelector('.skPlayer-curMusic').getAttribute('data-index'));if(index === curIndex){this.play();

}else{this.switchMusic(index + 1);

}

});this.dom.timeline_total.addEventListener('click', (event) => {

let e = event || window.event;

let percent = (e.clientX - Util.leftDistance(this.dom.timeline_total)) / this.dom.timeline_total.clientWidth;if(!isNaN(this.audio.duration)){this.dom.timeline_played.style.width = Util.percentFormat(percent);this.dom.timetext_played.innerHTML = Util.timeFormat(percent * this.audio.duration);this.audio.currentTime = percent * this.audio.duration;

}

});if(!this.isMobile){this.dom.volumeline_total.addEventListener('click', (event) => {

let e = event || window.event;

let percent = (e.clientX - Util.leftDistance(this.dom.volumeline_total)) / this.dom.volumeline_total.clientWidth;this.dom.volumeline_value.style.width = Util.percentFormat(percent);this.audio.volume = percent;if(this.audio.muted){this.toggleMute();

}

});

}

}View Code

至此,核心代码基本完成,接下来就是自己根据需要完成API部分。

最后我们暴露模块:

module.exports = skPlayer;

一个HTML5音乐播放器就大功告成了 ~ !

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面是一个简单的音乐播放器的Python代码示例: ```python import os import pygame # 初始化Pygame pygame.init() # 播放器类 class MusicPlayer: def __init__(self): # 播放器状态 self.playing = False # 歌曲列表 self.songs = [] # 当前歌曲索引 self.current_song_index = 0 # 创建Pygame音乐播放器 pygame.mixer.init() # 添加歌曲 def add_song(self, file_path): # 获取文件名 file_name = os.path.basename(file_path) # 添加到歌曲列表 self.songs.append({'file_path': file_path, 'file_name': file_name}) # 播放歌曲 def play_song(self, index): # 加载歌曲文件 file_path = self.songs[index]['file_path'] pygame.mixer.music.load(file_path) # 播放歌曲 pygame.mixer.music.play() # 更新播放器状态 self.playing = True self.current_song_index = index # 暂停歌曲 def pause_song(self): pygame.mixer.music.pause() self.playing = False # 继续播放歌曲 def unpause_song(self): pygame.mixer.music.unpause() self.playing = True # 停止歌曲 def stop_song(self): pygame.mixer.music.stop() self.playing = False # 上一首歌曲 def prev_song(self): if self.current_song_index > 0: self.stop_song() self.play_song(self.current_song_index - 1) # 下一首歌曲 def next_song(self): if self.current_song_index < len(self.songs) - 1: self.stop_song() self.play_song(self.current_song_index + 1) # 测试代码 if __name__ == '__main__': # 创建播放实例 player = MusicPlayer() # 添加歌曲 player.add_song('song1.mp3') player.add_song('song2.mp3') player.add_song('song3.mp3') # 播放歌曲 player.play_song(0) # 暂停歌曲 player.pause_song() # 继续播放歌曲 player.unpause_song() # 上一首歌曲 player.prev_song() # 下一首歌曲 player.next_song() ``` 以上代码仅为演示用途,实际应用中需要对界面、播放列表、播放器状态等方面进行更加细致的设计和实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值