安卓:可靠的录音,所有设备 [英] Android: Reliable Audio Recording, All Devices

查看:158
本文介绍了安卓:可靠的录音,所有设备的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有人可以跟我一个可靠的方式来记录整个使用MediaRecorder所有设备的音频共享?我只是想记录的低码率AMR格式的音频文件,而根据谷歌在所有设备的标准。这是一堆垃圾。

Can someone please share with me a RELIABLE way to record audio across all devices using MediaRecorder? I'm simply trying to record a low-bitrate AMR format audio file, which according to google is standard across all devices. That's a bunch of crap.

在我的经验中,有很多场外的品牌设备,平板电脑等。当你使用默认AudioEn coder.AMR_NB将失败可怕。我的解决方法是目前使用反射来查询什么EN codeRS是在父类,然后通过每一个循环与errorlistener,看看哪一个不会失败。这不仅是不光彩的,但它并没有捕捉到所有的设备。我也试着设置为默认的AudioEn codeR和OUTPUTFORMAT选项(恒为0),这可怕的失败,在某些设备上也是如此。

In my experience, there are many off-brand devices, tablets, etc. that will fail horribly when you use the default AudioEncoder.AMR_NB. My workaround is currently to use reflection to poll what encoders are in the superclass, then looping through each one with an errorlistener to see which one doesn't fail. Not only is this not graceful, but it doesn't catch all devices. I have also tried setting to default on the AudioEncoder and OutputFormat options (constant 0) and this fails horribly on some devices as well.

下面是我使用的是什么,如果默认AMR EN codeR不起作用:

Here is what i'm using if the default AMR encoder doesn't work:

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

然后我遍历每个连接codeR,设置错误侦听器。如果它成功地结束我将它设置为默认的连接codeR作为设置。

Then i loop through each encoder, setting an error listener. If it ends successfully i set it as the default encoder as a setting.

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() {

我不断的循环,如果监听器捕获了一个错误:

I continue the loop if the listener catches an error:

if (arg1 == MediaRecorder.MEDIA_RECORDER_ERROR_UNKNOWN) {

此方法适用于大多数设备。那么其他人呢? 我仍然有贯穿裂缝落入设备,坦率地说,我想 几乎所有的设备的东西可靠????

This technique works for most devices. What about the rest? I still have devices that fall through the cracks and frankly i'd like something RELIABLE for nearly all devices????

推荐答案

那么,既然没有人愿意来发布解决方案,这里是我使用什么,现在,它的工作原理,但有点乱。我开始用setupAudio()方法,该方法尝试三种常见的音频连接codeR和容器的设置。这适用于大多数设备。如果它不工作,则默认为一个额外的方法setupAltAudio(),它通过列出的设备连接codeR值的周期,并尝试每一个。我敢肯定有人会附和说为什么不使用OnErrorListener()?这并不为许多设备的工作方式将引发怪异,非致命错误,如果我来了回复,我可以停止有效的录制设置。

Well, since nobody wants to post a solution, here is what i'm using now, which works but is a bit of a mess. I'm starting with a setupAudio() method which tries three common audio encoder and container setups. This will work for most devices. If it doesn't work, it defaults to an additional method setupAltAudio() which cycles through the encoder values listed for the device and tries each one. I'm sure someone will chime in and say "why not use OnErrorListener()"? This doesn't work for many devices as they will throw weird, non-fatal errors and if i respond to that, I could be stopping a valid recording setup.

错误一般是不可恢复发生在设置的MediaRecorder,所以我乱七八糟赶上setAudioEn codeR()和prepare()和start()方法。如果在这里抛出一个异常,我没有一个有效的音频录制设置。我已经没有清理此code然而,和它在它的一些元素,可以得到改善。一旦音频连接codeR是成功的,我保存了EN codeR和集装箱值设置,并重新运行setupAudio()方法。会发生什么事这个时候,是它吸引这些设置,并直接转到的startRecording()。因此,在所有的,我想最常见的MediaRecorder设置第一,然后我使用反射来循环通过每个连接codeR作为试错法。 编辑: 该setupAltAudio缺少一个细节。主回路需要被初始化(i)至audioLoop的一个值,它是在设置。这种跟踪其连接$ C $的CR上次测​​试。

Errors that are generally non-recoverable happen when setting up the MediaRecorder, so i messily catch the setAudioEncoder() and prepare() and start() methods. If it throws an exception here, I don't have a valid audio recording setup. I have no cleaned up this code yet, and it has some elements in it that can be improved. Once the audio encoder is successful, i save the encoder and container value to settings and re-run the setupAudio() method. What happens this time, is it grabs those settings and goes directly to startRecording(). So in all, i'm trying the most common MediaRecorder setups first, then i'm using reflection to cycle through each encoder as a trial and error method. The setupAltAudio is missing one detail. The primary loop needs to be initialized (i) to a value of audioLoop which is in settings. This keeps track of which encoder it last tested.

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();

这篇关于安卓:可靠的录音,所有设备的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