FFmpeg进程即使在finishAndRemoveTask()之后仍保持运行

时间:2018-10-09 20:50:32

标签: java android ffmpeg minimize

我有一个程序可以获取Audio files,并使用Bravobit FFmpeg Bravobit FFmpeg github进行转换。

它可以按预期工作,直到有人在转换过程中最小化屏幕为止。我正在尝试解决此问题,但到目前为止我还没有成功。

此部分位于Main Activity中,该部分创建并启动我的AudioProcessor

AudioProcessor ac = new AudioProcessor(getApplicationContext(), PostNewActivity.this);
                ac.setBackgroundMp3File(backgroundAudio);
                ac.setMicPcmFile(micOutputPCM);
                ac.setOutputFile(tempOutFile);
                ac.setListener(new AudioProcessor.AudioProcessorListener() {
                    public void onStart() {
                        Log.d("Audioprocessor", "Audioprocessor is successful");
                    }

                    public void onSuccess(File output) {
                        Log.d("Audioprocessor", "Audioprocessor is successful");
                        goToPublishView();
                    }

                    public void onError(String message) {
                        System.out.println("Audioprocessor: " + message);

                    }

                    public void onFinish() {
                        Log.d("Audioprocessor", "Audioprocessor is finshed");
                   }


                });

                try {
                    if (tempOutFile.exists()) {
                        tempOutFile.delete();
                    }
                    ac.process();
                } catch (Exception ex) {
                    System.out.println("Processing failed!");
                    ex.printStackTrace();
                }

这是AudioProcessor本身:

public class AudioProcessor {

    private Context context;
    private FFmpeg ffmpeg;
    private AudioProcessorListener listener;

    private File micPcmFile;
    private File backgroundMp3File;

    private File pcmtowavTempFile;
    private File mp3towavTempFile;
    private File combinedwavTempFile;

    private File outputFile;
    private File volumeChangedTempFile;

    TextView extensionDownload, percentProgress;


    public AudioProcessor(Context context, Activity activity) {
        ffmpeg = null;
        ffmpeg = FFmpeg.getInstance(context);
        percentProgress = activity.findViewById(R.id.percentProgress);
        percentProgress.setSingleLine(false);
        this.context = context;
        prepare();
    }

