Android使用FFMPEG合并两个具有不同(大小,编解码器,帧,宽高比)的视频

标签 android video merge ffmpeg

我正在制作一个应用程序,它合并两个或两个以上的视频文件,这些文件是我从另一个 Activity 中获得的。选择文件后,我们将文件传递给发生合并的另一个 Activity 。我已经按照这个链接做同样的事情:AndroidWarZone FFMPEG

在这里,我找到了如何仅合并具有不同质量的两个文件的方法。命令如下:

String[] complexCommand = {"ffmpeg","-y","-i","/storage/emulated/0/videokit/sample.mp4",
"-i","/storage/emulated/0/videokit/in.mp4","-strict","experimental",
"-filter_complex",
"[0:v]scale=640x480,setsar=1:1[v0];[1:v]scale=640x480,setsar=1:1[v1];[v0][0:a][v1][1:a] concat=n=2:v=1:a=1",
"-ab","48000","-ac","2","-ar","22050","-s","640x480","-r","30","-vcodec","mpeg4","-b","2097k","/storage/emulated/0/vk2_out/out.mp4"}

由于我的数组中有一个选定视频的列表,我将其传递到下一页,因此我对命令进行了一些更改,如下所示:
private void mergeVideos() {
    String savingPath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/video.mp4";

    ArrayList<File> fileList = mList;

    List<String> filenames = new ArrayList<String>();

    for (int i = 0; i < fileList.size(); i++) {
        filenames.add("-i");
        filenames.add(fileList.get(i).toString());
    }

    Log.e("Log===",filenames.toString());

    String joined = TextUtils.join(", ",filenames);

    Log.e("Joined====",joined);

    String complexCommand[] = {"-y", joined,
            "-filter_complex",
            "[0:v]scale=640x480,setsar=1:1[v0];[1:v]scale=640x480,setsar=1:1[v1];[v0][0:a][v1][1:a] concat=n=2:v=1:a=1",
            "-ab","48000","-ac","2","-ar","22050","-s","640x480","-r","30","-vcodec","mpeg4","-b","2097k", savingPath};
    Log.e("RESULT====",Arrays.toString(complexCommand));

   execFFmpegBinary(complexCommand);  }

在日志中,这是我得到的输出:

这是我在 mList 中添加的接收数据
E/RECEIVED DATA=====: [/mnt/m_external_sd/DCIM/Camera/VID_31610130_011933_454.mp4, /mnt/m_external_sd/DCIM/Camera/VID_23120824_054526_878.mp4]
E/RESULT====: [-y, -i, /mnt/m_external_sd/DCIM/Camera/VID_31610130_011933_454.mp4, -i, /mnt/m_external_sd/DCIM/Camera/VID_23120824_054526_878.mp4, -filter_complex, [0:v]scale=640x480,setsar=1:1[v0];[1:v]scale=640x480,setsar=1:1[v1];[v0][0:a][v1][1:a] concat=n=2:v=1:a=1, -ab, 48000, -ac, 2, -ar, 22050, -s, 640x480, -r, 30, -vcodec, mpeg4, -b, 2097k, /storage/emulated/0/video.mp4]

这里的结果是进入 exeFFMPEGBinary() 的 complexCommand但不工作。

这是我的 exceFFMPEGBinary()
private void execFFmpegBinary(final String[] combine) {
    try{
    fFmpeg.execute(combine, new ExecuteBinaryResponseHandler() {
        @Override
        public void onFailure(String s) {
            Log.d("", "FAILED with output : " + s);
        }

        @Override
        public void onSuccess(String s) {
            Log.d("", "SUCCESS with output : " + s);
            Toast.makeText(getApplicationContext(),"Success!",Toast.LENGTH_SHORT)
                    .show();
        }

        @Override
        public void onProgress(String s) {
            Log.d("", "progress : " + s);
        }

        @Override
        public void onStart() {
            progressDialog.setMessage("Processing...");
            progressDialog.show();
        }

        @Override
        public void onFinish() {
            progressDialog.dismiss();
        }
    });
} catch (FFmpegCommandAlreadyRunningException e) {
    // do nothing for now
}
}

我已经完成了这个并运行了我的项目,现在的问题是它没有合并/连接任何东西,只是一个 progressDialog 出现了几分之一秒,我得到的只是我的日志中的这个:
E/FFMPEG====: ffmpef : coorect loaded

这意味着 ffmpeg 正在加载并且没有实现任何东西。我没有得到关于 onFailur、onSuccess()、onStart() 的任何日志。

任何建议都会帮助我实现我的目标。谢谢。

注意:我已经使用 Mp4Parser 完成了此合并,但其中有一个小故障,它需要具有相同规范的文件。所以这不是我的要求。

编辑

我做了一些更多的研究并将其连接起来,但这也不起作用,这是链接:Concatenating two files

我也从一个链接中找到了这些东西:FFMPEG Merging/Concatenating
并发现他的代码运行良好。但不是我的。

我也使用过该命令,但它不起作用,也没有给我任何日志结果。除了 FFMPEG 加载。

这是命令:
complexCommand = new String[]{"-y", "-i", file1.toString(), "-i", file2.toString(), "-strict", "experimental", "-filter_complex",
            "[0:v]scale=1920x1080,setsar=1:1[v0];[1:v] scale=iw*min(1920/iw\\,1080/ih):ih*min(1920/iw\\,1080/ih), pad=1920:1080:(1920-iw*min(1920/iw\\,1080/ih))/2:(1080-ih*min(1920/iw\\,1080/ih))/2,setsar=1:1[v1];[v0][0:a][v1][1:a] concat=n=2:v=1:a=1","-ab", "48000", "-ac", "2", "-ar", "22050", "-s", "1920x1080", "-vcodec", "libx264","-crf","27","-q","4","-preset", "ultrafast", rootPath + "/output.mp4"};

最佳答案

请先使用演示,确保它在您的设备上运行。
如果是这样,请从博客中获取合并命令,并在演示中使用它。
现在,在您的应用程序中尝试一个简单的命令,如果它有效,请尝试合并命令。
如果其中任何步骤失败,请直接与我联系。

关于Android使用FFMPEG合并两个具有不同(大小,编解码器,帧,宽高比)的视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46051764/

相关文章:

c++ - 如何使用 FFMPEG sws_scaler api 从 AV_PIX_FMT_VAAPI 转换为 AV_PIX_FMT_YUV420?

iphone - 如何在 Mobile Safari 中播放视频

python - 在python中合并两个不同长度的列表

merge - 如何选择要合并附加到工作项的变更集?

java - 在 getView() 方法中使用 if/switch 语句时 CustomListViewAdapter 行为不当

android - 从 Android Studio 中的应用程序中删除 Google Play 服务

java - 在 Android 上使用来自 libGDX 的 SQLite

video - MPEG-4 或 Matroska 是否可以实现可变分辨率?

git - git 如何知道要保留一行的哪个版本?

android - 如何通过 JNi 将 JAVA 对象发送到 C 并将 java 对象值分配给 C 结构?