@94ai/nf-audio 3.1.37 → 3.1.39

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.
@@ -1,10 +1,10 @@
1
- declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{}, {
1
+ declare const _default: __VLS_WithTemplateSlots<import("vue-demi").DefineComponent<{}, {
2
2
  showPopper: typeof showPopper;
3
3
  $props: {
4
4
  readonly visible?: string | boolean | undefined;
5
5
  };
6
6
  $emit: (event: "update:visible", ...args: any[]) => void;
7
- }, {}, {}, {}, import("vue/types/v3-component-options").ComponentOptionsMixin, import("vue/types/v3-component-options").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{}>>, {}>, {
7
+ }, {}, {}, {}, import("vue/types/v3-component-options").ComponentOptionsMixin, import("vue/types/v3-component-options").ComponentOptionsMixin, {}, string, Readonly<import("vue-demi").ExtractPropTypes<{}>>, {}>, {
8
8
  reference?(_: {}): any;
9
9
  default?(_: {}): any;
10
10
  }>;
@@ -0,0 +1,8 @@
1
+ import NfAudio from './nf-audio.vue'
2
+ import { Vue2, PluginObject } from 'vue-demi'
3
+
4
+ NfAudio.install = (app: typeof Vue2) => {
5
+ app!.component('nf-audio', NfAudio)
6
+ }
7
+
8
+ export default NfAudio as typeof NfAudio & PluginObject<undefined>
@@ -0,0 +1,43 @@
1
+ <template>
2
+ <div class="more-btn-box">
3
+ <el-popover placement="right" popper-class="audio-popover">
4
+ <div class="audio-btn-list">
5
+ <el-popover placement="right" popper-class="audio-popover">
6
+ <div class="audio-btn-list">
7
+ <div v-for="(item,index) in multipleArray" :key="index" class="btn-item" :class="speed===item?'active':''" @click="handleSpeed(item)">x {{ item }}</div>
8
+ </div>
9
+ <div slot="reference" class="btn-item">倍速</div>
10
+ </el-popover>
11
+ <div class="btn-item" @click="handleDown">下载</div>
12
+ </div>
13
+ <div slot="reference" class="more-icon">
14
+ <span class="more-btn"></span>
15
+ </div>
16
+ </el-popover>
17
+ </div>
18
+ </template>
19
+
20
+ <script>
21
+ export default {
22
+ name: 'more-btn',
23
+ components: {},
24
+ data() {
25
+ return {
26
+ multipleArray: ['1.0', '1.25', '1.5', '1.75', '2.0'],
27
+ speed: ''
28
+ }
29
+ },
30
+ mounted() {
31
+ },
32
+ methods: {
33
+ handleDown() {
34
+ this.$emit('down')
35
+ },
36
+ handleSpeed(speed) {
37
+ this.speed = speed
38
+ this.$emit('speed', speed)
39
+ }
40
+ }
41
+ }
42
+
43
+ </script>
@@ -0,0 +1,287 @@
1
+ <template>
2
+ <div class="nf-audio-strip">
3
+ <audio @canplay="getDuration" controls crossOrigin="anonymous" @timeupdate="updateTime" @ended="handleAudioEnded" v-show="false" ref="audio"
4
+ :src="audioSrc"/>
5
+ <div class="nf-fast">
6
+ <span class="nf-fast-icon" @click="jumpToTime"></span>
7
+ <!-- 以下是 快进/快退 功能 -->
8
+ <!--
9
+ <div>
10
+ <span class="pre" @click="handleBack">
11
+ <i class="el-icon-d-arrow-left"></i>
12
+ <span style="color: #C7C7C9;font-size: 13px;margin-left: 10px">-{{ backSecond }}s</span>
13
+ </span>
14
+ <span style="display:inline-block; height: 20px; width: 100px;"></span>
15
+ <span class="next" @click="handleForward">
16
+ <span style="color: #C7C7C9;font-size: 13px;margin-right: 10px">+{{ forwardSecond }}s </span>
17
+ <i class="el-icon-d-arrow-right"></i>
18
+ </span>
19
+ </div>
20
+ -->
21
+ </div>
22
+ <div class="nf-audio">
23
+ <div class="play" @click="handlePauseOrPlay">
24
+ <span class="pause-icon" v-show="!paused"></span>
25
+ <span class="play-icon" v-show="paused"></span>
26
+ </div>
27
+ <div class="time">
28
+ <span class="startTime">{{ currentDuration }}</span>/
29
+ <span class="endTime">{{ duration }}</span>
30
+ </div>
31
+ <div class="progress" ref="progress" @click="clickProgress" @mouseup="handleMouseup">
32
+ <div class="currentProgress" ref="currentProgress">
33
+ <span class="circle" ref="circle" @mousedown="handleMousedown"></span>
34
+ </div>
35
+ </div>
36
+ <div class="nf-volume-panel">
37
+ <volumeTool :visible.sync="volumeVisible">
38
+ <template v-slot:reference>
39
+ <div class="volume" v-if="volume == 0"></div>
40
+ <div class="volume-mute" v-else></div>
41
+ </template>
42
+ <el-slider
43
+ v-model="volumeValue"
44
+ vertical
45
+ :min="0"
46
+ :max="100"
47
+ :show-tooltip="volumeVisible"
48
+ :class="volumeValue===0 ? 'volume-mute' : 'volume-phonic'"
49
+ @change="rangeVolume"
50
+ height="60px">
51
+ </el-slider>
52
+ </volumeTool>
53
+ </div>
54
+ <div class="option">
55
+ <moreBtn @down="downRecord()" @speed="changeSpeed" />
56
+ </div>
57
+ </div>
58
+ </div>
59
+ </template>
60
+
61
+ <script>
62
+ import volumeTool from './volume-tool.vue'
63
+ import moreBtn from './more-btn.vue'
64
+ import { Message } from 'element-ui'
65
+
66
+ export default {
67
+ name: "nf-audio",
68
+ components: { volumeTool, moreBtn },
69
+ props: {
70
+ audioSrc: {
71
+ type: String,
72
+ default: ''
73
+ },
74
+ backSecond: {
75
+ type: Number,
76
+ default: 3
77
+ },
78
+ forwardSecond: {
79
+ type: Number,
80
+ default: 10
81
+ },
82
+ startTime: {
83
+ type: Number,
84
+ default: 0
85
+ }
86
+ },
87
+ data() {
88
+ return {
89
+ duration: '00:00',
90
+ currentDuration: '00:00',
91
+ audio: '',
92
+ volume: 0.8,
93
+ paused: true,
94
+ showVolumePanel: false,
95
+ volumeVisible: false,
96
+ volumeValue: 80,
97
+ speed: 1.0
98
+ }
99
+ },
100
+ mounted() {
101
+ this.audio = this.$refs.audio
102
+ },
103
+ methods: {
104
+ //后退
105
+ handleBack() {
106
+ if (this.audio.currentTime > this.backSecond) {
107
+ this.audio.currentTime = this.audio.currentTime - this.backSecond
108
+ }
109
+ },
110
+ //前进
111
+ handleForward() {
112
+ if (this.audio.duration - this.audio.currentTime > this.forwardSecond) {
113
+ this.audio.currentTime = this.audio.currentTime + 10
114
+ }
115
+ },
116
+ //暂停或播放
117
+ handlePauseOrPlay() {
118
+ if (this.audio.readyState >= 2) {
119
+ // 如果音频资源已加载元数据或更多,可以播放
120
+ this.audio.paused ? this.audio.play() : this.audio.pause()
121
+ this.audio.playbackRate = this.speed
122
+ this.paused = !this.paused
123
+ console.log(this.paused);
124
+ } else {
125
+ console.log("Audio is not ready yet.");
126
+ Message.warning("音频还未加载完成")
127
+ }
128
+ },
129
+ //视频在可以播放时触发
130
+ getDuration() {
131
+ this.duration = this.timeFormat(this.$refs.audio.duration)
132
+ this.audio.volume = this.volume //默认百分百音量
133
+ //监听音量的变化
134
+ // this.audio.addEventListener('volumechange',(volumeValue)=>{
135
+ // console.log(this.audio.volume)
136
+ // })
137
+ },
138
+ //将单位为秒的的时间转换成mm:ss的形式
139
+ timeFormat( number ) {
140
+ let minute = parseInt(number / 60);
141
+ let second = parseInt(number % 60);
142
+ minute = minute >= 10 ? minute : "0" + minute;
143
+ second = second >= 10 ? second : "0" + second;
144
+ return minute + ":" + second;
145
+ },
146
+ //进度条发生变化时触发
147
+ updateTime() {
148
+ if (!this.$refs.progress) return
149
+ this.currentDuration = this.timeFormat(this.audio.currentTime)
150
+ //如果不是正在移动 和 没有暂停播放就执行
151
+ if ( !this.audio.paused) {
152
+ // 设置当前时间
153
+ let MoveX = this.$refs.progress.clientWidth * ( this.audio.currentTime / this.audio.duration )
154
+ //播放时更新距离
155
+ this.$refs.currentProgress.style.width = MoveX + 'px'
156
+ this.$refs.circle.style.left = MoveX - ( this.$refs.circle.clientWidth / 2 ) + 'px'
157
+ this.paused = false
158
+ }
159
+ },
160
+ handleAudioEnded(){
161
+ // 在这里处理音频播放完毕的逻辑
162
+ console.log('音频播放完毕!');
163
+ this.paused = true
164
+ },
165
+ //点击进度条更新进度
166
+ clickProgress( e ) {
167
+ if(this.duration === '00:00'){
168
+ Message.warning("音频还未加载完成")
169
+ return false
170
+ }
171
+ //如果不是正在移动 和 没有暂停播放就执行
172
+ if (!this.audio.paused) {
173
+ this.updateProgress(e.offsetX)
174
+ }
175
+ },
176
+ //更新进度
177
+ updateProgress( MoveX ) {
178
+ //当前移动的位置 = 当前移动的位置 / 当前进度条的可视长度 //this.$refs.progress.clientWidth 注意一定要拿总长度 否则会拿进度条已经走过的长度
179
+ let clickProgress = ( MoveX / this.$refs.progress.clientWidth )
180
+ //设置播放的时间 = 总时长 * 当前点击的长度
181
+ this.audio.currentTime = this.audio.duration * clickProgress
182
+ //设置移动的位置
183
+ this.$refs.currentProgress.style.width = MoveX + 'px'
184
+ this.$refs.circle.style.left = MoveX - ( this.$refs.circle.clientWidth / 2 ) + 'px'
185
+ },
186
+ //鼠标弹起
187
+ handleMouseup() {
188
+ if(this.duration === '00:00'){
189
+ Message.warning("音频还未加载完成")
190
+ return false
191
+ }
192
+ // 销毁的时候清除定时器
193
+ const timer = setTimeout(() => {
194
+ this.audio.play()
195
+ this.paused = false
196
+ clearTimeout(timer)
197
+ }, 200)
198
+
199
+ this.$once('hook:beforeDestroy', () => {
200
+ clearTimeout(timer)
201
+ })
202
+ },
203
+ //调整进度
204
+ handleMousedown() {
205
+ this.audio.pause()
206
+ this.paused = true
207
+ let progress = this.$refs.progress
208
+ //进度条 左 边距离页面左边的距离 移动最小值
209
+ let moveMin = progress.offsetParent.offsetLeft + progress.offsetLeft
210
+ //进度条 右 边距离页面左边的距离 移动最大值
211
+ let moveMax = progress.offsetParent.offsetLeft + progress.offsetLeft + progress.clientWidth
212
+ //小圆圈的宽度
213
+ let circleWidth = ( this.$refs.circle.clientWidth / 2 )
214
+ let moveX = ( e ) => {
215
+ if (e.pageX >= moveMax) {
216
+ return
217
+ } else if (e.pageX <= moveMin) {
218
+ return
219
+ }
220
+ this.$refs.circle.style.left = e.pageX - moveMin - circleWidth + 'px'
221
+ this.updateProgress(e.pageX - moveMin)
222
+ }
223
+ //获取当前鼠标的位置 X
224
+ document.addEventListener('mousemove', moveX)
225
+ //鼠标弹起来
226
+ document.addEventListener('mouseup', () => {
227
+ document.removeEventListener('mousemove', moveX)
228
+ })
229
+ },
230
+ rangeVolume(val){
231
+ console.log(val);
232
+ },
233
+ /** 设置倍速播放 */
234
+ changeSpeed(command) {
235
+ const audioPlayer = this.$refs.audio
236
+ if (audioPlayer) {
237
+ audioPlayer.playbackRate = command
238
+ }
239
+ this.speed = command
240
+ },
241
+ downRecord() {
242
+ this.$emit('downloadCallback')
243
+ },
244
+ calcMoveX() {
245
+ if (!this.audio.paused) {
246
+ // 设置当前时间
247
+ let MoveX = this.$refs.progress.clientWidth * ( this.audio.currentTime / this.audio.duration )
248
+ //播放时更新距离
249
+ this.$refs.currentProgress.style.width = MoveX + 'px'
250
+ this.$refs.circle.style.left = MoveX - ( this.$refs.circle.clientWidth / 2 ) + 'px'
251
+ }
252
+ },
253
+ jumpToTime(){
254
+ this.audio.pause()
255
+ const formatStartT = this.timeFormat(this.startTime)
256
+ if(this.duration === '00:00'){
257
+ Message.warning("音频还未加载完成")
258
+ return false
259
+ }
260
+ if(formatStartT >= this.duration){
261
+ this.audio.currentTime = this.duration
262
+ this.currentDuration = this.timeFormat(this.audio.currentTime)
263
+ this.calcMoveX()
264
+ this.audio.play()
265
+ console.error("开始时间不能大于总时长");
266
+ return false
267
+ }else if(formatStartT >= '00:00' && formatStartT < this.duration){
268
+ this.audio.currentTime = this.startTime
269
+ this.currentDuration = this.timeFormat(this.audio.currentTime)
270
+ this.calcMoveX()
271
+ this.audio.play()
272
+ }else{
273
+ this.audio.currentTime = 0
274
+ this.currentDuration = this.timeFormat(this.audio.currentTime)
275
+ this.calcMoveX()
276
+ this.audio.play()
277
+ }
278
+ }
279
+ },
280
+ watch:{
281
+ volumeValue(val){
282
+ this.volume = val/100
283
+ this.audio.volume = val/100
284
+ }
285
+ }
286
+ }
287
+ </script>
@@ -0,0 +1 @@
1
+ import '@94ai/nf-theme-chalk/lib/css/nf-audio.css'
@@ -0,0 +1 @@
1
+ import '@94ai/nf-theme-chalk/lib/nf-audio.scss'
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div class="nf-volume-tool" :class=" visible ? 'nf-tool-show':'nf-tool-hide'" @click="showPopper" >
3
+ <div ref="reference">
4
+ <slot name="reference"/>
5
+ </div>
6
+ <transition name="slide-fade">
7
+ <div ref="popperRef" class="nf-popper" v-show="visible" >
8
+ <slot/>
9
+ </div>
10
+ </transition>
11
+
12
+ </div>
13
+ </template>
14
+
15
+ <script setup>
16
+ import { watch, ref ,onUnmounted} from 'vue-demi'
17
+
18
+ const emits = defineEmits(['update:visible'])
19
+ const props = defineProps({
20
+ visible: [Boolean, String]
21
+ })
22
+ const reference = ref()
23
+ const popperRef = ref()
24
+
25
+ watch(() => props.visible, ( newValue ) => {
26
+ if (newValue) {
27
+ window.addEventListener('mousedown',docClick)
28
+ }else {
29
+ window.removeEventListener('mousedown',docClick)
30
+ }
31
+ })
32
+
33
+ function docClick(e){
34
+ //如果点击的是音量 或者 是音量面板 则 不隐藏音量面板
35
+ if (popperRef.value.contains(e.target) || reference.value.contains(e.target)){
36
+ return
37
+ }
38
+ emits('update:visible', false)
39
+ }
40
+
41
+ function showPopper() {
42
+ emits('update:visible', true)
43
+ }
44
+
45
+ onUnmounted(()=>{
46
+ emits('update:visible', false)
47
+ })
48
+ defineExpose({
49
+ showPopper
50
+ })
51
+ </script>
52
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@94ai/nf-audio",
3
- "version": "3.1.37",
3
+ "version": "3.1.39",
4
4
  "description": "> TODO: description",
5
5
  "keywords": [],
6
6
  "author": "liuxiangxiang <liuxiangxiang@94ai.com>",
@@ -14,7 +14,7 @@
14
14
  "url": "http://94ai.gitlab.com/zoujiahe/common-ui.git"
15
15
  },
16
16
  "dependencies": {
17
- "@94ai/nf-theme-chalk": "^3.1.37",
17
+ "@94ai/nf-theme-chalk": "^1.0.0",
18
18
  "vue-demi": "^0.14.5"
19
19
  },
20
20
  "peerDependenciesMeta": {
@@ -30,5 +30,5 @@
30
30
  "types": "lib/index.d.ts",
31
31
  "main": "lib/nf-audio.cjs.js",
32
32
  "module": "lib/nf-audio.esm-bundler.js",
33
- "gitHead": "14dfc729b9988003d4686b414e1e9c0aaa7c4dcd"
33
+ "gitHead": "2b60696b405feafbbaeed385e5bcf666ceefbf2c"
34
34
  }