gpt4 book ai didi

java - 结合音频与视频(无 ffmpeg)-Java

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:22:10 26 4
gpt4 key购买 nike

我正在构建一个小程序来捕获屏幕和麦克风输入(音频)。我能够单独录制这些文件,但找不到将这些文件组合起来制作新视频和音频的方法。

视频文件为.mov格式,音频文件为.wav格式。它们的长度完全相同。

有什么办法可以合并这些文件吗?我尝试过 Java,但找不到合并两个文件的方法。

此外,我必须在没有 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();
}

}

您的类必须实现 ControllerListener、DataSinkListener。非常适合我良好的视频和音频同步(音频半秒偏移但对我来说不是问题)。

关于java - 结合音频与视频(无 ffmpeg)-Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14013874/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com