0

I have a long array of MP3 audio chunks, each one is encoded to Base64 String. Each chunk contains MP3 data only, no headers.

Given that all the chunks are equal in sampling rate, resolution, and number of channels - How can I concatenate all the chunks to a single valid MP3 file including required headers.

I plan to do it using Java, but any command-line app that can be executed from Java should do as well.

Thanks!

Forepick
  • 919
  • 2
  • 11
  • 31
  • can you concatenate files as regular mp3s? thats your starting point - search round for "concatenate mp3 in java" - list your results here and then we will see if there isnt an answer yet – gpasch Mar 30 '16 at 14:59
  • I searched quite a lot about concatenating MP3 files, most of the solutions are some external app dependent. Anyway - my problem is different, I don't want to concat files but chunk of a bare MP3 data. Audio Frames only, no headers, no meta tags, Which means I'll have to generate these tags myself to make it a valid mp3 file... (or is there some good command line tool to do it...) – Forepick Mar 31 '16 at 21:09

1 Answers1

1

You will need the following:

decode base64 to byte data

combine/concat all the byte data of the files

save to a wav

convert to mp3

For getting the bytes out of base64 you can use any method (java 8 apache etc) - I assume you can do that and I havent done anything on it: Decode Base64 data in Java.

So I assume you can do something like this

byte[] bytes = "Hello, World!".getBytes("UTF-8");
String encoded = Base64.getEncoder().encodeToString(bytes);
byte[] decoded = Base64.getDecoder().decode(encoded);

and you have two files converted to byte arrays b1 and b2.

Then you concat the bytes and save to a wav file. If lame mp3 converter is available to you and you can use it (legal issues possibly) then you can do that. Otherwise use some audio software to convert wav to mp3.

  try {
    byte[] outData=new byte[b1.length+b2.length+];
    for(i=0; i<b1.length; i++) outData[i]=b1[i];
    for(i=0; i<b2.length; i++) outData[b1.length+i]=b2[i];
    AudioFormat af=audioInputStream.getFormat();
    InputStream byteArrayInputStream=new ByteArrayInputStream(outData);
    AudioFormat af=new AudioFormat(44100f, 16, 2, true, true);

    File fo=new File("out-"+(System.currentTimeMillis()/1000)+".wav");

    AudioInputStream audioOutputStream=new AudioInputStream(byteArrayInputStream, af, outData.length/af.getFrameSize());
    AudioSystem.write(audioOutputStream, AudioFileFormat.Type.WAVE, fo);

  String cmd="\""+"C:/lame"+"\""+
                " -h "+fo.getName()+" "+fo.getName().substring(0, fo.getName().lastIndexOf(".")+1)+"mp3";
        Runtime rt = Runtime.getRuntime();
        final Process pr=rt.exec(cmd);

    Thread th=new Thread() {
      public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(pr.getErrorStream());
            BufferedReader br = new BufferedReader(isr);
            String line=null;
            int i=0;
            while ( (line = br.readLine()) != null) {
System.out.println("line "+i+" >" + line);
                i++;
            }
  }
  catch(Exception ex) { ex.printStackTrace(); }
      }
    };
    th.start();


        int exitVal=pr.waitFor();
        System.out.println("ExitValue: " + exitVal);
  }
  catch(Exception ex) { ex.printStackTrace(); }

--

To make sure the next file starts at a good boundary (generally 4 bytes) do the following:

    int add=4-b1.length%4;
    byte[] outData=new byte[b1.length+add+b2.length+];
    for(i=0; i<b1.length; i++) outData[i]=b1[i];
    for(i=0; i<b2.length; i++) outData[b1.length+add+i]=b2[i];

the same if you have many files.

Community
  • 1
  • 1
gpasch
  • 2,672
  • 3
  • 10
  • 12
  • Thanks for the detailed answer. But as I wrote above, what I have is a set of MP3 audio chunks. If I decode and concat them I get a sort-of invalid MP3 file, not a WAV. The chunks contain MP3 audio data only, without valid headers or meta data, and I think this is the main problem. When I just decode, concat and play them - it sounds very choppy, like I have a few milliseconds of silence between every two frames. – Forepick Apr 02 '16 at 21:27
  • have you put together a program? please post it to see what happens – gpasch Apr 02 '16 at 21:42
  • I don't have a program yet since I'm don't have a clue how to set up these headers... – Forepick Apr 03 '16 at 20:29