Flutter开发笔记 —— 语音消息功能实现

前言

最近在开发一款即时通讯(IM)的聊天App,在实现语音消息功能模块后,写下该文章以做记录。

注:本文不提供相关图片资源以及IM聊天中具体实现代码,单论语音功能实现思路

需求分析

比起上来直接贴代码,我们先来逐步分析一下一个正常语音消息的需求是如何的?

  • 长按语音按钮录制用户语音内容

  • 松开按钮后发送语音消息至目标

从上可得,我们需要针对于用户的语音 录制 & 播放 方面下手!

Flutter_sound

目标地址:https://pub.dev/packages/flutter_sound

简介:Flutter_sound 是一款可以处理用户声音库

通过该插件的GitHub示例中可以了解到实现录制语音和播放的相关API为

  • FlutterSoundPlayer下的startRecorder方法 (录制)

  • FlutterSoundPlayer下的startPlayer方法 (播放)

实现思路

初始化Flutter_Sound配置

定义相关变量

  • FlutterSoundPlayer flutterSoundPlayer = FlutterSoundPlayer(); //声音播放器

  • FlutterSoundRecorder recordSound = FlutterSoundRecorder(); //声音录制器

  • Timer? recordTimer // 计时器,用来控制录音时长;

  • String timeString = "" // 用来做回显时长

  • List voicePlayList =[]; //用来控制语音播放列表

  • String voicePath = ""; //临时储存语音文件路径

初始化声音配置方法

dart 复制代码
  /*
   * @author Marinda
   * @date 2023/6/26 15:25
   * @description 初始化声音设置
   */
  initSoundSetting() async{
    await flutterSoundPlayer.openPlayer();
    await recordSound.openRecorder();
  }

录制用户语音

dart 复制代码
  /*
   * @author Marinda
   * @date 2023/6/26 15:31
   * @description 录音
   */
   recordSound() async{
    PermissionStatus status = await Permission.microphone.request();
    int time = 0;
    //权限校验
    if (status != PermissionStatus.granted) throw RecordingPermissionException("麦克风权限未授权!");
    var dir = await getExternalStorageDirectory();
    Uuid uuid = Uuid();
    String filePath = p.join(dir?.path ?? "",uuid.v4()+".mp4");
    File file = File(filePath);
    file.openWrite();
    state.voicePath.value = filePath;
    Log.i("录音保存的位置:${filePath}");
    await state.recordSound.startRecorder(
        //目标文件位置
        toFile: filePath,
        //这里可以认为是那种源
        codec: Codec.aacMP4,
        //采样率
        bitRate: 8000,
        //为1即可
        numChannels: 1
    );
  
    recordTimer = Timer.periodic(Duration(seconds: 1), (_) {
      time++;
      timeString = time.toString();
    });
  }

播放实现

dart 复制代码
  /*
   * @author Marinda
   * @date 2023/10/7 14:28
   * @description 播放语音信息 目前先做本地语音缓存处理
   */
  playVoice(String voiceUrl) async{
    Uint8List uint8list = Uint8List(0);
    //视为网络http
    if(voiceUrl.startsWith("http")){
      uint8list = ...获取MP4文件二进;
    }else{
      File voiceFile = File(voiceUrl);
      //如果不存在
      if(!voiceFile.existsSync()){
        BotToast.showText(text: "语音播放失败");
        return;
      }
      uint8list  = await voiceFile.readAsBytes();
    }

    //如果存在则进行移除播放
    if(voicePlayList.contains(tag)){
      voicePlayList.remove(tag);
      await flutterSoundPlayer.stopPlayer();
      return;
    }
    //加入语音信息队列
    voicePlayList.add(tag);
 
    await flutterSoundPlayer.startPlayer(
      fromURI: data.expandAddress,
      fromDataBuffer: uint8list,
      codec: Codec.aacMP4,
      sampleRate: 8000,
        numChannels: 1,
      whenFinished: (){
      //  播放完毕
        state.voicePlayList.remove(tag);
      }
    );
  }

结束录制

dart 复制代码
  /*
   * @author Marinda
   * @date 2023/6/26 15:33
   * @description
   */
  stopRecordSound() async{
    await recordSound.stopRecorder();
    if(recordTimer!.isActive){
      recordTimer!.cancel();
      recordTimer = null;
    }
    // 这里实现你的语音消息发送逻辑
    Log.i("停止录制!");
    timeString.value = "";
    voicePath.value = "";
  }

结束语

难度不大,主要是围绕着录音文件进行处理

值得注意的点是在播放录音文件时

记得获取目标的二进制流一并携带至startPlayer方法fromDataBuffer字段中

否则可能会出现无法播放或程序未响应等危险情况!

感谢你的观看!

相关推荐
恋猫de小郭4 小时前
Flutter 官方 LLM 动态 UI 库 flutter_genui 发布,让 App UI 自己生成 UI
android·前端·flutter
守.护5 小时前
云计算学习笔记——HTTP服务、NFS服务篇
笔记·学习·云计算
tangweiguo030519875 小时前
FlutterActivity vs FlutterFragmentActivity:全面对比与最佳实践
android·flutter
wdfk_prog5 小时前
[Linux]学习笔记系列 -- lib/dump_stack.c 栈回溯打印(Stack Trace Dumping) 内核调试与错误诊断的基石
linux·运维·服务器·c语言·笔记·学习
ITKEY_5 小时前
flutter日期选择国际化支持
开发语言·javascript·flutter
i.ajls5 小时前
无监督学习,推荐系统以及强化学习笔记
笔记·学习·机器学习
农夫三拳_有点甜5 小时前
Flutter SystemChrome 完整指南
flutter
葱段5 小时前
【Flutter】TextField 监听长按菜单粘贴点击事件
android·flutter·dart
聆风吟º6 小时前
【Spring Boot 报错已解决】Web server failed to start. Port 8080 was already in use.
spring boot·笔记·技术干货
Suckerbin6 小时前
LAMPSecurity: CTF6靶场渗透
笔记·安全·web安全·网络安全