@94ai/nf-audio 3.1.13

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.
@@ -0,0 +1,480 @@
1
+ import { ref, watch, onUnmounted } from "vue-demi";
2
+ import { normalizeComponent } from "@94ai/vue2-runtime-helpers";
3
+ import { Message } from "element-ui";
4
+ const __sfc_main = {};
5
+ __sfc_main.props = {
6
+ visible: [Boolean, String]
7
+ };
8
+ __sfc_main.setup = (__props, __ctx) => {
9
+ const emits = __ctx.emit;
10
+ const props = __props;
11
+ const reference = ref();
12
+ const popperRef = ref();
13
+ watch(() => props.visible, (newValue) => {
14
+ if (newValue) {
15
+ window.addEventListener("mousedown", docClick);
16
+ } else {
17
+ window.removeEventListener("mousedown", docClick);
18
+ }
19
+ });
20
+ function docClick(e) {
21
+ if (popperRef.value.contains(e.target) || reference.value.contains(e.target)) {
22
+ return;
23
+ }
24
+ emits("update:visible", false);
25
+ }
26
+ function showPopper() {
27
+ emits("update:visible", true);
28
+ }
29
+ onUnmounted(() => {
30
+ emits("update:visible", false);
31
+ });
32
+ return Object.assign({
33
+ reference,
34
+ popperRef,
35
+ showPopper
36
+ }, {
37
+ showPopper
38
+ });
39
+ };
40
+ const _sfc_main$2 = __sfc_main;
41
+ var _sfc_render$2 = function render() {
42
+ var _vm = this, _c = _vm._self._c;
43
+ _vm._self._setupProxy;
44
+ return _c("div", {
45
+ staticClass: "nf-volume-tool",
46
+ class: _vm.visible ? "nf-tool-show" : "nf-tool-hide",
47
+ on: {
48
+ "click": _vm.showPopper
49
+ }
50
+ }, [_c("div", {
51
+ ref: "reference"
52
+ }, [_vm._t("reference")], 2), _c("transition", {
53
+ attrs: {
54
+ "name": "slide-fade"
55
+ }
56
+ }, [_c("div", {
57
+ directives: [{
58
+ name: "show",
59
+ rawName: "v-show",
60
+ value: _vm.visible,
61
+ expression: "visible"
62
+ }],
63
+ ref: "popperRef",
64
+ staticClass: "nf-popper"
65
+ }, [_vm._t("default")], 2)])], 1);
66
+ };
67
+ var _sfc_staticRenderFns$2 = [];
68
+ var __component__$2 = /* @__PURE__ */ normalizeComponent(_sfc_main$2, _sfc_render$2, _sfc_staticRenderFns$2, false, null, null, null, null);
69
+ const volumeTool = __component__$2.exports;
70
+ const _sfc_main$1 = {
71
+ name: "more-btn",
72
+ components: {},
73
+ data() {
74
+ return {
75
+ multipleArray: ["1.0", "1.25", "1.5", "1.75", "2.0"],
76
+ speed: ""
77
+ };
78
+ },
79
+ mounted() {
80
+ },
81
+ methods: {
82
+ handleDown() {
83
+ this.$emit("down");
84
+ },
85
+ handleSpeed(speed) {
86
+ this.speed = speed;
87
+ this.$emit("speed", speed);
88
+ }
89
+ }
90
+ };
91
+ var _sfc_render$1 = function render2() {
92
+ var _vm = this, _c = _vm._self._c;
93
+ return _c("div", {
94
+ staticClass: "more-btn-box"
95
+ }, [_c("el-popover", {
96
+ attrs: {
97
+ "placement": "right",
98
+ "popper-class": "audio-popover"
99
+ }
100
+ }, [_c("div", {
101
+ staticClass: "audio-btn-list"
102
+ }, [_c("el-popover", {
103
+ attrs: {
104
+ "placement": "right",
105
+ "popper-class": "audio-popover"
106
+ }
107
+ }, [_c("div", {
108
+ staticClass: "audio-btn-list"
109
+ }, _vm._l(_vm.multipleArray, function(item, index) {
110
+ return _c("div", {
111
+ key: index,
112
+ staticClass: "btn-item",
113
+ class: _vm.speed === item ? "active" : "",
114
+ on: {
115
+ "click": function($event) {
116
+ return _vm.handleSpeed(item);
117
+ }
118
+ }
119
+ }, [_vm._v("x " + _vm._s(item))]);
120
+ }), 0), _c("div", {
121
+ staticClass: "btn-item",
122
+ attrs: {
123
+ "slot": "reference"
124
+ },
125
+ slot: "reference"
126
+ }, [_vm._v("倍速")])]), _c("div", {
127
+ staticClass: "btn-item",
128
+ on: {
129
+ "click": _vm.handleDown
130
+ }
131
+ }, [_vm._v("下载")])], 1), _c("div", {
132
+ staticClass: "more-icon",
133
+ attrs: {
134
+ "slot": "reference"
135
+ },
136
+ slot: "reference"
137
+ }, [_c("i", {
138
+ staticClass: "iconfont icon-gengduo1 more-btn"
139
+ })])])], 1);
140
+ };
141
+ var _sfc_staticRenderFns$1 = [];
142
+ var __component__$1 = /* @__PURE__ */ normalizeComponent(_sfc_main$1, _sfc_render$1, _sfc_staticRenderFns$1, false, null, null, null, null);
143
+ const moreBtn = __component__$1.exports;
144
+ const _sfc_main = {
145
+ name: "nf-audio",
146
+ components: {
147
+ volumeTool,
148
+ moreBtn
149
+ },
150
+ props: {
151
+ audioSrc: {
152
+ type: String,
153
+ default: ""
154
+ },
155
+ backSecond: {
156
+ type: Number,
157
+ default: 3
158
+ },
159
+ forwardSecond: {
160
+ type: Number,
161
+ default: 10
162
+ },
163
+ startTime: {
164
+ type: Number,
165
+ default: 0
166
+ }
167
+ },
168
+ data() {
169
+ return {
170
+ duration: "00:00",
171
+ currentDuration: "00:00",
172
+ audio: "",
173
+ volume: 0.8,
174
+ paused: true,
175
+ showVolumePanel: false,
176
+ volumeVisible: false,
177
+ volumeValue: 80,
178
+ speed: 1
179
+ };
180
+ },
181
+ mounted() {
182
+ this.audio = this.$refs.audio;
183
+ },
184
+ methods: {
185
+ //后退
186
+ handleBack() {
187
+ if (this.audio.currentTime > this.backSecond) {
188
+ this.audio.currentTime = this.audio.currentTime - this.backSecond;
189
+ }
190
+ },
191
+ //前进
192
+ handleForward() {
193
+ if (this.audio.duration - this.audio.currentTime > this.forwardSecond) {
194
+ this.audio.currentTime = this.audio.currentTime + 10;
195
+ }
196
+ },
197
+ //暂停或播放
198
+ handlePauseOrPlay() {
199
+ if (this.audio.readyState >= 2) {
200
+ this.audio.paused ? this.audio.play() : this.audio.pause();
201
+ this.audio.playbackRate = this.speed;
202
+ this.paused = !this.paused;
203
+ } else {
204
+ console.log("Audio is not ready yet.");
205
+ Message.warning("音频还未加载完成");
206
+ }
207
+ },
208
+ //视频在可以播放时触发
209
+ getDuration() {
210
+ this.duration = this.timeFormat(this.$refs.audio.duration);
211
+ this.audio.volume = this.volume;
212
+ },
213
+ //将单位为秒的的时间转换成mm:ss的形式
214
+ timeFormat(number) {
215
+ let minute = parseInt(number / 60);
216
+ let second = parseInt(number % 60);
217
+ minute = minute >= 10 ? minute : "0" + minute;
218
+ second = second >= 10 ? second : "0" + second;
219
+ return minute + ":" + second;
220
+ },
221
+ //进度条发生变化时触发
222
+ updateTime() {
223
+ if (!this.$refs.progress)
224
+ return;
225
+ this.currentDuration = this.timeFormat(this.audio.currentTime);
226
+ if (!this.audio.paused) {
227
+ let MoveX = this.$refs.progress.clientWidth * (this.audio.currentTime / this.audio.duration);
228
+ this.$refs.currentProgress.style.width = MoveX + "px";
229
+ this.$refs.circle.style.left = MoveX - this.$refs.circle.clientWidth / 2 + "px";
230
+ this.paused = false;
231
+ }
232
+ },
233
+ handleAudioEnded() {
234
+ console.log("音频播放完毕!");
235
+ this.paused = true;
236
+ },
237
+ //点击进度条更新进度
238
+ clickProgress(e) {
239
+ if (this.duration === "00:00") {
240
+ Message.warning("音频还未加载完成");
241
+ return false;
242
+ }
243
+ if (!this.audio.paused) {
244
+ this.updateProgress(e.offsetX);
245
+ }
246
+ },
247
+ //更新进度
248
+ updateProgress(MoveX) {
249
+ let clickProgress = MoveX / this.$refs.progress.clientWidth;
250
+ this.audio.currentTime = this.audio.duration * clickProgress;
251
+ this.$refs.currentProgress.style.width = MoveX + "px";
252
+ this.$refs.circle.style.left = MoveX - this.$refs.circle.clientWidth / 2 + "px";
253
+ },
254
+ //鼠标弹起
255
+ handleMouseup() {
256
+ if (this.duration === "00:00") {
257
+ Message.warning("音频还未加载完成");
258
+ return false;
259
+ }
260
+ const timer = setTimeout(() => {
261
+ this.audio.play();
262
+ this.paused = false;
263
+ clearTimeout(timer);
264
+ }, 200);
265
+ this.$once("hook:beforeDestroy", () => {
266
+ clearTimeout(timer);
267
+ });
268
+ },
269
+ //调整进度
270
+ handleMousedown() {
271
+ this.audio.pause();
272
+ this.paused = true;
273
+ let progress = this.$refs.progress;
274
+ let moveMin = progress.offsetParent.offsetLeft + progress.offsetLeft;
275
+ let moveMax = progress.offsetParent.offsetLeft + progress.offsetLeft + progress.clientWidth;
276
+ let circleWidth = this.$refs.circle.clientWidth / 2;
277
+ let moveX = (e) => {
278
+ if (e.pageX >= moveMax) {
279
+ return;
280
+ } else if (e.pageX <= moveMin) {
281
+ return;
282
+ }
283
+ this.$refs.circle.style.left = e.pageX - moveMin - circleWidth + "px";
284
+ this.updateProgress(e.pageX - moveMin);
285
+ };
286
+ document.addEventListener("mousemove", moveX);
287
+ document.addEventListener("mouseup", () => {
288
+ document.removeEventListener("mousemove", moveX);
289
+ });
290
+ },
291
+ rangeVolume(val) {
292
+ console.log(val);
293
+ },
294
+ /** 设置倍速播放 */
295
+ changeSpeed(command) {
296
+ const audioPlayer = this.$refs.audio;
297
+ if (audioPlayer) {
298
+ audioPlayer.playbackRate = command;
299
+ }
300
+ this.speed = command;
301
+ },
302
+ downRecord() {
303
+ this.$emit("downloadCallback");
304
+ },
305
+ calcMoveX() {
306
+ if (!this.audio.paused) {
307
+ let MoveX = this.$refs.progress.clientWidth * (this.audio.currentTime / this.audio.duration);
308
+ this.$refs.currentProgress.style.width = MoveX + "px";
309
+ this.$refs.circle.style.left = MoveX - this.$refs.circle.clientWidth / 2 + "px";
310
+ }
311
+ },
312
+ jumpToTime() {
313
+ this.audio.pause();
314
+ const formatStartT = this.timeFormat(this.startTime);
315
+ if (this.duration === "00:00") {
316
+ Message.warning("音频还未加载完成");
317
+ return false;
318
+ }
319
+ if (formatStartT >= this.duration) {
320
+ this.audio.currentTime = this.duration;
321
+ this.currentDuration = this.timeFormat(this.audio.currentTime);
322
+ this.calcMoveX();
323
+ this.audio.play();
324
+ console.error("开始时间不能大于总时长");
325
+ return false;
326
+ } else if (formatStartT >= "00:00" && formatStartT < this.duration) {
327
+ this.audio.currentTime = this.startTime;
328
+ this.currentDuration = this.timeFormat(this.audio.currentTime);
329
+ this.calcMoveX();
330
+ this.audio.play();
331
+ } else {
332
+ this.audio.currentTime = 0;
333
+ this.currentDuration = this.timeFormat(this.audio.currentTime);
334
+ this.calcMoveX();
335
+ this.audio.play();
336
+ }
337
+ }
338
+ },
339
+ watch: {
340
+ volumeValue(val) {
341
+ this.volume = val / 100;
342
+ this.audio.volume = val / 100;
343
+ }
344
+ }
345
+ };
346
+ var _sfc_render = function render3() {
347
+ var _vm = this, _c = _vm._self._c;
348
+ return _c("div", {
349
+ staticClass: "nf-audio-strip"
350
+ }, [_c("audio", {
351
+ directives: [{
352
+ name: "show",
353
+ rawName: "v-show",
354
+ value: false,
355
+ expression: "false"
356
+ }],
357
+ ref: "audio",
358
+ attrs: {
359
+ "controls": "",
360
+ "crossOrigin": "anonymous",
361
+ "src": _vm.audioSrc
362
+ },
363
+ on: {
364
+ "canplay": _vm.getDuration,
365
+ "timeupdate": _vm.updateTime,
366
+ "ended": _vm.handleAudioEnded
367
+ }
368
+ }), _c("div", {
369
+ staticClass: "nf-fast"
370
+ }, [_c("i", {
371
+ staticClass: "iconfont icon-zanting1 nf-fast-icon",
372
+ on: {
373
+ "click": _vm.jumpToTime
374
+ }
375
+ })]), _c("div", {
376
+ staticClass: "nf-audio"
377
+ }, [_c("div", {
378
+ staticClass: "play",
379
+ on: {
380
+ "click": _vm.handlePauseOrPlay
381
+ }
382
+ }, [_c("i", {
383
+ directives: [{
384
+ name: "show",
385
+ rawName: "v-show",
386
+ value: !_vm.paused,
387
+ expression: "!paused"
388
+ }],
389
+ staticClass: "iconfont icon-zanting2 pause-icon"
390
+ }), _c("i", {
391
+ directives: [{
392
+ name: "show",
393
+ rawName: "v-show",
394
+ value: _vm.paused,
395
+ expression: "paused"
396
+ }],
397
+ staticClass: "iconfont icon-bofang1 play-icon"
398
+ })]), _c("div", {
399
+ staticClass: "time"
400
+ }, [_c("span", {
401
+ staticClass: "startTime"
402
+ }, [_vm._v(_vm._s(_vm.currentDuration))]), _vm._v("/ "), _c("span", {
403
+ staticClass: "endTime"
404
+ }, [_vm._v(_vm._s(_vm.duration))])]), _c("div", {
405
+ ref: "progress",
406
+ staticClass: "progress",
407
+ on: {
408
+ "click": _vm.clickProgress,
409
+ "mouseup": _vm.handleMouseup
410
+ }
411
+ }, [_c("div", {
412
+ ref: "currentProgress",
413
+ staticClass: "currentProgress"
414
+ }, [_c("span", {
415
+ ref: "circle",
416
+ staticClass: "circle",
417
+ on: {
418
+ "mousedown": _vm.handleMousedown
419
+ }
420
+ })])]), _c("div", {
421
+ staticClass: "nf-volume-panel"
422
+ }, [_c("volumeTool", {
423
+ attrs: {
424
+ "visible": _vm.volumeVisible
425
+ },
426
+ on: {
427
+ "update:visible": function($event) {
428
+ _vm.volumeVisible = $event;
429
+ }
430
+ },
431
+ scopedSlots: _vm._u([{
432
+ key: "reference",
433
+ fn: function() {
434
+ return [_vm.volume == 0 ? _c("i", {
435
+ staticClass: "iconfont icon-yinliang_guanbi volume-mute"
436
+ }) : _c("i", {
437
+ staticClass: "iconfont icon-yinliang_kaiqi volume"
438
+ })];
439
+ },
440
+ proxy: true
441
+ }])
442
+ }, [_c("el-slider", {
443
+ class: _vm.volumeValue === 0 ? "volume-mute-slider" : "volume-phonic",
444
+ attrs: {
445
+ "vertical": "",
446
+ "min": 0,
447
+ "max": 100,
448
+ "show-tooltip": _vm.volumeVisible,
449
+ "height": "60px"
450
+ },
451
+ on: {
452
+ "change": _vm.rangeVolume
453
+ },
454
+ model: {
455
+ value: _vm.volumeValue,
456
+ callback: function($$v) {
457
+ _vm.volumeValue = $$v;
458
+ },
459
+ expression: "volumeValue"
460
+ }
461
+ })], 1)], 1), _c("div", {
462
+ staticClass: "option"
463
+ }, [_c("moreBtn", {
464
+ on: {
465
+ "down": function($event) {
466
+ return _vm.downRecord();
467
+ },
468
+ "speed": _vm.changeSpeed
469
+ }
470
+ })], 1)])]);
471
+ };
472
+ var _sfc_staticRenderFns = [];
473
+ var __component__ = /* @__PURE__ */ normalizeComponent(_sfc_main, _sfc_render, _sfc_staticRenderFns, false, null, null, null, null);
474
+ const NfAudio = __component__.exports;
475
+ NfAudio.install = (app) => {
476
+ app.component("nf-audio", NfAudio);
477
+ };
478
+ export {
479
+ NfAudio as default
480
+ };
@@ -0,0 +1,51 @@
1
+ declare const _default: import("vue").DefineComponent<{
2
+ audioSrc: {
3
+ type: StringConstructor;
4
+ default: string;
5
+ };
6
+ backSecond: {
7
+ type: NumberConstructor;
8
+ default: number;
9
+ };
10
+ forwardSecond: {
11
+ type: NumberConstructor;
12
+ default: number;
13
+ };
14
+ startTime: {
15
+ type: NumberConstructor;
16
+ default: number;
17
+ };
18
+ }, {}, {
19
+ duration: string;
20
+ currentDuration: string;
21
+ audio: string;
22
+ volume: number;
23
+ paused: boolean;
24
+ showVolumePanel: boolean;
25
+ volumeVisible: boolean;
26
+ volumeValue: number;
27
+ speed: number;
28
+ }, {}, {}, import("vue/types/v3-component-options").ComponentOptionsMixin, import("vue/types/v3-component-options").ComponentOptionsMixin, {}, string, Readonly<import("vue").ExtractPropTypes<{
29
+ audioSrc: {
30
+ type: StringConstructor;
31
+ default: string;
32
+ };
33
+ backSecond: {
34
+ type: NumberConstructor;
35
+ default: number;
36
+ };
37
+ forwardSecond: {
38
+ type: NumberConstructor;
39
+ default: number;
40
+ };
41
+ startTime: {
42
+ type: NumberConstructor;
43
+ default: number;
44
+ };
45
+ }>>, {
46
+ audioSrc: string;
47
+ backSecond: number;
48
+ forwardSecond: number;
49
+ startTime: number;
50
+ }>;
51
+ export default _default;
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ import '@94ai/nf-theme-chalk/lib/css/nf-audio.css'
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+ import '@94ai/nf-theme-chalk/lib/nf-audio.scss'
@@ -0,0 +1,15 @@
1
+ declare const _default: __VLS_WithTemplateSlots<import("vue-demi").DefineComponent<{}, {
2
+ showPopper: typeof showPopper;
3
+ $emit: (event: "update:visible", ...args: any[]) => void;
4
+ visible?: string | boolean | undefined;
5
+ $props: {
6
+ readonly visible?: string | boolean | undefined;
7
+ };
8
+ }, {}, {}, {}, import("vue/types/v3-component-options").ComponentOptionsMixin, import("vue/types/v3-component-options").ComponentOptionsMixin, {}, string, Readonly<import("vue-demi").ExtractPropTypes<{}>>, {}>, {
9
+ reference?(_: {}): any;
10
+ default?(_: {}): any;
11
+ }>;
12
+ export default _default;
13
+ type __VLS_WithTemplateSlots<T, S> = T & (new () => {
14
+ $scopedSlots: S;
15
+ });
@@ -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
+ <i class="iconfont icon-gengduo1 more-btn"/>
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>