我有多个mp4文件,它们是整个mp4文件的一部分。他们只是被分割成更小的文件。
我希望使用Java中的mp4,以编程方式将这些文件组合成一个jcodec文件。目前,我正在使用以下代码来执行此操作:
import org.jcodec.common.DemuxerTrack;
import org.jcodec.common.MuxerTrack;
import org.jcodec.common.io.SeekableByteChannel;
import org.jcodec.common.model.Packet;
import org.jcodec.containers.mp4.Brand;
import org.jcodec.containers.mp4.demuxer.MP4Demuxer;
import org.jcodec.containers.mp4.muxer.MP4Muxer;
import java.io.File;
import java.util.List;
import static org.jcodec.common.io.NIOUtils.readableChannel;
import static org.jcodec.common.io.NIOUtils.writableChannel;
public class Main {
public static void main(String[] args) throws Exception {
File outputFile = new File("file_path_output.mp4");
outputFile.mkdirs();
outputFile.delete();
File[] inputFiles = new File[]{
new File("file_path_1.mp4"),
new File("file_path_2.mp4"),
new File("file_path_3.mp4"),
};
SeekableByteChannel output = writableChannel(outputFile);
MP4Muxer mp4Muxer = MP4Muxer.createMP4Muxer(output, Brand.MP4);
MuxerTrack mixedVideoTrack = null;
MuxerTrack mixedAudioTrack = null;
for (File input : inputFiles) {
SeekableByteChannel byteChannel = readableChannel(input);
MP4Demuxer demuxer = MP4Demuxer.createMP4Demuxer(byteChannel);
List<DemuxerTrack> videoTracks = demuxer.getVideoTracks();
List<DemuxerTrack> audioTracks = demuxer.getAudioTracks();
if (mixedVideoTrack == null) {
mixedVideoTrack = mp4Muxer.addVideoTrack(videoTracks.get(0).getMeta().getCodec(), videoTracks.get(0).getMeta().getVideoCodecMeta());
}
if (mixedAudioTrack == null) {
mixedAudioTrack = mp4Muxer.addAudioTrack(audioTracks.get(0).getMeta().getCodec(), audioTracks.get(0).getMeta().getAudioCodecMeta());
}
for (DemuxerTrack videoTrack : videoTracks) {
Packet packet;
while ((packet = videoTrack.nextFrame()) != null) {
mixedVideoTrack.addFrame(packet);
}
}
for (DemuxerTrack audioTrack : audioTracks) {
Packet packet;
while ((packet = audioTrack.nextFrame()) != null) {
mixedAudioTrack.addFrame(packet);
}
}
demuxer.close();
}
mp4Muxer.finish();
output.close();
}
}
不幸的是,它不能工作,因为生成的视频不包含音频文件或正确的帧。例如,我得到的所有视觉框架如下所示:
有什么问题,我怎么解决呢?非常感谢。
发布于 2022-05-14 19:16:52
您可以使用ffmpeg来完成这一任务。
txt文件,具有:
您可以使用以下命令。
ffmpeg -f concat -i mp4list.txt -c:v copy -c:a copy merging.mp4
要帮助的资源:链接
String[] cmd = new String[]{"-f", "concat", "-safe", "0", "-i", "mp4list.txt", "-c", "copy", "-preset", "ultrafast", outFile};
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler(){
@Override
public void onFailure(String message){
}
@Override
public void onSuccess(String message){
}
@Override
public void onProgress(String message){
}
@Override
public void onStart(){
}
@Override
public void onFinish(){
}
}
发布于 2022-05-08 15:10:58
我不太懂jcodec
,但我以前使用过MP4parser
。如果您需要合并mp4文件,不管库是什么,那么我建议您使用这个库。我只是向您介绍它,因为我不知道您在合并文件方面是否有问题,因为库的复杂性。也许值得试一试。MP4Parser是非常简单和简单的。我还将留给您到maven存储库的链接。
https://search.maven.org/artifact/com.googlecode.mp4parser/isoparser/1.1.22/jar
下面是我所做的一个实现,向您展示如何从同一个原始视频中合并2个文件(以复制您的确切案例)。基本上,您有一个Movie
类,它代表您的mp4文件,包含一个List
of Track
(只有2);一个代表视频,另一个代表音频。
Track
和合并的视频Track
创建了一个Track
,以便将其设置为输出文件。Movie
中构建了Container
并使用FileOutputStream
保存了它。public class Main {
public static void main(String[] args) throws IOException {
MovieCreator mc = new MovieCreator();
Movie movie1 = mc.build("./test1.mp4");
Movie movie2 = mc.build("./test2.mp4");
//Fetching the video tracks from the movies and storing them into an array
Track[] vetTrackVideo = new Track[0];
vetTrackVideo = Stream.of(movie1, movie2)
.flatMap(movie -> movie.getTracks().stream())
.filter(movie -> movie.getHandler().equals("vide"))
.collect(Collectors.toList())
.toArray(vetTrackVideo);
//Fetching the audio tracks from the movies and storing them into an array
Track[] vetTrackAudio = new Track[0];
vetTrackAudio = Stream.of(movie1, movie2)
.flatMap(movie -> movie.getTracks().stream())
.filter(movie -> movie.getHandler().equals("soun"))
.collect(Collectors.toList())
.toArray(vetTrackAudio);
//Creating the output movie by setting a list with both video and audio tracks
Movie movieOutput = new Movie();
List<Track> listTracks = new ArrayList<>(List.of(new AppendTrack(vetTrackVideo), new AppendTrack(vetTrackAudio)));
movieOutput.setTracks(listTracks);
//Building the output movie and storing it into a Container
DefaultMp4Builder mp4Builder = new DefaultMp4Builder();
Container c = mp4Builder.build(movieOutput);
//Writing the output file
FileOutputStream fos = new FileOutputStream("output.mp4");
c.writeContainer(fos.getChannel());
fos.close();
}
}
在这里,我还将给您留下一个指向我的github存储库和测试mp4文件的链接,以便您可以测试合并示例。
https://stackoverflow.com/questions/72132908
复制相似问题