uniapp+vue3实现音乐播放器,包含上一首、下一首、暂停、播放、下载音频、下载视频、进度条拖拽、歌词等

uni-app中实现音乐播放器

1、主要利用的是uni-app中提供的uni.createInnerAudioContext()来进行实现;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、代码示例

(1)主页面代码展示

<template><view class="songDetailContainer"><view class="bg" :style="{ backgroundImage: `url(${song.imageUrl})` }"></view><view class="content"><view class="title">{{ song.title }}</view><view class="discContainer discAnimation" v-show="current == 0"><view class="disc"></view><view class="circle"><image class="musicImg" :src="song.imageUrl"></image></view></view><scroll-viewclass="h-full":scroll-y="true":refresher-enabled="false":scroll-anchoring="true"v-show="current == 1"><view class="prompt" v-html="song.lyric" style="white-space: pre-line"> </view></scroll-view><u-tabsclass="u-tabs-con":list="list1"@change="handleChange":current="current":scrollable="true"active-color="#fff"inactive-color="#ccc4c2":gutter="20":bar-width="20"></u-tabs><view class="share"><u-icon name="share" color="#fff" size="40" @click="shareClick"></u-icon><text> 分享 </text></view><!-- 进度条控制区域 --><view class="progressControl"><text>{{ currentTimeText }}</text><sliderstyle="width: 560rpx"@change="handleSliderChange":value="sliderIndex":max="maxSliderIndex"activeColor="#ea588e"backgroundColor="#b9c2c5"block-color="#fff"block-size="12"/><text>{{ totalTimeText }}</text></view><!-- 底部控制播放区域 --><view class="musicControl"><u-icon name="star" color="#fff" size="60" @click="starClick"></u-icon><u-iconname="rewind-left-fill"@click="handlePrev"color="#fff"size="60"id="pre"></u-icon><u-iconname="pause-circle-fill"@click="onPauseAudio"v-if="isPlay"color="#fff"size="80"></u-icon><u-iconname="play-circle-fill"@click="onPlayAudio"v-elsecolor="#fff"size="80"></u-icon><u-iconname="rewind-right-fill"@click="handleNext"color="#fff"size="60"id="next"></u-icon><u-icon name="grid" @click="show = true" color="#fff" size="60"></u-icon></view></view></view><u-action-sheetclass="action-sheet":list="data.list"v-model="show"@click="sheetClick"cancel-text="关闭"></u-action-sheet><!-- #ifdef H5 -->
</template><script lang="ts" setup>
import { ref, reactive, onUnmounted } from 'vue'
import moment from 'moment'
import { onLoad } from '@dcloudio/uni-app'
import { download } from '@/utils/download'
import { drawingRecord } from '@/api/music'
let id = ref(0) // 歌曲详情对象
const song = ref({}) // 歌曲详情对象
const isPlay = ref(false) // 音乐是否播放
const currentTime2 = ref(0) // 实时时间
const audioList = ref([]) // 音乐列表
let index = 0
const show = ref(false)
const innerAudioContext = uni.createInnerAudioContext()
const startId = ref(0)
const endId = ref(0)
const sliderIndex = ref(0) //滑块当前值
const maxSliderIndex = ref(100) //滑块最大值
const currentTimeText = ref('00:00') //视频已播放长度文字
const totalTimeText = ref('00:00') //视频总长度文字
onLoad((options: any) => {id.value = options.idstartId.value = options.startIdendId.value = options.endIdgetAudioList()})
const getAudioList = async () => {const { lists } = await drawingRecord({status: 3,startId: startId.value,endId: endId.value,pageNo: 1,pageSize: 100})audioList.value = listsfor (let i = 0; i < audioList.value.length; i++) {if (audioList.value[i].id == id.value) {index = iconsole.info('index', i)}}song.value = audioList.value[index]innerAudioContext.autoplay = trueinnerAudioContext.src = song.value.audioUrlinnerAudioContext.play()isPlay.value = true
}innerAudioContext.onEnded(() => {isPlay.value = falsecurrentTimeText.value = '00:00'sliderIndex.value = 0handleNext()
})
innerAudioContext.onTimeUpdate(() => {currentTimeText.value = moment(innerAudioContext.currentTime * 1000).format('mm:ss')sliderIndex.value = innerAudioContext.currentTime
})
innerAudioContext.onCanplay(function () {totalTimeText.value = moment(innerAudioContext.duration * 1000).format('mm:ss')maxSliderIndex.value = innerAudioContext.duration
})innerAudioContext.onPause(() => {currentTime2.value = innerAudioContext.currentTime
})
innerAudioContext.onPlay(() => {innerAudioContext.seek(currentTime2.value)console.log(currentTime2.value, 'currentTime2.value')
})const onPauseAudio = () => {innerAudioContext.pause()isPlay.value = false
}
const onPlayAudio = () => {innerAudioContext.src = song.value.audioUrlinnerAudioContext.play()isPlay.value = true
}const handlePrev = () => {innerAudioContext.stop()sliderIndex.value = 0currentTimeText.value = '00:00'currentTime2.value = 0if (index == 0) {index = audioList.value.length}innerAudioContext.src = audioList.value[index - 1].audioUrlsong.value.title = audioList.value[index - 1].titlesong.value.imageUrl = audioList.value[index - 1].imageUrlsong.value.duration = audioList.value[index - 1].durationsong.value.lyric = audioList.value[index - 1].lyricinnerAudioContext.play()isPlay.value = trueindex -= 1console.log(index, 'index')
}
const handleNext = () => {innerAudioContext.stop()sliderIndex.value = 0currentTimeText.value = '00:00'currentTime2.value = 0console.log(sliderIndex.value, currentTimeText.value, '下一首')if (index == audioList.value.length - 1) {index = -1}innerAudioContext.src = audioList.value[index + 1].audioUrlsong.value.title = audioList.value[index + 1].titlesong.value.imageUrl = audioList.value[index + 1].imageUrlsong.value.duration = audioList.value[index + 1].durationsong.value.lyric = audioList.value[index + 1].lyricinnerAudioContext.play()isPlay.value = trueindex += 1console.log(index, 'index')
}// 文件下载
const onFileDownload = async (drawing: any) => {uni.setClipboardData({data: drawing,success: function () {uni.showToast({ title: '复制成功,请打开浏览器下载', duration: 2000 })}})
}const data = reactive({list: [{text: '下载音频',fontSize: 28},{text: '下载视频',fontSize: 28}]
})
const sheetClick = (index: number) => {if (index == 0) {onFileDownload(song.value.audioUrl)} else if (index == 1) {onFileDownload(song.value.videoUrl)}
}
//变更滑块位置
const handleSliderChange = (e) => {changePlayProgress(e.detail ? e.detail.value : e)
}
//更改播放进度
const changePlayProgress = (value: any) => {sliderIndex.value = valueinnerAudioContext.seek(value)currentTimeText.value = moment(value * 1000).format('mm:ss')
}
// tabs部分
const current = ref(0)
const list1 = ref([{ customMode: 0, name: '歌曲' },{ customMode: 1, name: '歌词' }
])const handleChange = (index: number) => {current.value = index
}
const starClick = () => {uni.showToast({ title: '敬请期待' })
}
const shareClick = () => {uni.showToast({ title: '敬请期待' })
}
onUnmounted(() => {innerAudioContext.destroy()
})
</script><style lang="scss" scoped>
.songDetailContainer {height: 100vh;width: 100%;position: relative;.bg {width: 100%;height: 100vh;position: absolute;z-index: 0;background-size: cover;background-repeat: no-repeat;filter: blur(60px);}.content {display: flex;justify-content: space-around;flex-direction: column;align-items: center;.title {color: #fff;position: absolute;top: 30rpx;}.prompt {color: #fff;position: absolute;top: 80rpx;left: 40rpx;right: 40rpx;font-size: 38rpx;line-height: 68rpx;}.h-full {position: absolute;top: 120rpx;left: 40rpx;right: 40rpx;height: 800rpx;width: calc(100% - 80rpx);}.u-tabs-con {position: absolute;bottom: 300rpx;color: #fff;}}
}
.content ::v-deep .u-tabs {background: none !important;
}
.share {position: absolute;bottom: 320rpx;right: 50rpx;color: #fff;display: flex;align-items: center;text {margin-left: 10rpx;font-size: 24rpx;}
}
/* 磁盘 */
.discContainer {position: relative;top: 200rpx;// width: 598rpx;// height: 598rpx;width: 490rpx;height: 490rpx;border: 1rpx solid #e6e6e6;border-radius: 50%;
}.discAnimation {animation: disc 8s linear infinite;animation-delay: 1s;
}/*@keyframes: 设置动画帧1) from to- 使用于简单的动画,只有起始帧和结束帧- 北京 - 上海  直达2) 百分比- 多用于复杂的动画,动画不止两帧- 北京 - 上海 ---> 北京 -- 天津 --- 深圳 --- 上海- 0% - 100%, 可以任意拆分
*/
@keyframes disc {from {transform: rotate(0deg);}to {transform: rotate(360deg);}
}.disc {width: 100%;height: 100%;
}.songDetailContainer .discContainer .musicImg {position: absolute;left: 0;right: 0;top: 0;bottom: 0;margin: auto;width: 370rpx;height: 370rpx;border: 1rpx solid transparent;border-radius: 50%;
}
.circle {position: absolute;left: 30rpx;top: 30rpx;width: 430rpx;height: 430rpx;border: 1rpx solid #e6e6e6;border-radius: 50%;
}
/* 底部控制播放区域 */
.musicControl {position: absolute;bottom: 80rpx;left: 60rpx;width: calc(100% - 120rpx);display: flex;justify-content: space-between;
}
.musicControl text {width: 20%;height: 120rpx;line-height: 120rpx;text-align: center;color: #fff;font-size: 50rpx;
}
.musicControl text.big {font-size: 80rpx;
}
/* 进度条控制区域 */
.progressControl {position: absolute;bottom: 200rpx;width: 640rpx;height: 80rpx;line-height: 80rpx;display: flex;color: #fff;
}.action-sheet ::v-deep .u-action-sheet-item {align-items: baseline;padding-left: 30rpx;
}
</style>

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

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

相关文章

记录uni-app横屏项目:自定义弹出框

目录 前言&#xff1a; 正文&#xff1a; 前言&#xff1a;横屏的尺寸问题 最近使用了uniapp写了一个横屏的微信小程序和H5的项目&#xff0c;也是本人首次写的横屏项目&#xff0c;多少是有点踩坑不太适应。。。 先说最让我一脸懵的点&#xff0c;尺寸大小&#xff0c;下面一…

vxe-弹窗初始化激活选中Vxe-Table表格中第一行input输入框

1.实现效果 2.Modal弹窗的渲染过程 一、Vue组件的生命周期 Vue组件从创建到销毁会经历一系列的生命周期钩子&#xff0c;这些钩子为开发者提供了在不同阶段插入自定义逻辑的机会。在Modal弹窗的上下文中&#xff0c;这些生命周期钩子同样适用。 beforeCreate&#xff1a;组件…

Qt中的高分辨率及缩放处理

写在前面 使用Qt开发界面客户端&#xff0c;需要考虑不同分辨率及缩放对UI界面的影响&#xff0c;否则会影响整体的交互使用。 问题 高分辨率/缩放设备上图片/图标模糊 若不考虑高分辨及缩放处理&#xff0c;在高分辨率/缩放设备上&#xff0c;软件中的图片、图标可能会出现…

解决jupyter argparse报错

jupyter argparse报错 文章目录 一、jupyter argparse报错 一、jupyter argparse报错 args parser.parse_args()这行代码改为&#xff1a; args parser.parse_args(args[])完整的代码为&#xff1a; import argparseparser argparse.ArgumentParser() parser.add_argumen…

sourcetree中常用功能使用方法及gitlab冲突解决

添加至缓存&#xff1a;等于git add 提交&#xff1a;等于git commit 拉取/获取&#xff1a;等于git pull ,在每次要新增代码或者提交代码前需要先拉取一遍服务器中最新的代码&#xff0c;防止服务器有其他人更新了代码&#xff0c;但我们自己本地的代码在我们更新前跟服务器不…

Java实战中如何使用多线程(线程池)及其为什么使用?

这个话题在入行之前就想过很多次&#xff0c;很多8古文或者你搜索的结果都是告诉你什么提高高并发或者是一些很高大上的话&#xff0c;既没有案例也没有什么公式去证明&#xff0c;但是面试中总是被问到&#xff0c;也没有实战经历&#xff0c;所以面试时一问到多线程的东西就无…

深度学习入门——与学习相关的技巧

前言 本章将介绍神经网络的学习中的一些重要观点&#xff0c;主题涉及寻找最优权重参数的最优化方法、权重参数的初始值、超参数的设定方法等 此外&#xff0c;为了应对过拟合&#xff0c;本章还将介绍权值衰减、Dropout等正则化方法&#xff0c;并进行实现。 最后将对近年来…

细说MCU用单路DAC模块设计和输出锯齿波的实现方法

目录 一、STM32G474RE的DAC模块 二、配置 1.配置DAC 2.选择时钟源和Debug 3.配置系统时钟 三、代码修改 1.启动DAC 2.给DAC的数据输出寄存器赋值 3.运行并观察输出 一、STM32G474RE的DAC模块 有些MCU本身就带有数/模转换器(Digital to Analog Converter,DAC)模块&am…

昇思25天学习打卡营第20天|Diffusion扩散模型

Mindspore框架利用扩散模型DDPM生成高分辨率图像&#xff08;生成高保真图像项目实践&#xff09; Mindspore框架利用扩散模型DDPM生成高分辨率图像|&#xff08;一&#xff09;关于denoising diffusion probabilistic model &#xff08;DDPM&#xff09;模型Mindspore框架利…

差分进化算法原理及其MATLAB/Python代码

1.算法简介 引用自&#xff1a;Storn R, Price K. Differential evolution–a simple and efficient heuristic for global optimization over continuous spaces[J]. Journal of global optimization, 1997, 11: 341-359. 今天给大家带来的是一个非常经典的智能优化算法–差分…

【多模态】42、LLaVA-UHD | 支持任意纵横比和大分辨率图像输入的 LLaVA

论文&#xff1a;LLaVA-UHD: an LMM Perceiving Any Aspect Ratio and High-Resolution Images 代码&#xff1a;https://github.com/thunlp/LLaVA-UHD 出处&#xff1a;清华 | 新加坡国立大学 | 中国科学院大学 一、背景 现有的很多 LMM 都是将图像处理成固定的纵横比&…

Ubuntu编译ffmpeg并添加cmake工程

文章目录 前言前提须知为什么要自己编译 FFmpeg前提软件包与工具的安装编译ffmpeg写CMakeList.txt包含ffmpeg到我们项目中 总结 前言 FFmpeg 是一个领先的多媒体框架&#xff0c;能够解码、编码、转码、复用、解复用、流化、过滤和播放几乎所有人类和机器创造的内容。FFmpeg 包…

设计模式11-原型模式

设计模式11-原型模式 写在前面对象创建模式典型模式原型模式动机结构代码推导应用特点要点总结 原型模式与工厂方法模式对比工厂方法模式原型模式什么时候用什么模式 写在前面 对象创建模式 通过对象创建模式绕开动态内存分配来避免创建过程中所导致的耦合过紧的问题。从而支…

数学建模--国赛备赛---TOPSIS算法

目录 1.准备部分 1.1提交材料 1.2MD5码相关要求 2.TOPSIS算法 2.1算法概述 2.2基本概念 2.3算法核心思想 2.4拓展思考 3.适用赛题 3.1适用赛题说明 3.2适用赛题举例 4.赛题分析 4.1指标的分类 4.2数据预处理 4.2.1区间型属性的变换 4.2.2向量规范化 4.3数据加…

基于 Three.js 的 3D 模型加载优化

作者&#xff1a;来自 vivo 互联网前端团队- Su Ning 作为一个3D的项目&#xff0c;从用户打开页面到最终模型的渲染需要经过多个流程&#xff0c;加载的时间也会比普通的H5项目要更长一些&#xff0c;从而造成大量的用户流失。为了提升首屏加载的转化率&#xff0c;需要尽可能…

IDEA的断点调试(Debug)

《IDEA破解、配置、使用技巧与实战教程》系列文章目录 第一章 IDEA破解与HelloWorld的实战编写 第二章 IDEA的详细设置 第三章 IDEA的工程与模块管理 第四章 IDEA的常见代码模板的使用 第五章 IDEA中常用的快捷键 第六章 IDEA的断点调试&#xff08;Debug&#xff09; 第七章 …

【内网安全】横向移动-Kerberos-SPN-WinRM-RDP

目录 环境介绍与横向移动前置域横向移动-WinRM-WinRS移动条件&#xff1a; 步骤0、攻击机开启winrm服务&#xff1a;1.CS探针5985端口&#xff1a;2.连接目标主机并执行命令&#xff1a;3.上线CS&MSF:4.CS内置横向移动-winrm 域横向移动-RDP简介与条件RDP横向移动连接的三种…

TCP状态转换详解

1.什么是TCP的状态转换 TCP&#xff08;Transmission Control Protocol&#xff0c;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层协议。在 TCP 连接的生命周期中&#xff0c;连接的状态会随着不同阶段的通信而发生变化&#xff0c;这些变化被称为状…

嵌入式Linux入门知识点汇总-启动过程、设备树、设备框架、锁

目录 1.BootLoader启动过程? 引导加载程序(Bootloader) 补充u-boot的理解 通用的bootloader 2.系统调用过程? 3.设备驱动模型的三个重要成员? 4.驱动和设备注册是否存在先后顺序? 5.framebuffer机制? 6.字符设备和块设备的区别并分别举例? 1.字符设备 2.块设备…

SVN 服务 安装部署 Docker(compose) 方式

通过 dockerhub 或者 命令行运行 &#xff1a; docker search svn 查看 svn 的镜像 如命令行&#xff1a; [rootSGP ~]# docker search svn NAME DESCRIPTION STARS OFFICIAL AUTOMATED garethflower…