[英]Combine Audio with Video(without ffmpeg) - Java
I am building an applet to capture screen and microphone input (audio). 我正在构建一个applet来捕获屏幕和麦克风输入(音频)。 I am able to record these files separately but could not find a way to combine these files to make a new video with audio.
我能够单独记录这些文件,但无法找到一种方法来组合这些文件来制作带有音频的新视频。
Video file is in .mov
format and audio is in .wav
format. 视频文件采用
.mov
格式,音频采用.wav
格式。 They have exact same length. 它们的长度完全相同。
Is there any way to combine these files? 有没有办法合并这些文件? I have tried Java but could not find a way to combine two files.
我尝试过Java,却找不到合并两个文件的方法。
Also I have to do it without ffmpeg
since it needs to be installed on client side. 此外,我必须在没有
ffmpeg
情况下这样做,因为它需要安装在客户端。
private void mergeFiles() {
try {
DataSource videoDataSource = javax.media.Manager.createDataSource(oml.getURL()); //your video file
DataSource audioDataSource = javax.media.Manager.createDataSource(realAudioFile.toURI().toURL()); // your audio file
DataSource mixedDataSource = null; // data source to combine video with audio
DataSource arrayDataSource[] = new DataSource[2]; //data source array
DataSource outputDataSource = null; // file to output
DataSink outputDataSink = null; // datasink for output file
MediaLocator videoLocator = new MediaLocator(oml.getURL()); //media locator for video
MediaLocator audioLocator = new MediaLocator(realAudioFile.toURI().toURL()); //media locator for audio
FileTypeDescriptor outputType = new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME); //output video format type
Format outputFormat[] = new Format[2]; //format array
VideoFormat videoFormat = new VideoFormat(VideoFormat.JPEG); // output video codec MPEG does not work on windows
javax.media.format.AudioFormat audioMediaFormat = new javax.media.format.AudioFormat(
javax.media.format.AudioFormat.LINEAR, 44100, 16, 1); //audio format
outputFormat[0] = videoFormat;
outputFormat[1] = audioMediaFormat;
//create processors for each file
Processor videoProcessor = Manager.createProcessor(videoDataSource);
Processor audioProcessor = Manager.createProcessor(audioDataSource);
Processor processor = null;
//start video and audio processors
videoProcessor.realize();
audioProcessor.realize();
//wait till they are realized
while(videoProcessor.getState() != 300 && audioProcessor.getState() != 300) {
Thread.sleep(100);
}
//get processors dataoutputs to merge
arrayDataSource[0] = videoProcessor.getDataOutput();
arrayDataSource[1] = audioProcessor.getDataOutput();
videoProcessor.start();
audioProcessor.start();
//create merging data source
mixedDataSource = javax.media.Manager.createMergingDataSource(arrayDataSource);
mixedDataSource.connect();
mixedDataSource.start();
//init final processor to create merged file
ProcessorModel processorModel = new ProcessorModel(mixedDataSource, outputFormat, outputType);
processor = Manager.createRealizedProcessor(processorModel);
processor.addControllerListener(this);
processor.configure();
//wait till configured
while(processor.getState() < 180) {
Thread.sleep(20);
}
processor.setContentDescriptor(new ContentDescriptor(FileTypeDescriptor.QUICKTIME));
TrackControl tcs[] = processor.getTrackControls();
Format f[] = tcs[0].getSupportedFormats();
tcs[0].setFormat(f[0]);
processor.realize();
//wait till realized
while(processor.getState() < 300) {
Thread.sleep(20);
}
//create merged file and start writing media to it
outputDataSource = processor.getDataOutput();
MediaLocator outputLocator = new MediaLocator("file:/"+directory.getAbsolutePath()+"/yourmovfile.mov");
outputDataSink = Manager.createDataSink(outputDataSource, outputLocator);
outputDataSink.open();
outputDataSink.addDataSinkListener(this);
outputDataSink.start();
processor.start();
while(processor.getState() < 500) {
Thread.sleep(100);
}
//wait until writing is done
waitForFileDone();
//dispose processor and datasink
outputDataSink.stop();
processor.stop();
outputDataSink.close();
processor.close();
} catch (NoDataSourceException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IncompatibleSourceException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoDataSinkException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoProcessorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CannotRealizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Object waitFileSync = new Object();
boolean fileDone = false;
boolean fileSuccess = true;
Object waitSync = new Object();
boolean stateTransitionOK = true;
/**
* Block until file writing is done.
*/
boolean waitForFileDone() {
synchronized (waitFileSync) {
try {
while (!fileDone)
waitFileSync.wait();
} catch (Exception e) {
}
}
return fileSuccess;
}
/**
* Event handler for the file writer.
*/
public void dataSinkUpdate(DataSinkEvent evt) {
if (evt instanceof EndOfStreamEvent) {
synchronized (waitFileSync) {
fileDone = true;
waitFileSync.notifyAll();
}
} else if (evt instanceof DataSinkErrorEvent) {
synchronized (waitFileSync) {
fileDone = true;
fileSuccess = false;
waitFileSync.notifyAll();
}
}
}
@Override
public void controllerUpdate(ControllerEvent evt) {
if (evt instanceof ConfigureCompleteEvent
|| evt instanceof RealizeCompleteEvent
|| evt instanceof PrefetchCompleteEvent) {
synchronized (waitSync) {
stateTransitionOK = true;
waitSync.notifyAll();
}
} else if (evt instanceof ResourceUnavailableEvent) {
synchronized (waitSync) {
stateTransitionOK = false;
waitSync.notifyAll();
}
} else if (evt instanceof EndOfMediaEvent) {
evt.getSourceController().stop();
evt.getSourceController().close();
}
}
your class must implement ControllerListener, DataSinkListener. 您的类必须实现ControllerListener,DataSinkListener。 worked perfectly for me good video and audio sync (half a second shift in audio but not a problem for me).
完美地为我提供了良好的视频和音频同步(音频半转,但对我来说不是问题)。
Import of the above code which may be help to someone: 导入上述代码可能对某人有所帮助:
import java.io.IOException;
import javax.media.CannotRealizeException;
import javax.media.ConfigureCompleteEvent;
import javax.media.ControllerEvent;
import javax.media.ControllerListener;
import javax.media.DataSink;
import javax.media.EndOfMediaEvent;
import javax.media.Format;
import javax.media.IncompatibleSourceException;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.NoDataSinkException;
import javax.media.NoDataSourceException;
import javax.media.NoProcessorException;
import javax.media.PrefetchCompleteEvent;
import javax.media.Processor;
import javax.media.ProcessorModel;
import javax.media.RealizeCompleteEvent;
import javax.media.ResourceUnavailableEvent;
import javax.media.control.TrackControl;
import javax.media.datasink.DataSinkErrorEvent;
import javax.media.datasink.DataSinkEvent;
import javax.media.datasink.DataSinkListener;
import javax.media.datasink.EndOfStreamEvent;
import javax.media.format.VideoFormat;
import javax.media.protocol.ContentDescriptor;
import javax.media.protocol.DataSource;
import javax.media.protocol.FileTypeDescriptor;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.