【问题标题】:How to kill FFmpeg currently running process?如何杀死FFmpeg当前正在运行的进程?
【发布时间】:2020-03-20 16:31:31
【问题描述】:

我正在开发一个使用 FFmpeg 修剪视频的应用程序。当修剪过程开始并且我取消它时,FFmpeg 完全终止。如何只杀死当前工作进程来实现?

   /* define PID */
  try {
     String pid = ffmpeg.toString();
     pid = pid.substring(pid.indexOf("[") + 1, pid.indexOf("]"));
     Process process = Runtime.getRuntime().exec("kill -2 " + pid);

     process.waitFor();
     ffmpeg.wait();
  } catch (IOException | InterruptedException e) {
     Log.e(TAG, "kill_ffmpeg: exception failed ",e );
     e.printStackTrace();
  }

这是我现在一直在使用的代码。当此代码唤醒时,活动会重新启动,但索引超出范围。

这是我一直在使用 FFmpeg Here 实现视频编辑功能的库

在这个 FFmpeg 库中有一个名为 killRunningProcess() 的方法。当我使用这个方法时,显示一个名为cannot resolve method killRunningProcess()的错误

当调用特定代码时,如何在不发生内存泄漏和应用程序崩溃的情况下终止进程?

【问题讨论】:

  • 在 exec - "sudo kill -9 " 中试试这个命令。如果您只是想根据您的要求重新启动,也可以试试这个。停止:sudo kill -s SIGSTOP ,重新启动:sudo kill -s SIGCONT 。希望它会帮助你。而且您使用的是 Windows pc,我觉得基于可访问性、安全性等 (-_-) 使用 FFmpeg 存在很多问题。
  • 我会尝试使用你的代码,我正在使用 mac

标签: java android android-ffmpeg


【解决方案1】:

根据谷歌搜索,我找到了以下对我有用的解决方案。我定义了类(FFmpeg_Handling),方法简单地取消了。

class FFmpeg_Handling {
    private FFmpeg ffmpeg;
    void loadFFMpegBinary(Context context) {
        try {
            if (ffmpeg == null) {
                ffmpeg = FFmpeg.getInstance(context);
            }
            ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
                @Override
                public void onFailure() {}

                @Override
                public void onSuccess() {}

            });
        } catch (Exception ignored) {}
    }


    void execFFmpegBinary(final String[] command) throws FFmpegCommandAlreadyRunningException {

        ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
            @Override
            public void onFailure(String s) {}

            @Override
            public void onSuccess(String s) {}

            @Override
            public void onProgress(String s) {}

            @Override
            public void onStart() {}

            @Override
            public void onFinish() {}


        });

    }

    void cancel(){
        ffmpeg.killRunningProcesses();
    }

}

然后在需要的时候,我通过instacne调用cancel方法。

实例化:

FFmpeg_Handling fh=new FFmpeg_Handling();

调用取消方法:

fh.cancel();

【讨论】:

    【解决方案2】:

    使用以下方法从进程对象中获取进程 ID:

    public static int getPid(java.lang.Process p) {
        int pid = -1;
    
        try {
            Field f = p.getClass().getDeclaredField("pid");
            f.setAccessible(true);
            pid = f.getInt(p);
            f.setAccessible(false);
        } catch (Throwable e) {
            pid = -1;
        }
        return pid;
    }
    

    然后通过调用以下命令向进程发送信号以终止: android.os.Process.sendSignal(pid, 15); // 15 is the value for SIG_TERM 参考:https://github.com/WritingMinds/ffmpeg-android-java/issues/33#issuecomment-218816755

    【讨论】:

    • 我尝试将它与 id 一起使用,但对我不起作用\
    • 你总是可以尝试 SIGKILL,-9。希望有帮助
    【解决方案3】:

    您不必添加或导入任何东西,您只需调用file中已声明的方法即可

    private void killAllreadyRunningProcess(FFmpeg ffmpeg){
        if(ffmpeg.isFFmpegCommandRunning())
            ffmpeg.killRunningProcess();
    }
    

    【讨论】:

    • 我已经尝试过了,但我无法导入函数,显示为cannot resolve function killRunningProcess()
    • 那么你没有使用其他库而不是github.com/WritingMinds/ffmpeg-android-java library
    • 我可以看到你在我的 FFmpeg 库中指定的方法。它比你想象的要复杂,一开始我尝试使用它并失败了,这里又没有任何反应。
    • 您能否发布您的代码,以便我们都知道它有多复杂。
    • 这只是取消点击进度对话框。同谋是从 FFmpeg 库中获取相应的函数。
    【解决方案4】:

    解决方案:

    示例:

    private FFtask fFtask;
    
    // Using your ffmpg Initialize :
    
     fFtask = FFmpeg.getInstance(baseActivity).execute(command, new ExecuteBinaryResponseHandler() {
    
    }
    
    // Cancel Button Click
    
     if (fFtask != null && !fFtask.isProcessCompleted()) {
                                Log.e(TAG, "on Cancel Click: FFmpeg is RUNNING!!");
                                fFtask.killRunningProcess();
    
                                FileUtils.deleteFileFromPath(outPath);
                            } else {
                                Log.i(TAG, "on Cancel Click Not fftask intilization Cancel Dislog not work");
                            }
    
    private void completeExporting() {
            if (dialog != null && dialog.isShowing()) {
                try {
                    dialog.dismiss();
                    Log.i(TAG, "completeExporting: ");
                    if (fFtask != null) {
                        fFtask.killRunningProcess();
                    }
                } catch (Throwable e) {
                    AppUtils.throwFatalException(e);
    
                }
    
            }
        }
    

    onDestroy:

     @Override
            public void onDestroy() {
                super.onDestroy();
                Log.i(TAG, "[onDestroy] ");
    
                completeExporting();
    
            }
    

    使用 FFmpeg:

    【讨论】:

    • 在哪里可以得到这个界面?我的库中没有这个接口package com.github.hiteshsondhi88.libffmpeg;
    • 我能帮你吗..?
    • 我的知识不足,我只是将接口复制粘贴到我的接口包中,无法导入killRunningProcess()deleteFileFromPath()。有什么建议吗?
    • 老兄,我的回答是取消按钮单击 ffmpeg 进度停止使用 fFtask.killRunningProcess(); 并在杀死进度时删除您的输出路径。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-18
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    相关资源
    最近更新 更多