Как смешивать/накладывать два mp3 файла в один mp3 файл (не конкатенировать)

Я хочу объединить два mp3 файла в один mp3 файл. Например, если 1-й файл равен 1мин, а второй файл - 30 секунд, то выход должен быть один мин. В течение одной минуты он должен воспроизводить оба файла.

Ответы

Ответ 1

Прежде всего, , чтобы смешивать два аудиофайла, вам нужно манипулировать их исходным представлением; поскольку сжат файл MP3, у вас нет прямого доступа к необработанному представлению сигнала. Вам необходимо декодировать сжатый поток MP3, чтобы "понять" волновую форму ваших аудиосигналов, а затем вы сможете их смешивать.

Таким образом, чтобы смешивать два сжатых аудиофайла в один сжатый аудиофайл, необходимы следующие шаги:

  • декодировать сжатый файл с использованием декодера для получения необработанных данных (NO PUBLIC SYSTEM API для этого, вам нужно сделать это вручную!).
  • смешать два необработанных несжатых потока данных (при необходимости применяя обрезку аудио). Для этого вам нужно рассмотреть формат необработанных данных, полученный с вашим декодером (PCM)
  • закодировать необработанные смешанные данные в сжатый файл MP3 (согласно декодеру, вам нужно сделать это вручную с помощью кодировщика)

Подробнее aboud MP3-декодеры можно найти здесь.

Ответ 2

Я не уверен, что вы хотите сделать это на Android-телефоне (выглядит так из-за ваших тегов), но если я прав, попробуйте LoopStack, это мобильный DAW (сам не пробовал).

Если вы просто "микшируете" два файла без регулировки объема вывода, который может вывести ваш вывод. Однако я не уверен, возможно ли "смешивать" два mp3 файла без их декодирования.

Если вам удобно объединить их на своем ПК, попробуйте Audacity, это бесплатный рабочий стол DAW.

Ответ 3

Я не делал этого в Android, но я сделал это с помощью Adobe flex. Думаю, логика остается прежней. Я выполнил следующие шаги:

  • Я извлек оба mp3s в два байтовых массива. (song1ByteArray, song2ByteArray)
  • Узнайте больше массив байтов. (Скажем, song1ByteArray больше).
  • Создайте функцию, которая возвращает смешанный массив байтов.

    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;
    }
    

Ответ 4

1. Опубликовать микширование аудио в Android

2. Еще одно сообщение о микшировании аудио в Android

3. Вы могли бы использовать Java Sound для микширования двух аудиофайлов

Пример:


// 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. Попробуйте AudioConcat, у которого есть опция -m для микширования


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. Вы можете использовать ffmpeg android wrapper, используя синтаксис и подход, как описано здесь

Ответ 5

Этот парень использовал библиотеку JLayer в проекте, очень похожем на ваш. Он также дает вам руководство о том, как интегрировать эту библиотеку в ваше приложение Android напрямую перекомпилировать банку.

Перефразируя его код, очень легко выполнить свою задачу:

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;
}

Обратите внимание, что я добавил затухание и отсечение в последних строках: вам всегда нужно делать оба при смешивании двух осциллограмм. Если у вас нет требований к памяти/времени, вы можете сделать int [] из суммы образцов и оценить наилучшее ослабление, чтобы избежать обрезки.

Ответ 6

Чтобы объединить (дублировать) два звуковых файла, вы можете использовать Эта библиотека FFMPEG.

Вот Документация

В своем примере вы можете просто ввести нужную команду. Поэтому давайте поговорим о команде, которая нам нужна.

-i [FISRST_FILE_PATH] -i [SECOND_FILE_PATH] -filter_complex amerge -ac 2 -c:a libmp3lame -q:a 4 [OUTPUT_FILE_PATH]

Для первого и второго путей к файлу вы получите абсолютный путь к звуковому файлу. 1- Если он находится в хранилище, это подпапка для Environment.getExternalStorageDirectory().getAbsolutePath()

2- Если это активы, значит, это должна быть подпапка для file:///android_asset/

Для выходного пути обязательно добавьте расширение напр.

String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/File Name.mp3"

Ответ 7

Я не получил никакого прекрасного решения. Но мы можем сделать какой-то трюк здесь..:) Вы можете назначить оба mp3 файла двум различным объектам MediaPlayer. Затем воспроизводите оба файла за один раз с помощью button.compare и mp3 файлов, чтобы найти самую длинную продолжительность. После этого используйте AudioReorder для записи на эту длительность. он решит вашу проблему. Я знаю, что это не правильный путь, но надеюсь, что это вам поможет..:)