android - superponer - unir mp3
Cómo mezclar/superponer dos archivos de audio mp3 en un solo archivo mp3(no concatenar) (7)
1. Publicar en la mezcla de audio en Android
2. Otra publicación sobre la mezcla de audio en Android.
3. Podrías aprovechar Java Sound para mezclar dos archivos de audio
Ejemplo:
// First convert audiofile to audioinputstream
audioInputStream = AudioSystem.getAudioInputStream(soundFile);
audioInputStream2 = AudioSystem.getAudioInputStream(soundFile2);
// Create one collection list object using arraylist then add all AudioInputStreams
Collection list=new ArrayList();
list.add(audioInputStream2);
list.add(audioInputStream);
// Then pass the audioformat and collection list to MixingAudioInputStream constructor
MixingAudioInputStream mixer=new MixingAudioInputStream(audioFormat, list);
// Finally read data from mixed AudionInputStream and give it to SourceDataLine
nBytesRead =mixer.read(abData, 0,abData.length);
int nBytesWritten = line.write(abData, 0, nBytesRead);
4. Pruebe AudioConcat que tiene una opción -m
para mezclar
java AudioConcat [ -D ] [ -c ] | [ -m ] | [ -f ] -o outputfile inputfile ...
Parameters.
-c
selects concatenation mode
-m
selects mixing mode
-f
selects float mixing mode
-o outputfile
The filename of the output file
inputfile
the name(s) of input file(s)
5. Podría usar ffmpeg android wrapper usando una sintaxis y enfoque como se explica here
Quiero fusionar dos archivos mp3 en un archivo mp3. Por ejemplo, si el primer archivo es 1 minuto y el segundo archivo es 30 segundos, la salida debería ser un minuto. En ese min. Debe reproducir ambos archivos.
No estoy seguro de si quieres hacerlo en un teléfono con Android (se parece a eso debido a tus etiquetas), pero si tengo razón, prueba con LoopStack , es un DAW móvil (no lo intenté yo mismo).
Si solo está "mezclando" dos archivos sin ajustar el volumen de salida, su salida podría recortarse. Sin embargo, no estoy seguro de si es posible "mezclar" dos archivos mp3 sin descodificarlos.
Si está bien para que los fusione en su PC, pruebe Audacity , es una aplicación de escritorio gratuita.
No lo he hecho en Android, pero lo había hecho usando Adobe Flex. Supongo que la lógica sigue siendo la misma. Seguí los siguientes pasos:
- Extraje ambos mp3s en matrices de dos bytes. (
song1ByteArray
,song2ByteArray
) - Descubre la matriz de bytes más grande. (Digamos que
song1ByteArray
es el más grande). Crear una función que devuelve la matriz de bytes mixta.
private ByteArray mix2Songs(ByteArray song1ByteArray, ByteArray song2ByteArray){ int arrLength=song1ByteArray.length; for(int i=0;i<arrLength;i+=8){ // here if you see we are incrementing the length by 8 because a sterio sound has both left and right channels 4 bytes for left +4 bytes for right. // read left and right channel values for the first song float source1_L=song1ByteArray.readFloat();// I''m not sure if readFloat() function exists in android but there will be an equivalant one. float source1_R=song1ByteArray.readFloat(); float source2_L=0; float source2_R=0; if(song2ByteArray.bytesAvailable>0){ source2_L=song1ByteArray.readFloat();//left channel of audio song2ByteArray source2_R=song1ByteArray.readFloat(); //right channel of audio song2ByteArray } returnResultArr.writeFloat((source_1_L+source_2_L)/2); // average value of the source 1 and 2 left channel returnResultArr.writeFloat((source_1_R+source_2_R)/2); // average value of the source 1 and 2 right channel } return returnResultArr; }
No obtuve ninguna solución fina. Pero podemos hacer algunos trucos aquí ... :) Puede asignar ambos archivos mp3 a dos objetos diferentes de MediaPlayer. Luego, reproduzca ambos archivos a la vez con button.compare ambos archivos mp3 para encontrar el duración más larga.después de que utilice un AudioReorder para grabar a esa duración. solucionará tu problema ... Sé que no es una forma correcta pero espero que te ayude ... :)
Para fusionar (superponer) dos archivos de sonido, puede usar la biblioteca Esta FFMPEG .
Aquí está la Documentation
En su muestra solo puede ingresar el comando que desee. Entonces hablemos del comando que necesitamos.
-i [FISRST_FILE_PATH] -i [SECOND_FILE_PATH] -filter_complex amerge -ac 2 -c:a libmp3lame -q:a 4 [OUTPUT_FILE_PATH]
Para las rutas del primer y segundo archivo, obtendrá la ruta absoluta del archivo de sonido. 1- Si está almacenado, entonces es una subcarpeta para Environment.getExternalStorageDirectory().getAbsolutePath()
2- Si está activo, debería ser una subcarpeta para el file:///android_asset/
Para la ruta de salida, asegúrese de agregar la extensión ej.
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/File Name.mp3"
Primero que todo, para mezclar dos archivos de audio necesitas manipular su representación en bruto ; ya que un archivo MP3 está comprimido , no tiene acceso directo a la representación en bruto de la señal. Debe descodificar el flujo de MP3 comprimido para "entender" la forma de onda de sus señales de audio y luego podrá mezclarlas.
Por lo tanto, para mezclar dos archivos de audio comprimidos en un solo archivo de audio comprimido, se requieren los siguientes pasos:
- decodifique el archivo comprimido usando un decodificador para obtener los datos en bruto ( NO HAY UNA API DE SISTEMA PÚBLICO disponible para esto, ¡debe hacerlo manualmente )
- mezcle las dos secuencias de datos sin comprimir sin procesar (aplique el recorte de audio si es necesario). Para esto, debe considerar el formato de datos sin procesar obtenido con su decodificador ( PCM )
- codifique los datos mezclados en bruto en un archivo MP3 comprimido (según el decodificador, debe hacerlo manualmente usando un codificador )
Más información sobre decodificadores de MP3 se puede encontrar here .
Este tipo usó la biblioteca JLayer en un proyecto muy similar al tuyo. También te brinda una guía sobre cómo integrar esa biblioteca en tu aplicación de Android que recompila directamente el archivo.
Parafraseando su código es muy fácil realizar tu tarea:
public static byte[] decode(String path, int startMs, int maxMs)
throws IOException, com.mindtherobot.libs.mpg.DecoderException {
ByteArrayOutputStream outStream = new ByteArrayOutputStream(1024);
float totalMs = 0;
boolean seeking = true;
File file = new File(path);
InputStream inputStream = new BufferedInputStream(new FileInputStream(file), 8 * 1024);
try {
Bitstream bitstream = new Bitstream(inputStream);
Decoder decoder = new Decoder();
boolean done = false;
while (! done) {
Header frameHeader = bitstream.readFrame();
if (frameHeader == null) {
done = true;
} else {
totalMs += frameHeader.ms_per_frame();
if (totalMs >= startMs) {
seeking = false;
}
if (! seeking) {
SampleBuffer output = (SampleBuffer) decoder.decodeFrame(frameHeader, bitstream);
if (output.getSampleFrequency() != 44100
|| output.getChannelCount() != 2) {
throw new com.mindtherobot.libs.mpg.DecoderException("mono or non-44100 MP3 not supported");
}
short[] pcm = output.getBuffer();
for (short s : pcm) {
outStream.write(s & 0xff);
outStream.write((s >> 8 ) & 0xff);
}
}
if (totalMs >= (startMs + maxMs)) {
done = true;
}
}
bitstream.closeFrame();
}
return outStream.toByteArray();
} catch (BitstreamException e) {
throw new IOException("Bitstream error: " + e);
} catch (DecoderException e) {
Log.w(TAG, "Decoder error", e);
throw new com.mindtherobot.libs.mpg.DecoderException(e);
} finally {
IOUtils.safeClose(inputStream);
}
}
public static byte[] mix(String path1, String path2) {
byte[] pcm1 = decode(path1, 0, 60000);
byte[] pcm2 = decode(path2, 0, 60000);
int len1=pcm1.length;
int len2=pcm2.length;
byte[] pcmL;
byte[] pcmS;
int lenL; // length of the longest
int lenS; // length of the shortest
if (len2>len1) {
lenL = len1;
pcmL = pcm1;
lenS = len2;
pcmS = pcm2;
} else {
lenL = len2;
pcmL = pcm2;
lenS = len1;
pcmS = pcm1;
}
for (int idx = 0; idx < lenL; idx++) {
int sample;
if (idx >= lenS) {
sample = pcmL[idx];
} else {
sample = pcmL[idx] + pcmS[idx];
}
sample=(int)(sample*.71);
if (sample>127) sample=127;
if (sample<-128) sample=-128;
pcmL[idx] = (byte) sample;
}
return pcmL;
}
Tenga en cuenta que agregué atenuación y recorte en las últimas filas: siempre tiene que hacer ambas cosas cuando se mezclan dos formas de onda. Si no tiene requisitos de memoria / tiempo, puede hacer un int [] de la suma de las muestras y evaluar cuál es la mejor atenuación para evitar el recorte.