微信小程序从入坑到放弃二十七:可控制播放进度的音乐播放器(初级版)

摘要:
微信小程序官方文档中的audio音频播放器可控制播放可暂停,但无法实现通过拖拽时间轴达到跳帧的功能。因此,为了尽可能还原UI原型,只好造轮子了。最终使用movable-area + wx.createInnerAudioContext(音频API)完成了需求。此版为初级版,性能欠佳,下篇续写优化版…

大纲

    • 一、起因
    • 二、UI界面拆解
    • 三、方案评选
      • 3.1、原生的audio音频组件相差甚远
      • 3.2、slider 滑动选择器组件无法在滑块位置设置播放进度
      • 3.3、progress 进度条组件无法设置滑块及播放进度
      • 3.4、movable-area 组件通过改造暂可行
      • 3.5、最终可行的一个方案
    • 四、浅析坑及细节
      • 4.1、遇到的坑
      • 4.2、细节
    • 五、demo源码
    • 六、来源

一、起因

年后,公司的微信小程序中新增了一个需求:在资讯文章中添加音频。最终效果如图:资讯文章中的音频播放器.gif
微信小程序从入坑到放弃二十七:可控制播放进度的音乐播放器(初级版)_第1张图片

二、UI界面拆解

从上图中可以得到以下信息:

  • 播放/暂停按钮、
  • 播放时间轴、
  • 总播放时间、
  • 当前播放时间、
  • 播放过的时间显示主色调、
  • 拖拽时用tips显示当前播放时间。

看官有没有惊呆?一个乍看不起眼的组件,竟然包含了接近完整的音乐播放器的功能。“麻雀虽小,五脏俱全。”用在这里再合适不过了。

三、方案评选

3.1、原生的audio音频组件相差甚远

拿到产品的需求后,首先艺灵我想的是:微信小程序中有没有自带的音乐播放器组件呢? 然后我就找到了audio 音频(点击访问官方文档)
,但发现默认的audio组件UI界面与我们的相差甚远!如图:audio音频组件默认效果图.png
微信小程序从入坑到放弃二十七:可控制播放进度的音乐播放器(初级版)_第2张图片
既然原生的不行,那我们通过一个自定义的音频时间轴来映射原生的audio是不是就可以了呢?那此时我们需要先解决音频时间轴的问题。

3.2、slider 滑动选择器组件无法在滑块位置设置播放进度

在UI原型中,最难处理的应该算那个 拖拽滑块儿控制播放进度 的操作了。对于滑块功能,微信小程序官方文档中提供了slider 滑动选择器(点击访问官方文档)。看似很接近了,但在实际操作中却发现:无法设置时时的播放进度。 如图:slider滑动选择器组件很接近UI原型了但无法设置时时播放进度.png微信小程序从入坑到放弃二十七:可控制播放进度的音乐播放器(初级版)_第3张图片

3.3、progress 进度条组件无法设置滑块及播放进度

继续看文档,艺灵又找到了progress 进度条(点击访问官方文档),如图:progress进度条组件默认效果图.png微信小程序从入坑到放弃二十七:可控制播放进度的音乐播放器(初级版)_第4张图片
但这个也跟我们的UI原型差很多且无法定制。

3.4、movable-area 组件通过改造暂可行

最接近且改动最少的sliderprogress因限制因素相继排除,难道我们只能硬造轮子了吗?还好,我们可以借助movable-area 可移动的视图容器(点击访问官方文档)进行改造。如图:movable-area虽然默认样式不咋样,但可通过wxss进行修改呀.png微信小程序从入坑到放弃二十七:可控制播放进度的音乐播放器(初级版)_第5张图片

3.5、最终可行的一个方案

绕了一大圈并经过实践,艺灵最终推荐的方案是:movable-area(负责实现拖拽) + wx.createInnerAudioContext(控制音频API的播放、暂停、跳帧等)

四、浅析坑及细节

前面在讨论视觉上的方案,看似已经实现了80%,但实际上革命才刚刚开始!

4.1、遇到的坑

  • 只有播放的音频才能在真机上获取时长(言外之意:音频需要自动播放,否则初始化时无法准确获取总时间);
  • onPlay中必须要调用this.innerAudioContext.duration,否则切换播放和暂停时会出现异常;
  • movable-view组件的animation属性默认为true,此处要修改为false
  • 此版会存在卡顿现象

4.2、细节

  • 1、音频地址必须是网络地址,不能是本地;
  • 2、页面加载(ready)后动态获取时间轴的有效长度,即:总长度- 滑块长度;
  • 3、触摸(touchStart)进度条的把柄时停止播放;
  • 4、拖拽过程(bindchange)中,动态计算出当前播放位置(currentTime);
  • 5、触摸结束(touchEnd)后使用seek跳转到当前位置;
  • 6、跳转会触发(onSeeked)函数,此时要自动播放;
  • 7、音频播放结束(onEnded)后,重置成初始状态;
  • 8、离开页面(detached)时销毁音频,否则会继续播放;

  • 总体来说,实现过程中的坑和要注意的细节还是挺多的,diyAudioPlayer.wxml代码有20余行。大致如下:
<view class="my-audio">
 <view class="audio-box">
  <!-- 播放/暂停的图标 start -->
  <image class="audio__status" src="{{(isPlay ? pauseSrc : playSrc)}}" mode="widthFix" bindtap="{{isPlay ? 'goPause' : 'goPlay'}}"></image>
  <!-- 播放/暂停的图标 end -->
  <view class="audio__content">
   <view class="audio__progress">
    <movable-area class="audio__progress">
     <movable-view class="audio__progress_bar {{isCanplay ? '' : 'audio__progress_loading'}}" x="{{x}}" direction="horizontal" bindchange="bindchange" bindtouchmove="touchMove" bindtouchend="touchEnd" bindtouchstart="touchStart" animation="{{false}}" >{{progress}}/{{total}}
      <!-- 按住拖拽时的tips start -->
      <view class="audio__progress_tips" wx:if="{{isTouchMove}}">{{progress}}/{{total}}</view>
      <!-- 按住拖拽时的tips end -->
     </movable-view>
    </movable-area>
    <!-- 已经播放的进度 start -->
    <view class="audio__progress_current" wx:if="{{isProgress}}" style="width:{{x}}px"></view>
    <!-- 已经播放的进度 end -->
   </view>
  </view>
 </view>
</view>

完整的js代码有2百多行,已上传到github,此处就不粘贴了。最终效果如图:可控制播放进度的音乐播放器.png
点我观看最终效果

五、demo源码

demo源码已上传到了github上,如果看官需要研究源码,可以点击下面的链接进行访问并下载。github仓库

源码中会有必要注释和本篇文章中的示例,若看官在拉完代码后有疑问,可与艺灵联系,方式见下方二维码或右侧。

最后,由于是初级版,所以本文的demo在真机上会大概率出现卡顿的现象,明天会续写优化版。看官记得明天来看哦~

以下内容续写于:2020-05-12 号夜

优化后的文章地址:微信小程序从入坑到放弃二十八:开发一款DIY音乐播放器(WXS优化版)

六、来源

原文首发于艺灵设计,转载请注明来源,谢谢!

你可能感兴趣的:(微信小程序-日常踩坑)