赞
踩
案例展示:
在本案例中vue使用的vue3 的setup语法糖的写法。
一、安装wavesurfer.js
- npm install wavesurfer.js
- 或者
- yarn add wavesurfer.js
二、wavesurfer的使用
- <script lang="ts" setup>
- import { onMounted, ref, nextTick, h } from 'vue';
- import WaveSurfer from 'wavesurfer.js/dist/wavesurfer';
- import Regions from 'wavesurfer.js/dist/plugins/regions';
- import Timeline from 'wavesurfer.js/dist/plugins/timeline';
- import _ from 'lodash';
- let wavesurfer = ref();
- let waveform = ref();
- let wsRegions = ref();
- let start_time = ref(0);
- let table_data = ref<any>([]);
- let ws_regions_end = ref<any>(null);
- let current_time = ref<string>('00:00:000');
- let duration_time = ref<string>('00:00:000');
-
- function getImageUrl() {
- return new URL('/src/assets/voice.mp3', import.meta.url).href;
- }
-
- const formatTime = (seconds: number) => {
- const minutes = Math.floor(seconds / 60);
- const remainingSeconds = Math.floor(seconds % 60);
- const milliseconds = Math.floor((seconds - Math.floor(seconds)) * 1000);
-
- const formattedMinutes = String(minutes).padStart(2, '0');
- const formattedSeconds = String(remainingSeconds).padStart(2, '0');
- const formattedMilliseconds = String(milliseconds).padStart(3, '0');
- return `${formattedMinutes}:${formattedSeconds}:${formattedMilliseconds}`;
- };
- const init = () => {
- wavesurfer.value = WaveSurfer.create({
- container: waveform.value,
- cursorColor: 'red', // 播放进行时线条颜色
- cursorWidth: 1, // 播放进行时线条宽度
- waveColor: '#4986ff', // 未播放的波纹颜色
- progressColor: 'blue', // 已播放的波纹颜色
- audioRate: 1, // 倍速
- height: 200, // 高度
- url: getImageUrl()
- });
- wsRegions.value = wavesurfer.value.registerPlugin(Regions.create());
- wavesurfer.value.registerPlugin(
- Timeline.create({
- height: 20,
- primaryLabelInterval: 2,
- // insertPosition: 'beforebegin',
- style: {
- fontSize: '10px',
- color: '#6A3274'
- }
- })
- );
- };
-
- /* 播放时暂停,暂停时播放 */
- function clickMusic() {
- wavesurfer.value.playPause();
- }
-
- /* 设置开始时间 */
- function setStart(current: number) {
- if (table_data.value.length <= 0) {
- start_time.value = 0;
- } else {
- // 重组二维数组
- let res = table_data.value.map((item: any) => [item.start, item.end]);
- /* 检测当前时间是否在二维数组中间 */
- let isIn: any = _.some(res, (subArray) => {
- let start = subArray[0];
- let end = subArray[1];
- return current >= start && current <= end;
- });
-
- if (isIn) {
- // 在已分割的片段内
- start_time.value = -1;
- alert('不可切割');
- } else {
- // 不在分割的片段内,且获取start值
- let obj = _.minBy(res, (subArray: any) => {
- if (subArray[1] < current) {
- return Math.abs(subArray[1] - current);
- }
- });
- if (obj) {
- start_time.value = obj[1];
- } else {
- start_time.value = 0;
- }
- }
- }
- return start_time.value;
- }
- /* 剪切 */
- function cutMusic() {
- wavesurfer.value.pause(); // 暂停播放
- let current = wavesurfer.value.getCurrentTime();
- let start = setStart(current);
- if (start == -1) {
- return false;
- }
- let _item = {
- start: start,
- end: current,
- // content: contentEle.value,
- content: `${formatTime(start)} 至 ${formatTime(current)}`,
- color: 'hsla(200, 50%, 70%, 0.4)',
- drag: false,
- resize: false
- };
- console.log(wsRegions.value, '---------');
- wsRegions.value.addRegion(_item);
- table_data.value = wsRegions.value.regions;
- }
- function drawRegion() {
- table_data.value.forEach((item: any) => {
- wsRegions.value.addRegion(item);
- });
- }
- function delRegions(id: string) {
- table_data.value = table_data.value.filter((item: any) => item.id != id);
- wsRegions.value.clearRegions();
- wsRegions.value.regions = [];
- drawRegion();
- }
- function currentPlay(start: number, end: number) {
- ws_regions_end.value = end;
- wavesurfer.value.setTime(start);
- wavesurfer.value.play();
- }
-
- async function makedata(res: any, current: number, flag: 'prev' | 'next') {
- let index = res.indexOf(current);
- if (index == -1) return;
- if (flag == 'prev') {
- if (index == 0) {
- alert('无上一个切割位置');
- return;
- }
- wavesurfer.value.setTime(res[index - 1]);
- wavesurfer.value.isPlaying() ? wavesurfer.value.play() : wavesurfer.value.pause();
- } else {
- if (index == res.length - 1) {
- alert('无下一个切割位置');
- return;
- }
- wavesurfer.value.setTime(res[index + 1]);
- wavesurfer.value.isPlaying() ? wavesurfer.value.play() : wavesurfer.value.pause();
- }
- }
-
- async function changeTime(flag: 'prev' | 'next') {
- let current = wavesurfer.value.getCurrentTime();
- let res: any = [current];
- table_data.value.map((item: any) => {
- if (res.indexOf(item.start) == -1) {
- res.push(item.start);
- }
- if (res.indexOf(item.end) == -1) {
- res.push(item.end);
- }
- });
- res.sort(function (a: any, b: any) {
- return a - b;
- });
- await makedata(res, current, flag);
- }
- onMounted(() => {
- nextTick(() => {
- init();
- wavesurfer.value.on('audioprocess', () => {
- current_time.value = formatTime(wavesurfer.value.getCurrentTime());
- if (ws_regions_end.value !== null && wavesurfer.value.getCurrentTime() >= ws_regions_end.value - 0.1) {
- wavesurfer.value.pause(); // 暂停播放
- wavesurfer.value.setTime(ws_regions_end.value);
- current_time.value = formatTime(ws_regions_end.value);
- ws_regions_end.value = null;
- }
- });
- wavesurfer.value.on('ready', function () {
- duration_time.value = formatTime(wavesurfer.value.getDuration());
- });
- });
- });
- </script>
未解决问题:
区域 wsRegions的content值。官方文档提示可接收string和HTMLElement两种格式。但在插入HTMLElement格式时只显示最后一次添加的内容。(有没有童鞋知道为什么呢?)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。