Android:将视频路径传递到FFmpeg

Android:将视频路径传递到FFmpeg,android,ffmpeg,video-watermarking,Android,Ffmpeg,Video Watermarking,我开发了一个应用程序,可以播放gallery中的视频。我想在选定的视频中使用FFmpeg命令添加水印。但是我不知道如何将路径传递到FFmpeg命令。我找不到关于这方面的适当教程或参考资料。我的编码如下: MainActivity.java: public class MainActivity extends Activity { public ProgressDialog progressBar; String workFolder = null; String demoVideoFolder

我开发了一个应用程序,可以播放gallery中的视频。我想在选定的视频中使用FFmpeg命令添加水印。但是我不知道如何将路径传递到FFmpeg命令。我找不到关于这方面的适当教程或参考资料。我的编码如下:

MainActivity.java:

public class MainActivity extends Activity {
public ProgressDialog progressBar;

String workFolder = null;
String demoVideoFolder = null;
String demoVideoPath = null;
String vkLogPath = null;
LoadJNI vk;
private final int STOP_TRANSCODING_MSG = -1;
private final int FINISHED_TRANSCODING_MSG = 0;
private boolean commandValidationFailedFlag = false;

Button button;
VideoView videoView;
private static final int PICK_FROM_GALLERY = 1;


private void runTranscodingUsingLoader() {
    Log.i(Prefs.TAG, "runTranscodingUsingLoader started...");

    PowerManager powerManager = (PowerManager)MainActivity.this.getSystemService(Activity.POWER_SERVICE);
    PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VK_LOCK");
    Log.d(Prefs.TAG, "Acquire wake lock");
    wakeLock.acquire();

    

    String[] complexCommand = {"ffmpeg","-y" ,"-i", "/sdcard/videokit/in.mp4","-strict","experimental",
            "-vf", "movie=/sdcard/videokit/watermark.png [watermark];" +
            " [in][watermark] overlay=main_w-overlay_w-10:10 [out]","-s",
            "320x240","-r", "30", "-b", "15496k", "-vcodec", "mpeg4","-ab",
            "48000", "-ac", "2", "-ar", "22050", "/sdcard/videokit/out1.mp4"};
    ///////////////////////////////////////////////////////////////////////


    vk = new LoadJNI();
    try {
        // running complex command with validation
        vk.run(complexCommand, workFolder, getApplicationContext());

        // running without command validation
        //vk.run(complexCommand, workFolder, getApplicationContext(), false);

        // running regular command with validation
        //vk.run(GeneralUtils.utilConvertToComplex(commandStr), workFolder, getApplicationContext());

        Log.i(Prefs.TAG, "vk.run finished.");
        // copying vk.log (internal native log) to the videokit folder
        GeneralUtils.copyFileToFolder(vkLogPath, demoVideoFolder);

    } catch (CommandValidationException e) {
        Log.e(Prefs.TAG, "vk run exeption.", e);
        commandValidationFailedFlag = true;

    } catch (Throwable e) {
        Log.e(Prefs.TAG, "vk run exeption.", e);
    }
    finally {
        if (wakeLock.isHeld()) {
            wakeLock.release();
            Log.i(Prefs.TAG, "Wake lock released");
        }
        else{
            Log.i(Prefs.TAG, "Wake lock is already released, doing nothing");
        }
    }

    // finished Toast
    String rc = null;
    if (commandValidationFailedFlag) {
        rc = "Command Vaidation Failed";
    }
    else {
        rc = GeneralUtils.getReturnCodeFromLog(vkLogPath);
    }
    final String status = rc;
    MainActivity.this.runOnUiThread(new Runnable() {
        public void run() {
            Toast.makeText(MainActivity.this, status, Toast.LENGTH_LONG).show();
            if (status.equals("Transcoding Status: Failed")) {
                Toast.makeText(MainActivity.this, "Check: " + vkLogPath + " for more information.", Toast.LENGTH_LONG).show();
            }
        }
    });
}


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    button = (Button) findViewById(R.id.button);
    
    videoView = (VideoView) findViewById(R.id.videoview);

    button.setOnClickListener(new View.OnClickListener() {

        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent intent = new Intent();

            intent.setType("video/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);

            startActivityForResult(Intent.createChooser(intent, "Complete action using"), PICK_FROM_GALLERY);
        }
    });

}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != RESULT_OK) return;

    if (requestCode == PICK_FROM_GALLERY) {
        Uri mVideoURI = data.getData();
        videoView.setVideoURI(mVideoURI);
        videoView.start();
        demoVideoFolder = mVideoURI.getPath();
        demoVideoPath = demoVideoFolder;
        savevideo(mVideoURI);

    }


}
private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        Log.i(Prefs.TAG, "Handler got message");
        if (progressBar != null) {
            progressBar.dismiss();

            // stopping the transcoding native
            if (msg.what == STOP_TRANSCODING_MSG) {
                Log.i(Prefs.TAG, "Got cancel message, calling fexit");
                vk.fExit(getApplicationContext());


            }
        }
    }
};

