Advertisement
DVS_studio

Untitled

Mar 6th, 2024 (edited)
628
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 4.07 KB | None | 0 0
  1. // ignore_for_file: avoid_web_libraries_in_flutter
  2.  
  3. import 'dart:async';
  4. import 'dart:html';
  5. import 'dart:js_util';
  6. import 'dart:typed_data';
  7.  
  8. import 'package:dio/dio.dart';
  9. import 'package:flutter/material.dart';
  10. import 'package:flutter/services.dart';
  11. import 'package:js/js.dart';
  12.  
  13. @JS('getWaveBlob')
  14. external Blob toWav(Blob blob);
  15.  
  16. final dio = Dio();
  17.  
  18. class _Recorder {
  19.   MediaRecorder? _mediaRecorder;
  20.   List<Blob>? _audioBlobParts;
  21.   String? _recordingUrl;
  22.  
  23.   Future<void> init() async {
  24.     assert(_mediaRecorder == null);
  25.  
  26.     final stream = await window.navigator.mediaDevices?.getUserMedia({'audio': true});
  27.     if (stream == null) return;
  28.     _mediaRecorder = MediaRecorder(stream);
  29.  
  30.     _audioBlobParts = [];
  31.     _mediaRecorder!.addEventListener('dataavailable', _onDataAvailable);
  32.   }
  33.  
  34.   void _onDataAvailable(Event event) {
  35.     final blobEvent = event as BlobEvent;
  36.     _audioBlobParts!.add(blobEvent.data!);
  37.   }
  38.  
  39.   Future<void> start() async {
  40.     assert(_mediaRecorder != null);
  41.  
  42.     _mediaRecorder!.start();
  43.   }
  44.  
  45.   /// Stops the recorder and returns an URL pointing to the recording.
  46.   Future<String> stop() async {
  47.     assert(_mediaRecorder != null);
  48.  
  49.     final completer = Completer<String>();
  50.  
  51.     Future<void> onStop(_) async {
  52.       assert(_audioBlobParts != null);
  53.  
  54.       final blob = Blob(_audioBlobParts!);
  55.       _audioBlobParts = null;
  56.       final newBlob = await promiseToFuture<Blob>(toWav(blob));
  57.       completer.complete(Url.createObjectUrl(newBlob));
  58.     }
  59.  
  60.     _mediaRecorder!.addEventListener('stop', onStop);
  61.     _mediaRecorder!.stop();
  62.     _recordingUrl = await completer.future;
  63.     _mediaRecorder!.removeEventListener('stop', onStop);
  64.  
  65.     return _recordingUrl!;
  66.   }
  67.  
  68.   Future<Uint8List> toBytes() async {
  69.     assert(_recordingUrl != null);
  70.  
  71.     final result = await Dio().get(_recordingUrl!, options: Options(responseType: ResponseType.bytes));
  72.     return result.data;
  73.   }
  74.  
  75.   void dispose() {
  76.     assert(_mediaRecorder != null);
  77.  
  78.     _mediaRecorder!.removeEventListener('dataavailable', _onDataAvailable);
  79.     _mediaRecorder = null;
  80.   }
  81. }
  82.  
  83. void main() {
  84.   runApp(const MicrophoneExampleApp());
  85. }
  86.  
  87. class MicrophoneExampleApp extends StatefulWidget {
  88.   const MicrophoneExampleApp({super.key});
  89.   @override
  90.   State<MicrophoneExampleApp> createState() => _MicrophoneExampleAppState();
  91. }
  92.  
  93. class _MicrophoneExampleAppState extends State<MicrophoneExampleApp> {
  94.   _Recorder? _recorder;
  95.  
  96.   @override
  97.   void dispose() {
  98.     _recorder?.dispose();
  99.     super.dispose();
  100.   }
  101.  
  102.   Future<void> _initRecorder() async {
  103.     _recorder?.dispose();
  104.     await window.navigator.permissions?.query({'name': 'microphone'});
  105.     _recorder = _Recorder();
  106.     await _recorder!.init();
  107.   }
  108.  
  109.   @override
  110.   Widget build(BuildContext context) {
  111.     return MaterialApp(
  112.       home: Scaffold(
  113.         body: Row(
  114.           children: [
  115.             OutlinedButton(
  116.               onPressed: _initRecorder,
  117.               child: const Text('Restart recorder'),
  118.             ),
  119.             OutlinedButton(
  120.               onPressed: () {
  121.                 _recorder?.start();
  122.               },
  123.               child: const Text('Start recording'),
  124.             ),
  125.             OutlinedButton(
  126.               onPressed: () => _recorder?.stop(),
  127.               child: const Text('Stop recording'),
  128.             ),
  129.             OutlinedButton(
  130.               onPressed: send,
  131.               child: const Text('Stop recording'),
  132.             ),
  133.           ],
  134.         ),
  135.       ),
  136.     );
  137.   }
  138.  
  139.   Future<void> send() async {
  140.     final bytes = await _recorder!.toBytes();
  141.     final resp3 = await dio.post(
  142.       'https://api.openai.com/v1/audio/transcriptions',
  143.       data: FormData.fromMap({
  144.         'model': 'whisper-1',
  145.         'file': MultipartFile.fromBytes(bytes.toList(), filename: 'file.wav'),
  146.       }),
  147.       options: Options(
  148.         headers: {
  149.           'Content-Type': 'multipart/form-data',
  150.           'Authorization': 'Bearer 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',
  151.         },
  152.       ),
  153.     );
  154.     print(resp3);
  155.   }
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement