Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

uploading audio web by MultipartFile #278

Closed
tas-unn opened this issue Jan 23, 2024 · 6 comments
Closed

uploading audio web by MultipartFile #278

tas-unn opened this issue Jan 23, 2024 · 6 comments

Comments

@tas-unn
Copy link

tas-unn commented Jan 23, 2024

I have not received a response, my issues are closed without answer (262,267)

Package version
5.0.3

Environment
Windows 10 Pro

Describe the bug

how to upload a file via dio that was recorded via web?

const encoder = AudioEncoder.wav;
const config = RecordConfig(encoder: encoder);

To Reproduce

Steps to reproduce the behavior:

  1. took an example from the site

  2. Changed the config

  3. Added dio package

  4. Commented out the write to the file, uncommented the write to the stream

  5. in audio_recorder.dart file after line:
    Amplitude? _amplitude;
    i've added
    List? mybytes;
    and
    // Record to stream
    // await recordStream(_audioRecorder, config);
    replaced by
    mybytes= await recordStream(_audioRecorder, config);
    and on _stop()
    var formData=FormData();
    formData.files.add(MapEntry(
    "message_bytes",
    MultipartFile.fromBytes(
    mybytes!.cast())));
    var response = await Dio().post(
    "https://my.site/sendtest.php",
    data: formData,
    );

  6. The sent data contains some bytes (the array is not empty), but the file is broken

Expected behavior

successful file upload

Additional context

@MannaYang
Copy link

@tas-unn
I got the same error, but now i use record to recording a whole file in my project and then upload it . You should care and control the recording time.

ChatGPT-Flutter-Web

The source use code in here :

void startRecord(WidgetRef ref, bool state, int configValue) async {
    if (!checkMultiModalStatus(ref, configValue)) return;
    if (state) {
      ///
      /// Important Note:
      /// ```
      /// final path = await recorder.stop();
      /// ```
      /// only support web, if you use it not in web, please get the actual file
      /// pub lib:[https://pub.dev/packages/record]
      ///
      final path = await recorder.stop();
      if (path == null) {
        ref.read(allowRecordProvider.notifier).updateStatus(false);
        return;
      }
      final result = await http.get(Uri.parse(path));
      ref.read(uploadFileProvider.notifier).uploadFileUrl(result.bodyBytes);
      ref.read(allowRecordProvider.notifier).updateStatus(false);
      return;
    }
    if (await recorder.hasPermission()) {
      await recorder.start(const RecordConfig(encoder: AudioEncoder.wav),
          path: "");
    }
    ref.read(allowRecordProvider.notifier).updateStatus(true);
  }

@llfbandit
Copy link
Owner

Again... @tas-unn, you can't stream wav as I answered before.
Uploading issue is unrelated to this package. Follow @MannaYang guidance or use cross_file package to retrieve the content of the blob.

@AliKarimiENT
Copy link

Could you please sure the related link to @MannaYang guidance for us?

@MannaYang
Copy link

Could you please sure the related link to @MannaYang guidance for us?

@AliKarimiENT

Hello, my source code in here, you can use it as a reference :

Project : ChatGPT-Flutter-Web

Data flow is : UI(click) - Provider(state) - Repository(parse) - HttpRequest(handle)

With audio recording :

multi_modal_audio.dart

void startRecord(WidgetRef ref, bool state, int configValue) async {
    if (!checkMultiModalStatus(ref, configValue)) return;
    if (state) {
      ///
      /// Important Note:
      /// ```
      /// final path = await recorder.stop();
      /// ```
      /// only support web, if you use it not in web, please get the actual file
      /// pub lib:[https://pub.dev/packages/record]
      ///
      final path = await recorder.stop();
      if (path == null) {
        ref.read(allowRecordProvider.notifier).updateStatus(false);
        return;
      }
      final result = await http.get(Uri.parse(path));
      ref.read(uploadFileProvider.notifier).uploadFileUrl(result.bodyBytes);
      ref.read(allowRecordProvider.notifier).updateStatus(false);
      return;
    }
    if (await recorder.hasPermission()) {
      await recorder.start(const RecordConfig(encoder: AudioEncoder.wav),
          path: "");
    }
    ref.read(allowRecordProvider.notifier).updateStatus(true);
  }

With file provider :

file_provider.dart

///
  /// Upload audio
  ///
  Future<void> uploadFileUrl(Uint8List data) async {
    try {
      state =
          FileUpload(code: StatusProvider.state_1, msg: t.app.uploading);
      await ref
          .read(fileRepositoryProvider.notifier)
          .uploadFileUrl("audio.wav", data, (data) {
        final code = data['code'];
        final msg = data['msg'];
        if (code != 0) {
          state = FileUpload(code: code, msg: msg);
          return;
        }
        var temp = FileInfo.fromJson(data['data']);
        state = FileUpload(code: StatusProvider.state_0, msg: msg, data: temp);
      });
    } catch (e) {
      state = FileUpload(code: StatusProvider.stateDefault, msg: e.toString());
    }
  }

With file repository :

file_repository.dart

///
  /// Upload audio
  ///
  Future uploadFileUrl(String fileName, Uint8List data,
      Function(Map<String, dynamic> parans) onUpload) async {
    try {
      var uri = Uri.http(ApiProvider.backendUrl, 'api/llm/v1/file/upload');
      final response = await ref
          .read(httpRequestProvider.notifier)
          .multipartFileUrl(uri, fileName, data);
      await for (var data in response.stream.transform(utf8.decoder)) {
        Logger().d('data = $data');
        final result = jsonDecode(data);
        onUpload(result);
      }
    } catch (e) {
      onUpload({'msg': 'File upload error = $e', 'code': -1});
    }
  }

With http request :

http_provider.dart

///
  /// http - multipartFile bytes
  ///
  Future<http.StreamedResponse> multipartFileUrl(
    Uri url,
    String fileName,
    Uint8List? bytes, {
    int timeout = _fileTime,
  }) async {
    var file = http.MultipartFile.fromBytes('files', bytes as List<int>,
        filename: fileName);
    var request = http.MultipartRequest('POST', url)
      ..headers.addAll({'Authorization': _latestToken})
      ..files.add(file);
    var response = request.send().timeout(_timeout(timeout));
    return _handleStreamResponse(response);
  }

@AliKarimiENT
Copy link

@MannaYang thanks for your help
For the web is the same code and it will work on the web too?

@MannaYang
Copy link

@MannaYang thanks for your help
For the web is the same code and it will work on the web too?

@AliKarimiENT Yes,try it now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants