简体   繁体   中英

create mp4 from pictures and mp3 java using xuggler

Im trying to combine a list of pictures to an mp4 movie with adding an mp3 file. The length of the movie the user can choose either the length of the mp3 file or choose it manual. And if the user chooses manual (length!=mp3 file length) the mp3 file should be cut or looped.

No it works with the pictures but without sound :(

private void convertImageToVideo() {

    IMediaWriter writer = ToolFactory.makeWriter(outputFilename);

    long delay = videotime / PicPathList.size();

    long milliseconds = 0;

    //adds Pictures to the mp4 stream
    for (int i = 0; i < PicPathList.size(); i++) {



        BufferedImage bi;
        try {
            bi = ImageIO.read(new File(PicPathList.get(i)));
            bi = Tools.prepareForEncoding(bi);

            int width=bi.getWidth();
            int height=bi.getHeight();

            if(width%2==1){
                width++;
            }

            if(height%2==1){
                height++;
            }

            if (i == 0) {
                writer.addVideoStream(0, 0, ID.CODEC_ID_H264, width, height);
            }
        //debug
            //  System.out.println(PicPathList.get(i) + ", bi:" + bi.getWidth() + "x"
            //        + bi.getHeight() + ", ms:" + milliseconds);
            writer.encodeVideo(0, bi, milliseconds, TimeUnit.MILLISECONDS);
            milliseconds += delay;
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("Error");
        }





    }

    writer.close();

//at this part Im trying to combine the further generated mp4 file with the mp3 file

     String inputVideoFilePath = outputFilename;
        String inputAudioFilePath = this.musicFile.getAbsolutePath();
        String outputVideoFilePath = "outputFilename";

        IMediaWriter mWriter = ToolFactory.makeWriter(outputVideoFilePath);

        IContainer containerVideo = IContainer.make();
        IContainer containerAudio = IContainer.make();

        // check files are readable
        containerVideo.open(inputVideoFilePath, IContainer.Type.READ, null);

       containerAudio.open(inputAudioFilePath, IContainer.Type.READ, null);

        // read video file and create stream
        IStreamCoder coderVideo = containerVideo.getStream(0).getStreamCoder();

        IPacket packetvideo = IPacket.make();
        int width = coderVideo.getWidth();
        int height = coderVideo.getHeight();

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

        IPacket packetaudio = IPacket.make();


        mWriter.addAudioStream(1, 0,coderAudio.getCodecID(), coderAudio.getChannels(), coderAudio.getSampleRate());
        mWriter.addVideoStream(0, 0, width, height);

        while (containerVideo.readNextPacket(packetvideo) >= 0) {

            containerAudio.readNextPacket(packetaudio);

            // video packet
            IVideoPicture picture = IVideoPicture.make(coderVideo.getPixelType(), width, height);
            coderVideo.decodeVideo(picture, packetvideo, 0);
            if (picture.isComplete()) 
                mWriter.encodeVideo(0, picture);

            // audio packet 
            IAudioSamples samples = IAudioSamples.make(512, coderAudio.getChannels(),      IAudioSamples.Format.FMT_S32);
            coderAudio.decodeAudio(samples, packetaudio, 0);
            if (samples.isComplete()) 
                mWriter.encodeAudio(1, samples);

        }

        coderAudio.close();
        coderVideo.close();
        containerAudio.close();
        containerVideo.close();
        mWriter.close();
}

You may use another jar file to merge your video and audio. Please notice this is not the right way to do it, but I didn't have any choice and time to dig into Xuggler codes.

I hope it works for you, too.

package MP4;

/**
 *
 * @author Pasban
 */
import com.coremedia.iso.boxes.Container;
import com.googlecode.mp4parser.authoring.Movie;
import com.googlecode.mp4parser.authoring.Track;
import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder;
import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class MuxMp4 {

    public static void merge(String audio, String video, String output) throws IOException {

        Movie countVideo = MovieCreator.build(video);
        Movie countAudioEnglish = MovieCreator.build(audio);

        Track audioTrackEnglish = countAudioEnglish.getTracks().get(0);
        audioTrackEnglish.getTrackMetaData().setLanguage("eng");

        countVideo.addTrack(audioTrackEnglish);

        Container out = new DefaultMp4Builder().build(countVideo);
        FileOutputStream fos = new FileOutputStream(new File(output));
        out.writeContainer(fos.getChannel());
        fos.close();


    }
}

Check the MP4Parser sample codes for more information.

It is nice to mention that both of your files should be mp4. So you need to convert your mp3 to mp4 as well. and your video should not contain any sound, which in your case it does not.

AS I mentioned earlier, this in not the right way to do the job done.

I answered this question here which it is a complete answer.

JAVA - Xuggler - Play video while combining an MP3 audio file and a MP4 movie

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