Django实现简单的音乐播放器 4

news2024/11/23 5:32:19

在原有音乐播放器功能基础上,增加上传音乐功能。

 效果:

目录

配置上传路径

配置路由

视图处理歌曲

引入类库

保存歌曲文件

模板上传

设置菜单列表

设置菜单列表样式

脚本设置

上传效果

1.显示菜单列表

2.点击上传歌曲

3.上传完成

4.查看保存文件

增加数据库操作

修改验证入库方法

修改歌曲加载方法

上传歌曲入库

总结


配置上传路径

在mymp3/settings.py文件中,最底下加上以下配置:

MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')

配置路由

path(r'upload_music', views.upload_music, name='upload_music'),

视图处理歌曲

文件上传时,文件数据存储在request.FILES属性中。

注意:from表单上传文件需要加 enctype=”multipare/form-data”

上传必须是post请求。

引入类库

from django.conf import settings
from django.views.decorators.csrf import csrf_exempt

保存歌曲文件

通过csrf_exempt装饰器豁免csrf验证,读取模板提交的文件并写入设置的路径中。

@csrf_exempt
def upload_music(request):
    """ 上传歌曲文件 """

    if request.method == 'POST':
        file = request.FILES['file']
        # 文件在服务端路径 获取配置
        filePath = os.path.join(settings.MEDIA_ROOT, file.name)
        # 保存文件
        with open(filePath, 'wb+') as fp:
            for info in file.chunks():
                fp.write(info)
        return JsonResponse({'code': 1, 'msg': '上传成功!'})
    else:
        return JsonResponse({'code': 0, 'msg': '请选择POST提交文件!'})

模板上传

使用layui的文件上传功能来进行上传歌曲文件;原来加载歌曲使用的是下拉菜单,但是无法绑定layui上传事件,就改为自己写菜单列表了。

设置菜单列表

去掉原来的功能列表设置,改为在歌曲列表元素上面添加菜单列表内容。

菜单列表如下:

<!--菜单列表-->
<div id="menu-open">
    <span class="layui-icon layui-icon-app menu-open"></span>
    <ul class="menu-list none">
        <li class="loadMusic">加载歌曲</li>
        <li class="uploadMusic">上传歌曲</li>
    </ul>
</div>
<!--菜单列表-->

设置菜单列表样式

通过给最外层的播放器容器设置相对浮动,菜单列表设置绝对浮动,调试后还是原来的位置。

<style>
    .none {
        display: none;
    }

    #music-player{
        position:relative;
    }

    #menu-open {
        position:absolute;
        top:24px;
        right:35px;
    }

    #menu-open span{
        color:#fff;
    }

    .menu-list {
        position:absolute;
        top:18px;
        right:-82px;
        margin: 5px 0;
        background-color:#fff;
    }

    .menu-list li{
        line-height: 26px;
        color: rgba(0,0,0,.8);
        font-size: 14px;
        white-space: nowrap;
        cursor: pointer;
        padding:0 20px;
    }
</style>

脚本设置

因为功能列表修改为菜单列表了,并在原来基础上增加上传功能绑定,故脚本修改较大。

内容如下:

layui.use(['dropdown', 'util', 'layer', 'table'], function () {
        var dropdown = layui.dropdown
            , util = layui.util
            , layer = layui.layer
            , $ = layui.jquery
            , upload = layui.upload;

        // 上传音乐
        var uploadInst = upload.render({
            elem: '.uploadMusic'
            , url: '/upload_music'
            ,accept: 'audio'
            ,exts: 'mp3'
            , done: function (res) {
                if(res.code > 0) {
                    layer.alert(res.msg, {icon: 1})
                } else {
                    layer.alert(res.msg, {icon: 5})
                }
            }
            , error: function () {
                layer.alert('请求异常', {icon: 5})
            }
        });


        // 打开菜单列表
        $("#menu-open").on('click', function () {
            $(".menu-list").toggleClass("none");
        })


        // 关闭菜单列表 点击菜单列表外的其他部分时关闭菜单列表
        $(document).on('click', function (e) {
            if ($(e.target).closest('.music-player').length < 1) {
                $('.menu-list').addClass("none");
            }
        })


        // 请求接口 导入歌曲到数据库
        $('.loadMusic').click(function(){
            $.ajax({
                  type: 'GET',
                  url: "/load_music",
                  data: {id:1},
                  success: function (data) {
                      layer.alert(data, {icon: 1})
                  }.bind(this),
                  error: function (e) {
                      console.log("ERROR : ", e);

                 }
            });
        })
    })

