【问题标题】:how to synchronise audio and video using xuggler如何使用 xuggler 同步音频和视频
【发布时间】:2016-02-26 00:25:30
【问题描述】:

我正在 java 中使用 xuggler 开发 Screen Recorder with Audio。 我已经成功地分别创建了视频文件和音频文件。 现在我想同步这两个文件。我曾尝试使用“ConcatenateAudioAndVideo.java”,但是当我运行该文件时,它只会生成44bytes 文件。 谁能告诉我有什么问题? 提前致谢。

【问题讨论】:

    标签: java xuggler


    【解决方案1】:

    我还遇到了同步两个文件(音频和视频)的问题。在 Internet 上有很多技巧可以做到这一点,但没有完整的代码示例。我通过使用 xuggler 编写代码解决了这个问题。这是代码。如果您有任何问题,请务必提出。我会尽我所能帮助你。这是代码:

    import com.xuggle.mediatool.IMediaWriter;
    import com.xuggle.mediatool.ToolFactory;
    import com.xuggle.xuggler.IAudioSamples;
    import com.xuggle.xuggler.ICodec;
    import com.xuggle.xuggler.IContainer;
    import com.xuggle.xuggler.IPacket;
    import com.xuggle.xuggler.IStream;
    import com.xuggle.xuggler.IStreamCoder;
    import com.xuggle.xuggler.IVideoPicture;
    
    
     /**
     * This class is used to merge audio and video file.
     *
     * @author Arslaan Ejaz
     */
    public class DecodeAndSaveAudioVideo {
    
     public static void main(String[] args)
      {
    
        String filenamevideo = "f:/testvidfol/video.mp4"; //this is the input file for video. you can change extension
        String filenameaudio = "f:/testvidfol/audio.wav"; //this is the input file for audio. you can change extension
    
    
        IMediaWriter mWriter = ToolFactory.makeWriter("f:/testvidfol/audiovideooutput.flv"); //output file
    
        IContainer containerVideo = IContainer.make();
        IContainer containerAudio = IContainer.make();
    
        if (containerVideo.open(filenamevideo, IContainer.Type.READ, null) < 0)
            throw new IllegalArgumentException("Cant find " + filenamevideo);
    
        if (containerAudio.open(filenameaudio, IContainer.Type.READ, null) < 0)
            throw new IllegalArgumentException("Cant find " + filenameaudio);
    
        int numStreamVideo = containerVideo.getNumStreams();
        int numStreamAudio = containerAudio.getNumStreams();
    
        System.out.println("Number of video streams: "+numStreamVideo + "\n" + "Number of audio streams: "+numStreamAudio );
    
    int videostreamt = -1; //this is the video stream id
    int audiostreamt = -1;
    
    IStreamCoder  videocoder = null;
    
        for(int i=0; i<numStreamVideo; i++){
            IStream stream = containerVideo.getStream(i);
            IStreamCoder code = stream.getStreamCoder();
    
            if(code.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO)
            {
                videostreamt = i;
                videocoder = code;
                break;
            }
    
        }
    
        for(int i=0; i<numStreamAudio; i++){
            IStream stream = containerAudio.getStream(i);
            IStreamCoder code = stream.getStreamCoder();
    
            if(code.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO)
            {
                audiostreamt = i;
                break;
            }
    
        }
    
        if (videostreamt == -1) throw new RuntimeException("No video steam found");
        if (audiostreamt == -1) throw new RuntimeException("No audio steam found");
    
        if(videocoder.open()<0 ) throw new RuntimeException("Cant open video coder");
        IPacket packetvideo = IPacket.make();
    
        IStreamCoder audioCoder = containerAudio.getStream(audiostreamt).getStreamCoder();
    
        if(audioCoder.open()<0 ) throw new RuntimeException("Cant open audio coder");
        mWriter.addAudioStream(1, 1, audioCoder.getChannels(), audioCoder.getSampleRate());
    
        mWriter.addVideoStream(0, 0, videocoder.getWidth(), videocoder.getHeight());
    
        IPacket packetaudio = IPacket.make();
    
        while(containerVideo.readNextPacket(packetvideo) >= 0 ||
                containerAudio.readNextPacket(packetaudio) >= 0){
    
            if(packetvideo.getStreamIndex() == videostreamt){
    
                //video packet
                IVideoPicture picture = IVideoPicture.make(videocoder.getPixelType(),
                        videocoder.getWidth(),
                        videocoder.getHeight());
                int offset = 0;
                while (offset < packetvideo.getSize()){
                    int bytesDecoded = videocoder.decodeVideo(picture, 
                            packetvideo, 
                            offset);
                    if(bytesDecoded < 0) throw new RuntimeException("bytesDecoded not working");
                    offset += bytesDecoded;
    
                    if(picture.isComplete()){
                        System.out.println(picture.getPixelType());
                        mWriter.encodeVideo(0, picture);
    
                    }
                }
            } 
    
            if(packetaudio.getStreamIndex() == audiostreamt){   
            //audio packet
    
                IAudioSamples samples = IAudioSamples.make(512, 
                        audioCoder.getChannels(),
                        IAudioSamples.Format.FMT_S32);  
                int offset = 0;
                while(offset<packetaudio.getSize())
                {
                    int bytesDecodedaudio = audioCoder.decodeAudio(samples, 
                            packetaudio,
                            offset);
                    if (bytesDecodedaudio < 0)
                        throw new RuntimeException("could not detect audio");
                    offset += bytesDecodedaudio;
    
                    if (samples.isComplete()){
                         mWriter.encodeAudio(1, samples);
    
            }
                }
    
        }
    
      }
    }
    }
    

    【讨论】:

    • @arslaan ejaz 我试过你的代码,但只想知道你在这里使用的库是什么,特别是它们的版本。我收到以下错误:Exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.Logger.trace(Ljava/lang/String;Ljava/lang/Object;)V
    • 您可以从包括 xuggler 5.4 在内的 openimaj 库中获取所有内容。 youtube 链接:www.youtube.com/watch?v=TNEQ0eNqLgA
    • @arslaan ejaz:您能帮我寻找带音频文件的视频吗?我已成功创建音频视频文件,但在 MAC os 中查找时遇到问题...如果您知道请帮忙
    • @arslaanejaz:我使用了你的代码并得到了输出视频文件,但我无法在 javafx 场景媒体和其他播放器中播放它。这是我使用的代码stackoverflow.com/questions/33923058/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-11
    • 2013-10-29
    • 2016-04-25
    • 2011-05-02
    • 1970-01-01
    • 2012-12-16
    • 1970-01-01
    相关资源
    最近更新 更多