如何在java使用音频_java – 如何使用xuggler同步音频和视频

本文提供了一个使用Xuggler库在Java中同步音频和视频的完整代码示例。通过读取输入的视频和音频文件,创建一个MediaWriter来写入输出文件,并使用IStreamCoder解码和编码视频帧和音频样本,实现音视频的同步合并。
摘要由CSDN通过智能技术生成

我还在解决同步两个文件(音频和视频)的问题.有很多提示可以在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

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

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

{

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

}

}

}

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值