HarmonyOS 录音与音频播放

系统 OpenHarmony
录音和音频播放在app中是一个很常见的功能,本文将介绍在HarmonyOS 如何使用录音和音频播放功能。

[[410205]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

引言

录音和音频播放在app中是一个很常见的功能,本文将介绍在HarmonyOS 如何使用录音和音频播放功能。

功能介绍

1.录音

1.1 使用录音前需要先申请录音权限

在 config.json文件中添加权限声明

  1. "reqPermissions": [     
  2.      { 
  3.        "name""ohos.permission.MICROPHONE"
  4.        "reason""the app need microphone"
  5.        "usedScene": { 
  6.          "ability": [ 
  7.            "com.iflytek.demo.MainAbility" 
  8.          ], 
  9.          "when""always" 
  10.        } 
  11.      } 
  12.    ] 

然后在MainAbility中动态申请麦克风权限

  1. private void requestPermission() { 
  2.         if (verifySelfPermission("ohos.permission.MICROPHONE") != IBundleManager.PERMISSION_GRANTED) { 
  3.             // 应用未被授予权限 
  4.             if (canRequestPermission("ohos.permission.MICROPHONE")) { 
  5.                 // 是否可以申请弹框授权(首次申请或者用户未选择禁止且不再提示) 
  6.                 requestPermissionsFromUser(new String[]{"ohos.permission.MICROPHONE"}, REQUEST_MICROPHONE); 
  7.             } else { 
  8.                 // 显示应用需要权限的理由,提示用户进入设置授权 
  9.             } 
  10.         } else { 
  11.             // 权限已被授予 
  12.         } 
  13.     } 
  14.  
  15.     /** 
  16.      * 权限回调 
  17.      */ 
  18.     @Override 
  19.     public void onRequestPermissionsFromUserResult(int requestCode, 
  20.                                                    String[] permissions, 
  21.                                                    int[] grantResults) { 
  22.         switch (requestCode) { 
  23.             case REQUEST_MICROPHONE: { 
  24.                 // 匹配requestPermissions的requestCode 
  25.                 if (grantResults.length > 0 && grantResults[0] == IBundleManager.PERMISSION_GRANTED) { 
  26.                     // 权限被授予 
  27.                     // 注意:因时间差导致接口权限检查时有无权限,所以对那些因无权限而抛异常的接口进行异常捕获处理 
  28.                     AppLog.e("MainAbility""已经获取到录音权限"); 
  29.                 } else { 
  30.                     // 权限被拒绝 
  31.                     AppLog.e("MainAbility""录音权限被拒绝"); 
  32.                 } 
  33.             } 
  34.         } 
  35.     } 

1.2 录音功能使用的是 AudioCapturer类,主要接口如下:

初始化AudioCapturer,先通过 AudioStreamInfo设置录音音频基本参数,再通过AudioCapturerInfo设置录音源等信息。

  1. /** 
  2.     * 创建默认的录音对象 
  3.     */ 
  4.    public void initConfig() { 
  5.  
  6.        if (audioCapturer != null && audioCapturer.getState() != AudioCapturer.State.STATE_STOPPED) { 
  7.            audioCapturer.release(); 
  8.        } 
  9.        audioCapturer = null
  10.        AudioStreamInfo audioStreamInfo = new AudioStreamInfo.Builder() 
  11.                // 音频采样率 16000 
  12.                .sampleRate(AUDIO_SAMPLE_RATE) 
  13.                // 录音数据格式 16-bit PCM 
  14.                .encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT) 
  15.                // 声道设置 单声道 
  16.                .channelMask(AudioStreamInfo.ChannelMask.CHANNEL_IN_MONO) 
  17.                .build(); 
  18.        AudioCapturerInfo audioCapturerInfo = new AudioCapturerInfo.Builder() 
  19.                .audioStreamInfo(audioStreamInfo) 
  20.                // 录音源 
  21.                .audioInputSource(AudioCapturerInfo.AudioInputSource.AUDIO_INPUT_SOURCE_MIC) 
  22.                .build(); 
  23.        audioCapturer = new AudioCapturer(audioCapturerInfo); 
  24.        bufferSizeInBytes = AudioCapturer.getMinBufferSize(AUDIO_SAMPLE_RATE, 1, 2); 
  25.    } 

开始录音,通过 audioCapturer.read() 获取音频。

  1. /** 
  2.     * 开始录音 
  3.     * 
  4.     * @param listener 音频流的监听回调 
  5.     */ 
  6.    public void startRecord(final RecordListener listener) { 
  7.        if (audioCapturer.getState() == AudioCapturer.State.STATE_UNINITIALIZED) { 
  8.            throw new IllegalStateException("AudioCapturer need init first"); 
  9.        } 
  10.        if (isRecording()) { 
  11.            throw new IllegalStateException("AudioCapturer is in recording now"); 
  12.        } 
  13.        // 开始录音 
  14.        audioCapturer.start(); 
  15.        final byte[] audioData = new byte[bufferSizeInBytes]; 
  16.        while (isRecording()) { 
  17.            int size = audioCapturer.read(audioData, 0, bufferSizeInBytes); 
  18.            if (size > 0 && listener != null) { 
  19.                if (size == bufferSizeInBytes) { 
  20.                    // 通过回掉回传录音数据 
  21.                    listener.onRead(audioData); 
  22.                } else { 
  23.                    // 通过回掉回传录音数据 
  24.                    final byte[] copy = new byte[size]; 
  25.                    System.arraycopy(audioData, 0, copy, 0, size); 
  26.                    listener.onRead(copy); 
  27.                } 
  28.            } 
  29.        } 
  30.        if (finishCallBack != null) { 
  31.            finishCallBack.onFinish(); 
  32.        } 
  33.    } 

