Skip to content

Latest commit

 

History

History
240 lines (196 loc) · 8.1 KB

h5.md

File metadata and controls

240 lines (196 loc) · 8.1 KB

h5接入使用说明

H5 调用原生功能原理说明

H5页面最终是通过webview展示出来的,通过配置webview,使webview能够识别来自H5中的js请求; 然后webview再调用原生提供的接口实现 h5 与原生交互,反之亦行;

WebView录音API接口参数说明

1. startRecording(String json) 开始录接口,传递参数的格式字符串json格式,具体说明如下:

> 音频格式参数json【默认key和value】:
  ```java
  {
    "audioRate":"16000",
  	"channelConfig":"16",
  	"audioFormat":"1"
  	"uploadUrl":"http://"   // 可选
  }
  ```
  其中:
  * audioRate: 采样频率字段;  目前使用:16000,默认使用:16000
  * channelConfig: 通道设置字段 ;目前只使用:单声道:16,可选值如下:

       - 单声道:16
       - 多声道传入:12

  * audioFormat:文件格式,目前只使用:PCM_16BIT:1,可选值如下:

    - PCM 16位:1 【默认】
    - PCM 8位:2
    - WAV文件:3
    - AMR压缩文件:4
    - SPX:5

  * uploadUrl : 传入需要上传的服务器地址,需要以http开头;

     若传入此参数,程序会将生成好的语音文件,上传到指定的url地址,并返回url的响应(最好是json格式),回调给H5的js定义的方法`parseRecordComplete`;

2. finishRecording() 结束录音接口

3. cancelRecording() 取消录音接口

h5 简单使用示例代码

以下为 html 示例代码: !示例html代码

<script type="text/javascript">

        // 调用原生开始录
        function start () {
			var json = '{"audioRate":"16000","channelConfig":"16", "audioFormat" : "1"}'
			window.Android.startRecording(json);     // 调用webview开放接口开始录音
        }

        // 调用原生结束
        function end() {
			window.Android.finishRecording();
        }

        // android 原生回调 js
		function parseRecordComplete(result) {  // result 为 startRecording() 时 指定的服务器url回传的信息
			if(!/\s+/.test(result)) {
			    alert("文件已生成: " + result)
		    }
		}
</script>

开始录音 结束录音

H5 js 供Webview回调方法

H5 需定义一个js方法,供WebView录音完成时,回调H5时用; 用来表示一个操作结束;如 parseRecordComplete(result)

function parseRecordComplete(result) {  // result 为 startRecording() 时 指定的服务器url回传的信息
    // h5 自己的操作
}

webview参考配置如下:

注:如果您是H5开发人员,可省略这一步;供Android开发查看

注:因为目前语音识别只支持 PCM 格式,故一些配置不生效。先预留一些配置实现;


// 录音sdk api
private RecordAPI recordAPI;

webView.getSettings().setJavaScriptEnabled(true);
// 支持JavaScript调用,标识符 Android
webView.addJavascriptInterface(new RecordJavaScriptInterface(), "Android");


/**
* JavaScript调用Native 示例代码
*/
private class RecordJavaScriptInterface {

    // 路径
    String originPath;
    // 录音文件上传路径
    String uploadUrl = "http://wwww";

    /**
     * 格式类型
     * @param type
     * @return
     */
    private VoiceType getVoiceType(int type) {
        switch (type) {
            case 1:
                return VoiceType.PCM_16BIT;
            case 2:
                return VoiceType.PCM_8BIT;
            case 3:
                return VoiceType.WAV;
            case 4:
                return VoiceType.AMR;
            case 5:
                return VoiceType.SPEEX;
        }
        return VoiceType.PCM_16BIT;
    }

    /**
     * 目前只支持 PCM 无损格式,原因见上
     * @param json
     * @return
     */
    private void initRecordAPI(String json) {
        try {
            JSONObject object = new JSONObject(json);
            // audioRate: 采样频率字段。目前使用:16000
            int rate = object.getInt("audioRate");
            // 文件格式 (1:PCM_16位,2:PCM_位,3:WAV格式,4:AMR格式,5:SPX格式)
            VoiceType voiceType = getVoiceType(object.getInt("audioFormat"));
            Object channel;
            if (object.getInt("channelConfig") == 16) { // 通道,目前:单声道:16
                channel = AudioRecordParam.AudioInChannel.CHANNEL_IN_MONO;
            } else {
                channel = AudioRecordParam.AudioInChannel.CHANNEL_IN_STEREO;
            }
            recordAPI = VoiceManager.with(H5TestActivity.this).getRecordAPI(voiceType, new AudioRecordParam(rate, (AudioRecordParam.AudioInChannel) channel));
        } catch (Exception e) {
            Log.e(H5TestActivity.class.getSimpleName(), e.toString());
        }
    }

    ///////////////////////// 与 JS 交互的接口定义如下
    @JavascriptInterface
    public void startRecording(String json) {
        // ===== 1.初始化录音组件
        initRecordAPI(json);
        if (recordAPI == null) {
            Toast.makeText(getApplicationContext(), "录音组件初始化失败,请检查参数设置! " + json, Toast.LENGTH_SHORT).show();
            return;
        }

        try {
            // 2. ==== 设置临时文件:开通输出流到指定的文件
            File fpath = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/better");
            fpath.mkdirs();// 创建文件夹
            File mAudioFile = new File(fpath, "recoding.wav");
            originPath = fpath.getAbsolutePath() + "/recoding.wav";

            // 3.==== 判断是否有需要uploadUrl
            JSONObject object = new JSONObject(json);
            final String uploadUrl = object.optString("uploadUrl");


            // 4.=== 开始录音
            recordAPI.startRecord(originPath, new RecordListener() {
                @Override
                public void onStart() {
                }

                @Override
                public void onFinishRecord(long duration, final String filePath) {
                    Toast.makeText(getApplicationContext(), "录音结束,开始上传文件 " + duration, Toast.LENGTH_SHORT).show();
                    if (!TextUtils.isEmpty(uploadUrl)) {
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                Log.d("hehe", "开始上传" + filePath);
                                final String info = UploadUtils.getResponseString(uploadUrl, filePath);
                                RecordUtils.getMainHandler().post(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (H5TestActivity.this != null && !H5TestActivity.this.isFinishing()) {
                                            // 原生回调 H5 中的 js
                                            webView.loadUrl("javascript:parseRecordComplete('" + info + "')");
                                        }
                                    }
                                });
                            }
                        }).start();
                    }
                }

                @Override
                public void onCancel() {
                }

                @Override
                public void onError(Exception e) {
                    Toast.makeText(getApplicationContext(), "出错啦 " + e.getMessage(), Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onAmplitudeChanged(int volume) {
                }
            });
        } catch (Exception e) {
            Log.e(H5TestActivity.class.getSimpleName(), e.toString());
        }
    }

    @JavascriptInterface
    public void finishRecording() {
        if (recordAPI != null) {
            recordAPI.stopRecord();
        }
    }

    @JavascriptInterface
    public void cancelRecording() {
        if(recordAPI != null) {
            recordAPI.cancelRecord();
        }
    }