先来个效果图韵下味:

需求:

  1. 音频的播放,暂停,中间按钮状态的变化,播放时实时更新播放进度;
  2. 前进15s,后退15s;
  3. 进度条拖动。

一开始想着这3个功能应该挺简单的。不就是播放,暂停,前进,后退么~呵~写的时候发现自己还是太年轻。当然,这跟自己的技术功底有关系。现在把我遇到的难点及要注意的点说一下~

  1. 需要设置一个名为seekPosition的全局变量,初始值为0。我们要在播放的时候实时记录播放的位置,存到该变量里,这是方便在前进15s 或 后退15s 时计算时间点。
  2. 前进15s时要判断剩余时间是否>15s,如果<15s,则返回到开始位置;
  3. 后退15s时要判断播放时间是否>15s,如果<15s,则返回到开始位置;
  4. 点击播放时,要先判断seekPisition是否>0,如果>0,则跳转到seekPosition的位置,并播放;
  5. 拖动时,要先让音频停止播放,拖动结束后,再播放音频。并且要计算拖动位置对应的时间。

完整代码:

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);
}
}
}
})

大概就是这些了~有更好解决方案的欢迎留言哈~~

微信小程序——音频播放器的更多相关文章

  1. 微信小程序音频播放 InnerAudioContext 的用法

    今天项目上涉及到了微信小程序播放音频功能,所以今天跟着一些教程做了个简单的播放器 1.实现思路 刚开始想着有没有现成的组件可以直接用,找到了微信的媒体组件 audio,奈何看着 1.6.0版本开始,该 ...

  2. 微信小程序音乐播放器

    写在前面 1.入门几天小白的作品,希望为您有帮助,有好的意见或简易烦请赐教 2.微信小程序审核音乐类别已经下架,想要发布选题需慎重.附一个参考链接,感谢https://www.hishop.com.c ...

  3. 微信小程序 - 音频播放(1.2版本和1.2版本之后)

    不多说了,直接贴code // 1.2版本以后便不在维护 wx.getBackgroundAudioManager({ success:function(res){ var status =res.s ...

  4. 微信小程序音乐播放器组件

    wxml <image bindtap="click" src="{{isPlay?'/images/':'/images/'}}"/> JS Pa ...

  5. 微信小程序自运营器 微信小程序自动运营器(让你的微信小程序,公众号零运营成本,24小时全自动运营)

    自动发单,自动评价,自动评论,自动推广 微信小程序自运营器  微信小程序自动运营器(让你的微信小程序,公众号零运营成本,24小时全自动运营) 我们会根据你的微信公众号或微信小程序定制开发带有一定AI智 ...

  6. 微信小程序api拦截器

    微信小程序api拦截器 完美兼容原生小程序项目 完美兼用小程序api的原本调用方式,无痛迁移 小程序api全Promise化 和axios一样的请求方式 小程序api自定义拦截调用参数和返回结果 强大 ...

  7. 微信小程序音频背景播放

    由于微信小程序官方将音频的样式固定死了,往往再工作中和UI设计师设计出来的样式不符,故一般都采用背景音频播放来实现自定义的UI样式的音频播放,即使用官网API提供的BackgroundAudioMan ...

  8. 微信小程序音乐播放

    最近在写一个艾美食艾音乐的微信小程序,其中有用到音乐播放的功能,基本播放切换功能已经实现,但是在反复切换歌曲.重新进入歌曲以及单曲循环.列表循环的测试过程中还是发生了bug,特此写一篇文章,捋一下思路 ...

  9. 微信小程序音频长度获取的问题

    小程序推荐使用wx.createInnerAudioContext()创建的innerAudioContext,我们也通过这个接口创建音频.音频的长度可以通过属性获取: 但是,给innerAudioC ...

随机推荐

  1. 17 SpringMVC response响应

    1.Model.ModelMap和ModelAndView的使用详解 Spring-MVC在请求处理方法可出现和返回的参数类型中,最重要就是Model和ModelAndView了,对于MVC框架,控制 ...

  2. Label&Button

    Button中的bg参数设置按钮背景颜色,fg参数设置字体颜色 pack中的fill参数告诉Packer让QUIT按钮占据剩余的水平空间,而expand参数则引导它填充整个水平可视空间,将按钮拉伸到左 ...

  3. SQL SERVER 数据库查询表信息

    SELECT 表名 then d.name else '' end, 表说明 then isnull(f.value,'') else '' end, 字段序号 = a.colorder, 字段名 = ...

  4. (八)pdf的构成之文件体(page属性)

    资源(Resources) 类型:字典 属性: Font :一个字典,内部是该资源包含的各个字体的名称(字体名称F开头) ProcSet :该资源中使用图画还是文字,可选 /PDF /Text /Im ...

  5. 【Linux】Ubuntu修改root用户密码

    使用vmware安装ubuntu的时候,安装完之后发现没有root用户密码,只有新建用户,这个时候需要重新设置root用户密码 在新建用户下面运行 sudo passwd root

  6. MSP---企业上云需要考虑的问题

    一.评估 1.应用是否可以上云: 2.时间:规划时间,迁移时间 2.成本:人力成本,资源成本 二.上云 1.如何上云:选择云厂商,选择MSP 2.云选择:公有云,私有云,混合云,多云(不要最贵的,也不 ...

  7. python爬虫-有道翻译-js加密破解

    有道翻译-js加密破解 这是本地爬取的网址:http://fanyi.youdao.com/ 一.分析请求 我们在页面中输入:水果,翻译后的英文就是:fruit.请求携带的参数有很多,先将参数数据保存 ...

  8. onActivityResult方法的使用

    转发自:https://blog.csdn.net/hacker_crazy/article/details/78345450 在进行界面间的跳转和传递数据的时候,我们有的时候要获得跳转之后界面传递回 ...

  9. Java web服务端参数校验Javax.validation (springboot)

    一.基本使用 Javax.validation是spring集成自带的一个参数校验接口.可通过添加注解来设置校验条件. 下面以springboot项目为例进行说明.创建web项目后,不需要再添加其他的 ...

  10. 【开发笔记】- MySQL EXPLAIN用法和结果的含义

    转自:http://blog.chinaunix.net/uid-540802-id-3419311.html explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择 ...