【vue 剪辑音频】

剪辑音频

<div v-if="waveformFlag" id="waveform"></div>
 //音波生成
    handelReaderNew(){
      var that = this
      console.log("handelReaderNew")
     //引入wavesurfer.min.js
      that.wavesurfer = this.$WaveSurfer.create({
            container: '#waveform',
            waveColor: 'violet',
            progressColor: 'purple'
      });      
      // 接收传入的音频
      if(that.isTailor){
      //this.videoForm.audioPath  音频在线地址
        that.wavesurfer.load(this.videoForm.audioPath);
      }else{
       //音频文件 转base64
        let url = URL.createObjectURL(that.tailorMusiceFile);
        console.log(url,"转base64")
        that.wavesurfer.load(url);
      }
      // 事件
      that.wavesurfer.on('ready', function () {
          that.wavesurfer.play();
      });
      
      const wsRegions = that.wavesurfer.registerPlugin(this.$RegionsPlugin.create())
      const random = (min, max) => Math.random() * (max - min) + min
      const randomColor = () => `rgba(${random(0, 255)}, ${random(0, 255)}, ${random(0, 255)}, 0.5)`      
      console.log(wsRegions,"this")
      that.wavesurfer.on('decode', function () {
        wsRegions.addRegion({
          start: 0,
          end: 20,
          content: '截取部分',
          color: 'rgba(193, 114, 245, 0.5)', 
        })
      });

      // Loop  选中区域播放
      let loop = true
      that.wavesurfer.on('click', (relativeX) => {
        that.wavesurfer.playPause()
        loop = false
        console.log('Click点击的位置',that.wavesurfer, relativeX)
      })
      var activeRegion = null
      wsRegions.on('region-in', (region) => {
        console.log('region-in')
        activeRegion = region
      })
      wsRegions.on('region-out', (region) => {
        console.log('region-out')
        if (activeRegion === region) {
          if (loop) {
            region.play()
          } else {
            activeRegion = null
          }
        }
      })
      wsRegions.on('region-clicked', (region, e) => {
        console.log('点击区域',region,e)
        loop = true
        e.stopPropagation() // prevent triggering a click on the waveform
        activeRegion = region
        region.play()
        region.setOptions({ color: 'rgba(193, 114, 245, 0.5)' })    
      })
      wsRegions.on('region-updated', (region) => {
        that.tailorStartTime = region.start //片段开始时间(以秒为单位)
        that.tailorendTime = region.end  //片段结束时间(以秒为单位)
        console.log('范围移动', region)
      })
      // Update the zoom level on slider change
      wsRegions.once('decode', () => {
        console.log(1310)
      })
      wsRegions.on('interaction', () => {
        console.log('interaction')
        activeRegion = null
      })
    },

