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

看一下客户端界面
在这里插入图片描述

全部搞定!!!!!!!!!!!!!!!!!! ( ̄▽ ̄)"
看到这么帅又这么无私的博主,确定不关注一波么 (●ˇ∀ˇ●)

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