123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- /**
- * @fileoverview audio 组件
- */
- const context = require('./context')
- Component({
- data: {
- time: '00:00'
- },
- properties: {
- name: String, // 音乐名
- author: String, // 作者
- poster: String, // 海报图片地址
- autoplay: Boolean, // 是否自动播放
- controls: Boolean, // 是否显示控件
- loop: Boolean, // 是否循环播放
- src: { // 源地址
- type: String,
- observer (src) {
- this.setSrc(src)
- }
- }
- },
- created () {
- // 创建内部 context
- this._ctx = wx.createInnerAudioContext()
- this._ctx.onError(err => {
- this.setData({
- error: true
- })
- this.triggerEvent('error', err)
- })
- this._ctx.onTimeUpdate(() => {
- const time = this._ctx.currentTime
- const min = parseInt(time / 60)
- const sec = Math.ceil(time % 60)
- const data = {}
- data.time = (min > 9 ? min : '0' + min) + ':' + (sec > 9 ? sec : '0' + sec)
- // 不在拖动状态下需要更新进度条
- if (!this.lastTime) {
- data.value = time / this._ctx.duration * 100
- }
- this.setData(data)
- })
- this._ctx.onEnded(() => {
- if (!this.properties.loop) {
- this.setData({
- playing: false
- })
- }
- })
- // #ifndef ALIPAY
- },
- attached () {
- context.set(this.id, this)
- // #endif
- // #ifdef MP-ALIPAY
- context.set(this.properties.id, this)
- this.setSrc(this.properties.src)
- // #endif
- },
- // #ifdef MP-ALIPAY
- didUpdate (e) {
- if (e.src !== this.properties.src) {
- this.setSrc(this.properties.src)
- }
- },
- // #endif
- detached () {
- this._ctx.destroy()
- // #ifndef MP-ALIPAY
- context.remove(this.id)
- // #endif
- // #ifdef MP_ALIPAY
- context.remove(this.properties.id)
- // #endif
- },
- // #ifndef ALIPAY | TOUTIAO
- pageLifetimes: {
- show () {
- // 播放被后台打断时,页面显示后自动继续播放
- if (this.data.playing && this._ctx.paused) {
- this._ctx.play()
- }
- }
- },
- // #endif
- methods: {
- /**
- * @description 设置源
- * @param {string} src 源地址
- */
- setSrc (src) {
- this._ctx.autoplay = this.properties.autoplay
- this._ctx.loop = this.properties.loop
- this._ctx.src = src
- if (this.properties.autoplay && !this.data.playing) {
- this.setData({
- playing: true
- })
- }
- },
- /**
- * @description 播放音乐
- */
- play () {
- this._ctx.play()
- this.setData({
- playing: true
- })
- this.triggerEvent('play'
- // #ifdef MP-ALIPAY
- , {
- target: {
- id: this.props.id
- }
- }
- // #endif
- )
- },
- /**
- * @description 暂停音乐
- */
- pause () {
- this._ctx.pause()
- this.setData({
- playing: false
- })
- this.triggerEvent('pause')
- },
- /**
- * @description 设置播放速率
- * @param {Number} rate 播放速率
- */
- playbackRate (rate) {
- this._ctx.playbackRate = rate
- },
- /**
- * @description 停止音乐
- */
- stop () {
- this._ctx.stop()
- this.setData({
- playing: false,
- time: '00:00'
- })
- this.triggerEvent('stop')
- },
- /**
- * @description 控制进度
- * @param {number} sec 秒数
- */
- seek (sec) {
- this._ctx.seek(sec)
- },
- /**
- * @description 移动进度条
- * @param {event} e
- * @private
- */
- _seeking (e) {
- // 避免过于频繁 setData
- if (e.timeStamp - this.lastTime < 200) return
- const time = Math.round(e.detail.value / 100 * this._ctx.duration)
- const min = parseInt(time / 60)
- const sec = time % 60
- this.setData({
- time: (min > 9 ? min : '0' + min) + ':' + (sec > 9 ? sec : '0' + sec)
- })
- this.lastTime = e.timeStamp
- },
- /**
- * @description 进度条移动完毕
- * @param {event} e
- * @private
- */
- _seeked (e) {
- this._ctx.seek(e.detail.value / 100 * this._ctx.duration)
- this.lastTime = undefined
- }
- }
- })
|