上传效果

1.显示菜单列表

2.点击上传歌曲

3.上传完成

4.查看保存文件

增加数据库操作

目前只是实现文件上传功能,还需要把对文件进行验证和把相应歌曲信息加入数据库,这样播放列表就能显示和播放该歌曲了。

修改验证入库方法

把原来的insert_music方法改为两个方法,一个负责验证歌曲信息,另一个负责入库操作;并修改函数返回格式。

如下:

def auth_music(name):
    """ 验证歌曲文件 """

    ext = 'mp3'
    # 判断文件后缀
    fileInfo = name.split('.')
    if len(fileInfo) != 2:
        return {'code': 0, 'msg': '文件有误'}

    if fileInfo[1] != ext:
        return {'code': 0, 'msg': '请上传MP3文件'}

    # 查询歌曲是否存在
    info = Single.objects.filter(title=name).first()
    if info:
        return {'code': 0, 'msg': '歌曲已存在'}
    else:
        return {'code': 1, 'msg': '可以上传'}


def insert_music(name):
    """ 把歌曲信息插入数据表 """

    single = Single()
    single.title = name
    signers = name.split('-')
    single_1 = signers[1].strip('') if len(signers) > 1 else '未知'
    single.singer = single_1.strip('.mp3')
    single.songUrl = '/static/media/' + name

    # 随机1-10专辑封面图片
    sui_num = random.randint(1, 10)
    single.imageUrl = '/static/images/' + str(sui_num) + '.png'
    flag = single.save()
    if flag:
        return {'code': 0, 'msg': '上传失败,请重试!'}
    else:
        return {'code': 1, 'msg': '上传成功'}

修改歌曲加载方法

因为上述方法歌曲加载功能有使用,所以也需要相应修改,具体为:在循环中调用验证歌曲信息函数,通过判断返回值决定是否入库操作。

def load_music(request):
    """ 加载本地的歌曲 """

    # 项目路径
    app_path = os.path.abspath(os.path.dirname(__file__))
    # 获取媒体资源目录下所有歌曲文件
    path = app_path + '/../static/media/'
    files = os.listdir(path)

    for file in files:
        flag = auth_music(file)
        if flag['code'] > 0:
            print(insert_music(file))
        else:
            print(flag['msg'])

    return HttpResponse('加载本地音乐成功!')

上传歌曲入库

修改歌曲验证和入库方法就是为了方法通用,这样上传文件直接可以使用,并返回提示信息。

@csrf_exempt
def upload_music(request):
    """ 上传歌曲文件 """

    if request.method == 'POST':
        file = request.FILES['file']
        flag = auth_music(file.name)
        if flag['code'] < 1:
            return JsonResponse(flag)

        # 文件在服务端路径 获取配置
        filePath = os.path.join(settings.MEDIA_ROOT, file.name)
        # 保存文件
        with open(filePath, 'wb+') as fp:
            for info in file.chunks():
                fp.write(info)

        # 入库操作
        flag = insert_music(file.name)
        return JsonResponse(flag)
    else:
        return JsonResponse({'code': 0, 'msg': '请选择POST提交文件!'})

注意:通过request.FILES获取的文件,此时也就是file为文件对象,如果入库需要使用file获取文件名称来入库。

音乐播放器版本2源码

链接:百度网盘 请输入提取码

提取码:e5th

总结

在原来基础上增加单独歌曲文件上传,使用了layui控件实现上传,

后端验证歌曲文件,保存本地并入库处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/745221.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python批量读取csv(xlsx)文件指定表头获取内容(表头可乱序)

程序背景 我们在日常办公中经常会遇到去csv或者excel文件中去剪切自己需要的列&#xff0c;然后重新粘贴在新的文件中&#xff0c;但是这样的工作方式非常的耗时&#xff0c;且效率低下&#xff0c;那么是否有一种方法&#xff0c;只要我提供表头就可以快速将我需要的表头生成一…

刚刚出炉!速看7月编程语言排行榜!

2023年已经过半&#xff0c;最新一期的编程语言排行榜你看了吗&#xff1f;刚刚&#xff0c;全球知名编程语言社区TIOBE公布了7月榜单&#xff0c;和播妞一起来看吧&#xff01; TIOBE 7 月 TOP 15 编程语言&#xff1a; 详细榜单可参考官网&#xff1a; https://www.tiobe.co…

超越廉价: 制造一种稀缺性,产品/服务本身具有一种不可复制、与众不同的特性。

文章目录 I 超越廉价1.1 培养自己的稀缺性1.2 为核心客户提供一些价值I 超越廉价 制造一种稀缺性,产品/服务本身具有一种不可复制、与众不同的特性。 时效性:具有时效性的东西天然具有不可复制的特性直播的时效性是重播不可替代的地方人的技能也是有时效性的,当满大街都是某…

最大正方形(力扣)暴力 + 动态规划 JAVA

在一个由 ‘0’ 和 ‘1’ 组成的二维矩阵内&#xff0c;找到只包含 ‘1’ 的最大正方形&#xff0c;并返回其面积。 示例 1&#xff1a; 输入&#xff1a;matrix [[“1”,“0”,“1”,“0”,“0”],[“1”,“0”,“1”,“1”,“1”],[“1”,“1”,“1”,“1”,“1”],[“1”,“…

陆航组训VR虚拟交互教学软件提高团队协作水平

出于陆航独特的空中环境&#xff0c;难以确保航空兵连队接受高质量的空中飞行训练&#xff0c;造成陆航连队无法保持良好的战备状态&#xff0c;随着VR虚拟现实技术越来越成熟&#xff0c;VR公司深圳华锐视点充分了解陆航训练教学的重点和难点&#xff0c;制作陆航训练VR教学课…

大模型技术发展概述 - (一)

文本内容参考论文《A Survey of Large Language Models》 论文标题&#xff1a;A Survey of Large Language Models 论文链接&#xff1a;https://arxiv.org/pdf/2303.18223v10.pdf 因为这个论文内容太多了&#xff0c;所以我的文章分成几篇来展示&#xff01;目录如下&#x…

每日一练 | 华为认证真题练习Day76

1、标准STP模式下&#xff0c;下列非根交换机中的哪个端口会转发由根交换机产生的TC置位BPDU&#xff1f; A. 根端口 B. 备份端口 C. 预备端口 D. 指定端口 2、STP协议中根桥发出的配置BPDU报文中的Message Age为0。 A. 对 B. 错 3、STP中选举根端口时需要考虑以下哪些参…

若依官方前端手册 小笔记

提供确认窗体信息 this.$modal.confirm(确认信息).then(function() {... }).then(() > {... }).catch(() > {}); 提供遮罩层信息 // 打开遮罩层 this.$modal.loading("正在导出数据&#xff0c;请稍后...");// 关闭遮罩层 this.$modal.closeLoading(); 验证…

Android 进程与进程之间的通讯 详解及实现步骤 -- 两个app实现

详情如下&#xff1a; 一、Intent二、Messenger三、AIDL四、广播五、文件 分两个app -- 客户端为&#xff1a;jinc1application、服务端为&#xff1a;jinc2application 一、Intent 这是 Android 中最常用的通讯方式&#xff0c;主要用于启动 Activity、Service 等 jinc1applic…

校园网免认证/校园网pojie

我们的目标是xiao yuan wang pojie 我们使用一个简单的python脚本&#xff0c;用于jiechu /pojie校园网只能登录一台手机和一台电脑的限制&#xff0c;仅供学习。 原理 我们利用已有可正常上网的校园网账户作为跳板&#xff0c;连上网后在后台下线账号所登录的设备&#xff0…

CNVnator软件的安装