    /**
     * Program main method. Starts running program
     * @throws Exception
     */
    public void process() throws Exception {
        if (!ffmpeg.isSupported()) {
            Log.e("AudioProcessor", "FFMPEG not supported! Cannot convert audio!");
            throw new Exception("FFMPeg has to be supported");
        }
        if (!checkIfAllFilesPresent()) {
            Log.e("AudioProcessor", "All files are not set yet. Please set file first");
            throw new Exception("Files are not set!");
        }

        Log.e("AudioProcessor", "Start processing audio");
        listener.onStart();



        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                convertPCMToWav();
            }
        }, 200);
    }

    /**
     * Prepares program
     */
    private void prepare() {
        prepareTempFiles();
    }

    /**
     * Converts PCM to wav file. Automatically create new file.
     */
    private void convertPCMToWav() {
        Log.e("AudioProcessor", "Convert PCM TO Wav");
        //ffmpeg -f s16le -ar 44.1k -ac 2 -i file.pcm file.wav
        String[] cmd = { "-f" , "s16le", "-ar", "44.1k", "-i", micPcmFile.toString(), "-y", pcmtowavTempFile.toString()};
        ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

            @Override
            public void onStart() {
                super.onStart();
                percentProgress.setVisibility(View.VISIBLE);
                percentProgress.setText("Converting your recording\n"+"1/5");
            }

            @Override
            public void onSuccess(String message) {
                super.onSuccess(message);
                convertMP3ToWav();
            }
            @Override
            public void onFailure(String message) {
                super.onFailure(message);
                onError(message);
                convertPCMToWav();
            }
        });
    }

    /**
     * Converts mp3 file to wav file.
     * Automatically creates Wav file
     */
    private void convertMP3ToWav() {
        Log.e("AudioProcessor", "Convert MP3 TO Wav");

        //ffmpeg -i file.mp3 file.wav
        String[] cmd = { "-i" , backgroundMp3File.toString(), "-y", mp3towavTempFile.toString() };
        ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
            @Override
            public void onStart() {
                super.onStart();
                percentProgress.setText("Converting background audio\n"+"2/5");
                Log.e("AudioProcessor", "Starging convertgf MP3 TO Wav");
            }

            @Override
            public void onSuccess(String message) {
                super.onSuccess(message);
                changeMicAudio();
            }
            @Override
            public void onFailure(String message) {
                super.onFailure(message);
                Log.e("AudioProcessor", "Failed to convert MP3 TO Wav");
                //onError(message);
                throw new RuntimeException("Failed to convert MP3 TO Wav");
                //convertMP3ToWav();
            }
        });
    }

    /**
     * Combines 2 wav files into one wav file. Overlays audio
     */
    private void combineWavs() {
        Log.e("AudioProcessor", "Combine wavs");
        //ffmpeg -i C:\Users\VR1\Desktop\_mp3.wav -i C:\Users\VR1\Desktop\_pcm.wav -filter_complex amix=inputs=2:duration=first:dropout_transition=3 C:\Users\VR1\Desktop\out.wav

        String[] cmd = { "-i" , pcmtowavTempFile.toString(), "-i", volumeChangedTempFile.toString(), "-filter_complex", "amix=inputs=2:duration=first:dropout_transition=3", "-y",combinedwavTempFile.toString()};
        ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

            @Override
            public void onStart() {
                super.onStart();
                percentProgress.setText("Combining the two audio files\n"+"4/5");
            }

            @Override
            public void onSuccess(String message) {
                super.onSuccess(message);
                encodeWavToAAC();

            }
            @Override
            public void onFailure(String message) {
                super.onFailure(message);
                onError(message);
            }
        });
    }

    private void changeMicAudio(){
        Log.e("AudioProcessor", "Change audio volume");
        //ffmpeg -i input.wav -filter:a "volume=1.5" output.wav

        String[] cmdy = { "-i", mp3towavTempFile.toString(),  "-af", "volume=0.9", "-y",volumeChangedTempFile.toString()};
        ffmpeg.execute(cmdy, new ExecuteBinaryResponseHandler() {

            @Override
            public void onStart() {
                super.onStart();
                percentProgress.setText("Normalizing volume\n"+"3/5");
            }

            @Override
            public void onSuccess(String message) {
                combineWavs();
                super.onSuccess(message);
            }
            @Override
            public void onFailure(String message) {
                super.onFailure(message);
                Log.e("AudioProcessor", message);
            }
        });
    }


    /**
     * Do something on error. Releases program data (deletes files)
     * @param message
     */
    private void onError(String message) {
        release();
        if (listener != null) {
            //listener.onError(message);
        }
    }
    /**
     * Encode to AAC
     */
    private void encodeWavToAAC() {
        Log.e("AudioProcessor", "Encode to AAC");
        //ffmpeg -i file.wav -c:a aac -b:a 128k -f adts output.m4a
        String[] cmd = { "-i" , combinedwavTempFile.toString(), "-c:a", "aac", "-b:a", "128k", "-f", "adts", "-y",outputFile.toString()};
        ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

            @Override
            public void onStart() {
                super.onStart();
                percentProgress.setText("Normalizing volume\n"+"3/5");
            }

            @Override
            public void onSuccess(String message) {
                super.onSuccess(message);
                if (listener != null) {
                    listener.onSuccess(outputFile);
                }
                release();
            }
            @Override
            public void onFailure(String message) {
                super.onFailure(message);
                onError(message);
                encodeWavToAAC();
            }
        });
    }

    /**
     * Uninitializes class
     */
    private void release() {
        if (listener != null) {
            listener.onFinish();
        }
        destroyTempFiles();
    }

    /**
     * Prepares temp required files by deleteing them if they exsist.
     * Files cannot exists before ffmpeg actions. FFMpeg automatically creates those files.
     */
    private void prepareTempFiles() {
        pcmtowavTempFile = new File(context.getFilesDir()+ Common.TEMP_LOCAL_DIR + "/" + "_pcm.wav");
        mp3towavTempFile = new File(context.getFilesDir()+ Common.TEMP_LOCAL_DIR + "/" + "_mp3.wav");
        combinedwavTempFile = new File(context.getFilesDir()+ Common.TEMP_LOCAL_DIR + "/" + "_combined.wav");
        volumeChangedTempFile = new File(context.getFilesDir()+ Common.TEMP_LOCAL_DIR + "/" + "_volumeChanged.wav");

        destroyTempFiles();
    }

    /**
     * Destroys temp required files
     */
    private void destroyTempFiles() {

        pcmtowavTempFile.delete();
        mp3towavTempFile.delete();
        combinedwavTempFile.delete();
        volumeChangedTempFile.delete();
    }

    /**
     * Checks if all files are set, so we can process them
     * @return - all files ready
     */
    private boolean checkIfAllFilesPresent() {
        if(micPcmFile == null || backgroundMp3File == null || outputFile == null) {
            Log.e("AudioProcessor", "All files are not set! Set all files!");
            return false;
        }
        return true;
    }

    public void setOutputFile(File outputFile) {
        this.outputFile = outputFile;
    }

    public void setListener(AudioProcessorListener listener) {
        this.listener = listener;
    }

    public void setMicPcmFile(File micPcmFile) {


        this.micPcmFile = micPcmFile;
    }

    public void setBackgroundMp3File(File backgroundMp3File) {
        this.backgroundMp3File = backgroundMp3File;
    }


    public interface AudioProcessorListener {
        void onStart();
        void onSuccess(File output);
        void onError(String message);
        void onFinish();
    }
}

我通常如何进行测试并使其崩溃,是让AudioProcessor进入第二种方法,即convertMP3ToWav(),然后关闭应用程序。当我再次启动它并开始处理文件时,应用程序崩溃。

我已经尝试了许多方法,并且考虑过使用Main Activity

中的这段代码将应用程序最小化时,将其重新启动。
@Override
protected void onUserLeaveHint()
{
    if (Build.VERSION.SDK_INT >= 21) {
        finishAndRemoveTask();
    } else {
        finish();
    }
}

我认为它可以阻止一切,但仍然崩溃。经过一些调试后,我发现即使我最小化应用程序并执行finishAndRemoveTask()AudioProcessor仍然可以正常工作,并且仍然可以执行所有ffmpeg命令,甚至调用{{1 }}方法。

在最小化应用程序时,如何完全停止所有操作或至少停止并清除onSuccess()/onFinish()

0 个答案:

没有答案