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

需求:
- 音频的播放,暂停,中间按钮状态的变化,播放时实时更新播放进度;
- 前进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 ...
随机推荐
- Go基础编程实践(八)—— 系统编程
捕捉信号 // 运行此程序,控制台将打印"Waiting for signal" // 按Ctrl + C 发送信号以关闭程序,将发生中断 // 随后控制台依次打印"Si ...
- Flink WorkCount代码
Flink-scala所需依赖 <properties> <flink.version>1.7.0</flink.version> </properties& ...
- Huber Loss 介绍
Huber Loss 是一个用于回归问题的带参损失函数, 优点是能增强平方误差损失函数(MSE, mean square error)对离群点的鲁棒性. 当预测偏差小于 δ 时,它采用平方误差,当预测 ...
- Ambari调整日志级别:How to enable debug logging in Ambari Server and Ambari Agent ?
PURPOSE When troubleshooting Ambari issues, it may be necessary to enable debug logging in the Ambar ...
- iOS 12中获取WiFi的SSID
开始搞智能家居,wifi获取不到了?? 小插曲 旧方法失效,19-12-15更新,ios13开始需要请求定位信息 SSID全称Service Set IDentifier, 即Wifi网络的公开名称. ...
- CSS-图片整合笔记
注意点: 概念:图片整合技术( css sprite 或 精灵图).通过将多个图片融合到一张图片,然后通过CSS background 背景定位技术技巧布局网页背景 优势:减少 http iis 请求 ...
- 网络编程之 tcp服务器(一)
1.创建套接字 2.bind绑定ip和port 作为服务方,ip port 应该是固定的,所以要绑定;客户端一般不绑定 3.listen使套接字变成监听套接字,即变为被动链接 4.accept等待客户 ...
- MySQL Install--MySQL安装相关知识和问题
1.mysqld和mysqld_safe之间关系 mysqld_safe是一个启动脚本,用来启动MySQL服务器并监控MySQL服务的运行情况,并在其服务出现故障宕机后重启其服务. mysql.ser ...
- Upgrade Windows Server 2016 to Windows Server 2019
Pre-Upgrade Upgrade path: Windows Server 2016 can be upgraded to Windows 2019 in a single upgrade pr ...
- 云计算与大数据实验:Hbase shell终端操作之数据操作一
[实验目的] 1)学会向表中添加记录 2)学会添加记录时动态添加列 3)学会查看一条记录 4)学会查看表中的记录总数 5)学会删除记录 [实验原理] Hbase shell作为Hbase数据的客户端, ...