1. 下载CNVvator CNVvator软件比较难安装&#xff0c;其依赖root软件等 下载地址 点击其release&#xff0c;下载最新版本v0.4.1(CNVnator_v0.4.1.zip) 2. 安装依赖 root 软件 root 的下载地址 root , 选择下列Ubuntu 20版本 解压root压缩包&#xff1a; ##解压 tar -zxv…

pdf转图片操作方法是什么?分享两个简单的方法!

PDF转图片是一个常见的需求&#xff0c;无论是为了方便编辑、共享&#xff0c;还是为了其他用途&#xff0c;我们需要简单而有效的方法来实现这个目标。本文将介绍两种简单的PDF转图片方法&#xff1a;记灵在线工具和截图方法。 记灵在线工具是一个强大而易于使用的在线工具&a…

如何结合云原生和低代码

前言 云原生和低代码是当今IT领域最流行的两个概念。云原生是一种应用架构设计、应用部署乃至应用开发过程的方式&#xff0c;而低代码是一种快速开发应用的方法。这两者有什么关系&#xff1f;如何结合呢&#xff1f; 先思考一个问题——一个杯子和一个苹果如何结合&#xf…

七牛云的使用(图片超详讲解)

一、为什么要使用七牛云的OSS(对象存储服务)&#xff1f; 二、七牛云使用&#xff1a; 登录七牛云官网&#xff0c;注册并认证 (初次认证有30天免费使用权限)新建存储空间 点击创建的空间名字&#xff0c;进入 空间概括如下&#xff1a; 阅读帮助文档&#xff0c;在自己的…

JavaCV实现byte[]转RTMP流

需求&#xff1a;通过私有的api我可以不断收到byte[]形式的视频数据&#xff0c;现在我需要处理这些数据&#xff0c;最终推送出RTMP流。 实现&#xff1a;通过管道流将不断收到的byte[]视频数据转化为输入流然后提供给JavaCV的FFmpegFrameGrabber使用&#xff0c;然后通过FFmp…

两种传输层协议TCP和UDP【图解TCP/IP(笔记十二)】

文章目录 两种传输层协议TCP和UDPTCP与UDP区分UDP的特点及其目的TCP的特点及其目的 两种传输层协议TCP和UDP 在TCP/IP中能够实现传输层功能的、具有代表性的协议是TCP和UDP。 ■ TCP TCP是面向连接的、可靠的流协议。流就是指不间断的数据结构&#xff0c;你可以把它想象成排…

【C++】C++11 (2): 右值引用、移动构造、移动赋值和模板的可变参数

一、右值引用和移动语义 C11更新后&#xff0c;容器中增加的新方法有插入接口函数的右值引用版本 这些接口的意义在哪&#xff1f;网上都说它们能提高效率&#xff0c;它们是如何提高效率的&#xff1f; 请看下面的右值引用和移动语义的介绍。另外emplace还涉及模板的可变参…

开发跨平台APP,是用Flutter还是React Native开发框架?

随着移动互联网的飞速发展&#xff0c;对于开发人员而言&#xff0c;如何快速地开发出兼容不同平台&#xff08;iOS、Android&#xff09;的应用&#xff0c;成为了一个重要的问题。 跨平台应用程序开发框架的好处&#xff1a; 1. 一个App适用于多个设备&#xff1b; 2. 一个…

问一下路过的大神keil5与keil5mdk 的区别是什么?

从Keil C51都Keil5 MDK&#xff0c;不知不觉已经用了Keil十几年。 虽然现在新增了一些开发环境&#xff0c;不过keil对于老工程师来说&#xff0c;应该是最亲切的了… Keil出过很多个版本&#xff0c;很多人最熟悉的是Keil C51和Keil5 MDK。 我们在做STM32程序开发编译的时候…

Centos7安装SDWebui

Centos7安装SDWebui 1.nvidia显卡驱动安装 #查看显卡编号 lspci | grep -i vga#查询显卡型号 http://pci-ids.ucw.cz/mods/PC/10de?actionhelp?helppci#安装依赖包 yum install kernel-devel gcc -y #查看nouveau是否已禁用&#xff0c;如果有内容说明没有禁用 lsmod | gre…