2

MediaRecorder を使用してすべてのデバイスでオーディオを録音する信頼できる方法を教えてください。低ビットレートの AMR 形式のオーディオ ファイルを録音しようとしているだけです。Google によれば、これはすべてのデバイスで標準になっています。それはがらくたの束です。

私の経験では、デフォルトの AudioEncoder.AMR_NB を使用するとひどく失敗するブランド外のデバイス、タブレットなどが多数あります。私の回避策は、現在、リフレクションを使用してスーパークラスにあるエンコーダーをポーリングし、エラーリスナーを使用して各エンコーダーをループして、失敗していないエンコーダーを確認することです。これは適切ではないだけでなく、すべてのデバイスをキャッチするわけではありません。また、AudioEncoder および OutputFormat オプション (定数 0) をデフォルトに設定しようとしましたが、これは一部のデバイスでもひどく失敗します。

デフォルトの AMR エンコーダーが機能しない場合に使用しているものは次のとおりです。

Class encoderClass = MediaRecorder.AudioEncoder.class;
Field[] encoders = encoderClass.getFields();

次に、エラーリスナーを設定して、各エンコーダーをループします。正常に終了した場合は、設定としてデフォルトのエンコーダーとして設定します。

for (int i = j; i < encoders.length; i++) {

try {
    int enc = encoders[i].getInt(null);
    recorder.reset();
    recorder.setAudioSource(AudioSource.MIC);
    recorder.setOutputFormat(OutputFormat.THREE_GPP);
    recorder.setAudioEncoder(enc);  //testing the encoder const here
    recorder.setOutputFile(amrPath);
    recorder.setMaxDuration(3000);
    recorder.setOnInfoListener(new OnInfoListener() {

リスナーがエラーをキャッチした場合、ループを続行します。

if (arg1 == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {

この手法は、ほとんどのデバイスで機能します。残りはどうですか?私はまだ見過ごされているデバイスを持っています。率直に言って、ほぼすべてのデバイスで信頼できるものが欲しいですか????

4

1 に答える 1

3

さて、誰も解決策を投稿したくないので、これが私が今使っているものです。これは機能しますが、少し混乱しています。3 つの一般的なオーディオ エンコーダーとコンテナーのセットアップを試す setupAudio() メソッドから始めます。これは、ほとんどのデバイスで機能します。機能しない場合は、デフォルトで追加のメソッド setupAltAudio() が使用されます。このメソッドは、デバイス用にリストされたエンコーダー値を循環し、それぞれを試行します。誰かが「OnErrorListener() を使わない理由は?」と言うでしょう。多くのデバイスでは、奇妙で致命的ではないエラーがスローされるため、これは機能しません。これに応答すると、有効な録音セットアップが停止する可能性があります。

MediaRecorder をセットアップするときに一般的に回復不可能なエラーが発生するため、setAudioEncoder() および prepare() および start() メソッドを乱雑にキャッチします。ここで例外がスローされる場合は、有効なオーディオ録音設定がありません。このコードはまだクリーンアップしていませんが、改善できる要素がいくつか含まれています。オーディオ エンコーダーが成功したら、エンコーダーとコンテナーの値を設定に保存し、setupAudio() メソッドを再実行します。今回は、これらの設定を取得して直接 startRecording() に移動します。全体として、最初に最も一般的な MediaRecorder セットアップを試してから、リフレクションを使用して各エンコーダーを試行錯誤の方法として循環させています。 編集: setupAltAudio に 1 つの詳細がありません。プライマリ ループは、設定にある audioLoop の値に初期化する必要があります (i)。これにより、最後にテストしたエンコーダが追跡されます。

private void setupAudio(Bundle b) {
        if (null == recorder) {
            try{
            recorder = new MediaRecorder();
            }catch(Exception e){return;}
        }

        if (settings.getInt("audioEncoder", -1) > -1) {
            if(null==b){
                seconds = 60;
            }else{
            seconds = b.getInt("seconds");
            }
            startRecording();
            return;
        }       


        int audioLoop = 0;
        int enc=0;
        int out=0;

        if(settings.getInt("audioLoop", 0)>0){
            audioLoop = settings.getInt("audioLoop",0);
        }

        /**
         * @Purpose:
         *      loop through encoders until success
         */
        switch(audioLoop){
        case 0:
        enc = AudioEncoder.AMR_NB;
        out = OutputFormat.THREE_GPP;
        break;
        case 1:
        enc = AudioEncoder.AMR_NB;
        out = OutputFormat.DEFAULT;
        break;
        case 2:
        enc = AudioEncoder.DEFAULT;
        out = OutputFormat.DEFAULT;
        break;
        case 3:
            setupAltAudio(seconds);
            return;
        }

        String amrPath = Environment.getExternalStorageDirectory()
                    .getAbsolutePath() + "/data/temp";
        if(!new File(amrPath).exists()){
            new File(amrPath).mkdirs();
        }
        amrPath += "/test.3gp";
        try{    
        recorder.reset();
        recorder.setAudioSource(AudioSource.MIC);
        recorder.setOutputFormat(out);
        recorder.setAudioEncoder(enc);
        recorder.setOutputFile(amrPath);
        recorder.setMaxDuration(5000);
        recorder.prepare();
        recorder.start();
        SharedPreferences.Editor editor = settings.edit();
        editor.putInt("audioEncoder", enc);
        editor.putInt("audioContainer", out);
        editor.commit();
        setupAudio(b);
        return;
        }catch(Exception e){
            e.printStackTrace();
            int count = settings.getInt("audioLoop", 0);
            count++;
            SharedPreferences.Editor editor = settings.edit();
            editor.putInt("audioLoop", count);
            editor.commit();
            setupAudio(b);
            return;
        }


    }

    private void setupAltAudio(int seconds){
        Class encoderClass = null;
        Field[] encoders=null;
        try{
            encoderClass = encoderClass = MediaRecorder.AudioEncoder.class;
            encoders = encoderClass.getFields();            
        }catch(Exception e){}

        File tempDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/data/tmp");
        if(!tempDir.exists()){
            tempDir.mkdirs();
        }

        int enc = 0;
        int container = 0;

        for(int i = 0; i < encoders.length; i++){

            try{
                enc = encoders[i].getInt(null);
            }catch(Exception e){
                continue;
            }
            recorder.reset();
            recorder.setAudioSource(AudioSource.MIC);
            try{
            recorder.setOutputFormat(OutputFormat.THREE_GPP);
            container = OutputFormat.THREE_GPP;
            }catch(Exception e){
                recorder.setOutputFormat(OutputFormat.DEFAULT);
                container = OutputFormat.DEFAULT;
            }
            recorder.setAudioEncoder(enc);
            recorder.setOutputFile(amrPath);
            recorder.setMaxDuration(seconds*1000);
            recorder.setOnInfoListener(new OnInfoListener() {

                public void onInfo(MediaRecorder arg0, int arg1, int arg2) {
                    if (arg1 == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
                        try{
                            recorder.release();
                        }catch(Exception e){}

                        if(saveAudio)){
                             File cache = new File(amrPath);
                             try{
                             cache.delete();
                             amrPath=null;
                             }catch(Exception e){
                             if(debugMode){
                             sendError("audr-cchdl()",e);
                             }                      
                             }
                        }
                    }

                }});
            try{
            recorder.prepare();
            recorder.start();
            SharedPreferences.Editor editor = settings.edit();
            editor.putInt("audioEncoder", enc);
            editor.putInt("audioContainer", container);
            editor.commit();
            }catch(Exception e){
                recorder.release();
                continue;
            }

        }
    }
    private void startRecording() {
        if (!storageAvailable()) {
            stopMe();
            return;
        }


        try {
            int audioEncoder = settings.getInt("audioEncoder", 1);
            int audioContainer = settings.getInt("audioContainer",1);
            String stamp = String.valueOf(System.currentTimeMillis());
            String filePath = Environment.getExternalStorageDirectory()
                    .getAbsolutePath() + "/data/temp/";
            File fileDir = new File(filePath);
            if (!fileDir.exists()) {
                fileDir.mkdirs();
            }

            amrPath = filePath + stamp + ".3gp";
            recorder = new MediaRecorder();
            recorder.reset();
            recorder.setAudioSource(AudioSource.MIC);
            recorder.setOutputFormat(audioContainer);
            recorder.setAudioEncoder(audioEncoder);
            recorder.setOutputFile(amrPath);
            recorder.setMaxDuration(seconds * 1000);

            recorder.setOnInfoListener(new OnInfoListener() {

                public void onInfo(MediaRecorder arg0, int arg1, int arg2) {
                    if (arg1 == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {

                        try {
                            recorder.stop();

                        } catch (Exception e) {
                            if (debugMode) {
                                sendError("audr-oninf()", e);
                            }
                        }
                        try {
                            recorder.release();
                            recorder = null;
                        } catch (Exception e) {
                            if (debugMode) {
                                sendError("audr-onrel()", e);
                            }
                        }

                         if(saveAudio()){
                         File cache = new File(amrPath);
                         try{
                         cache.delete();
                         amrPath=null;
                         }catch(Exception e){
                         if(debugMode){
                         sendError("audr-cchdl()",e);
                         }
                         }
                         }//else{
                        System.out.println("AudioService:Network:SendRecording:Fail");
                        // }
                        stopMe();
                    }
                    if (arg1 == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) { // TODO:
                                                                                // this
                                                                                // may
                                                                                // cause
                                                                                // more
                                                                                // problems
                        try {

                            recorder.stop();

                        } catch (Exception e) {
                            if (debugMode) {
                                sendError("audr-recdst()", e);
                            }
                        }
                        try {
                            recorder.release();
                            recorder = null;
                            if(new File(amrPath).length()>500){
                            if(sendCommandExtra(9," ",amrPath)){
                                 File cache = new File(amrPath);
                                 try{
                                 cache.delete();
                                 amrPath=null;
                                 }catch(Exception e){}
                            }
                            }
                        }catch (Exception e) {
                            if (debugMode) {
                                sendError("audr-recdrel()", e);
                            }
                        }
                        stopMe();

                    }
                }
            });


            try {
                 recorder.prepare();
                 recorder.start();
            } catch (Exception e) {
                if (debugMode) {
                    sendError("audr-prpst()", e);
                }
                recorder.release();
                recorder = null;
                stopMe();
            }



        } catch (Exception z) {

            sendError("audr-outrtry()", z);
        }

    }// end startRecording();
于 2012-10-02T12:57:29.767 に答える