在android中使用FFMPEG转换音频文件

时间:2018-02-28 07:29:39

标签: android ffmpeg android-ffmpeg

我正在开发Android应用程序,我已经要求记录调用并将它们转换为WAVE(.wav)格式并发送到服务器。

我能够在手机中成功录制和保存音频。录制的文件mime类型是3gpp,现在我想将这个3gpp文件转换为wav。我尝试使用FFMPEG但无法转换它。我在这里发布我的代码,任何帮助都会感激不尽。

将录制的文件从aac转换为wav时,我遇到错误

Exception while trying to run: [Ljava.lang.String;@64075a0
    java.io.IOException: Cannot run program "/data/user/0/com.sms.example.example/files/ffmpeg": error=2, No such file or directory
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:983)
        at java.lang.Runtime.exec(Runtime.java:691)
        at java.lang.Runtime.exec(Runtime.java:559)
        at com.github.hiteshsondhi88.libffmpeg.ShellCommand.run(ShellCommand.java:10)
        at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:38)
        at com.github.hiteshsondhi88.libffmpeg.FFmpegExecuteAsyncTask.doInBackground(FFmpegExecuteAsyncTask.java:10)
        at android.os.AsyncTask$2.call(AsyncTask.java:305)
        at java.util.concurrent.FutureTask.run(FutureTask.java:237)
        at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
        at java.lang.Thread.run(Thread.java:761)
     Caused by: java.io.IOException: error=2, No such file or directory
        at java.lang.UNIXProcess.forkAndExec(Native Method)
        at java.lang.UNIXProcess.<init>(UNIXProcess.java:133)
        at java.lang.ProcessImpl.start(ProcessImpl.java:128)
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:964)

记录器服务

public class CallService extends Service {

    //util object creation
    NetworkUtils networkUtils;
    SharedPref sharedPref;

    MediaRecorder recorder;
    File audiofile;
    String name, phonenumber;
    String audio_format;
    public String Audio_Type;
    int audioSource;
    Context context;
    private Handler handler;
    Timer timer;
    Boolean offHook = false, ringing = false;
    Toast toast;
    Boolean isOffHook = false;
    private boolean recordstarted = false;

    private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
    private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
    private CallBr br_call;

