微信小程序——音频播放器
先来个效果图韵下味:

需求:
- 音频的播放,暂停,中间按钮状态的变化,播放时实时更新播放进度;
- 前进15s,后退15s;
- 进度条拖动。
一开始想着这3个功能应该挺简单的。不就是播放,暂停,前进,后退么~呵~写的时候发现自己还是太年轻。当然,这跟自己的技术功底有关系。现在把我遇到的难点及要注意的点说一下~
- 需要设置一个名为seekPosition的全局变量,初始值为0。我们要在播放的时候实时记录播放的位置,存到该变量里,这是方便在前进15s 或 后退15s 时计算时间点。
- 前进15s时要判断剩余时间是否>15s,如果<15s,则返回到开始位置;
- 后退15s时要判断播放时间是否>15s,如果<15s,则返回到开始位置;
- 点击播放时,要先判断seekPisition是否>0,如果>0,则跳转到seekPosition的位置,并播放;
- 拖动时,要先让音频停止播放,拖动结束后,再播放音频。并且要计算拖动位置对应的时间。
完整代码:
wxml:
<view class=" audio-content">
<image src="{{logo640x360}}" class="bg-blur"></image>
<view class="bg-gray"></view>
<view class="container-cover">
<view class="cover">
<image src="{{logo640x360}}" class="cover-image"></image>
<view class="cover-tip">词不达意.mp3</view>
</view>
</view>
<view class="audio-inner row item-center">
<view class="audio-desc">{{currentProcess}}</view>
<view class="audio-progress-wrap">
<van-slider value="{{sliderValue}}" step="{{sliderStep}}" active-color="#09bb07" use-button-slot bind:change="onSliderChange" bind:drag="onSliderDrag">
<view class="slider-button" slot="button"></view>
</van-slider>
</view>
<view class="audio-desc">{{productDetail.duration}}</view>
</view>
<!-- 播放器控制条 -->
<section class="speech-player js_control_bar">
<view class="player-bar row justify-center item-center">
<view class="backward js_audio_backward" title="后退15s">
<ss-icon name="back-15" size="32px" color="#fff" block="{{true}}" bind:click="backward" />
</view>
<view class="play" title="播放/暂停">
<view class="circle-loading" wx:if="{{loading}}"></view>
<ss-icon name="play-outline" size="50px" color="#fff" block="{{true}}" wx:if="{{pause}}" bind:click="audioPlay" />
<ss-icon name="pause-outline" size="50px" color="#fff" block="{{true}}" wx:if="{{playing}}" bind:click="audioPause" />
</view>
<view class="forward js_audio_forward" title="前进15s">
<ss-icon name="forward-15" size="32px" color="#fff" block="{{true}}" bind:click="forward" />
</view>
</view>
</section>
</view>
这里面用到了有赞的小程序组件 icon组件 和 slider 组件。如果你要用的话把上面的 <ss-icon> 换成<van-icon>,并且需要自己找阿里矢量图标库查找对应的图标。
js:
// components/product/audio/index.js let audioUrl = "",
seekPosition = 0;
const audioContext = wx.createInnerAudioContext(); Component({
options: {
multipleSlots: true,
addGlobalClass: true
}, /**
* 组件的属性列表
*/
properties: {
productId: Number,
},
/**
* 组件的初始数据
*/
data: {
pause: true,
playing: false,
loading: false,
productDetail: {},
audioDuration: 0,
currentProcess: '00:00',
sliderStep:1
}, /**
* 组件的方法列表
*/
methods: {
//音频播放
audioPlay(e) {
const _this = this;
let audioDuration = _this.data.audioDuration;
if (audioUrl) {
if (seekPosition) {
//如果有指定位置,则跳转到指定位置
audioContext.seek(seekPosition);
}
audioContext.play();
_this.setData({
pause: false,
playing: true,
loading: false,
})
} else {
//getJSON是我自己封装的
ss.getJSON('获取音频如果需要发送请求,这里面放请求地址', {
放你自己的参数
}, res => {
audioUrl = res.t;
audioContext.src = audioUrl;
if (seekPosition) {
audioContext.seek(seekPosition);
}
audioContext.play();
audioContext.onPlay(() => {
console.log('onPlay')
}) audioContext.onWaiting(() => {
console.log('onWaiting')
_this.setData({
pause: false,
playing: false,
loading: true,
})
}) audioContext.onCanplay(() => {
console.log('onCanplay')
_this.setData({
pause: false,
playing: true,
loading: false
})
setTimeout(() => {
audioContext.duration
}, 500) _this.audioStatus();
}) audioContext.onError((res) => {
console.log(res.errMsg)
})
})
} }, //播放暂停
audioPause: function() {
const _this = this;
audioContext.pause();
_this.setData({
pause: true,
playing: false,
loading: false
})
}, //记录播放状态
audioStatus: function() {
const _this = this;
//音频播放进度更新事件
audioContext.onTimeUpdate(() => {
seekPosition = audioContext.currentTime;
_this.setData({
currentProcess: ss.formatSecToMin(audioContext.currentTime),
sliderValue: audioContext.currentTime / _this.data.audioDuration * 100,
})
})
//音频播放结束
audioContext.onEnded(() => {
seekPosition = 0;
_this.setData({
sliderValue: 0,
currentProcess: '00:00',
playing: false,
pause: true
})
})
}, //开始拖动
onSliderDrag(e) {
const _this = this;
if (_this.data.playing) {
_this.audioPause()
}
let sliderValue = e.detail.value;
seekPosition = _this.data.audioDuration / 100 * sliderValue;
_this.setData({
currentProcess: ss.formatSecToMin(seekPosition)
}) }, //拖动结束
onSliderChange(e) {
const _this = this;
_this.audioPlay()
}, //前进15s
forward() {
const _this = this,
audioDuration = _this.data.audioDuration;
let currentTime;
if (_this.data.playing) {
currentTime = audioContext.currentTime;
}
if (_this.data.pause) {
currentTime = seekPosition;
} if (audioDuration - currentTime > 15) {
seekPosition = currentTime + 15;
_this.setData({
sliderValue: seekPosition / audioDuration * 100,
currentProcess: ss.formatSecToMin(seekPosition)
});
} else {
seekPosition = audioDuration;
_this.setData({
sliderValue: 0,
currentProcess: '00:00'
});
}
if (audioUrl && _this.data.playing) {
audioContext.seek(seekPosition);
}
}, //后退15s
backward() {
const _this = this,
audioDuration = _this.data.audioDuration;
let currentTime;
if (_this.data.playing) {
currentTime = audioContext.currentTime;
}
if (_this.data.pause) {
currentTime = seekPosition;
} if (currentTime > 15) {
seekPosition = currentTime - 15;
} else {
seekPosition = 0;
}
_this.setData({
sliderValue: seekPosition / audioDuration * 100,
currentProcess: ss.formatSecToMin(seekPosition)
});
if (audioUrl && _this.data.playing) {
audioContext.seek(seekPosition);
}
}
}
})
大概就是这些了~有更好解决方案的欢迎留言哈~~
微信小程序——音频播放器的更多相关文章
- 微信小程序音频播放 InnerAudioContext 的用法
今天项目上涉及到了微信小程序播放音频功能,所以今天跟着一些教程做了个简单的播放器 1.实现思路 刚开始想着有没有现成的组件可以直接用,找到了微信的媒体组件 audio,奈何看着 1.6.0版本开始,该 ...
- 微信小程序音乐播放器
写在前面 1.入门几天小白的作品,希望为您有帮助,有好的意见或简易烦请赐教 2.微信小程序审核音乐类别已经下架,想要发布选题需慎重.附一个参考链接,感谢https://www.hishop.com.c ...
- 微信小程序 - 音频播放(1.2版本和1.2版本之后)
不多说了,直接贴code // 1.2版本以后便不在维护 wx.getBackgroundAudioManager({ success:function(res){ var status =res.s ...
- 微信小程序音乐播放器组件
wxml <image bindtap="click" src="{{isPlay?'/images/':'/images/'}}"/> JS Pa ...
- 微信小程序自运营器 微信小程序自动运营器(让你的微信小程序,公众号零运营成本,24小时全自动运营)
自动发单,自动评价,自动评论,自动推广 微信小程序自运营器 微信小程序自动运营器(让你的微信小程序,公众号零运营成本,24小时全自动运营) 我们会根据你的微信公众号或微信小程序定制开发带有一定AI智 ...
- 微信小程序api拦截器
微信小程序api拦截器 完美兼容原生小程序项目 完美兼用小程序api的原本调用方式,无痛迁移 小程序api全Promise化 和axios一样的请求方式 小程序api自定义拦截调用参数和返回结果 强大 ...
- 微信小程序音频背景播放
由于微信小程序官方将音频的样式固定死了,往往再工作中和UI设计师设计出来的样式不符,故一般都采用背景音频播放来实现自定义的UI样式的音频播放,即使用官网API提供的BackgroundAudioMan ...
- 微信小程序音乐播放
最近在写一个艾美食艾音乐的微信小程序,其中有用到音乐播放的功能,基本播放切换功能已经实现,但是在反复切换歌曲.重新进入歌曲以及单曲循环.列表循环的测试过程中还是发生了bug,特此写一篇文章,捋一下思路 ...
- 微信小程序音频长度获取的问题
小程序推荐使用wx.createInnerAudioContext()创建的innerAudioContext,我们也通过这个接口创建音频.音频的长度可以通过属性获取: 但是,给innerAudioC ...
随机推荐
- 递归实现全排列python
python递归实现"abcd"字符串全排列 1.保持a不动,动bcd 2.保持b不动,动cd 3.保持c不动,动d def pailie(head="",st ...
- golang使用json格式实现增删查改
需求和思路 在一般的小项目或者一个小软件,例如客户端之类的小程序中,可能会需要数据的持久化.但是使用一般的数据库(Mysql)之类的不合适.使用sqlite3这种嵌入式的是个较好的方法,但是Go语言中 ...
- 通过 SMB 共享目录
在 system1 上配置SMB服务 ,要求: 1.您的 SMB 服务器必须是 STAFF 工作组的一个成员 2.共享 /common 目录,共享名必须为 common 3.只有 group8.exa ...
- .Net Core SignalR+LayUi(1)-简单入门
本系列主要开发客服聊天系统的总结. 基于.Net Core2.2 +SignalR+Layui实现的人对人聊天功能 SignalR简介 SignalR是一个.Net Core/.Net Framewo ...
- mysql-数据库查询语句汇总
目录 数据库查询语句 ***** 添加数据补充: 所有的select 关键字 where 条件 distinct 去除重复记录 指定字段 取别名 group by having order limit ...
- 【转载】C#中使用decimal.TryParse方法将字符串转换为十进制decimal类型
在C#编程过程中,将字符串string转换为decimal类型过程中,时常使用decimal.Parse方法,但decimal.Parse在无法转换的时候,会抛出程序异常,其实还有个decimal.T ...
- 解决vue-cli项目开发中跨域问题
一.开发环境中跨域 使用 Vue-cli 创建的项目,开发地址是 localhost:8080,需要访问非本机上的接口http://10.1.0.34:8000/queryRole.不同域名之间的访问 ...
- python基础知识和练习代码
1.编译:将高级语言源代码转换成目标代码(机器语言),程序便可运行. 好处:目标代码执行速度更快:目标代码在相同操作系统上使用灵活. 2.解释:将高级语言源代码逐条转换成目标代码同时逐条执行,每次 ...
- Docker 基础篇 入门篇
1.Docker入门 1.为什么要用docker? 相比于传统: 部署非常慢 成本非常高 资源浪费 难于迁移和扩展 可能会被限定硬件厂商 由于物理机的诸多问题,后来出现了虚拟机 一个物理机可以部署多个 ...
- The Middle English word was Affrike非洲
Africa (n.) Latin Africa (terra) "African land, Libya, the Carthaginian territory, the province ...