使用 JavaScript开发的跨平台音乐、书籍播放器
演示效果
歌曲推荐界面
歌手搜索界面
歌词预览界面
书籍推荐界面
代码实现过程
首页代码:
'use strict';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './style.css';
import $ from 'jquery';
import Message from 'lrh-message';
export default class Dashboard extends Component {
constructor() {
super();
this.current = 1;
this.state = {
folderList: []
}
}
componentDidMount() {
$.subscribe('closeDashboard', () => {
$('.dashboard').hide();
});
$.subscribe('showDashboard', () => {
$('.dashboard').show();
});
$('.defaultSelected').click();
}
loadTuiJianFolder(page) {
if (typeof page !== 'number') {
this.addSelectedClass(page);
page = 1;
}
this.current = page;
let url = 'http://www.kugou.com/yy/special/index/' + page + '-0-1.html';
$.get(url, (result) => {
let $li = $(result).find('#ulAlbums li');
let list = [];
$.each($li, (i, item) => {
let folder = {
title: $(item).find('a').attr('title'),
url: $(item).find('a').attr('href'),
image: $(item).find('img').attr('_src')
}
list.push(folder);
});
if (list.length > 10) {
list.length = 10;
}
this.setState({ folderList: list });
}).fail(function () {
new Message('warning', '载入歌曲分类失败。');
});
}
goToThisMusicList(e) {
let page = $(e.target).text();
this.loadTuiJianFolder(Number(page));
}
loadMusicList(e) {
let url = $(e.target).parent().attr('data');
if (url.indexOf('singer') !== -1) {
let value = $(e.target).next().text();
let url = `http://mobilecdn.kugou.com/api/v3/search/song?format=jsonp&keyword=${value}&page=1&pagesize=30&showtype=1&callback=kgJSONP238513750<span style="white-space:pre"></span>`;
$.ajax({
url: url,
method: 'GET',
contentType: 'json',
success: (result) => {
result = result.substring(1, result.length - 1);
$.publish('showMusicByThisList', { result: result });
$.publish('listBySearch');
$.publish('closeDashboard');
$.publish('closeArticleDashboard');
},
error: (error) => {
new Message('warning', '搜索歌曲失败,请重新搜索。');
}
})
} else {
$.get(url, (result) => {
let $li = $(result).find('#songs li');
let songs = {
data: {
info: []
}
};
$.each($li, (i, item) => {
let music = {
songname: $(item).find('.text').text().split(' - ')[1],
singername: $(item).find('.text').text().split(' - ')[0],
hash: $(item).find('a').attr('data').split('|')[0],
album_name: '',
duration: ''
};
songs.data.info.push(music);
});
$.publish('showMusicByThisList', { result: JSON.stringify(songs) });
$.publish('closeDashboard');
$.publish('listBySearch');
}).fail(function () {
new Message('warning', '歌曲加载失败,请重新点击。');
});
}
}
loadSinger(e) {
this.addSelectedClass(e);
let url = 'http://www.kugou.com/yy/html/singer.html';
$.get(url, (result) => {
let $li = $(result).find('#list_head li');
let list = [];
$.each($li, (i, item) => {
let folder = {
title: $(item).find('a').attr('title'),
url: 'singer' + i,
image: $(item).find('img').attr('_src')
}
list.push(folder);
});
this.setState({ folderList: list });
}).fail(function () {
new Message('warning', '加载热门歌手失败,请尝试重新点击。');
});
}
addSelectedClass(e) {
$('.musicNavbar li').removeClass('selectedNavbar');
$(e.target).addClass('selectedNavbar');
}
render() {
let current = this.current;
let page = [];
if (this.state.folderList[0] && this.state.folderList[0].url.indexOf('singer') === -1) {
for (let i = 0; i < 5; i++) {
if (i + 1 === current) {
page.push(<li key={Math.random()} className="musicCurrentPage">{i + 1}</li>);
} else {
page.push(<li key={Math.random()} onClick={this.goToThisMusicList.bind(this)}>{i + 1}</li>);
}
}
}
let folderList = this.state.folderList.map((folder, i) => {
return (
<li className="oneFolder" key={i} data={folder.url}>
<img style={{width:'150px',height:'150px'}} src={folder.image} onClick={this.loadMusicList.bind(this)} />
<p className="folderTitle" title={folder.title}>{folder.title}</p>
</li>
)
});
return (
<div className="dashboard">
<ul className="musicNavbar">
<li className="selectedNavbar defaultSelected" onClick={this.loadTuiJianFolder.bind(this)}>个性推荐</li>
<li onClick={this.loadSinger.bind(this)}>热门歌手</li>
</ul>
<ul>{folderList}</ul>
<ul className="musicPagination">
{page}
</ul>
</div>
)
}
}
歌词预览代码:
'use strict';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import './style.css';
import $ from 'jquery';
import Message from 'lrh-message';
export default class MusicDetail extends Component {
constructor() {
super();
this.state = {
image: './static/images/panda.jpg',
songName: '未知',
singername: '未知',
lyric: '没有歌词',
audioName: '未知'
}
}
componentDidMount() {
$.subscribe('openBigWindow', () => {
$('.musicDetail').show();
});
$.subscribe('selectedOneMusic', (o, args) => {
this.setDetail(args.hash);
});
$.subscribe('changeLyricLine', (o, args) => {
this.changeLyricLine(args);
});
}
changeLyricLine(args) {
let $lyricLineGroup = $('.lyricLine');
$.each($lyricLineGroup, (i, item) => {
let timeStr = $(item).attr('id').substring(1, 6);
let time = Number(timeStr.split(':')[0]) * 60 + Number(timeStr.split(':')[1]);
if (time === args.time) {
$(item).get(0).scrollIntoView(true);
let top = $('.detailLyric').get(0).scrollTop;
$('.detailLyric').get(0).scrollTop = top - 100;
$('.lyricLine').css({
color: '#000'
});
$(item).css({
color: '#fff'
});
}
});
}
setDetail(hash) {
if(hash.indexOf('local') !== -1){
this.setState({ image: './static/images/panda.jpg' });
this.setState({ songName: $('#' + hash).attr('data').split(' - ')[0].split('/')[1] });
this.setState({ singername: $('#' + hash).attr('data').split(' - ')[1].split('.mp3')[0] });
this.setState({ lyric: '没有歌词' });
this.setState({ audioName: '未知' });
return;
}else if(hash.indexOf('article') !== -1){
this.setState({ image: './static/images/panda.jpg' });
this.setState({ songName: '未知'});
this.setState({ singername: '未知' });
this.setState({ lyric: '没有歌词' });
this.setState({ audioName: '未知' });
return;
}
let url = `http://www.kugou.com/yy/index.php?r=play/getdata&hash=${hash}`;
$.ajax({
url: url,
method: 'GET',
contentType: 'json',
success: (result) => {
this.setState({ image: JSON.parse(result).data.img });
this.setState({ songName: JSON.parse(result).data.song_name });
this.setState({ singername: JSON.parse(result).data.author_name });
this.setState({ audioName: JSON.parse(result).data.audio_name });
let lyrics = JSON.parse(result).data.lyrics;
for(let i = 0; i < 13; i++){
lyrics += '[lyric'+ i +'] \r\n';
}
this.setState({ lyric: lyrics });
},
error: (error) => {
new Message('warning', '获取歌曲信息失败。');
}
})
}
closeBigWindow() {
$('.musicDetail').hide();
}
render() {
this.lyrics = this.state.lyric.split('\r\n');
let lyricLine = this.lyrics.map((line) => {
return (
<p title={line.split(']')[1]} className="lyricLine" key={Math.random()} id={line.split(']')[0]}>{line.split(']')[1]}</p>
)
});
return (
<div className="musicDetail">
<div className="detailHeader"><i className="fa fa-compress" aria-hidden="true" onClick={this.closeBigWindow.bind(this)}></i></div>
<div className="detailContent">
<img className="musicImg" src={this.state.image} />
<img className="musicBar" src="./static/images/bar.png" />
<p className="detailName">
<span title={this.state.songName} style={{ fontWeight: 'bold', fontSize: '20px', display: 'inline-block', marginBottom: '10px',overflow:'hidden',width: '300px' }}>{this.state.songName}</span><br />
<span style={{fontWeight: 'bold',display: 'inline-block', marginRight: '10px', width: '100px'}}>歌手: {this.state.singername}</span>
<span style={{fontWeight: 'bold', display: 'inline-block', width: '190px'}}>专辑: {this.state.audioName.substring(0, 10)}</span>
</p>
<div className="detailLyric">{lyricLine}</div>
</div>
</div>
)
}
}
项目文件结构截图
注:
下载之后请先将后缀名 .zip 改成 .7z再进行解压使用 JavaScript开发的跨平台音乐、书籍播放器
注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权
使用 JavaScript开发的跨平台音乐、书籍播放器的更多相关文章
- iOS开发拓展篇—音乐的播放
iOS开发拓展篇—音乐的播放 一.简单说明 音乐播放用到一个叫做AVAudioPlayer的类,这个类可以用于播放手机本地的音乐文件. 注意: (1)该类(AVAudioPlayer)只能用于播放本地 ...
- Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用
Android第三方开源SeekBarCompat:音乐类播放器等APP进度条常用 Android平台原生的SeekBar设计简单,然而,比如现在流行的一些音乐播放器的播放进度控制条,如果直接使 ...
- iOS开发——音频篇——音乐的播放
一.简单说明 音乐播放用到一个叫做AVAudioPlayer的类,这个类可以用于播放手机本地的音乐文件. 注意: (1)该类(AVAudioPlayer)只能用于播放本地音频. (2)时间比较短的(称 ...
- html 音乐 QQ播放器 外链 代码 播放器 外链 代码
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha QQ播放器 外链 代码 播放器 外链 代码 ======== 歌曲链接 QQ播放器 外链 ...
- 自己实现一个简单的网络音乐mp3播放器
大繁至简,把思路搞清楚才是最重要的,如何去做依托于使用什么来实现这项功能 列出我使用的基本类 NSURLSessionDataTask 数据获取类 NSFileHandle 数据缓存和数据读取类 Au ...
- HTML音乐悬浮播放器
话不多说先上代码 <link rel="stylesheet" href="http://47.102.203.92/css/APlayer.min.css&quo ...
- android音乐播放器开发 SweetMusicPlayer 载入歌曲列表
上一篇写了播放器的总体实现思路,http://blog.csdn.net/huweigoodboy/article/details/39855653,如今来总结下载入歌曲列表. 代码地址:https: ...
- Dewplayer 音乐播放器
Dewplayer 是一款用于 Web 的轻量级 Flash 音乐播放器.提供有多种样式选择,支持播放列表,并可以通过 JavaScript 接口来控制播放器. 注意事项: 该播放器只支持 mp3 格 ...
- 自制 h5 音乐播放器 可搜索
闲言碎语: 有好几天没有发表博客了,这也是因为一直开发音乐和完善我的博客项目,好不容易抽出时间总结一下这几天所做的东西,笔试又不断通知,实则匆忙 今天难得逃了一次课,就趁这时间,该写写就写写吧~~ 进 ...
随机推荐
- 基于V4L2的视频驱动开发【转】
转自:http://blog.chinaunix.net/uid-10747583-id-298573.html Tags:V4L2驱动框架.API.操作流程…… 原文地址:http://www.ee ...
- python bisect模块二分法查找
#!/usr/bin/env python # encoding: utf-8 import bisect import sys #将一个元素插入到一个有序列表的合适位置 #使用这个模块的函数前先确保 ...
- Vue全局异常捕获
之前没注意过这么个小技巧 , 可能在Vue文档里也有 暂时先记下了 方便摘要 Vue全局配置 errorHandler可以进行全局错误收集,我们可以根据这个特性对前端异常做这样的处理:业务错误直接写 ...
- 顺序栈操作--数据结构(C++)版
最近学习数据结构,一开始接触感觉好难,颓废了一段时间,后来又重新翻开学习,突然感觉到很大的兴趣.对这些代码的运用都有了 一些新的认识.下面简单的讲述下最新学到的顺序栈,不知道大家学习的时候会不会有感觉 ...
- 在vc6里头文件sys/timeb.h里struct timeb各变量的具体含义?
timeb的定义:struct _timeb{ time_t time; unsigned short millitm; short timezon ...
- CSS变量使用解析
很早直接就了解到CSS变量相关的内容,奈何之前使用价值不高(很多主流浏览器不兼容) 最近发现主流浏览器都已经支持了这一变化 这一重要的变化,可能会让你发现,原生CSS从此变的异常强大~,下面看一下如何 ...
- 洛谷 P1181 数列分段Section I【贪心/最少分成多少合法的连续若干段】
题目描述 对于给定的一个长度为N的正整数数列A[i],现要将其分成连续的若干段,并且每段和不超过M(可以等于M),问最少能将其分成多少段使得满足要求. 输入输出格式 输入格式: 输入文件divide_ ...
- WORDPRESS改为https部署
1.确保你已经正确开启了httpd 2.4.6的https配置,并且配置了该网站的虚拟主机,如下所示: <VirtualHost *:443> DocumentRoot "/ap ...
- 基础博弈论之——简单的博弈问题【hdu1525】【Euclid‘s Game】
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=60481118 由于今天考了一道博弈的问题,我竟什 ...
- Django学习笔记2:处理表单
1.HTTP请求 HTTP协议以"请求-回复"的方式工作. 客户发送请求时,可以在请求中附加数据.服务器通过解析请求,就可以获得客户传来的数据,并根据URL来提供特定的服务. (1 ...