录制音频并将文件上传到 firebase 存储 Flutter Web

Sum*_*_VE 2 voice-recording flutter flutter-web

我正在使用flutter_sound包来录制和播放音频。在 Flutter Web 上,停止录制时,录制器会返回以下类型的路径/URL:blob:http://localhost:63986/b60f31ce-b94d-48c8-8a4a-2d939effe6d8

我想将录音上传到 Firebase Storage,但 dart.io 无法用于 flutter-web,因此无法使用 File 方法。即使经过搜索,我也没有找到实现它的方法。我不知道如何继续。如何将音频写入文件并将其上传到 firebase?

我的代码:

  import 'dart:html' as html;
  import 'dart:io' as io;

  final recorder = FlutterSoundRecorder();
  final player = FlutterSoundPlayer();
  String fileName;

  @override
  void initState() {
    super.initState();
    initRecorder();
  }

  @override
  void dispose() {
    recorder.closeRecorder();
    player.closePlayer();
    super.dispose();
  }

  Future<void> initRecorder() async {
    if (!kIsWeb) {
      final status = await Permission.microphone.request();
      if (status != PermissionStatus.granted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Grant Permission form mic first!')),
        );
      }
    }
    await recorder.openRecorder();
    await player.openPlayer();
    recorder.setSubscriptionDuration(Duration(milliseconds: 500));
  }

  Future<void> record() async {
    fileName = DateTime.now().toString();
    await recorder.startRecorder(toFile: fileName);
  }

  Future<void> stop() async {
    path = await recorder.stopRecorder();
    if (kIsWeb) {
      if (path == null) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Grant Permission for mic first!')),
        );
      } else {
        // Get File from path and upload it to Firebase

        print(path);
        // not working for Web
        // final audioFile = io.File(path);

        // html.File() doesn't take path/Url as parameter but
        // File(List<Object> fileBits, String fileName,[Map? options])

        /*
        await FirebaseStorage.instance
            .ref()
            .child('users/uploads/$fileName.mp3')
            .putData(file!.bytes!);*/
      }
    } else if (!kIsWeb) {
      if (path == null) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Grant Permission for mic first!')),
        );
      } else {
        //final audioFile = io.File(path);
        // await FirebaseStorage.instance
        //     .ref()
        //     .child('users/uploads/$fileName.mp3')
        //     .putFile(audioFile);
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

小智 6

我已经研究了好几天了,我终于弄清楚了!

当您调用时startRecorder(toFile: audioLocation)audioLocation将在您调用后的文件位置stopRecorder(),存储在html.window.sessionStoragehtmlimport 'dart:html' as html;)中。

因此,您需要添加import 'package:http/http.dart' as http;、创建一个fileName(无论您希望在 Firebase Storage 中调用该文件),然后插入以下代码段。

var ref = await storage.ref().child('path/to/file/$fileName');
Uri blobUri = Uri.parse(html.window.sessionStorage[audioFile]!);
http.Response response = await http.get(blobUri);
await ref.putData(response.bodyBytes, SettableMetadata(contentType: 'video/mp4'));
Run Code Online (Sandbox Code Playgroud)

这可能不是最好的方法,但这是我最终让它发挥作用的方法!祝你好运!!