HTML5   发布时间:2022-04-25  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了node-webkit-MusicBox 基于nwjs ,html5 ,制作的音乐盒子大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

太长?单击目录直接去看最终效果,在最下边



文件下载地址:http://download.csdn.net/detail/u013934914/9180053

1.思路(简单设想)

index.html 实现 对页面显示,并调用绑定ymusic.js中的方法
需要:
    绘出基本页面样式
    实现窗口的放大缩小关闭
    实现调用播放器对象,并实现对事件的监听,通过监听改变文字或样式等

ymusic.js 实现对播放器的再次封装;(为了方便控制):
需要:
    重写html5的事件
    加入播放列表功能
    加入歌词功能(正在实现...)
    加入播放模式


2.index.html的实现

这里只是一部分概括的js代码,具体在https://github.com/ymma/node-webkit-MusicBox/blob/master/music/index.html

<script> var gui = require("nw.gui"); mwin = gui.Window.get(); $(function(){ //这里绑定window的一些事件,比如关闭和缩小,可扩展 var windBarEvent = function(){ $('#win_btn_close').click(function(){ }); $('#win_btn_min').click(function(){ }); } windBarEvent(); music(); }); //之所以不写成类的形式,因为数据不统一,抽象成类太麻烦,太杂 function @H_597_26@music(){ //一些全局变量 var musicList = [],//播放列表的数据 playListNow,//正在播放的列表的索引 media; //播放器对象 //一些dom节点 var domPgNow = $('#pgNow'),domBody = $('.body'),//主要是为了设置背景图片 domUlCList = $('#ulCList'),//所有列表 domUlMList = $('#ulMList'),//当前音乐播放列表 ... //包括播放,暂停,上一首,下一首等事件 var barEvent = function(){ },//创建播放器,并绑定修改样式的一些方法 createMedia = function(){ },//给音乐列表赋予数据 loadListData = function(){ },//加载播放列表的一些方法 loadList = function(){ var loadPlayHtml = function(num){ //加载第num个列表中的音乐列表,正在播放的列表的html },loadListHtml = function(){ //加载列表[比如认列表,手机列表,xxx] } loadListHtml(); loadPlayHtml(playListNow); //加载第n个列表 }//加载歌词的一些方法 loadLrc = function(arr){ } loadListData(); //1,加载列表数据 createMedia(); //2,加载播放器对象 barEvent(); //3,加载基本事件 loadList(); //4,加载列表的HTML,并绑定事件 } </script>


3.ymusic.js

文件在这https://github.com/ymma/node-webkit-MusicBox/blob/master/music/public/js/ymusic.js

var fs = require("fs");
var iconv = require('iconv-lite'); 
var Utils = {
    calctime : function(timE){
        var hour,minute,second,timer = '';
        hour = String(parseInt(time/3600,10));
        minute = String(parseInt((time % 3600) / 60,10));
        second = String(parseInt(time % 60,10));
        if(hour != '0'){
            if(hour.length == 1) hour = '0' + hour;
            timer += (hour + ':');
        }
        if(minute.length == 1) minute = '0' + minute;
        timer += (minute + ':');
        if(second.length == 1) second = '0' + second;
        timer += second;
        return timer;
    },/** * @L_675_31@随机数,在min和max之间,且不能为not */
    getRandom : function(notindex,min,maX){
        var temp=[];
        for(var i=min;i<=max;i++){ if(i != notindeX){ temp.push(i); } }
        return temp[parseInt(Math.random() * temp.length)];
    }
}

function ymedia(arg){
    this.arg = arg;
    this.init();
}
ymedia.prototype = {
    /** * 基本配置 */
    config : {
        musicMode : ['单曲播放','单曲循环','顺序播放','循环播放','随机播放']
    },/** * 初始化全局变量 */
    init : function(){
        this.playList = [];    //音乐列表
        this.currentMusic = 0;  //第一首
        this.currentMusicInfo = null;
        this.playmode = 3;      //列表循环播放
        this.volumeNum = 0;   //音量为0.5
        this.recordList = [];   //音乐播放记录
        this.audio = document.createElement('audio');   //播放器对象
        this.rewriteEvent();
        this.prevNum = 0;   //仅随机播放时有效,上prevNum首
    },/** * 将指定路径的歌词转换成数组 */
    parseLyric : function(lrC){
        if(!lrC) return '';
        var data = fs.readFileSync('public/lrc/' + lrc);
        //这里应该做读取文件出错的处理
        data = iconv.decode(data,'gbk');//把数组转换为gbk中文
        var lyric = data.split('\r\n'),//按行分割
            lrc = new Array(); //新建一个数组存放最后结果
        for(var i=0,len=lyric.length,d,t,dt,_t,pt;i<len;i++) {
            d = lyric[i].@H_836_30@match(/\[\d{2}:\d{2}((\.|\:)\d{2})\]/g);  //正则匹配播放时间
            if( d == null) conTinue;    //过滤掉空行等非歌词正文部分
            t = lyric[i].split(d); //以时间为分割点分割每行歌词,数组最后一个为歌词正文
            dt = String(d).split(':');  //[01:14.48]
            _t = parseInt(dt[0].split('[')[1])*60 + parseFloat(dt[1].split(']')[0]);
            _t = _t.toFixed(2); //保留两位小数
            //判断是否为翻译,
            //特点:一般翻译的时间和上一行的时间相同,则被认定为翻译
            //一般歌词的形式为:比如:
            // [00:04.53]I have nobody
            // [00:07.13]我一无
            // [00:07.13]for my owwnnn
            // [00:10.35]所有 
            if(pt == d){    //相同的话,将数据保存当上个数组中
                pt = lrc.length;
                _t = lrc[pt-1]; //@L_675_31@最后一个
                lrc[pt-1] = [_t[0],t[1]];  //将最后一个中文去掉,将英文赋给第二个元素
                lrc[pt-2][2] = _t[1];   //将最后一个中文赋给倒数第二个的第三个元素
            }else{lrc.push([_t,t[1]]); }
            pt = d+'';
        }
        return lrc;
    },/** * 根据time从arr中匹配到所在的行 * start : 开始遍历的索引 * arr 为歌词的数据:比如 [ [ '0.40','Lonely\r','寂寞,\r' ],[ '1.86','I\'m Mr Lonely\r','我是寂寞先生 \r' ]] * time 为要确定的时间:比如 0.40 或者 1,如果时间不匹配,则返回临近时间的小值 * return : [ '0.40','寂寞,\r' ] 的数组索引为:0 * 使用条件,数据必须存在,数据的数组[0]必须为时间,time必须为秒形式 */
    getLrcByTime : function(arr,time,start,end){
        if(!arr) return -1;
        if(!start || start == -1) start = 0;
        time = parseFloat(timE);
        var rindex = 0;
        for(var i=start;i<end;i++){
            if(time <= parseFloat(arr[i][0])){
                if((i-1)<start) rindex = -1 ;   //应该@L_675_31@上一个
                else rindex = i-1 ;
                break;
            }
        }
        return rindex;
    },/** * 重写播放器的监听事件 */
    rewriteEvent : function(){
        var audioDom = this.audio,arg = this.arg,_intPlayingTime,calctime = Utils.calctime; 

        //重写播放时的方法...
        var _onplaying = arg.onplaying;
        if(typeof(_onplaying) == 'function'){
            //当媒介已开始播放时运行的脚本。
            audioDom.onplaying = function(){
                var self = this,duration = this.audio.duration;    //总时长
                if(_intPlayingTimE) clearInterval(_intPlayingTimE);
                _intPlayingTime = seTinterval(function(){   //循环监听
                    if(self.audio.paused == true){
                        clearInterval(_intPlayingTimE);         //取消循环
                        return;
                    }
                    var curtime = self.audio.currentTime;   //当前时间
                    _onplaying((curtime/duration).toFixed(6),calctime(curtimE),curtime.toFixed(2));
                    if(curtime == duration) clearInterval(_intPlayingTimE);
                },500);//每隔0.5秒,执行
                if(typeof(arg.onplay) == 'function'){arg.onplay();}
            }.bind(this);
        }

        //当文件就绪可以开始播放时运行的脚本(缓冲已足够开始时)。
        audioDom.oncanplay = function(){   
            var duration = this.audio.duration,musicInfo = this.currentMusicInfo;
            musicInfo.duration = duration;
            musicInfo.time = calctime(duration);
            if(typeof(this.arg.onstartplay) == 'function'){
                this.arg.onstartplay(musicInfo); 
            }
        }.bind(this);

        //当目前的播放列表已结束时
        audioDom.onended = function(){
            this.playByIndex(this.getNexTindexBymodel());
        }.bind(this);
        //当媒介被用户或程序暂停时运行的脚本。
        audioDom.onpause = arg.onpause || null; 
    },/** * 得到播放器的状态 * 0:正在播放,1:已暂停,[可扩展] */
    getMediaStatus : function(){
        return this.audio.paused == false ? 0 : 1;
    },/** * 设置音量 */
    setVolume : function(v){
        if(!v) return;
        if(v < 0) v = 0;
        if(v > 10) v = 10;
        v = v/10;
        this.audio.volume = v;
    },/** * 根据百分比设置当前播放进度 */
    setCurrentTime : function(percent){
        if(!this.currentMusicInfo.duration) return;
        this.audio.currentTime = this.currentMusicInfo.duration * percent;
    },/** * 根据播放模式和当前音乐的索引,获得下一首的音乐索引 */
    getNexTindexBymodel : function() {
        var playmodel = parseInt(this.playmodE),currentNum = this.currentMusic,size = this.playList.length - 1,nextMusicNum;
        if(playmodel == 0){ //'单曲播放'
            nextMusicNum = -1;
        }else if(playmodel == 1){ //'单曲循环'
            nextMusicNum = currentNum;
        }else if(playmodel == 2){ //'顺序播放'
            nextMusicNum = (currentNum+1) > size ? -1 : currentNum+1;//超过最后一首,则不播放
        }else if(playmodel == 3){ //'循环播放'
            nextMusicNum = (currentNum+1) > size ? 0 : currentNum+1;//超过最后一首,则播放第一首
        }else if(playmodel == 4){ //'随机播放'
            nextMusicNum = Utils.getRandom(currentNum,0,sizE);
        }
        // console.log('当前模式为:%s\t共有%d首歌曲',this.config.musicMode[playmodel],size+1);
        // console.log('正在播放第'+currentNum+'首');
        // console.log('将要播放第'+nextMusicNum+'首');
        return nextMusicNum;
    },/** * 根据操作数量播放音乐:比如num=1,则播放下一首,-1:播放上一首 */
    playByNum : function(num){
        var playList = this.playList,size = playList.length - 1,curNum = this.currentMusic,nextNum = 0;
        if(num == 1){
            nextNum = this.getNexTindexBymodel();
        }else if(num == -1){
            var recordList = this.recordList,playmodel = parseInt(this.playmodE),rsize = recordList.length;
            if(playmodel == 0){ //'单曲播放'
                nextNum = -1;
            }else if(playmodel == 1){ //'单曲循环'
                nextNum = curNum;
            }else if(playmodel == 2 ){ //'顺序播放'
                nextNum = (curNum-1) < 0 ? -1 : curNum-1;//超过第一首,则不播放
            }else if(playmodel == 3 ){ //'循环播放' 
                nextNum = (curNum-1) < 0 ? size : curNum-1;//超过第一首,则播放最后一首歌
            }else if(playmodel == 4){ //'随机播放' -> 从播放记录中取得
                console.log(recordList);
                if(rsize <= 1){ //仅播放过一首歌时,
                    nextNum = -1;
                } else {
                    //这里有错误
                    var _temp = rsize - 2 - this.prevNum;   //如果是随机播放,则上一首,应该播放列表 - 单击上一首的次数 - 1(长度转成数) - 1(最后一条记录的上一条记录)
                    if(_temp < 0) _temp = 0;
                    nextNum = recordList[_temp].index;
                    this.playByIndex(nextNum,true,false); //不添加到播放记录中
                    this.prevNum += 1;
                    return;
                }
            }
        }
        this.playByIndex(nextNum);
    },/** * 根据音乐索引播放音乐,比如index=2,就是播放本列表的第二首音乐 * 这里触发刚播放音乐时的事件 * isplay : 是否播放[认为是] * isrecord : 是否添加到播放记录列表[认为是] */
    playByIndex : function(index,isplay,isrecord){
        var playList = this.playList;
        if(index < 0 || index >= playList.length){
            this.stop();
            return;
        }
        var musicInfo = this.playList[index];
        //得到歌词,并添加到音乐信息中
        try{
            // 0 = HAVE_NOTHING - 没有关于音频/视频是否就绪的信息
            // 1 = HAVE_MetaDATA - 关于音频/视频就绪的元数据
            // 2 = HAVE_CURRENT_DATA - 关于当前播放位置的数据是可用的,但没有足够的数据来播放下一帧/毫秒
            // 3 = HAVE_FUTURE_DATA - 当前及至少下一帧的数据是可用的
            // 4 = HAVE_ENOUGH_DATA - 可用数据足以开始播放
            // console.log(audio.readyStatE);
            this.audio.src = musicInfo.source.mp3; 
        }catch (E){
            console.log('try catch playByIndex:')
            console.log(E);
            console.log('\n');
        }
        this.currentMusic = index;
        musicInfo.lrcData = this.parseLyric(musicInfo.lrc);
        this.currentMusicInfo = musicInfo;
        if(typeof(this.arg.onswitch) == 'function'){
            this.arg.onswitch(indeX); 
        }
        if(isplay == false) return;
        this.play();
        if(isrecord == false) return;
        this.recordList.push({index:index,info:musicInfo});
    },/** * 播放音乐 * */
    play : function(){
        this.audio.play();
    },/** * 暂停 */
    pause : function(){
        this.audio.pause();
    },/** * 暂停播放,并重置界面,重置进度 */
    stop : function(){
        this.pause();   //暂停播放
        if(typeof(this.arg.onstop) == 'function'){
            this.arg.onstop();
        }
        this.audio.currentTime = 0;
    },/** * 重置播放列表 * */
    resetPlayList : function(playList){
        this.playList = playList;
        this.audio.volume = this.volumeNum;
        this.audio.muted = false;
        this.playByIndex(0,false); //播放第一首歌曲
    }
};


4.最终效果

其实注释掉index.html页面里的require这一段,仅执行music()这个方法可以直接在谷歌浏览器中看效果

node-webkit-MusicBox 基于nwjs ,html5 ,制作的音乐盒子

项目源码:https://github.com/ymma/node-webkit-MusicBox

大佬总结

以上是大佬教程为你收集整理的node-webkit-MusicBox 基于nwjs ,html5 ,制作的音乐盒子全部内容,希望文章能够帮你解决node-webkit-MusicBox 基于nwjs ,html5 ,制作的音乐盒子所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。