vue3中如何使用wavesurfer.js

案例展示:

在本案例中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格式时只显示最后一次添加的内容。(有没有童鞋知道为什么呢?)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 你可以在Vue3使用Three.js,首先需要安装Three.js库,然后在Vue组件引入Three.js库,可以使用import语句引入。接着,你可以在Vue组件使用Three.js的API来创建3D场景、模型等。需要注意的是,在Vue3使用Three.js时,需要使用Vue的生命周期函数来管理Three.js的渲染和更新。具体实现方法可以参考Three.js官方文档和Vue3官方文档。 ### 回答2: 在Vue3使用Three.js可以通过以下步骤实现: 1. 在你的Vue项目安装Three.js库。可以使用npm或者yarn来安装,命令如下: ``` npm install three ``` 或 ``` yarn add three ``` 2. 在Vue组件引入Three.js库。在需要使用Three.js的组件文件,添加以下代码: ```js import * as THREE from 'three'; ``` 这样,你就可以在该组件使用Three.js提供的所有功能和类。 3. 创建Three.js场景和渲染器。在Vue组件的`mounted`钩子函数,创建一个空的Three.js场景,并将其渲染到HTML页面上的某个容器,代码如下: ```js const scene = new THREE.Scene(); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.getElementById('container').appendChild(renderer.domElement); ``` 4. 添加和渲染Three.js的物体。在场景创建并添加需要渲染的物体,如立方体等,然后通过调用渲染器的`render`函数将场景渲染到页面上,代码如下: ```js const geometry = new THREE.BoxGeometry(); const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); const cube = new THREE.Mesh(geometry, material); scene.add(cube); renderer.render(scene, camera); // 其camera为相机对象,需要提前创建并设置 ``` 5. 在Vue组件使用动画循环更新场景。你可以使用Vue的`watch`侦听器或者使用Vue提供的动画插件,来持续更新Three.js场景的状态,并在每一帧重新渲染场景,以实现动态效果。 以上就是在Vue3使用Three.js的基本步骤。通过这些步骤,你可以在Vue项目使用Three.js创建出交互式和动态的3D图形。 ### 回答3: 在Vue3使用Three.js的步骤如下: 1. 安装Three.js:可以通过npm或者yarn命令行安装Three.js库。在项目根目录打开终端,执行以下命令: ``` npm install three ``` 或者 ``` yarn add three ``` 2. 创建Vue组件:在Vue项目创建一个新的Vue组件,用来承载Three.js场景和渲染器。可以在方法或者生命周期函数编写Three.js逻辑。 3. 引入Three.js:在Vue组件使用import语句引入Three.js库: ```javascript import * as THREE from 'three' ``` 4. 创建场景、渲染器和相机:在Vue组件的mounted生命周期函数创建Three.js所需的场景、渲染器和相机: ```javascript mounted () { const scene = new THREE.Scene() const renderer = new THREE.WebGLRenderer() const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000) renderer.setSize(window.innerWidth, window.innerHeight) this.$refs.container.appendChild(renderer.domElement) } ``` 5. 添加物体和光源:可以在Vue组件的mounted生命周期函数添加物体和光源到场景: ```javascript const geometry = new THREE.BoxGeometry() const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }) const cube = new THREE.Mesh(geometry, material) scene.add(cube) const light = new THREE.PointLight(0xffffff) light.position.set(0, 0, 10) scene.add(light) ``` 6. 渲染场景:在Vue组件的mounted生命周期函数使用requestAnimationFrame函数循环渲染场景: ```javascript function animate () { requestAnimationFrame(animate) renderer.render(scene, camera) } animate() ``` 7. 更新和交互:可以在Vue组件监听鼠标和键盘事件,并根据需要更新Three.js场景。 这些是在Vue3使用Three.js的基本步骤。根据具体需求,还可以使用其他Three.js功能,如纹理贴图、动画等等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值