用空閑時間做了一個小程序-文字轉(zhuǎn)語音2.0(語音播放進(jìn)度條)
一直在摸魚中賺錢的大家好呀~
上篇文章講到了獲取語音時長遇到的一些問題和樓主的解決方案,這篇文章就接著上文繼續(xù)往下實(shí)現(xiàn)語音播放進(jìn)度的解決方案。這篇文章會講到播放進(jìn)度條的實(shí)現(xiàn),希望這篇文章可以給更多的 魚友們(沒錯就是你們) 的解決一些開發(fā)中遇到的問題或者啟發(fā),也希望樓主的小程序有更多的 魚友 加入。

接上篇文章,先來看下知名UI設(shè)計(jì)師設(shè)計(jì)的UI圖。

既然要實(shí)現(xiàn)語音的播放進(jìn)度,那在整個過程中我們需要記錄這么幾個信息:
-
語音時長 (上篇文章已經(jīng)獲取)
-
語音是否正在播放
-
語音當(dāng)前播放的位置
在官方文檔中有幾個監(jiān)聽事件: onPlay : 監(jiān)聽音頻播放事件。 onPause : 監(jiān)聽音頻暫停事件。 onStop : 監(jiān)聽音頻停止事件。
他會在調(diào)用了 play ,觸發(fā) onPlay 監(jiān)聽事件,在這個事件中變更播放的狀態(tài)。同樣也要在觸發(fā) onPause 、 onStop 這兩個監(jiān)聽事件的時候變更播放的狀態(tài)。
在官方文檔中有一個監(jiān)聽事件: onTimeUpdate : 監(jiān)聽音頻播放進(jìn)度更新事件。他會在音頻播放的過程中不斷的觸發(fā),我們可以在這個事件中調(diào)用 audio.currentTime 獲取到當(dāng)前音頻播放的位置。
這些都比較簡單,貼下部分實(shí)現(xiàn)代碼:
js
const { url } = this.data.info
const audio = wx.createInnerAudioContext('audio')
audio.src = url
audio.onCanplay(() => {
audio.duration;
setTimeout(() => {
const duration = audio.duration
this.setData({ duration, durationText: Math.ceil(duration) + 's' })
}, 10000)
})
audio.onPlay(() => this.setData({ playing: true }))
audio.onTimeUpdate(() => this.setData({ currentTime: audio.currentTime }))
const stop = () => {
this.setData({ currentTime: audio.duration })
setTimeout(() => {
this.setData({ playing: false, currentTime: 0 })
}, 300)
}
audio.onPause(() => this.setData({ playing: false}))
audio.onEnded(stop)
audio.onStop(stop)
audio.onError(() => {
this.setData({ status: 0 })
wx.showToast({ title: '語音已失效!', icon: 'none', duration: 3000})
})
this.setData({ audio })
第二個難點(diǎn):播放進(jìn)度條的實(shí)現(xiàn)

先將一些簡單的工作完成,先畫個容器,容器里面將豎線按照從大到小都繪制完成:
js
<view class="audio flex-item_f-1 flex flex_a_i--center">
<image class="listen-image" src="/images/{{ playing ? 'stop' : 'play' }}.png" mode="aspectFill" bind:tap="listenHandle"></image>
<view class="progress-wrap flex-item_f-1 ">
<view class="height-full flex flex_a_i--center">
<view class="stage flex_s-0" wx:for="{{42}}" wx:key="item" style="height: {{ 100 - item % 4 * 25 + '%'}}"></view>
</view>
</view>
</view>
通過flex布局將豎線并排顯示,超出的部分隱藏?;竟ぷ魇亲鐾炅爽F(xiàn)在的難點(diǎn)是如何能讓這些豎線按照所在位置的百分比進(jìn)行變色呢?可以通過JS計(jì)算寬度等方式計(jì)算出要添加顏色的位置,但是這太麻煩了,不是我想要的方法。有沒有不通過JS的實(shí)現(xiàn)方式呢?那肯定有,下面來講一下我的實(shí)現(xiàn)思路。
CSS中有一個 clip-path 屬性: 使用裁剪方式創(chuàng)建元素的可顯示區(qū)域。配置 polygon 來計(jì)算顯示的區(qū)域。那我們需要一組相同的帶顏色的豎線覆蓋在原來的豎線上,我們只要從左往右按照播放進(jìn)度的百分比 (當(dāng)前播放時間除以音頻時長) 對有顏色的豎線進(jìn)行顯示即可,。貼一下我的實(shí)現(xiàn)代碼:
js
<view class="audio flex-item_f-1 flex flex_a_i--center">
<image class="listen-image" src="/images/{{ playing ? 'stop' : 'play' }}.png" mode="aspectFill" bind:tap="listenHandle"></image>
<view class="progress-wrap flex-item_f-1 ">
<view class="height-full flex flex_a_i--center">
<view class="stage flex_s-0" wx:for="{{42}}" wx:key="item" style="height: {{ 100 - item % 4 * 25 + '%'}}"></view>
</view>
<view class="clip-wrap flex flex_a_i--center" style="clip-path: polygon(0 0, 0 100%, {{ currentTime / duration * 100 + '%' }} 100%, {{ currentTime / duration * 100 + '%' }} 0);">
<view class="stage flex_s-0" wx:for="{{42}}" wx:key="item" style="height: {{ 100 - item % 4 * 25 + '%'}};"></view>
</view>
</view>
</view>
目前小程序還在審核中,審核通過之后即可體驗(yàn)語音分享功能。如果大家還有好的實(shí)現(xiàn)方式可以在評論區(qū)一起探討!
感謝大家觀看我今日的水文,文筆實(shí)在是不行,歡迎魚友們給小程序提提意見,或者有什么有趣的想法也可以與樓主提一提。最后希望大家到我的小程序來多坐坐。

最后的最后,如果覺得文章不錯的話,可以給小生的幾個開源項(xiàng)目點(diǎn)個Star?!
-
基于 Vue3 + Element-plus 管理后臺基礎(chǔ)功能框架
-
預(yù)覽: https://admin.gumingchen.icu
-
Github: https://github.com/gmingchen/agile-admin
-
Gitee: https://gitee.com/shychen/agile-admin
-
基礎(chǔ)版后端: https://github.com/gmingchen/java-spring-boot-admin
-
文檔: http://admin.gumingchen.icu/doc/
-
-
基于 Vue3 + Element-plus + websocket 即時聊天系統(tǒng)
-
預(yù)覽: http://im.gumingchen.icu
-
代碼: https://github.com/gmingchen/vue3-element-plus-im
-
后端代碼: https://github.com/gmingchen/java-im
-
-
基于 node 開發(fā)的后端服務(wù): https://github.com/gmingchen/node-server
