Closed ReniDelonzek closed 3 years ago
I do not really understand your question. Downloading a file from internet is something probably easy, but has nothing to do with Flutter Sound. The file can be anything, maybe the picture of a cat, a sound, a video, ... This is not Flutter Sound job to download a remote file.
Sorry, I must have expressed myself badly.
What I need to do is retrieve the file recorded by flutter_sound using the command flutterSoundRecorder.startRecorder (toFile: path)
. This running in the browser (web flutter)
So, you record a file "path" (toFile: path). This file contains your recording, and you can upload it to your server.
Do I understand correctly ?
Yes. However, it is not possible to recover a file through its path on the web (because the file class comes from dart.io).
In the documentation it is mentioned that the file url on the web is saved in localStorage
the LocalSessionStorage key will contain the URL of the recorded object
However there is no mention of any way to recover this url or how to manipulate it
Whow! Do you mean that your are using Flutter Sound On Web ?
I did not understood that. Sorry.
Just a moment, please...
This thing is a little tricky, because Web App does not have access to a real storage. I am going back in a few minutes...
The answer is here.
But I agree that it is not very explicit how to retrieve the URI. I am going to do better doc, now. I will post you something when done. (1/2 hour ?)
Whow! Do you mean that your are using Flutter Sound On Web ?
Yes!
I will post you something when done. (1/2 hour ?)
Of course, I wait without problems
You can read this
Basically, if you specified "myPath" as the startRecorder() parameter, then you can retrieve the URI doing :
myUrl = window.localStorage['myPath'];
I do not remember well. Just that it was really easy. Please let me know if you succeed. And send me your proposal that could be inserted in τ documentation.
Okay, I will test this and put the result here. Thank you very much
Hello, I tried with the following code
String path = '_flutter_sound';
await recorderModule.openAudioSession();
await recorderModule.startRecorder(
toFile: path,
codec: codec,
numChannels: 1,
);
And
await recorderModule.stopRecorder();
await recorderModule.closeAudioSession();
var myPref = window.localStorage['_flutter_sound'];
print('URL: ${myPref}');
However the result produced by window.localStorage ['_ flutter_sound']; was null
I noticed that this may be related to the order of execution of the data, because moments later it was printed on the console
recorder stopped
URL: null
On data available : Blob flutter_sound_recorder.js:278
recorder stopped
recorder stopped It prints twice, once after calling recorderModule.stopRecorder(), and once, a while later
It may be relevant to mention that I tested it on the edge browser. From what I understand, it behaves a little differently in Chrome, but neither worked as expected
@ReniDelonzek ,
I am going to look to your issue in a few days (you are now near the top of the TODO stack 😉 ). I will finish to complete #590 and I will handle your issue. Perhaps I will create a new API verb to get the URL or erase the recorded object.
Patience...
Right. thanks
@ReniDelonzek ,
I am working on your issue.
I have decided that the instruction stopRecorder()
will return a future to the URI of the recorded object.
URL myURL = await myRecorder.stopRecorder();
But I want also that things are same on iOS and Android.
myRecorder.startRecorder(path: 'foo'); // 'foo' is not a valid path file, so a temporary file 'foo' will be created
...
URL myURL = await myRecorder.stopRecorder(); // Returns an URI to the temporary file
I create also two new verbs
myRecorder.deleteRecord('foo');
URL myURL = await myRecorder.getRecordURL('foo'); // not sure that it is necessary
This looks pretty good. The important thing is to maintain consistency in the way you work for both mobile and web.
Looking forward to testing!
Hi @ReniDelonzek ,
I did the improvements that you requested. It works fine on the three platforms :
I am currently rewriting asynchronous processing done by τ. This is a major change and tricky. After the changes, we will be able to do :
myPlayer.openAudioSession(); // no need to wait
myPlayer.startPlayer(...); // no need to wait anymore the end of `openAudioSession()`
Also if the app is waiting on something (for example) :
await myPlayer.pausePlayer();
and the app does for example :
await myPlayer.pausePlayer(); // another call to the same function
or worst :
myPlayer.stopPlayer();
The first call to pausePlayer
will receive an exception instead of being stuck for ever.
τ is in the middle of two asynchronous clients : the OS and the App. Managing asynchronous processing is really tough.
I must do many tests before doing any release. Probably in a few days. Thank you for your patience.
@ReniDelonzek ,
Flutter Sound 7.6.0 is released.
stopRecorder()
now returns the URL of the recorded file. see here.
It works on
Sorry for the delay. I hope that I am not too late for your own developments.
Hello, first of all thank you for your excellent work! I tried to test this on the web with:
path = '_flutter_sound_${DateTime.now().millisecondsSinceEpoch}';
await recorderModule.openAudioSession();
await recorderModule.startRecorder(
toFile: path,
codec: codec,
numChannels: 1,
);
and
String url = await recorderModule.stopRecorder();
print('url: ${url}');
However, recording never starts, and no error log is printed. Am I doing something wrong?
Which codec ?
Codec.opusWebM
Are you using chrome or firefox ? On witch device ? With chrome you can open the console with "More tools > Developer tools"
Hello, I am using Edge in MacOs
I am creating min example -> https://github.com/ReniDelonzek/flutter_example
My edge version -> 88.0.705.56 (64 bits)
Flutter Doctor
[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[✓] Xcode - develop for iOS and macOS
[✓] Chrome - develop for the web
[✓] Android Studio (version 3.5)
[✓] VS Code (version 1.52.1)
[✓] Connected device (4 available)
• No issues found!
Reni,
I really needs your logs to help you.
What logs can I provide for you? As I said, the application prints few logs, and no errors.
The only logs I have are the ones printed on the browser console:
FS:---> openAudioSession ---> openAudioSession flutter_sound_recorder.js:45 initializeFlautoRecorder main.dart.js:4741 <--- openAudioSession
I hosted my example on github pages, you can try it here
Hello @Larpoux, any predictions to look at this, or even some roadmap that I can follow?
OK reni, I am going look to your example on Github. I will post you something in a few hours.
Reni, I confirm that it seems that there is a big problem in τ for Flutter Web.
I am going to fix it this afternoon. Sorry for this inconvenience.
@ReniDelonzek ,
I fixed something in Flutter Sound on Web. But before doing a release, I would like to test your App. Could you post the sources ?
@Larpoux My original app is a little too big to share, but you can use the example I published, working on it I can port it to my
@ReniDelonzek ,
I fixed a little bug in version 7.6.7 .
Your index.html is not good. The correct includes are :
<script src="https://cdn.jsdelivr.net/npm/tau_sound_core@7.6.7/js/flutter_sound/flutter_sound.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tau_sound_core@7.6.7/js/flutter_sound/flutter_sound_player.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tau_sound_core@7.6.7/js/flutter_sound/flutter_sound_recorder.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/howler@2/dist/howler.min.js"></script>
I run your example with this modifications in index.html and it runs OK now.
Note: I must look how to specify version range instead of a specific version.
@Larpoux
I did a quick test here and it looks like it worked really well!
There was only one detail, that even after the stop the browser window continued to indicate that it is recording, is it because in my example I do not call .closeAudioSession ()
?
Thank you very much for your excellent work
Calling several time "openAudioSession" without any "closeAudioSession" is not OK. But I am not sure this explains your problem.
I am going to look to this now.
BTW:
<script src="https://cdn.jsdelivr.net/npm/tau_sound_core@7/js/flutter_sound/flutter_sound.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tau_sound_core@7/js/flutter_sound/flutter_sound_player.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tau_sound_core@7/js/flutter_sound/flutter_sound_recorder.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/howler@2/dist/howler.min.js"></script>
This seems ok, to accept a version range "7.x.x". But I think this is dangerous in production, because you will not be able to control the version which will be used by your customer. Probably you want to test/check that the version used by your customer works well with your App.
Yes, I added the full version to my dependencies so I don't have any problems with that.
Regarding the problem, if I'm not mistaken in previous versions the 'closeAudioSession' was called under the hood by stopRecorder, but it seems that this has been removed, so that may be the problem
I tested it here by calling closeAudioSession right after stopRecorder, but the recording indicator continues
floatingActionButton: FloatingActionButton(
onPressed: () async {
if (!recorderModule.isRecording) {
String path =
'_flutter_sound_${DateTime.now().millisecondsSinceEpoch}';
await recorderModule.openAudioSession();
await recorderModule.startRecorder(
toFile: path,
codec: Codec.opusWebM,
numChannels: 1,
);
} else {
String uri = await recorderModule.stopRecorder();
print(uri);
await recorderModule.closeAudioSession();
}
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
I do not see any problem : your button is a flip/flop : once it starts the recorder, and after it closes the recorder.
Note : in your real application, if you need to do several records, you will probably open the session during the initialization and not each time you startRecorder()
Note also that Flutter is doing multi-tasks : it is possible that your App calls two times your function very quickly and the recorder is not yet stopped the second time. In a real app, you probably need to disable your button, or something like that during the stopRecorder processing.
I tried this code, but the browser window still indicates it is recording, even after stopRecorder and closeAudioSession
My real use case will be a chat application. However, I believe that the audio focus must be requested and released between the audio recording, since when not recording, the user may want to use the focus for another application.
Note also that Flutter is doing multi-tasks : it is possible that your App calls two times your function very quickly and the recorder is not yet stopped the second time. In a real app, you probably need to disable your button, or something like that during the stopRecorder processing.
Yes, I will take this care in the actual application
By the way, I am curious how you can live with an App which does not work on iOS or Safari.
The current situation is really bad : we really must support webkit soon.
Almost none (or none) of my clients use safari as a browser, in any case it will not be difficult to guide you to use edge / chrome instead. I just need it to work well on these browsers
@Larpoux
I'm looking at this now and I couldn't understand how I can work with the returned url. Could you give me an example of how I get a List
Hello!
I've been working on it today. The correct way to retrieve a list of bytes (which was my original question) is with:
final result = await http.get(_recordingUrl);
return result.bodyBytes;
I came to this code looking at the example here
I tried this code, but the browser window still indicates it is recording, even after stopRecorder and closeAudioSession
Regarding this problem, I found out that it is a problem in your js code, I found this answer in the stackoverflow that indicates how to solve
Thank you very much for your patience!
With this merged PR solves the last problem. Thank you very much
I looked in the documentation but found nothing about it. I need the file / bit list to send the recording to the server