public void runTranscoding() {
    progressBar = new ProgressDialog(MainActivity.this);
    progressBar.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
    progressBar.setTitle("FFmpeg4Android Direct JNI");
    progressBar.setMessage("Press the cancel button to end the operation");
    progressBar.setMax(100);
    progressBar.setProgress(0);

    progressBar.setCancelable(false);
    progressBar.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {
            handler.sendEmptyMessage(STOP_TRANSCODING_MSG);
        }
    });

    progressBar.show();

    new Thread() {
        public void run() {
            Log.d(Prefs.TAG,"Worker started");
            try {
                //sleep(5000);
                runTranscodingUsingLoader();
                handler.sendEmptyMessage(FINISHED_TRANSCODING_MSG);

            } catch(Exception e) {
                Log.e("threadmessage",e.getMessage());
            }
        }
    }.start();

    // Progress update thread
    new Thread() {
        ProgressCalculator pc = new ProgressCalculator(vkLogPath);
        public void run() {
            Log.d(Prefs.TAG,"Progress update started");
            int progress = -1;
            try {
                while (true) {
                    sleep(300);
                    progress = pc.calcProgress();
                    if (progress != 0 && progress < 100) {
                        progressBar.setProgress(progress);
                    }
                    else if (progress == 100) {
                        Log.i(Prefs.TAG, "==== progress is 100, exiting Progress update thread");
                        pc.initCalcParamsForNextInter();
                        break;
                    }
                }

            } catch(Exception e) {
                Log.e("threadmessage",e.getMessage());
            }
        }
    }.start();
}

public void savevideo (Uri mVideoURI){
    demoVideoFolder = mVideoURI.getPath();
    demoVideoPath = demoVideoFolder;
    Log.i(Prefs.TAG, getString(R.string.app_name) + " version: " + GeneralUtils.getVersionName(getApplicationContext()));

    Button invoke = (Button) findViewById(R.id.button);
    invoke.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            Log.i(Prefs.TAG, "run clicked.");
            runTranscoding();
        }
    });

    workFolder = getApplicationContext().getFilesDir() + "/";
    Log.i(Prefs.TAG, "workFolder (license and logs location) path: " + workFolder);
    vkLogPath = workFolder + "vk.log";
    Log.i(Prefs.TAG, "vk log (native log) path: " + vkLogPath);
    GeneralUtils.copyLicenseFromAssetsToSDIfNeeded(this, workFolder);
    GeneralUtils.copyDemoVideoFromAssetsToSDIfNeeded(this, demoVideoFolder);
    int rc = GeneralUtils.isLicenseValid(getApplicationContext(), workFolder);
    Log.i(Prefs.TAG, "License check RC: " + rc);

}
}
Tis命令来自一个示例项目。如何将视频路径传递到此命令?我不知道如何编辑命令以支持我的要求。有人能指导我完成这件事吗。任何帮助都会很有帮助。多谢各位

 complexCommand = {"ffmpeg","-y" ,"-i",  "inputVideoPath","-strict","experimental",
        "-vf", "movie=/sdcard/videokit/watermark.png [watermark];" +
        " [in][watermark] overlay=main_w-overlay_w-10:10 [out]","-s",
        "320x240","-r", "30", "-b", "15496k", "-vcodec", "mpeg4","-ab",
        "48000", "-ac", "2", "-ar", "22050", "outputVideoPath"};
inputVideoPath是您需要指定要修改的视频位置的地方。 outputVideoPath是您需要指定视频输出位置的地方


[水印]之后还有另一条路径。这应该是水印图像的路径(如果有)。

我可以使用

ffmpeg -y -i /sdcard/videokit/in.mp4 -i /sdcard/videokit/watermark.png -filter_complex [0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10[out] -map [out] -map 0:a -codec:a copy /sdcard/videokit/out_ben.mp4
摘自

ffmpeg -y -i /sdcard/videokit/in.mp4 -i /sdcard/videokit/watermark.png -filter_complex [0:v][1:v]overlay=main_w-overlay_w-10:main_h-overlay_h-10[out] -map [out] -map 0:a -codec:a copy /sdcard/videokit/out_ben.mp4