Tecnología de front-end pura para cortar y fusionar audio

随着5G时代的来临,音视频的领域的必将嫌弃新的浪潮,只有不断的学习才能跟的上步伐,吧啦吧啦....

Bueno, realmente no puedo editarlo ~~~, ingrese rápidamente al tema, este artículo presenta principalmente las funciones
1. Seleccionar archivos de audio locales (múltiples segmentos)
2. Seleccionar reproducción de intervalo de audio (múltiples segmentos)
3. Combinar audiobuffer
4. Descargar y editar el audio posterior La
función de ejemplo general es relativamente simple, pero puede pensar si el video se puede usar en la forma, empalmando múltiples segmentos, y es seguro que el sonido del video debe ser extraído. La pantalla de video parte no se ha probado, y solo la función de audio es normal Tenga en cuenta que esto es puro La tecnología front-end no es para cargar archivos de audio al servidor y usar ffmpeg para cortarlos.

La demo se hizo hace mucho tiempo, y hoy finalmente tengo tiempo para ordenarla y revisarla yo mismo. Si hay algún error, espero que el gran dios pueda señalarlo.

Principales puntos de conocimiento:

  • AudioContext se ha mencionado en el artículo anterior,
    • decodeAudioData convierte filedata en audiobuffer
    • createBuffer crea un búfer de audio vacío
  • AudioBuffers es principalmente para editar los datos
    • getChannelData Obtiene los datos reales del búfer
    • ChannerlData.set establece datos de búfer

Primero publique la dirección de la experiencia: http://works.ibeeger.com/learn/audioctx/merge.html

Inserte la descripción de la imagen aquí
Seleccione varios segmentos, seleccione el intervalo para la escucha de prueba y haga clic para descargar después de la finalización El archivo de audio descargado es el intervalo de intervalo que seleccionó.
Por supuesto, todavía hay mucho margen de mejora, aquí solo hay una demostración de demostración

Aún mira el código.

decodificar conversión

const decodecFile = function(fileContent, id) {
    
    
				audioContext.decodeAudioData(fileContent, function(buffer) {
    
    
                    let index = id.replace(/choose/g,'');
                    buffers[index] = Object.assign({
    
    buffer: buffer},showBuffer(buffer, index));
				});
            }

Visualización

function showBuffer(buffer, index) {
    
    
             var cs = '';
             var ctx = '';
             var item = document.querySelectorAll('section>div')[index];
             if(item.querySelector('canvas')){
    
    
                 cs = buffers[index]['cs']
                 ctx = buffers[index]['ctx'];
             } else {
    
    
                cs = document.createElement('canvas');
                cs.width = window.innerWidth;
                ctx = cs.getContext('2d');
             }
             ctx.clearRect(0,0, cs.width, cs.height);
	const lth = buffer.getChannelData(1).length;
	const arr = buffer.getChannelData(1);
             let w = Math.floor(lth/cs.width/2);
	ctx.fillStyle ='#efefef'
	const list = []
	for(let i =0; i<cs.width; i++) {
    
    
		list.push(arr[i*w]*cs.height);
		ctx.fillRect(i,(cs.height-arr[i*w]*cs.height)/2,1,arr[i*w]*cs.height);
	};
             ctx.save();
             cs.dataset['index'] = index;
             cs.addEventListener('mousedown', mousedown, false);
             cs.addEventListener('touchstart', mousedown, false);
             cs.addEventListener('mousemove', mousemove, false);
             cs.addEventListener('touchmove', mousemove, false);
             cs.addEventListener('mouseup', mouseup, false);
             cs.addEventListener('touchend', mouseup, false);
             document.querySelectorAll("section>div")[index].appendChild(cs);
	return {
    
    
        cs: cs,
        ctx: ctx,
		step: w,
		list: list
	}
}

Reproducir el búfer de audio especificado

function start(buffer) {
    
    
             
             if (audioBufferSourceNode) {
    
    
				audioBufferSourceNode.stop();
             }
             audioContext = new AudioContext();
	const analyser = audioContext.createAnalyser();
                     audioBufferSourceNode = audioContext.createBufferSource();
	                 audioBufferSourceNode.connect(analyser);
                     analyser.connect(audioContext.destination);
	                 audioBufferSourceNode.buffer = buffer;
	                 audioBufferSourceNode.start(0);

					audioBufferSourceNode.onended = function() {
    
    
						isplay = false;
						cancelAnimationFrame(req);
					};
}

El último paso es descargar. Para ser honesto, este método aún no ha sido analizado, pero se ha encontrado el método correspondiente de Google
. También debe haber muchos parámetros que vale la pena estudiar.


    function 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
        setUint32(0x46464952);                         // "RIFF"
        setUint32(length - 8);                         // file length - 8
        setUint32(0x45564157);                         // "WAVE"
      
        setUint32(0x20746d66);                         // "fmt " chunk
        setUint32(16);                                 // length = 16
        setUint16(1);                                  // PCM (uncompressed)
        setUint16(numOfChan);
        setUint32(abuffer.sampleRate);
        setUint32(abuffer.sampleRate * 2 * numOfChan); // avg. bytes/sec
        setUint16(numOfChan * 2);                      // block-align
        setUint16(16);                                 // 16-bit (hardcoded in this demo)
      
        setUint32(0x61746164);                         // "data" - chunk
        setUint32(length - pos - 4);                   // chunk length
      
        // write interleaved data
        for(i = 0; i < abuffer.numberOfChannels; i++)
          channels.push(abuffer.getChannelData(i));
      
        while(pos < length) {
    
    
          for(i = 0; i < numOfChan; i++) {
    
                 // interleave channels
            sample = Math.max(-1, Math.min(1, channels[i][offset])); // clamp
            sample = (0.5 + sample < 0 ? sample * 32768 : sample * 32767)|0; // scale to 16-bit signed int
            view.setInt16(pos, sample, true);          // write 16-bit sample
            pos += 2;
          }
          offset++                                     // next source sample
        }
      
        // 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;
        }
      }

En este punto, creo que se han publicado los códigos más importantes. Los archivos de formato de audio descargados en la actualidad son relativamente grandes, lo que debería estar relacionado con la configuración de los parámetros que dije. Son Inserte la descripción de la imagen aquí
unos 10 MB por minuto. Hablaré contigo cuando tenga tiempo más tarde, y me despediré ~~
(El tamaño específico está determinado por los datos de audio después de la corrección)

Supongo que te gusta

Origin blog.csdn.net/uk_51/article/details/106882352
Recomendado
Clasificación