停止录音

  1. /** 
  2.     * 停止录音 
  3.     */ 
  4.    public synchronized void stopRecord() { 
  5.        if (isRecording()) { 
  6.            audioCapturer.stop(); 
  7.        } 
  8.    } 
  9.  
  10.    /** 
  11.     * 释放资源 
  12.     */ 
  13.    public synchronized void release() { 
  14.        if (audioCapturer != null) { 
  15.            audioCapturer.release(); 
  16.            audioCapturer = null
  17.        } 
  18.    } 

2. 音频播放

HarmonyOS 中,播放音频主要有 AudioRenderer 、Player 、SoundPlayer 3个类

AudioRenderer 用于播放pcm音频流

Player 主要用于播放mp3、m4a等格式的音频

SoundPlayer 用于播放短音频

2.1 AudioRenderer播放pcm音频

  1. /** 
  2.     * 播放pcm 
  3.     * 
  4.     * @param file pcm文件 
  5.     */ 
  6.    private void playPcm(File file) { 
  7.        if (file == null || !file.exists()) { 
  8.            showToast("文件不存在"); 
  9.            return
  10.        } 
  11.        AudioStreamInfo streamInfo = new AudioStreamInfo.Builder() 
  12.                // 16kHz 
  13.                .sampleRate(16000) 
  14.                // 混音 
  15.                .audioStreamFlag(AudioStreamInfo.AudioStreamFlag.AUDIO_STREAM_FLAG_MAY_DUCK) 
  16.                // 16-bit PCM 
  17.                .encodingFormat(AudioStreamInfo.EncodingFormat.ENCODING_PCM_16BIT) 
  18.                // 单声道输出 
  19.                .channelMask(AudioStreamInfo.ChannelMask.CHANNEL_OUT_MONO) 
  20.                // 媒体类音频 
  21.                .streamUsage(AudioStreamInfo.StreamUsage.STREAM_USAGE_MEDIA) 
  22.                .build(); 
  23.  
  24.        AudioRendererInfo audioRendererInfo = new AudioRendererInfo.Builder().audioStreamInfo(streamInfo) 
  25.                // pcm格式的输出流 
  26.                .audioStreamOutputFlag(AudioRendererInfo.AudioStreamOutputFlag.AUDIO_STREAM_OUTPUT_FLAG_DIRECT_PCM) 
  27.                .bufferSizeInBytes(1280) 
  28.                // false表示分段传输buffer并播放,true表示整个音频流一次性传输到HAL层播放 
  29.                .isOffload(false
  30.                .build(); 
  31.  
  32.        AudioRenderer renderer = new AudioRenderer(audioRendererInfo, AudioRenderer.PlayMode.MODE_STREAM); 
  33.        renderer.start(); 
  34.        try { 
  35.            FileInputStream inputStream = new FileInputStream(file); 
  36.            byte[] temp = new byte[1280]; 
  37.            while (inputStream.available() > temp.length) { 
  38.                int read = inputStream.read(temp); 
  39.                // 写入pcm到播放器 
  40.                renderer.write(temp, 0, read); 
  41.            } 
  42.        } catch (Exception e) { 
  43.            e.printStackTrace(); 
  44.        } 
  45.  
  46.    } 

2.2 Player 播放mp3

  1. /** 
  2.     * 播放音频 
  3.     * 
  4.     * @param file 源文件位置 
  5.     */ 
  6.    private void playMp3(File file) { 
  7.        try { 
  8.            player = new Player(getContext()); 
  9.            FileInputStream in = new FileInputStream(file); 
  10.            // 从输入流获取FD对象 
  11.            FileDescriptor fd = in.getFD(); 
  12.            player.setSource(new Source(fd)); 
  13.            player.prepare(); 
  14.            player.play(); 
  15.        } catch (Exception e) { 
  16.            e.printStackTrace(); 
  17.        } 
  18.    } 

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2011-07-18 15:32:14

iPhone 录音 播放

2011-08-08 18:19:09

iPhone音频播放

2011-08-02 16:58:15

iPhone AVAudioPla 音频播放

2011-07-27 09:50:31

iPhone AVAudioPla 音频

2009-09-03 13:50:31

AudacityRHEL5源码编译

2011-09-05 18:08:01

MTK音频播放器

2024-04-23 08:24:05

音频Android播放

2022-04-12 11:07:11

Hi3861鸿蒙操作系统

2016-12-21 16:42:15

androidmediaplayer

2023-09-20 11:53:23

2021-10-04 18:53:01

Linux 5.16 USB 音频驱动补丁

2012-06-04 13:44:08

2015-09-01 17:19:02

Chrome音频

2015-06-16 10:27:13

iOSAndroid音频

2021-01-19 13:30:52

Linux播放器互联网

2023-08-16 08:00:39

API网页端音频录制

2015-09-16 16:38:10

QmmpWinampUbuntu

2012-12-24 09:04:04

iOSUnity3D

2018-06-06 15:49:06

FPGA音频处理器

2015-09-01 16:29:53

小米录音机源码
点赞
收藏

51CTO技术栈公众号