简体   繁体   中英

how to merge two different audio in video using java xuggler

I need help to concatenate two separate audio files together. My first audio track lasts for 7 seconds and I want my second audio track to play immediately after the first.

The following is my code:

private void initVideo(String fileName){
    String inputAudioFilePath = "/Users/Document/Desktop/audio.mp3";

    createEmptyMP4(folder + "/" + fileName + ".mp4");
    writer = makeWriter(folder + "/" + fileName + ".mp4");
    screenBounds = Toolkit.getDefaultToolkit().getScreenSize();
    writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_MPEG4,screenBounds.width, screenBounds.height);
    startTime = System.nanoTime();

    IContainer containerAudio = IContainer.make();

    if(containerAudio.open(inputAudioFilePath, IContainer.Type.READ, null) < 0){
        throw new IllegalArgumentException("Cant find " + inputAudioFilePath);
    }

    // read audio file and create stream
    IStreamCoder coderAudio = containerAudio.getStream(0).getStreamCoder();

    if(coderAudio.open(null, null) < 0){
        throw new RuntimeException("Cant open audio coder");
    }

    IPacket packetaudio = IPacket.make();
    writer.addAudioStream(1, 0, coderAudio.getChannels(), coderAudio.getSampleRate());
    int a = -1;
    ArrayList<IAudioSamples> audioPac = new ArrayList<IAudioSamples>();

    while ((a = containerAudio.readNextPacket(packetaudio)) >= 0){
        if (a >= 0){
            // audio packet
            IAudioSamples samples = IAudioSamples.make(512, coderAudio.getChannels(), IAudioSamples.Format.FMT_S32);
            coderAudio.decodeAudio(samples, packetaudio, 0);
            audioPac.add(samples);
        }
    }

    for(int j=0; j < 300; j++){ 
        writer.encodeAudio(1, audioPac.get(j)); 
    }

    coderAudio.close();
    containerAudio.close();
}

let's say you have opened two audio files:

coderAudio1 <--- first.mp3

coderAudio2 <--- second.mp3

write all your audio first samples into your writer and when it is finished, start writing the second audio samples.

With some changes and control, you can add your video frames in between of two audios.

I wrote this code, but I get error on big files and I don't know the reason.

import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.IAudioSamples;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IPacket;
import com.xuggle.xuggler.IStreamCoder;

/**
 *
 * @author Pasban
 */
public class xuggleMergeAudioTest {

    public static void main(String[] args) {
        IContainer countainer1 = IContainer.make();
        countainer1.open("audio.mp3", IContainer.Type.READ, null);
        IStreamCoder audio1 = countainer1.getStream(0).getStreamCoder();
        audio1.open(null, null);


        IContainer countainer2 = IContainer.make();
        countainer2.open("audio2.mp3", IContainer.Type.READ, null);
        IStreamCoder audio2 = countainer2.getStream(0).getStreamCoder();
        audio2.open(null, null);

        IMediaWriter mWriter = ToolFactory.makeWriter("concatinated.mp3");
        mWriter.addAudioStream(0, 0, audio1.getChannels(), audio1.getSampleRate());

        IPacket packet = IPacket.make();
        while (countainer1.readNextPacket(packet) >= 0) {
            IAudioSamples samples = IAudioSamples.make(512, audio1.getChannels(), IAudioSamples.Format.FMT_S32);
            audio1.decodeAudio(samples, packet, 0);
            mWriter.encodeAudio(0, samples);
        }

        while (countainer2.readNextPacket(packet) >= 0) {
            IAudioSamples samples = IAudioSamples.make(512, audio2.getChannels(), IAudioSamples.Format.FMT_S32);
            audio2.decodeAudio(samples, packet, 0);
            mWriter.encodeAudio(0, samples);
        }

        mWriter.close();

    }
}

Also have you tried this demo from Xuggle: https://code.google.com/p/xuggle/source/browse/trunk/java/xuggle-xuggler/src/com/xuggle/mediatool/demos/ConcatenateAudioAndVideo.java?r=929

I think you have to check if channels and sample rates in both audios mach, too.

Creo que esta es una mejora, sirve para n archivos de audio

import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.IAudioSamples;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IPacket;
import com.xuggle.xuggler.IStreamCoder;

public class Concatenador_Audios {
public static void main(String[] args) {
        ConcatenarAudios("D:\\out concatenate.mp3", "D:\\in Audio (1).mp3", "D:\\in Audio (2).mp3", "D:\\in Audio (3).mp3");
    }

    public static void ConcatenarAudios(String Ruta_AudioConcatenado,String... ruta_Audio) {
        int n = ruta_Audio.length;
        IMediaWriter mWriter = ToolFactory.makeWriter(Ruta_AudioConcatenado);

        IPacket packet = IPacket.make();
        for (int i = 0; i < n; i++) {
            IContainer container = IContainer.make();
            container.open(ruta_Audio[i], IContainer.Type.READ, null);
            IStreamCoder audio = container.getStream(0).getStreamCoder();
            audio.open(null, null);
            if (i == 0) {
                mWriter.addAudioStream(0, 0, audio.getChannels(), audio.getSampleRate());
            }
            while (container.readNextPacket(packet) >= 0) {
                IAudioSamples samples = IAudioSamples.make(512, audio.getChannels(), IAudioSamples.Format.FMT_S32);
                audio.decodeAudio(samples, packet, 0);
                mWriter.encodeAudio(0, samples);
            }
            container.close();
            audio.close();
            }

            mWriter.close();
        }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM