Java 如何在Android中合并两个或多个视频文件?

Java 如何在Android中合并两个或多个视频文件?,java,android,video,Java,Android,Video,我想合并两个或多个视频文件(它们可能是两个mp4或两个3gp,或任何其他格式)。您可以使用的最通用的工具是ffmpeg(如上@Jeremy所述),但在手机上使用它需要一些工作;它也是LGPL许可的,它的一些编码器(特别是x264)是GPL 如果要连接的两个文件都使用类似的编码,并且都包含在从MP4派生的文件格式中(3GP就是这样),一个更简单的解决方案是使用纯java MP4解析器连接视频,而不接触媒体流本身。看一看,这是一个纯java的开源解析器,在Apache许可下获得许可,甚至在其wiki

我想合并两个或多个视频文件(它们可能是两个mp4或两个3gp,或任何其他格式)。

您可以使用的最通用的工具是ffmpeg(如上@Jeremy所述),但在手机上使用它需要一些工作;它也是LGPL许可的,它的一些编码器(特别是x264)是GPL


如果要连接的两个文件都使用类似的编码,并且都包含在从MP4派生的文件格式中(3GP就是这样),一个更简单的解决方案是使用纯java MP4解析器连接视频,而不接触媒体流本身。看一看,这是一个纯java的开源解析器,在Apache许可下获得许可,甚至在其wiki中有一个

您可以尝试INDE Media for Mobile,教程如下:

它在MediaComposer类中具有转码\remuxing功能,并且可以连接文件\文件段。由于它使用MediaCodecodeAPI,内部编码是在GPU上完成的,因此它对电池非常友好,并尽可能快地工作

github上显示了如何启用联接或其他功能的示例代码:


我将分享Java和Kotlin代码

    val epVideos = ArrayList<EpVideo>()
    epVideos.add(EpVideo("/storage/emulated/0/Contact/1.mp4")) // Video 1 Example
    epVideos.add(EpVideo("/storage/emulated/0/Contact/2.mp4")) // Video 2 Exmaple
    val outputOption = EpEditor.OutputOption ("/storage/emulated/0/merge.mp4"); //Output
    outputOption.setWidth(720) // output video width, default 480
    outputOption.setHeight(1280)
    outputOption.frameRate =  25 ; // output video frame rate, default 30

    EpEditor.merge(epVideos,outputOption,object:OnEditorListener{
        override fun onSuccess() {

        }

        override fun onFailure() {

        }


        override fun onProgress(progress: Float) {
            Log.d("Progress","$progress")
        }

    })
 private void mergeVideos() {
    ArrayList<EpVideo> epVideos =  new  ArrayList<>();
    epVideos.add(new EpVideo (file2)); // Video 1
    epVideos.add(new EpVideo (file1)); // Video 2
    EpEditor. OutputOption outputOption =new EpEditor.OutputOption(fileOutput);
    outputOption.setWidth(720);
    outputOption.setHeight(1280);
    outputOption.frameRate = 25 ;
    outputOption.bitRate = 10 ;
    EpEditor.merge(epVideos, outputOption, new  OnEditorListener() {
        @Override
        public  void  onSuccess () {
            Log.d("Status","Success");

        }

        @Override
        public  void  onFailure () {

        }

        @Override
        public  void  onProgress ( float  progress ) {
            // Get processing progress here
            Log.d("Progress",""+progress);
        }
    });

}
在内部,它使用FFmpeg,但重量很轻。添加两个不同类型或编解码器、帧率和比特率的视频的最简单方法是使用EpMedia Library

等级相关性

implementation 'com.github.yangjie10930:EpMedia:v0.9.5'
Kotlin代码

    val epVideos = ArrayList<EpVideo>()
    epVideos.add(EpVideo("/storage/emulated/0/Contact/1.mp4")) // Video 1 Example
    epVideos.add(EpVideo("/storage/emulated/0/Contact/2.mp4")) // Video 2 Exmaple
    val outputOption = EpEditor.OutputOption ("/storage/emulated/0/merge.mp4"); //Output
    outputOption.setWidth(720) // output video width, default 480
    outputOption.setHeight(1280)
    outputOption.frameRate =  25 ; // output video frame rate, default 30

    EpEditor.merge(epVideos,outputOption,object:OnEditorListener{
        override fun onSuccess() {

        }

        override fun onFailure() {

        }


        override fun onProgress(progress: Float) {
            Log.d("Progress","$progress")
        }

    })
 private void mergeVideos() {
    ArrayList<EpVideo> epVideos =  new  ArrayList<>();
    epVideos.add(new EpVideo (file2)); // Video 1
    epVideos.add(new EpVideo (file1)); // Video 2
    EpEditor. OutputOption outputOption =new EpEditor.OutputOption(fileOutput);
    outputOption.setWidth(720);
    outputOption.setHeight(1280);
    outputOption.frameRate = 25 ;
    outputOption.bitRate = 10 ;
    EpEditor.merge(epVideos, outputOption, new  OnEditorListener() {
        @Override
        public  void  onSuccess () {
            Log.d("Status","Success");

        }

        @Override
        public  void  onFailure () {

        }

        @Override
        public  void  onProgress ( float  progress ) {
            // Get processing progress here
            Log.d("Progress",""+progress);
        }
    });

}
val-epVideos=ArrayList()
epVideos.add(EpVideo(“/storage/emulated/0/Contact/1.mp4”)//视频1示例
epVideos.add(EpVideo(“/storage/emulated/0/Contact/2.mp4”)//视频2 Exmaple
val outputOption=EpEditor.outputOption(“/storage/emulated/0/merge.mp4”)//输出
setWidth(720)//输出视频宽度,默认值480
输出选项设置高度(1280)
outputOption.frameRate=25;//输出视频帧速率,默认为30
合并(epVideos,输出选项,对象:OnEditorListener{
覆盖成功的乐趣(){
}
覆盖失败(){
}
覆盖进度(进度:浮动){
Log.d(“进度”和“$Progress”)
}
})
Java代码

    val epVideos = ArrayList<EpVideo>()
    epVideos.add(EpVideo("/storage/emulated/0/Contact/1.mp4")) // Video 1 Example
    epVideos.add(EpVideo("/storage/emulated/0/Contact/2.mp4")) // Video 2 Exmaple
    val outputOption = EpEditor.OutputOption ("/storage/emulated/0/merge.mp4"); //Output
    outputOption.setWidth(720) // output video width, default 480
    outputOption.setHeight(1280)
    outputOption.frameRate =  25 ; // output video frame rate, default 30

    EpEditor.merge(epVideos,outputOption,object:OnEditorListener{
        override fun onSuccess() {

        }

        override fun onFailure() {

        }


        override fun onProgress(progress: Float) {
            Log.d("Progress","$progress")
        }

    })
 private void mergeVideos() {
    ArrayList<EpVideo> epVideos =  new  ArrayList<>();
    epVideos.add(new EpVideo (file2)); // Video 1
    epVideos.add(new EpVideo (file1)); // Video 2
    EpEditor. OutputOption outputOption =new EpEditor.OutputOption(fileOutput);
    outputOption.setWidth(720);
    outputOption.setHeight(1280);
    outputOption.frameRate = 25 ;
    outputOption.bitRate = 10 ;
    EpEditor.merge(epVideos, outputOption, new  OnEditorListener() {
        @Override
        public  void  onSuccess () {
            Log.d("Status","Success");

        }

        @Override
        public  void  onFailure () {

        }

        @Override
        public  void  onProgress ( float  progress ) {
            // Get processing progress here
            Log.d("Progress",""+progress);
        }
    });

}
private void mergeVideos(){
ArrayList epVideos=新建ArrayList();
添加(新的EpVideo(文件2));//视频1
添加(新的EpVideo(文件1));//视频2
EpEditor.OutputOption OutputOption=新的EpEditor.OutputOption(fileOutput);
输出选项。设置宽度(720);
输出选项。设置高度(1280);
outputOption.frameRate=25;
outputOption.bitRate=10;
合并(epVideos,outputOption,newoneditorlistener(){
@凌驾
成功时的公共无效(){
日志d(“状态”、“成功”);
}
@凌驾
公共失效失效(){
}
@凌驾
公共进度(浮动进度){
//在此处获取处理进度
Log.d(“进度”,“进度+进度”);
}
});
}

ffmpeg是一个处理视频转换和其他功能的强大库。这里有一个java绑定:我使用FileInputsRealm获取srouce文件,然后SequenceInputStream(stream1,stream2)组合两个文件,但它认为这种方法不适合视频文件,而且android也会遇到内存泄漏问题如果堆大小扩展超过16MBcool,mp4解析器可以处理这两个文件,但它不能正常工作超过2个文件,视频不能正确合并。它能同时处理2个以上的文件吗?@Mahesh合并两个文件,然后将合并的文件与下一个文件合并,依此类推?@Cheesebaron这可能是你所说的吗?