    public String file_name="", recordedFileName="",uploadedFileName="", base64_file="", statusMessage="";
    public int statusCode, file_size=0, delay = 1000,period = 5000;
    public FFmpeg fFmpeg;


    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onDestroy() {
        Log.d("service", "destroy");

        super.onDestroy();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        sharedPref = new SharedPref(this);
        networkUtils = new NetworkUtils(this);

        final IntentFilter filter = new IntentFilter();
        filter.addAction(ACTION_OUT);
        filter.addAction(ACTION_IN);
        this.br_call = new CallBr();
        this.registerReceiver(this.br_call, filter);

        fFmpeg = FFmpeg.getInstance(CallService.this);

        Timer task = new Timer();
        task.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {

                if (networkUtils.checkConnection()){

                }else{
       //                    Toast.makeText(CallService.this, getResources().getString(R.string.no_connection), Toast.LENGTH_SHORT).show();
                }

            }
        }, delay, period);




        // if(terminate != null) {
        // stopSelf();
        // }
        return START_STICKY;
    }

    public class CallBr extends BroadcastReceiver {
        Bundle bundle;
        String state;
        String inCall, outCall;
        public boolean wasRinging = false;
        public File sampleDir;

        @Override
        public void onReceive(Context context, Intent intent) {


            if (intent.getAction().equals(ACTION_IN)) {
                if ((bundle = intent.getExtras()) != null) {
                    state = bundle.getString(TelephonyManager.EXTRA_STATE);
                    if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
                        inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
                        wasRinging = true;
                        Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
                    } else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
                        if (wasRinging == true) {

                            Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();

                            String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
                            sampleDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "/OfficeRecordings/");
                            if (!sampleDir.exists()) {
                                sampleDir.mkdirs();
                            }


                            Log.d("TService", "onReceive: "+sampleDir);
                            file_name = "Incoming";
                            String path = Environment.getExternalStorageDirectory().getAbsolutePath();
    //                            try {
    //                                audiofile =     File.createTempFile(file_name, ".wav", sampleDir);
    //                                recordedFileName =  sampleDir + String.valueOf(System.currentTimeMillis() + ".wav");
    //
    //                            } catch (IOException e) {
    //                                e.printStackTrace();
    //                            }
    //                            recordedFileName =  sampleDir+"_"+ file_name +String.valueOf(System.currentTimeMillis() + ".wav");
                            uploadedFileName = sharedPref.getStringValue("userId")+"_"+sharedPref.getStringValue("mobile_number_prefs")+"_" +file_name +String.valueOf(System.currentTimeMillis()+ ".aac");
                            recordedFileName =  sampleDir+"/"+uploadedFileName;

                            recorder = new MediaRecorder();
                            //                      recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
                            //                        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);

                            recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                            recorder.setOutputFormat(MediaRecorder.OutputFormat.AAC_ADTS);
                            recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);


                           // recorder.setOutputFile(audiofile.getAbsolutePath());
                            recorder.setOutputFile(recordedFileName);
                            try {
                                recorder.prepare();
                            } catch (IllegalStateException e) {
                                e.printStackTrace();
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                            recorder.start();
                            recordstarted = true;
                        }
                    } else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                        wasRinging = false;
                        Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
                        if (recordstarted) {
                            recorder.stop();
                            recordstarted = false;

                            if (recordedFileName.isEmpty()){

                            }else{
                                convertFileToBase64(context);
                            }
                        }
                    }
                }
            } else if (intent.getAction().equals(ACTION_OUT)) {
                if ((bundle = intent.getExtras()) != null) {
                    outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
                    Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();

                    sampleDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath(), "/OfficeRecordings/");
                    if (!sampleDir.exists()) {
                        sampleDir.mkdirs();
                    }


                    Log.d("TService", "onReceive: "+sampleDir);
                    file_name = "Outgoing";
                    String path = Environment.getExternalStorageDirectory().getAbsolutePath();
                    uploadedFileName = sharedPref.getStringValue("userId")+"_"+sharedPref.getStringValue("mobile_number_prefs")+"_" +file_name +String.valueOf(System.currentTimeMillis() + ".amr");
                    recordedFileName =  sampleDir+"/"+uploadedFileName;
    //                    try {
    //                        audiofile = File.createTempFile(file_name, ".wav", sampleDir);
    //                        recordedFileName = audiofile.getName();
    //
    //                    } catch (IOException e) {
    //                        e.printStackTrace();
    //                    }

                    recorder = new MediaRecorder();
                    //                      recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
                    //                        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);

                    recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                    recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
                    recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
                    recorder.setOutputFile(audiofile.getAbsolutePath());
                    try {
                        recorder.prepare();
                    } catch (IllegalStateException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    recorder.start();
                    recordstarted = true;

                    if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
                        wasRinging = false;
                        Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
                        if (recordstarted) {
                            recorder.stop();
                            recordstarted = false;

                            if (recordedFileName.isEmpty()){

                            }else{

                                convertFileToBase64(context);
                            }
                        }
                    }

                }
            }

           // LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("callRecord"));
        }

        public void convertFileToBase64(Context context){

            File uploadedFile = new File(recordedFileName);

            Log.d("CallService", "convertFileToBase64: "+uploadedFile);

            String[] cmd = new String[4];
            cmd[0] = "ffmpeg ";
            cmd[1] = "-i ";
            cmd[2] = recordedFileName+" ";
            cmd[3] = " "+sampleDir+"/"+"sampleAudio.wav";

            execFFmpegBinary(cmd);

            file_size = Integer.parseInt(String.valueOf(uploadedFile.length()/1024));
            Log.d("CallService", "onReceive: "+file_size);

            byte[] byteArray = new byte[1024*11];

            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

            // File uploadedFile = new File(sampleDir+"/"+recordedFileName);

            Uri path = Uri.fromFile(uploadedFile);
            //  Uri path = Uri.fromFile(uploadedFile);


            Log.d("CallService", "convertFileToBase64: "+path);

            try {
                InputStream inputStream = context.getContentResolver().openInputStream(path);

                byte[] b = new byte[1024 * 11];
                int bytesRead = 0;

                while ((bytesRead = inputStream.read(b)) != -1) {
                    byteArrayOutputStream.write(b, 0, bytesRead);
                }


                byteArray = byteArrayOutputStream.toByteArray();

                Log.e("Byte array", ">" + byteArray);

            } catch (IOException e) {
                e.printStackTrace();
            }

            base64_file = Base64.encodeToString(byteArray, Base64.DEFAULT);

            Log.d("CallRecorder", "base64File: "+base64_file);
            if (!(base64_file.isEmpty())){
                Log.d("CallService", "convertFileToBase64: base64 not empty");

                if (networkUtils.checkConnection()){
                    uploadRecordedFileToServer();
                }else{
                    saveFileToLocalDB();
                    Toast.makeText(context, getString(R.string.no_connection), Toast.LENGTH_SHORT).show();
                }
            }

        }

        private void execFFmpegBinary(final String[] command) {
            try {
                fFmpeg.execute(command, new ExecuteBinaryResponseHandler() {
                    @Override
                    public void onFailure(String s) {
                        Log.d("CallService", "onFailure: "+s);
                        Toast.makeText(CallService.this, "Failed to convert", Toast.LENGTH_SHORT).show();
                    }

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

                    @Override
                    public void onProgress(String s) {
                        Log.d("CallService", "Started command : ffmpeg "+command);
                        Log.d("CallService", "progress : "+s);
                     //  progressDialog.setMessage("Processing\n"+s);
                    }

                    @Override
                    public void onStart() {

                        Log.d("CallService", "Started command : ffmpeg " + command);
    //                        progressDialog.setMessage("Processing...");
    //                        progressDialog.show();
                    }

                    @Override
                    public void onFinish() {
                        Log.d("CallService", "Finished command : ffmpeg "+command);
                      //  progressDialog.dismiss();
                    }
                });
            } catch (FFmpegCommandAlreadyRunningException e) {
                // do nothing for now
            }
        }

艾米的帮助真的很感激......提前谢谢!!!

1 个答案:

答案 0 :(得分:1)

请在执行命令之前先调用load binary方法。

FFmpeg ffmpeg = FFmpeg.getInstance(this);
    try {
        ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
            @Override
            public void onStart() {
            }

            @Override
            public void onFailure() {
            }

            @Override
            public void onSuccess() {
            }

            @Override
            public void onFinish() {
            }
        });
    } catch (FFmpegNotSupportedException e) {
    }

再试一次,如果不能正常工作,请告诉我。