Flutter Web 录制音频以流式传输

Posted

技术标签:

【中文标题】Flutter Web 录制音频以流式传输【英文标题】:Flutter Web Record Audio to Stream 【发布时间】:2021-05-23 10:30:07 【问题描述】:

我正在开发一个涉及 Speech to Text 组件的 Flutter Web 项目。我打算使用 Google 的 Speech to Text API (https://cloud.google.com/speech-to-text/docs)。我的关键要求之一是使用 API 的单一话语功能来识别说话者何时自动完成讲话。这要求我将音频从 Flutter 客户端直接流式传输到 Google 的 API,以便我可以接收该事件并对其进行处理。我正在使用 google_speech dart 插件 (https://pub.dev/packages/google_speech),并且相当肯定它会满足我的需求。

我正在努力寻找一种可以成功将音频录制到流中的实现,然后我可以将其发送到在 Flutter Web 中工作的 Google。

到目前为止,我唯一找不到似乎满足我需求的插件是 flutter_sound (https://pub.flutter-io.cn/packages/flutter_sound) 插件,因为它声称支持 Flutter Web,并且似乎能够在不使用 dart Stream 的情况下录制文件。我有一个初始实现,但由于库似乎挂起,我似乎在某处遗漏了一些东西。

这是我目前的实现:

class _LandingPageState extends State<LandingPage> 
  FlutterSoundRecorder _mRecorder = FlutterSoundRecorder();

  String _streamText = 'not yet recognized';

  _LandingPageState(this.interviewID);

  @override
  Widget build(BuildContext context) 
    //Build method works fine
  

  // Called elsewhere to start the recognition
  _submit() async 
   // Do some stuff
    await recognize();
   // Do some other stuff
  

  Future recognize() async 
    // Set up the Google Speech (google_speech plugin) recongition apparatus
    String serviceAccountPath = await rootBundle
        .loadString('PATH TO MY SERVICE ACCOUNT CREDENTIALS');
    final serviceAccount = ServiceAccount.fromString(serviceAccountPath);
    final speechToText = SpeechToText.viaServiceAccount(serviceAccount);
    final config = _getConfig();

    // Create the stream controller (flutter_sound plugin)
    StreamController recordingDataController = StreamController<Food>();

    // Start the recording and specify what stream sink it is using
    // which is the above stream controller's sink
    await _mRecorder.startRecorder(
      toStream: recordingDataController.sink,
      codec: Codec.pcm16,
      numChannels: 1,
      sampleRate: 44000,
    );

    // Set up the recognition stream and pass it the stream
    final responseStream = speechToText.streamingRecognize(
      StreamingRecognitionConfig(
        config: config,
        interimResults: true,
        singleUtterance: true,
      ),
      recordingDataController.stream,
    );

    responseStream.listen((data) 
      setState(() 
        _streamText =
            data.results.map((e) => e.alternatives.first.transcript).join('\n');
      );
    , onDone: () 
      setState(() 
        print("STOP LISTENING");
        print("STREAM TEXT = ");
        print("--------------------------------------");
        print(_streamText);
        print("--------------------------------------");
        // Stop listening to the mic
        recordingDataController.close();
      );
    );
  

  init() async 
    await Future.delayed(Duration(seconds: 1));
    await _sumbit();
  

  @override
  void initState() 
    super.initState();
    _openRecorder();
  

  @override
  void dispose() 
    super.dispose();
    _stopRecorder();
  

  RecognitionConfig _getConfig() => RecognitionConfig(
      encoding: AudioEncoding.LINEAR16,
      model: RecognitionModel.basic,
      enableAutomaticPunctuation: true,
      sampleRateHertz: 16000,
      languageCode: 'en-US');

  Future<void> _openRecorder() async 
    // These Permission calls dont seem to work on Flutter web 
    // var status = await Permission.microphone.request();
    // if (status != PermissionStatus.granted) 
    //   throw RecordingPermissionException('Microphone permission not granted');
    // 
    await _mRecorder.openAudiosession();
  

  Future<void> _stopRecorder() async 
    await _mRecorder.stopRecorder();
  


当它被调试时,库在启动记录器时挂起并声明“等待记录器被打开”,但它只是一直在那里等待。我试图调试该库,但目前还不清楚发生了什么。我担心这个库毕竟不支持 Flutter Web。会不会是因为没有授予麦克风权限导致库挂了?

我一直在使用这个例子来实现 flutter_sound:https://github.com/Canardoux/tau/blob/master/flutter_sound/example/lib/recordToStream/record_to_stream_example.dart

是否有其他库或方法支持将音频录制到 Flutter web 中的 dart 流?

【问题讨论】:

【参考方案1】:

问题是要录制到流媒体,您必须使用 PCM16 编解码器,但此编解码器不兼容在浏览器中录制音频。可以查看相关文档https://tau.canardoux.xyz/guides_codec.html

【讨论】:

你能推荐一个替代方案吗? 我正在寻找像您一样的解决方案。谁先找到它就说;)

以上是关于Flutter Web 录制音频以流式传输的主要内容,如果未能解决你的问题,请参考以下文章

从 nodejs 录制音频和流式传输到客户端

将音频记录从浏览器流式传输到服务器?

如何以 mp3 格式从麦克风流式传输声音?

Android:使用 AudioTrack 和 Socket 手动有效地流式传输音频

从 MIC 录制并流式传输到 TCP 服务器; MediaRecorder:启动失败:-38

流式传输实时音频