//上传MP3
    fileupload(){
      this.handelDestroy()
      this.waveformFlag = false
      this.waveformFlag = true      
      var file = this.musiceFile;
      // console.log(e,"上传的文件")
      // var file = e.target.files[0];
      let that = this     
      var reader = new FileReader();
      reader.onload = function (e){
        console.log(e,"文件1273")
        var arrBuffer = event.target.result;
        var audioCtx = new AudioContext();
        audioCtx.decodeAudioData(arrBuffer, function(audioBuffer) {
            // audioBuffer就是AudioBuffer
            // 音频时长 duration 
            // 声道数量 numberOfChannels
            // 采样率 sampleRate
            let channels = audioBuffer.numberOfChannels; // 声道数
            let rate = audioBuffer.sampleRate; // 采样率            
            let startOffset = rate * that.tailorStartTime; // 截取起点
            // let startOffset = rate * 2; // 截取起点
            let endOffend = rate * that.tailorendTime; // 截取终点
            // let endOffend = rate * 8; // 截取终点
            let frameCount = endOffend - startOffset; // 截取的时长
            // let frameCount = 100; // 截取的时长
            // 创建同样的采样率,同样声道数量,长度是x秒的空的audioBuffer
            console.log('截取起点:',startOffset,'截取终点:',endOffend,that.tailorendTime,'截取时长:',frameCount,"截取声道数:",channels)
            let newAudioBuffer = new AudioContext().createBuffer(channels, frameCount, rate);
            // 创建临时的Array存放复制的buffer数据
            let tempArray = new Float32Array(frameCount);
            let offSet = 0; // 裁剪后放置的起点位置
            // 声道的数据复制和写入
            for (let index = 0; index < channels; index++) {
              audioBuffer.copyFromChannel(tempArray, index, startOffset);
              newAudioBuffer.copyToChannel(tempArray, index, offSet);
            }
            console.log(audioBuffer,newAudioBuffer)
            //截取完自动播放
            // var source = audioCtx.createBufferSource();
            // source.buffer = newAudioBuffer
            // source.connect(audioCtx.destination);
            // source.start();
            //截取完转blon
            var myArrayBuffer = audioCtx.createBuffer(2, frameCount, audioCtx.sampleRate);  
            var anotherArray = new Float32Array();
            myArrayBuffer.copyFromChannel(anotherArray,1,0);      
            let num = Math.trunc(frameCount)
            var blob = that.bufferToWave(newAudioBuffer, num);
            that.tailorMusiceFile = blob
            that.isTailor = false
            that.handelReaderNew()
            //buffer转可上传文件
            that.tailorMusiceFile = new File([blob],'muice.mp3',{type:blob.type})
            console.log(newAudioBuffer,audioBuffer,blob,that.tailorMusiceFile,)              
            that.handleHttpRequestFucNew({file:that.tailorMusiceFile},2)
            
        });
      }
      reader.readAsArrayBuffer(file)
    },

	 //blob 转 base64
    getImageBase64(blob) {
      return new Promise((resolve,reject) => {
        const reader = new FileReader();
        reader.readAsDataURL(blob);
        reader.onload = () => {
          const base64 = reader.result;
          resolve(base64);
        }
        reader.onerror = error => reject(error);
      });
    },
	//文件转buffer
    bufferToWave(abuffer, len) {
      var numOfChan = abuffer.numberOfChannels,
      length = len * numOfChan * 2 + 44,
      buffer = new ArrayBuffer(length),
      view = new DataView(buffer),
      channels = [], i, sample,
      offset = 0,
      pos = 0;

      // write WAVE header
      // "RIFF"
      setUint32(0x46464952);
      // file length - 8                      
      setUint32(length - 8);
      // "WAVE"                     
      setUint32(0x45564157);
      // "fmt " chunk
      setUint32(0x20746d66);  
      // length = 16                       
      setUint32(16);  
      // PCM (uncompressed)                               
      setUint16(1); 
      setUint16(numOfChan);
      setUint32(abuffer.sampleRate);
      // avg. bytes/sec
      setUint32(abuffer.sampleRate * 2 * numOfChan);
      // block-align
      setUint16(numOfChan * 2);
      // 16-bit (hardcoded in this demo)
      setUint16(16);                           
      // "data" - chunk
      setUint32(0x61746164); 
      // chunk length                   
      setUint32(length - pos - 4);                   

      // write interleaved data
      for(i = 0; i < abuffer.numberOfChannels; i++)
          channels.push(abuffer.getChannelData(i));

      while(pos < length) {
          // interleave channels
          for(i = 0; i < numOfChan; i++) {
              // clamp
              sample = Math.max(-1, Math.min(1, channels[i][offset])); 
              // scale to 16-bit signed int
              sample = (0.5 + sample < 0 ? sample * 32768 : sample * 32767)|0; 
              // write 16-bit sample
              view.setInt16(pos, sample, true);          
              pos += 2;
          }
          // next source sample
          offset++                                     
      }

      // create Blob
      return new Blob([buffer], {type: "audio/wav"});

      function setUint16(data) {
          view.setUint16(pos, data, true);
          pos += 2;
      }

      function setUint32(data) {
          view.setUint32(pos, data, true);
          pos += 4;
      }
    },
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值