CocosCreator系列——用安卓原生實現錄音與播放功能

CocosCreator系列——用安卓原生實現錄音與播放功能

正式開始這篇文章之前先囉嗦一下,寫程序一定要細心細心再細心,一定要細心細心再細心,一定要細心細心再細心重要的事說三遍,其實自己一直都寫好了,但是一直不成功,發現多了一個“/”,然後不報錯了,不知道爲什麼還是沒聲音,why?why?why?why?why?我一腦子黑人問號臉?後來發現手機是靜音模式……好吧,我都服了我自己了。
開始正文先來點掌聲吧,👏👏👏爲了寫這個功能,花了我兩天時間研究安卓,真是客戶端什麼都要會啊,終於在第二天即將下班之際完成這個功能了,首先是CocosCreator客戶端代碼,同樣基於2.2.1版本,我註釋寫的挺詳細的,不懂的可以關注我一波,私信我給你講解一下,看js代碼吧:

cc.Class({
    extends: cc.Component,

    properties: {
        luyinBtn: cc.Node,
    },

    // use this for initialization
    onLoad: function () {
        if (cc.sys.isNative) {
        	//設置用來存放錄製語音的路徑
            this.setStorageDir(jsb.fileUtils.getWritablePath() + "audioS/");
        }

        this.luyinBtn.on(cc.Node.EventType.TOUCH_START, this.onVoiceTouch, this);//一直按着錄音
        this.luyinBtn.on(cc.Node.EventType.TOUCH_END, this.stopRecord, this);//擡起錄音完成
        this.luyinBtn.on(cc.Node.EventType.TOUCH_CANCEL, this.stopRecord, this);//擡起取消錄音,暫未實現,實際項目裏再說吧,這個簡單
    },

    setStorageDir: function (dir) {
        if (cc.sys.os == cc.sys.OS_ANDROID) {
            jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "setStorageDir", "(Ljava/lang/String;)V", dir);
        }
    },

    onVoiceTouch() {
        if (!cc.sys.isNative) {
            return;
        }
        //開始錄音啦!!!!!!!
        //先清理一下舊文件
        this.clearCache("record.mp3");
        if (cc.sys.os == cc.sys.OS_ANDROID) {
            cc.log("開始說話--------------------------------");
            jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "prepare", "(Ljava/lang/String;)V", "record.mp3");
        }
    },
    stopRecord: function () {
        if (!cc.sys.isNative) {
            return;
        }
        if (cc.sys.os == cc.sys.OS_ANDROID) {
            jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "stopRecord", "()V");
        }
    },
    clearCache: function (filename) {
        if (cc.sys.isNative) {
            var url = jsb.fileUtils.getWritablePath() + "/audioS/" + filename;
            if (jsb.fileUtils.isFileExist(url)) {
                jsb.fileUtils.removeFile(url);
            }
            if (jsb.fileUtils.isFileExist(url + ".mp3")) {
                jsb.fileUtils.removeFile(url + ".mp3");
            }
        }
    },

	//點擊播放的時候,調這個方法就可以了
    onPlay() {
        if (!cc.sys.isNative) {
            return;
        }
        if (cc.sys.os == cc.sys.OS_ANDROID) {
            jsb.reflection.callStaticMethod("org/cocos2dx/javascript/AppActivity", "playSound", "()V");
        }
    },


然後是Java代碼,先初始化一下各類參數錄音和播放主要依靠MediaRecorder和MediaPlayer兩個類來實現MediaRecorder用來實現錄音,MediaPlayer用來播放錄音

    public static String mDirString;//保存的路徑
    public static MediaRecorder mMediaRecorder;//錄音的文件類
    public static File audioFile; //錄音保存的文件
    public static boolean isRecoding = false;// true 表示正在錄音
    private static MediaPlayer mMediaPlayer;  //播放錄音文件

js端代碼在onLoad的時候會調用這個方法,然後把路徑傳過來

    public static void setStorageDir(String paramString) {
        //設置當前錄音文件路徑
        mDirString = paramString;
        Log.e("開始錄音之前:", mDirString);
    }

正式開始錄音方法,不得不說,打印log是調式程序的最佳選擇之一,通過log可以看出來哪一步出錯了,然後定位到具體問題

    public static void prepare(String paramString) {
        File destDir = new File(mDirString);//文件保存路徑
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);//設置播放源 麥克風
        Log.e("設置麥克風:", "成功");
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //設置輸入格式 3gp
        Log.e("設置輸入格式:", "成功");
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //設置編碼 AMR
        Log.e("設置編碼:", "成功");
        if (!destDir.exists()) {
            destDir.mkdirs();
        }
        Log.e("創建文件路徑:", "成功");
        try {
            audioFile = new File(mDirString, paramString);
            if (audioFile.exists()) {
                audioFile.delete();
                Log.e("刪除文件路徑:", "成功");
            }
            audioFile.createNewFile();
            Log.e("創建錄音文件:", "成功");
        } catch (Exception e) {
            throw new RuntimeException("Couldn't create recording audio file", e);
        }
        mMediaRecorder.setOutputFile(audioFile.getAbsolutePath());
        Log.e("設置錄音文件輸出路徑:", "成功");
        try {
            mMediaRecorder.prepare();
        } catch (IllegalStateException e) {
            throw new RuntimeException("IllegalStateException on MediaRecorder.prepare", e);
        } catch (IOException e) {
            throw new RuntimeException("IOException on MediaRecorder.prepare", e);
        }
        isRecoding = true;
        mMediaRecorder.start();
        Log.e("正在錄音:", "成功");
    }

錄音完成方法

    public static void stopRecord() {
        if (isRecoding) {
            if (mMediaRecorder != null) {
                try {
                    mMediaRecorder.stop();
                    Log.e("錄音完成:", "成功");
                } catch (IllegalStateException e) {
                    // TODO 如果當前java狀態和jni裏面的狀態不一致,
                    e.printStackTrace();
                    mMediaRecorder = null;
                    mMediaRecorder = new MediaRecorder();
                }
                mMediaRecorder.release();
                mMediaRecorder = null;
            }
        }
    }

最後,播放錄音方法

    public static void playSound(){
        if(mMediaPlayer==null){
            Log.e("新建播放類:", "成功");
            mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setOnErrorListener( new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    Log.e("mMediaPlayer錯誤監聽null:", "錯誤");
                    mMediaPlayer.reset();
                    return false;
                }
            });
        }else{
            Log.e("mMediaPlayer錯誤監聽有值:", "成功");
            mMediaPlayer.reset();
        }
        try {
            //詳見“MediaPlayer”調用過程圖
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            Log.e("mMediaPlayer設置類型:", "成功");
            mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener(){
                public void onCompletion(MediaPlayer paramAnonymousMediaPlayer) {}
            });

            mMediaPlayer.setDataSource(mDirString+"/record.mp3");
            Log.e("mMediaPlayer設置文件:", mDirString+"record.mp3");
            mMediaPlayer.prepare();
            mMediaPlayer.start();
            Log.e("mMediaPlayer開始播放:", "成功");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Log.e("語音error==",e.getMessage());
        }
    }

看一下客戶端界面
在這裏插入圖片描述

全部搞定!!!!!!!!!!!!!!!!!! ( ̄▽ ̄)"
看到這麼帥又這麼無私的博主,確定不關注一波麼 (●ˇ∀ˇ●)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章