[TOC]
源代码和文档
准备工作
我默认你拥有Django基础知识,并且设备中安装了python和Django环境,会使用pip包管理工具
#安装Django
pip install django
#创建项目和app
django-admin startproject myproject
cd myproject
python manage.py startapp myplayer
#创建超级用户
python manage.py createsuperuser
#如果报错先迁移一下数据库
python manage.py makemigrations
python manage.py migrate
修改配置
myproject/urls.py
from django.contrib import admin
from django.urls import path
from myplayer.views import AplayerView
urlpatterns = [
path('admin/', admin.site.urls),
path('myplayer/',AplayerView.as_view())
]
myproject/settings.py
import os
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#---------修改内容-----------
'myplayer',
]
...
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
#-------修改内容--------
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
...
#添加内容
STATICFILES_DIRS = (
os.path.join(BASE_DIR,'static'),
)
模型与视图
myplayer/models.py
from django.db import models
from django.utils.timezone import now
class Music(models.Model):
id = models.AutoField(primary_key=True)
created_time = models.DateTimeField('创建时间', default=now)
music_name = models.CharField(verbose_name='歌曲',max_length=100)
artist = models.CharField(verbose_name='歌手',max_length=40)
music_url = models.CharField(verbose_name='播放链接',max_length=200)
image_url = models.CharField(verbose_name='图片链接',max_length=200,blank=True)
lrc = models.TextField(verbose_name='歌词',blank=True)
status = models.BooleanField(verbose_name='是否启用',default=True)
peace_music = models.BooleanField(verbose_name='纯音乐',default=False)
class Meta:
verbose_name = '音乐'
verbose_name_plural = verbose_name
def save(self,*args,**kwargs):
if not self.lrc and not self.peace_music:
self.lrc = '[00:00.000] 暂无歌词\\n[00:01.000] 暂无歌词\\n[00:02.000] 暂无歌词\\n'
elif not self.lrc and self.peace_music:
self.lrc = '[00:00.000] 纯音乐,请欣赏\\n[00:01.000] 纯音乐,请欣赏\\n[00:02.000] 纯音乐,请欣赏\\n'
super(Music,self).save(*args,**kwargs)
def __str__(self):
return self.music_name + "-" + self.artist
myplayer/views.py
from django.shortcuts import render
from django.views import View
from myplayer.models import Music
class AplayerView(View):
def get(self,request,*args,**kwargs):
musics = []
for i in Music.objects.filter(status=True):
musics.append({
'name':i.music_name,
'artist':i.artist,
'url':i.music_url,
'cover':i.image_url,
'lrc':i.lrc,
})
context = {'musics':str(musics)[1:-1].replace('}, ','}*#')}
return render(request,'APlayer/myplayer.html',context=context)
管理后台
myplayer/admin.py
from django.contrib import admin
from .models import Music
from django.utils.html import format_html
# Register your models here.
class MusicAdmin(admin.ModelAdmin):
exclude = ('created_time',)
list_display = ('id','music_name','artist','created_time','image_link','audio_link','status','peace_music')
list_display_links = ('id','music_name')
list_filter = ['artist','created_time','status','peace_music']
def image_link(self, obj):
return format_html('<a href="%s" target="_blank">%s</a>' % (obj.image_url, '查看'))
image_link.short_description = '专辑图片'
def audio_link(self, obj):
return format_html('<a href="%s" target="_blank">%s</a>' % (obj.music_url, '播放'))
audio_link.short_description = '音乐外链'
admin.site.register(Music,MusicAdmin)
编写模板
在此之前需要引入静态文件,APlayer.min.js和APlayer.min.css
在项目根目录下新建static和templates文件夹,在两个文件夹下分别新建APlayer目录
将Github仓库的dist目录下的四个文件保存到static/APlayer目录中
新建templates/APlayer/myplayer.html:
<!DOCTYPE html>
{% load static%}
<html>
<head>
<meta charset="UTF-8">
<title>myplayer</title>
<link rel="stylesheet" href="{% static 'APlayer/APlayer.min.css' %}">
</head>
<script src="{% static 'APlayer/APlayer.min.js' %}"></script>
<body>
<div id="aplayer" style="width:600px;"></div>
<script>
function music_list(musics) {
var a = [];
var p;
for(i=0;i<musics.length;i++){
p = JSON.parse(musics[i].replaceAll("'","\""));
a[i] = {
name:p['name'],
artist:p['artist'],
url:p['url'],
cover:p['cover'],
lrc:p['lrc']
};
};
return a;
};
new APlayer({
container: document.getElementById('aplayer'),
loop: 'all',
theme: '#F57F17',
lrcType: 1,
listFolded: false,
audio: music_list('{{ musics }}'.replaceAll(''',"'").split('*#'))
});
</script>
</body>
</html>
收尾
#迁移数据库
python manage.py makemigrations
python manage.py migrate
#启动服务
python manage.py runserver
访问127.0.0.1:8000/admin在后台添加音乐
访问127.0.0.0:8000/myplayer/即可看到播放器
更多配置请参考APlayer中文文档
注意事项
自己在配置的时候踩了两个坑,把解决办法放在这里,方便各位可爱的读者
1:列表高度
当有多首音乐时,会自动渲染为一个播放列表,随着音乐增多列表高度也会发生变化,这不符合我们的期望
官方文档中提到listMaxHeight
参数可以自定义列表高度,该参数的默认值为250。一首歌的高度大概是33px,如果你想显示十首音乐,建议设置为330
设置完成后你会发现然并软,列表会无限度的变高,连默认值都失效了,经过多番尝试,发现导致该问题的是模板文件中的<!DOCTYPE html>
,删掉这一行设置就生效了。
在生产环境中,也许你的模板会继承自别的html文件,为了解决该问题,你可以在extends语句之前加上<!DOCTYPE>
,舍弃后面的html
2:歌词
歌词的引入方式有三种,详见官方文档,本文中采用的方式是在js中引入。在测试过程中我添加了一首纯音乐,因为没有歌词,所以在循环过程中引起函数错误,尝试添加“暂无歌词”字段后异常仍然存在,不死心的我看了一下官方文档,发现歌词是三句一组的,所以,将歌词改成如下形式:
[00:00.000] 纯音乐,请欣赏\n[00:01.000] 纯音乐,请欣赏\n[00:02.000] 纯音乐,请欣赏\n
这一次OK了,循环过程不再因异常而中止。在本文的代码中,我已经帮你完成了一部分工作,如果暂时没有歌词,把歌词部分留空即可,如果是纯音乐,还需要勾选“是否纯音乐”前面的框框
可优化内容
目前从视图向模板传递数据采用的是字符串,用js代码来处理,这种方法不尽如人意,可选的方法是以json格式传递数据,当然,仍然需要一段js代码将其渲染为列表
可以在models.py中写一个方法,判断音乐外链是否可用,在音乐很多时,该方法将会为你提供极大的便利