随着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
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
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)