JAVA-Xuggler-结合MP3音频文件和MP4电影播放视频
下面的代码使用JAVA和Xugler组合了MP3音频文件和MP4电影文件,并输出了组合的MP4文件 我想输出视频文件应自动播放,同时结合音频和视频文件JAVA-Xuggler-结合MP3音频文件和MP4电影播放视频,java,mp3,mp4,video-player,Java,Mp3,Mp4,Video Player,下面的代码使用JAVA和Xugler组合了MP3音频文件和MP4电影文件,并输出了组合的MP4文件 我想输出视频文件应自动播放,同时结合音频和视频文件 String inputVideoFilePath = "in.mp4"; String inputAudioFilePath = "in.mp3"; String outputVideoFilePath = "out.mp4"; IMediaWriter mWriter = ToolFactory.makeWriter(outputVideo
String inputVideoFilePath = "in.mp4";
String inputAudioFilePath = "in.mp3";
String outputVideoFilePath = "out.mp4";
IMediaWriter mWriter = ToolFactory.makeWriter(outputVideoFilePath);
IContainer containerVideo = IContainer.make();
IContainer containerAudio = IContainer.make();
// check files are readable
if (containerVideo.open(inputVideoFilePath, IContainer.Type.READ, null) < 0)
throw new IllegalArgumentException("Cant find " + inputVideoFilePath);
if (containerAudio.open(inputAudioFilePath, IContainer.Type.READ, null) < 0)
throw new IllegalArgumentException("Cant find " + inputAudioFilePath);
// read video file and create stream
IStreamCoder coderVideo = containerVideo.getStream(0).getStreamCoder();
if (coderVideo.open(null, null) < 0)
throw new RuntimeException("Cant open video coder");
IPacket packetvideo = IPacket.make();
int width = coderVideo.getWidth();
int height = coderVideo.getHeight();
// 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();
mWriter.addAudioStream(1, 0, 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();
String inputVideoFilePath=“in.mp4”;
字符串inputAudioFilePath=“in.mp3”;
字符串outputVideoFilePath=“out.mp4”;
IMediaWriter mWriter=ToolFactory.makeWriter(outputVideoFilePath);
IContainer containerVideo=IContainer.make();
IContainer容器audio=IContainer.make();
//检查文件是否可读
if(containervideofilepath,IContainer.Type.READ,null)小于0
抛出新的IllegalArgumentException(“找不到”+inputVideoFilePath);
if(containerAudio.open(inputAudioFilePath,IContainer.Type.READ,null)<0)
抛出新的IllegalArgumentException(“找不到”+inputAudioFilePath);
//读取视频文件并创建流
IStreamCoder coderVideo=containerVideo.getStream(0.getStreamCoder();
if(coderVideo.open(null,null)<0)
抛出新的运行时异常(“无法打开视频编码器”);
IPacket packetvideo=IPacket.make();
int-width=coderVideo.getWidth();
int height=coderVideo.getHeight();
//读取音频文件并创建流
IStreamCoder coderAudio=containerAudio.getStream(0.getStreamCoder();
if(coderAudio.open(null,null)<0)
抛出新的运行时异常(“无法打开音频编码器”);
IPacket packetaudio=IPacket.make();
addAudioStream(1,0,coderAudio.getChannel(),coderAudio.getSampleRate());
mWriter.addVideoStream(0,0,宽度,高度);
while(containerVideo.readNextPacket(packetvideo)>=0){
containerAudio.ReadnextPackage(packetaudio);
//视频包
IVideoPicture=IVideoPicture.make(coderVideo.getPixelType(),宽度,高度);
coderVideo.decodeVideo(图片,打包视频,0);
if(picture.isComplete())
编码视频(0,图片);
//音频包
IAudioSamples samples=IAudioSamples.make(512,coderAudio.getChannels(),IAudioSamples.Format.FMT_S32);
解码音频(样本,packetaudio,0);
if(samples.isComplete())
mWriter.encoder音频(1个样本);
}
coderAudio.close();
coderVideo.close();
containerAudio.close();
containerVideo.close();
mWriter.close();
如果有人知道在使用java Xugler组合音频和视频文件时自动播放视频文件。。请帮帮我。这真的很值得欣赏。它可能很旧,但你所需要做的就是把你的照片画在一张jpanel上。大概是这样的:
//Instead of
if (picture.isComplete()){
mWriter.encodeVideo(0, picture);
}
//Use
if (picture.isComplete()) {
mWriter.encodeVideo(0, picture);
IConverter converter = ConverterFactory.createConverter(ConverterFactory.XUGGLER_BGR_24, picture);
repaint_on_jpanel_thread(converter.toImage(picture));
//this is a function to paint the buffered image on your jpanel
}
这是完整的代码。
我还做了一些修改:如果音频较长,则单独编写其余部分,并在标题栏中添加音频和视频的进度。您可能需要检查文件中是否存在真正的视频或音频流,以防止出现错误
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.Global;
import com.xuggle.xuggler.IAudioSamples;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IPacket;
import com.xuggle.xuggler.IStreamCoder;
import com.xuggle.xuggler.IVideoPicture;
import com.xuggle.xuggler.video.ConverterFactory;
import com.xuggle.xuggler.video.IConverter;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
/**
*
* @author Pasban
*/
public class MergeVideoAudio extends JDialog {
Image image;
private double video_duration = 0.00001, video_read = 0, audio_duration = 0.00001, audio_read = 0;
public static void main(String[] args) {
final MergeVideoAudio merge = new MergeVideoAudio();
Thread thread = new Thread() {
@Override
public void run() {
merge.perform("y:/a.mp4", "y:/b.mp3", "y:/c.mp4");
merge.setVisible(false);
System.exit(0);
}
};
thread.run();
}
public void perform(String path_video, String path_audio, String path_output) {
IMediaWriter mWriter = ToolFactory.makeWriter(path_output);
IContainer containerVideo = IContainer.make();
IContainer containerAudio = IContainer.make();
// check files are readable
if (containerVideo.open(path_video, IContainer.Type.READ, null) < 0) {
throw new IllegalArgumentException("Cant find " + path_video);
}
if (containerAudio.open(path_audio, IContainer.Type.READ, null) < 0) {
throw new IllegalArgumentException("Cant find " + path_audio);
}
// read video file and create stream
IStreamCoder coderVideo = containerVideo.getStream(0).getStreamCoder();
if (coderVideo.open(null, null) < 0) {
throw new RuntimeException("Cant open video coder");
}
int width = coderVideo.getWidth();
int height = coderVideo.getHeight();
this.setSize(width, height);
this.setLocationRelativeTo(null);
this.setVisible(true);
// 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 packet = IPacket.make();
mWriter.addAudioStream(1, 0, coderAudio.getChannels(), coderAudio.getSampleRate());
mWriter.addVideoStream(0, 0, width, height);
video_duration = 0.000001 + (containerVideo.getDuration() == Global.NO_PTS ? 0 : (containerVideo.getDuration() / 1000.0));
audio_duration = 0.000001 + (containerAudio.getDuration() == Global.NO_PTS ? 0 : (containerAudio.getDuration() / 1000.0));
while (containerVideo.readNextPacket(packet) >= 0) {
video_read = (packet.getTimeStamp() * packet.getTimeBase().getDouble() * 1000);
// video packet
IVideoPicture picture = IVideoPicture.make(coderVideo.getPixelType(), width, height);
coderVideo.decodeVideo(picture, packet, 0);
if (picture.isComplete()) {
mWriter.encodeVideo(0, picture);
IConverter converter = ConverterFactory.createConverter(ConverterFactory.XUGGLER_BGR_24, picture);
this.setImage(converter.toImage(picture));
this.setProgress(video_duration, video_read, audio_duration, audio_read);
}
// audio packet
containerAudio.readNextPacket(packet);
audio_read = (packet.getTimeStamp() * packet.getTimeBase().getDouble() * 1000);
IAudioSamples samples = IAudioSamples.make(512, coderAudio.getChannels(), IAudioSamples.Format.FMT_S32);
coderAudio.decodeAudio(samples, packet, 0);
if (samples.isComplete()) {
mWriter.encodeAudio(1, samples);
this.setProgress(video_duration, video_read, audio_duration, audio_read);
}
}
//write the remaining audio, if your audio is longer than your video
while (containerAudio.readNextPacket(packet) >= 0) {
audio_read = (packet.getTimeStamp() * packet.getTimeBase().getDouble() * 1000);
IAudioSamples samples = IAudioSamples.make(512, coderAudio.getChannels(), IAudioSamples.Format.FMT_S32);
coderAudio.decodeAudio(samples, packet, 0);
if (samples.isComplete()) {
mWriter.encodeAudio(1, samples);
this.setProgress(video_duration, video_read, audio_duration, audio_read);
}
}
coderAudio.close();
coderVideo.close();
containerAudio.close();
containerVideo.close();
mWriter.close();
}
public MergeVideoAudio() {
this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public void setImage(final Image image) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
MergeVideoAudio.this.image = image;
repaint();
}
});
}
@Override
public synchronized void paint(Graphics g) {
if (image != null) {
g.drawImage(image, 0, 0, null);
}
}
public static String convertDurationHMSm(double time) {
long elapsed = (long) (time * 1000);
long duration = elapsed / 1000;
long ms = elapsed % 1000;
return String.format("%02d:%02d:%02d.%02d", duration / 3600, (duration % 3600) / 60, (duration % 60), ms / 10);
}
private void setProgress(double video_duration, double video_read, double audio_duration, double audio_read) {
this.setTitle("Video: " + (int) (100 * video_read / video_duration) + "%, Audio " + (int) (100 * audio_read / audio_duration) + "%");
}
}
嘿,当我尝试在视频文件中添加歌曲时,它会显示.com.xuggler.mediaTool.ToolFactory NoClassDefFoundError。如何解决此错误。请帮助我。Robin thnkx fr ur response。。如果您正在运行maven项目,请添加以下依赖项xuggle xuggle xuggle xuggler 5.4如果您没有运行maven,请将xuggler 5.4 jar下载到lib路径。我没有通过maven使用项目:(我使用的是3.4 lib。除了通过maven运行之外,还有其他方法吗?是的,你可以不使用maven运行,但应该使用正确的库。你使用3.4 lib(该版本似乎不正确)你可以通过此链接下载正确的jar文件=======================>()然后运行项目..或者尝试使用Maven项目运行它太简单了如果你使用Maven你只需要在pom.xml文件中添加两个东西。1)添加此存储库==>xuggle repo xuggle.googlecode.com/svn/trunk/repo/share/java/和一个依赖===>xuggle xuggle xuggle 5.4。如果您对mavenHi Slaven不满意,请分享您的邮件id,谢谢您帮助解决我的问题。请分享这个函数代码==>needrepaint_在线程上(converter.toImage(picture));我不熟悉jpanel,所以请分享一下这个函数代码。非常感谢。是的,视频在结合音频和视频时显示。再次感谢manHey Slaven我仍然需要一个说明,我应该在哪里使用此代码==>尝试{Thread.sleep((long)(1000/coderVideo.getFrameRate().getDouble());}catch(InterruptedException ex){ex.printStackTrace();}为了根据视频帧速率显示帧,您可以将其放在**while(视频袖珍阅读器)**中的任何位置,如果您愿意,您可以将其放在此处之后:this.setImage(converter.toImage(picture));真的没有区别,因为你会显示你手中的图像,你会等到通过帧延迟后再读取下一帧/图像。这对我不起作用。我能听到音频,但看不到图像,只有一个黑屏
try {
Thread.sleep((long) (1000 / coderVideo.getFrameRate().getDouble()));
} catch (InterruptedException ex) {
ex.printStackTrace();
}