uview-ultra 4.5.75 → 4.5.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +59 -0
- package/components/up-audio/audio-pool.js +2 -0
- package/components/up-audio/audio-pool.uts +2 -0
- package/components/up-audio/audio.js +19 -0
- package/components/up-audio/audio.uts +19 -0
- package/components/up-audio/props.js +43 -0
- package/components/up-audio/up-audio.uvue +418 -0
- package/components/up-audio/up-audio.vue +315 -0
- package/components/up-lottie/up-lottie.uvue +16 -2
- package/components/up-parse/node/node.vue +21 -3
- package/components/up-video/video.uts +1 -2
- package/libs/config/props.js +2 -0
- package/package.json +3 -3
- package/types/comps/audio.d.ts +57 -0
- package/types/comps.d.ts +121 -120
- package/types/index.d.ts +383 -382
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<view class="up-audio">
|
|
3
|
+
<!-- 播放/暂停按钮 -->
|
|
4
|
+
<view
|
|
5
|
+
class="up-audio__btn"
|
|
6
|
+
:style="{ backgroundColor: activeColor }"
|
|
7
|
+
@tap.stop="toggle"
|
|
8
|
+
>
|
|
9
|
+
<text class="up-audio__btn-icon">{{ playing ? '❚❚' : '▶' }}</text>
|
|
10
|
+
</view>
|
|
11
|
+
<!-- 主体:标题 + 时间 + 进度条 -->
|
|
12
|
+
<view class="up-audio__main">
|
|
13
|
+
<view class="up-audio__row">
|
|
14
|
+
<text
|
|
15
|
+
v-if="hasTitle"
|
|
16
|
+
class="up-audio__title"
|
|
17
|
+
>{{ displayTitle }}</text>
|
|
18
|
+
<text class="up-audio__time">{{ formatTime(currentTime) }} / {{ formatTime(duration) }}</text>
|
|
19
|
+
</view>
|
|
20
|
+
<slider
|
|
21
|
+
class="up-audio__slider"
|
|
22
|
+
:value="progress"
|
|
23
|
+
:max="100"
|
|
24
|
+
:block-size="10"
|
|
25
|
+
:activeColor="activeColor"
|
|
26
|
+
backgroundColor="#e4e7ed"
|
|
27
|
+
@changing="onChanging"
|
|
28
|
+
@change="onChange"
|
|
29
|
+
/>
|
|
30
|
+
</view>
|
|
31
|
+
<!-- 倍速 -->
|
|
32
|
+
<view
|
|
33
|
+
v-if="showRate"
|
|
34
|
+
class="up-audio__rate"
|
|
35
|
+
@tap.stop="changeRate"
|
|
36
|
+
>
|
|
37
|
+
<text class="up-audio__rate-text">{{ rateText }}</text>
|
|
38
|
+
</view>
|
|
39
|
+
</view>
|
|
40
|
+
</template>
|
|
41
|
+
|
|
42
|
+
<script setup>
|
|
43
|
+
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
|
44
|
+
import { props as audioProps } from './props.js'
|
|
45
|
+
import { commonProps } from '../../libs/composable/useUltraUI.js'
|
|
46
|
+
import { audioInstancePool } from './audio-pool.js'
|
|
47
|
+
/**
|
|
48
|
+
* up-audio 音频播放器
|
|
49
|
+
* @description uni-app 在 Vue3 中已废弃 <audio> 组件,本组件基于 uni.createInnerAudioContext 实现播放,可单独使用,up-parse 的音频节点也由本组件渲染。
|
|
50
|
+
* @tutorial https://uview-plus.jiangruyi.com/components/audio.html
|
|
51
|
+
* @property {String | Array} src 音频地址,支持数组多源,加载失败自动切换
|
|
52
|
+
* @property {String} title 标题,显示在音频条上
|
|
53
|
+
* @property {Boolean} loop 是否循环播放 (默认 false )
|
|
54
|
+
* @property {Boolean} showRate 是否显示倍速切换 (默认 true )
|
|
55
|
+
* @property {Array} rateList 可切换的倍速档位 (默认 [0.5, 0.75, 1, 1.25, 1.5, 2] )
|
|
56
|
+
* @property {String} activeColor 主题色(播放按钮、进度条选中色) (默认 '#2979ff' )
|
|
57
|
+
* @property {Boolean} showTitle 是否显示标题 (默认 true )
|
|
58
|
+
* @event {Function} play 开始播放时触发,参数 { source, src }
|
|
59
|
+
* @event {Function} error 加载/播放出错时触发,参数 { source, errMsg }
|
|
60
|
+
* @example <up-audio src="https://cdn.example.com/a.mp3" title="示例音频"></up-audio>
|
|
61
|
+
*/
|
|
62
|
+
defineOptions({
|
|
63
|
+
name: 'up-audio',
|
|
64
|
+
// #ifdef MP-WEIXIN
|
|
65
|
+
options: {
|
|
66
|
+
virtualHost: true
|
|
67
|
+
}
|
|
68
|
+
// #endif
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
const props = defineProps({
|
|
72
|
+
...commonProps,
|
|
73
|
+
...audioProps.props
|
|
74
|
+
})
|
|
75
|
+
const emit = defineEmits(['play', 'error'])
|
|
76
|
+
|
|
77
|
+
const playing = ref(false)
|
|
78
|
+
const currentTime = ref(0)
|
|
79
|
+
const duration = ref(0)
|
|
80
|
+
const progress = ref(0)
|
|
81
|
+
const srcIndex = ref(0)
|
|
82
|
+
const rate = ref(1)
|
|
83
|
+
const seeking = ref(false)
|
|
84
|
+
const errorMsg = ref('')
|
|
85
|
+
let ctx = null
|
|
86
|
+
|
|
87
|
+
const srcList = computed(() => {
|
|
88
|
+
if (Array.isArray(props.src)) return props.src.filter(Boolean)
|
|
89
|
+
return props.src ? [props.src] : []
|
|
90
|
+
})
|
|
91
|
+
const displayTitle = computed(() => props.title || '')
|
|
92
|
+
const hasTitle = computed(() => props.showTitle && displayTitle.value !== '')
|
|
93
|
+
const currentSrc = computed(() => srcList.value[srcIndex.value] || '')
|
|
94
|
+
const rateText = computed(() => {
|
|
95
|
+
const r = rate.value
|
|
96
|
+
return (Number.isInteger(r) ? r.toFixed(0) : String(r)) + 'x'
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// src 变化时重建播放器
|
|
100
|
+
watch(() => props.src, () => {
|
|
101
|
+
reset()
|
|
102
|
+
}, { deep: true })
|
|
103
|
+
|
|
104
|
+
onMounted(() => {
|
|
105
|
+
init()
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
onBeforeUnmount(() => {
|
|
109
|
+
destroy()
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
// 源变化时重建
|
|
113
|
+
function reset() {
|
|
114
|
+
destroy()
|
|
115
|
+
srcIndex.value = 0
|
|
116
|
+
currentTime.value = 0
|
|
117
|
+
duration.value = 0
|
|
118
|
+
progress.value = 0
|
|
119
|
+
playing.value = false
|
|
120
|
+
init()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function init() {
|
|
124
|
+
if (!currentSrc.value) return
|
|
125
|
+
const audioCtx = uni.createInnerAudioContext()
|
|
126
|
+
ctx = audioCtx
|
|
127
|
+
audioCtx.src = currentSrc.value
|
|
128
|
+
if (props.loop) audioCtx.loop = true
|
|
129
|
+
audioCtx.onPlay(() => {
|
|
130
|
+
playing.value = true
|
|
131
|
+
// 暂停实例池中的其它音频,保证多实例互斥
|
|
132
|
+
for (let i = audioInstancePool.length; i--;) {
|
|
133
|
+
if (audioInstancePool[i] !== audioCtx) {
|
|
134
|
+
try { audioInstancePool[i].pause() } catch (e) {}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
emit('play', {
|
|
138
|
+
source: 'audio',
|
|
139
|
+
src: currentSrc.value
|
|
140
|
+
})
|
|
141
|
+
})
|
|
142
|
+
audioCtx.onPause(() => { playing.value = false })
|
|
143
|
+
audioCtx.onStop(() => { playing.value = false })
|
|
144
|
+
audioCtx.onEnded(() => {
|
|
145
|
+
playing.value = false
|
|
146
|
+
currentTime.value = 0
|
|
147
|
+
progress.value = 0
|
|
148
|
+
})
|
|
149
|
+
audioCtx.onTimeUpdate(() => {
|
|
150
|
+
if (seeking.value) return
|
|
151
|
+
currentTime.value = audioCtx.currentTime || 0
|
|
152
|
+
if (audioCtx.duration) duration.value = audioCtx.duration
|
|
153
|
+
progress.value = duration.value ? (currentTime.value / duration.value) * 100 : 0
|
|
154
|
+
})
|
|
155
|
+
audioCtx.onCanplay(() => {
|
|
156
|
+
if (audioCtx.duration) duration.value = audioCtx.duration
|
|
157
|
+
})
|
|
158
|
+
audioCtx.onError(err => handleError(err))
|
|
159
|
+
audioInstancePool.push(audioCtx)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function destroy() {
|
|
163
|
+
if (ctx) {
|
|
164
|
+
const idx = audioInstancePool.indexOf(ctx)
|
|
165
|
+
if (idx > -1) audioInstancePool.splice(idx, 1)
|
|
166
|
+
try { ctx.destroy() } catch (e) {}
|
|
167
|
+
ctx = null
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function toggle() {
|
|
172
|
+
if (!ctx) return
|
|
173
|
+
if (playing.value) {
|
|
174
|
+
ctx.pause()
|
|
175
|
+
} else {
|
|
176
|
+
ctx.play()
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// 拖动进度条中(只更新本地显示)
|
|
181
|
+
function onChanging(e) {
|
|
182
|
+
seeking.value = true
|
|
183
|
+
progress.value = e.detail.value
|
|
184
|
+
currentTime.value = duration.value ? (duration.value * e.detail.value) / 100 : 0
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// 拖动结束,真正 seek
|
|
188
|
+
function onChange(e) {
|
|
189
|
+
seeking.value = false
|
|
190
|
+
progress.value = e.detail.value
|
|
191
|
+
if (ctx && duration.value) {
|
|
192
|
+
try { ctx.seek((duration.value * e.detail.value) / 100) } catch (err) {}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function changeRate() {
|
|
197
|
+
const list = (props.rateList && props.rateList.length) ? props.rateList : [0.5, 0.75, 1, 1.25, 1.5, 2]
|
|
198
|
+
let i = list.indexOf(rate.value)
|
|
199
|
+
if (i === -1) i = list.indexOf(1)
|
|
200
|
+
rate.value = list[(i + 1) % list.length]
|
|
201
|
+
if (ctx) {
|
|
202
|
+
try { ctx.playbackRate = rate.value } catch (e) {}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// 加载失败:尝试下一个源;全部失败则抛 error
|
|
207
|
+
function handleError(err) {
|
|
208
|
+
if (srcIndex.value < srcList.value.length - 1) {
|
|
209
|
+
srcIndex.value += 1
|
|
210
|
+
currentTime.value = 0
|
|
211
|
+
progress.value = 0
|
|
212
|
+
if (ctx) {
|
|
213
|
+
ctx.src = currentSrc.value
|
|
214
|
+
try { ctx.play() } catch (e) {}
|
|
215
|
+
}
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
playing.value = false
|
|
219
|
+
errorMsg.value = (err && err.errMsg) || '音频加载失败'
|
|
220
|
+
emit('error', {
|
|
221
|
+
source: 'audio',
|
|
222
|
+
errMsg: errorMsg.value
|
|
223
|
+
})
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function formatTime(sec) {
|
|
227
|
+
sec = Math.floor(sec || 0)
|
|
228
|
+
const m = Math.floor(sec / 60)
|
|
229
|
+
const s = sec % 60
|
|
230
|
+
return m + ':' + (s < 10 ? '0' + s : s)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
defineExpose({
|
|
234
|
+
toggle,
|
|
235
|
+
reset,
|
|
236
|
+
changeRate
|
|
237
|
+
})
|
|
238
|
+
</script>
|
|
239
|
+
|
|
240
|
+
<style
|
|
241
|
+
lang="scss"
|
|
242
|
+
scoped
|
|
243
|
+
>
|
|
244
|
+
.up-audio {
|
|
245
|
+
display: flex;
|
|
246
|
+
align-items: center;
|
|
247
|
+
padding: 12rpx 16rpx;
|
|
248
|
+
margin: 8rpx 0;
|
|
249
|
+
border-radius: 8rpx;
|
|
250
|
+
background-color: #f5f7fa;
|
|
251
|
+
|
|
252
|
+
&__btn {
|
|
253
|
+
flex-shrink: 0;
|
|
254
|
+
width: 56rpx;
|
|
255
|
+
height: 56rpx;
|
|
256
|
+
border-radius: 50%;
|
|
257
|
+
display: flex;
|
|
258
|
+
align-items: center;
|
|
259
|
+
justify-content: center;
|
|
260
|
+
margin-right: 16rpx;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
&__btn-icon {
|
|
264
|
+
color: #ffffff;
|
|
265
|
+
font-size: 22rpx;
|
|
266
|
+
line-height: 1;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
&__main {
|
|
270
|
+
flex: 1;
|
|
271
|
+
min-width: 0;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
&__row {
|
|
275
|
+
display: flex;
|
|
276
|
+
align-items: center;
|
|
277
|
+
justify-content: space-between;
|
|
278
|
+
margin-bottom: 2rpx;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
&__title {
|
|
282
|
+
flex: 1;
|
|
283
|
+
font-size: 26rpx;
|
|
284
|
+
color: #303133;
|
|
285
|
+
overflow: hidden;
|
|
286
|
+
text-overflow: ellipsis;
|
|
287
|
+
white-space: nowrap;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
&__time {
|
|
291
|
+
flex-shrink: 0;
|
|
292
|
+
font-size: 22rpx;
|
|
293
|
+
color: #909399;
|
|
294
|
+
margin-left: 12rpx;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
&__slider {
|
|
298
|
+
margin: 0;
|
|
299
|
+
padding: 0;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
&__rate {
|
|
303
|
+
flex-shrink: 0;
|
|
304
|
+
margin-left: 16rpx;
|
|
305
|
+
padding: 4rpx 12rpx;
|
|
306
|
+
border-radius: 20rpx;
|
|
307
|
+
border: 1px solid #dcdfe6;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
&__rate-text {
|
|
311
|
+
font-size: 22rpx;
|
|
312
|
+
color: #606266;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
</style>
|
|
@@ -37,8 +37,11 @@ defineOptions({
|
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* lottie-miniprogram 的 setup() 需要一个小程序 canvas 节点:
|
|
40
|
-
* 读 width / height、调 getContext('2d')
|
|
41
|
-
*
|
|
40
|
+
* 读 width / height、调 getContext('2d'),并在初始化时接管 requestAnimationFrame /
|
|
41
|
+
* cancelAnimationFrame(内部会执行 `canvas.cancelAnimationFrame.bind(canvas)`,
|
|
42
|
+
* 缺这两个方法会抛 "Cannot read properties of undefined (reading 'bind')")。
|
|
43
|
+
* uni-app x 没有 canvas 节点对象,这里用一个桩把 up-canvas 暴露的原生 2D 上下文
|
|
44
|
+
* 包装成它期望的形状。
|
|
42
45
|
*/
|
|
43
46
|
class UpLottieCanvasStub {
|
|
44
47
|
width: number = 0
|
|
@@ -54,6 +57,17 @@ class UpLottieCanvasStub {
|
|
|
54
57
|
getContext(type: string): CanvasRenderingContext2D {
|
|
55
58
|
return this.context
|
|
56
59
|
}
|
|
60
|
+
|
|
61
|
+
// 用 setTimeout 模拟 16ms 一帧;uni-app x 没有 canvas 节点级的 rAF
|
|
62
|
+
requestAnimationFrame(callback: (time: number) => void): number {
|
|
63
|
+
return setTimeout(() => {
|
|
64
|
+
callback(Date.now())
|
|
65
|
+
}, 16)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
cancelAnimationFrame(handle: number): void {
|
|
69
|
+
clearTimeout(handle)
|
|
70
|
+
}
|
|
57
71
|
}
|
|
58
72
|
|
|
59
73
|
const props = defineProps({
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
<iframe v-else-if="n.name==='iframe'" :style="n.attrs.style" :allowfullscreen="n.attrs.allowfullscreen" :frameborder="n.attrs.frameborder" :src="n.attrs.src" />
|
|
42
42
|
<embed v-else-if="n.name==='embed'" :style="n.attrs.style" :src="n.attrs.src" />
|
|
43
43
|
<!-- #endif -->
|
|
44
|
-
<!-- #ifndef
|
|
45
|
-
<!--
|
|
46
|
-
<audio v-else-if="n.name==='audio'" :
|
|
44
|
+
<!-- #ifndef APP-PLUS-NVUE -->
|
|
45
|
+
<!-- 音频:uni-app Vue3 已废弃 <audio> 组件,统一改用 up-audio 播放(基于 uni.createInnerAudioContext) -->
|
|
46
|
+
<up-audio v-else-if="n.name==='audio'" :src="n.src" :title="n.attrs.title || n.attrs.name" :loop="!!n.attrs.loop" @play="onAudioPlay" @error="onAudioError" />
|
|
47
47
|
<!-- #endif -->
|
|
48
48
|
<view v-else-if="(n.name==='table'&&n.c)||n.name==='li'" :id="n.attrs.id" :class="'_'+n.name+' '+n.attrs.class" :style="n.attrs.style">
|
|
49
49
|
<node v-if="n.name==='li'" :childs="n.children" :opts="opts" />
|
|
@@ -112,6 +112,10 @@ import { getCurrentInstance, nextTick, onBeforeUnmount, onMounted, reactive } fr
|
|
|
112
112
|
import node from './node'
|
|
113
113
|
// #endif
|
|
114
114
|
|
|
115
|
+
// #ifndef APP-PLUS-NVUE
|
|
116
|
+
import UpAudio from '../up-audio/up-audio.vue'
|
|
117
|
+
// #endif
|
|
118
|
+
|
|
115
119
|
defineOptions({
|
|
116
120
|
name: 'node',
|
|
117
121
|
options: {
|
|
@@ -233,6 +237,20 @@ function play(e) {
|
|
|
233
237
|
// #endif
|
|
234
238
|
}
|
|
235
239
|
|
|
240
|
+
/**
|
|
241
|
+
* @description 音频播放事件(up-audio 触发,转发给 up-parse)
|
|
242
|
+
*/
|
|
243
|
+
function onAudioPlay(payload) {
|
|
244
|
+
root?.$emit('play', payload)
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* @description 音频加载/播放错误事件(up-audio 触发,转发给 up-parse)
|
|
249
|
+
*/
|
|
250
|
+
function onAudioError(payload) {
|
|
251
|
+
root?.$emit('error', payload)
|
|
252
|
+
}
|
|
253
|
+
|
|
236
254
|
/**
|
|
237
255
|
* @description 图片点击事件
|
|
238
256
|
*/
|
package/libs/config/props.js
CHANGED
|
@@ -8,6 +8,7 @@ import config from './config.js'
|
|
|
8
8
|
import ActionSheet from '../../components/up-action-sheet/actionSheet.js'
|
|
9
9
|
import Album from '../../components/up-album/album.js'
|
|
10
10
|
import Alert from '../../components/up-alert/alert.js'
|
|
11
|
+
import Audio from '../../components/up-audio/audio.js'
|
|
11
12
|
import Avatar from '../../components/up-avatar/avatar.js'
|
|
12
13
|
import AvatarGroup from '../../components/up-avatar-group/avatarGroup.js'
|
|
13
14
|
import Backtop from '../../components/up-back-top/backtop.js'
|
|
@@ -106,6 +107,7 @@ const props = {
|
|
|
106
107
|
...ActionSheet,
|
|
107
108
|
...Album,
|
|
108
109
|
...Alert,
|
|
110
|
+
...Audio,
|
|
109
111
|
...Avatar,
|
|
110
112
|
...AvatarGroup,
|
|
111
113
|
...Backtop,
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "uview-ultra",
|
|
3
3
|
"name": "uview-ultra",
|
|
4
|
-
"displayName": "零云®UviewUltra v4重磅发布,大满贯全面兼容uniapp-x
|
|
5
|
-
"version": "4.5.
|
|
4
|
+
"displayName": "零云®UviewUltra v4重磅发布,大满贯全面兼容uniapp-x蒸汽模式、uniapp鸿蒙组件库。",
|
|
5
|
+
"version": "4.5.77",
|
|
6
6
|
"description": "uview-ultra全面兼容uni-app/uni-app-x/鸿蒙/nvue,全面的组件和便捷的工具会让您信手拈来,如鱼得水",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"uview",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"dcloudext": {
|
|
21
21
|
"sale": {
|
|
22
22
|
"regular": {
|
|
23
|
-
"price": "
|
|
23
|
+
"price": "9.90"
|
|
24
24
|
},
|
|
25
25
|
"sourcecode": {
|
|
26
26
|
"price": "0.00"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { AllowedComponentProps, VNodeProps } from './_common'
|
|
2
|
+
|
|
3
|
+
declare interface AudioProps {
|
|
4
|
+
/**
|
|
5
|
+
* 音频地址,支持单个地址或地址数组(多源,加载失败自动切换)
|
|
6
|
+
* @default ""
|
|
7
|
+
*/
|
|
8
|
+
src?: string | string[]
|
|
9
|
+
/**
|
|
10
|
+
* 标题,显示在音频条上
|
|
11
|
+
* @default ""
|
|
12
|
+
*/
|
|
13
|
+
title?: string
|
|
14
|
+
/**
|
|
15
|
+
* 是否循环播放
|
|
16
|
+
* @default false
|
|
17
|
+
*/
|
|
18
|
+
loop?: boolean
|
|
19
|
+
/**
|
|
20
|
+
* 是否显示倍速切换
|
|
21
|
+
* @default true
|
|
22
|
+
*/
|
|
23
|
+
showRate?: boolean
|
|
24
|
+
/**
|
|
25
|
+
* 可切换的倍速档位
|
|
26
|
+
* @default [0.5, 0.75, 1, 1.25, 1.5, 2]
|
|
27
|
+
*/
|
|
28
|
+
rateList?: number[]
|
|
29
|
+
/**
|
|
30
|
+
* 主题色(播放按钮、进度条选中色)
|
|
31
|
+
* @default "#2979ff"
|
|
32
|
+
*/
|
|
33
|
+
activeColor?: string
|
|
34
|
+
/**
|
|
35
|
+
* 是否显示标题
|
|
36
|
+
* @default true
|
|
37
|
+
*/
|
|
38
|
+
showTitle?: boolean
|
|
39
|
+
/**
|
|
40
|
+
* 开始播放时触发
|
|
41
|
+
*/
|
|
42
|
+
onPlay?: (e: { source: string; src: string }) => any
|
|
43
|
+
/**
|
|
44
|
+
* 加载/播放出错时触发
|
|
45
|
+
*/
|
|
46
|
+
onError?: (e: { source: string; errMsg: string }) => any
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
declare interface _Audio {
|
|
50
|
+
new (): {
|
|
51
|
+
$props: AllowedComponentProps &
|
|
52
|
+
VNodeProps &
|
|
53
|
+
AudioProps
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export declare const Audio: _Audio
|