Java 如何使用xuggler同步音频和视频

Java 如何使用xuggler同步音频和视频,java,xuggler,Java,Xuggler,我正在使用java中的xuggler开发带有音频的屏幕记录器。 我已经成功地分别创建了视频文件和音频文件。 现在我想同步这两个文件。我尝试过使用“ConcatenateAudioAndVideo.java”,但当我运行该文件时,它只会生成44字节的文件。 谁能告诉我出了什么问题? 提前感谢。我也遇到了同步两个文件(音频和视频)的问题。在互联网上有很多这样做的技巧,但没有一个完整的代码示例。我通过使用Xugler编写代码解决了这个问题。这是代码。如果你有任何问题,请一定要问。我会尽我所能帮助你。代

我正在使用java中的
xuggler
开发带有音频的
屏幕记录器。
我已经成功地分别创建了视频文件和音频文件。
现在我想同步这两个文件。我尝试过使用“ConcatenateAudioAndVideo.java”,但当我运行该文件时,它只会生成
44字节的文件。
谁能告诉我出了什么问题?

提前感谢。

我也遇到了同步两个文件(音频和视频)的问题。在互联网上有很多这样做的技巧,但没有一个完整的代码示例。我通过使用Xugler编写代码解决了这个问题。这是代码。如果你有任何问题,请一定要问。我会尽我所能帮助你。代码如下:

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

        }
            }

    }

  }
}
}
import com.xuggle.mediatool.IMediaWriter;
导入com.xuggle.mediatool.ToolFactory;
导入com.xuggle.xuggler.IAudioSamples;
导入com.xuggle.xuggler.ICodec;
导入com.xuggle.xuggler.IContainer;
导入com.xuggle.xuggler.IPacket;
导入com.xuggle.xuggler.IStream;
导入com.xuggle.xuggler.IStreamCoder;
导入com.xuggle.xuggler.IVideoPicture;
/**
*此类用于合并音频和视频文件。
*
*@author Arslaan Ejaz
*/
公共类解码和保存音频视频{
公共静态void main(字符串[]args)
{
String filenamevideo=“f:/testvidfol/video.mp4”;//这是视频的输入文件。您可以更改扩展名
String filenameaudo=“f:/testvidfol/audio.wav”;//这是音频的输入文件。您可以更改扩展名
IMediaWriter mWriter=ToolFactory.makeWriter(“f:/testvidfol/audiovideooutput.flv”);//输出文件
IContainer containerVideo=IContainer.make();
IContainer容器audio=IContainer.make();
if(containerVideo.open(filenamevideo,IContainer.Type.READ,null)<0)
抛出新的IllegalArgumentException(“找不到”+filenamevideo);
if(containerAudio.open(filenameaudio,IContainer.Type.READ,null)<0)
抛出新的IllegalArgumentException(“找不到”+filenameaudio);
int numStreamVideo=containerVideo.getNumStreams();
int numStreamAudio=containerAudio.getNumStreams();
System.out.println(“视频流的数量:+numStreamVideo+”\n“+”音频流的数量:+numstreamudio);
int videostreamt=-1;//这是视频流id
int audiostreamt=-1;
IStreamCoder videocoder=null;

对于(int i=0;i@arslaanejaz我尝试了你的代码,但只是想知道你在这里使用的库是什么,特别是它们的版本。我得到了以下错误:
线程“main”java.lang.NoSuchMethodError中的异常:org.slf4j.Logger.trace(Ljava/lang/String;Ljava/lang/Object;)V
您可以从openimaj库(包括xuggler 5.4)获得所有内容。youtube链接:www.youtube.com/watch?V=TNEQ0eNqLgA@arslaanejaz:你能帮我用音频文件查找视频吗?我已经成功创建了音频视频文件,但在MAC os中查找有问题…如果你需要帮助,请帮助know@arslaanejaz例如我用你的鳕鱼并获得了输出的视频文件,但我无法在javafx场景媒体和其他播放器中播放