audioplayers
audioplayers copied to clipboard
Add headers parameters in audio playerscontroller.play() function to GET the url with the good headers (authorization )
There is no possibility to add headers in the play() function. I love this project but without it I am getting 403 errors from because the JWT Authorization cannot be sent.
It would be great to have a headers parameters in the play function, because there is a lot of APIs that request headers like authorization application-type, ...
This is the error shown by your your package :
I/MediaHTTPConnection(24565): response code = 403
E/MediaHTTPConnection(24565): java.io.IOException
E/MediaHTTPConnection(24565): at android.media.MediaHTTPConnection.seekTo(MediaHTTPConnection.java:389)
E/MediaHTTPConnection(24565): at android.media.MediaHTTPConnection.getMIMEType(MediaHTTPConnection.java:499)
E/MediaHTTPConnection(24565): at android.media.IMediaHTTPConnection$Stub.onTransact(IMediaHTTPConnection.java:161)
E/MediaHTTPConnection(24565): at android.os.Binder.execTransactInternal(Binder.java:1220)
E/MediaHTTPConnection(24565): at android.os.Binder.execTransact(Binder.java:1179)
W/MediaHTTPConnection(24565): request failed with error => 403
V/MediaPlayerNative(24565): message received msg=100, ext1=1, ext2=-1005
E/MediaPlayerNative(24565): error (1, -1005)
E/MediaPlayer(24565): Error (1,-1005)
The package received this error because the server expect to receive in the request the headers:
{
...
"Authorization": jwtString
...
}
You should add an optional <Map>headers parameter to your play() function, and add the headers map when you make the get url request.
Example:
AudioPlayer audioPlayer = AudioPlayer();
audioPlayer
.play(
widget.msg.content["url"],
isLocal: false,
headers: {},
),
.onError((error, stackTrace) {
print(error);
return 0;
});
audioPlayer.onPlayerCompletion.listen((event) {
audioPlayer.dispose();
});
This should be implemented in each platform because it's an easy fix (headers is always propose with get, post ... requests), and other people will need it. But it my case it's only Android, Web and iOS.
I hope you will be able to add this little fix because this headers parameter is mandatory for us and we cannot use your package without it. Take care.
For people who need the headers, I have created a temporary solution to wait for this urgent feature. But you have to cache the file to give it to the audio player as a file, but it is not nice to do it this way. I don't recommend using this feature in production because of the file saved on the user's phone.
When you start the audio player, add this:
AudioPlayer? audioPlayer = null;
File? tempFile = null;
@override
void initState() {
print("init state");
super.initState();
audioPlayer = AudioPlayer();
if (audioPlayer != null && url != null && url != "") {
cacheVoc(widget.msg.content["url"]);
// CANNOT USE THE FOLLOWING BECAUSE NO HEADERS PARAMETER CAN BE GIVEN
// widget.audioPlayer
// .play(widget.msg.content["url"], isLocal: false)
// .onError((error, stackTrace) {
// print(error);
// return 0;
// });
}
}
Then define the cache function:
void cacheVoc(String url) async {
get(Uri.parse(url), headers: await getHttpHeader()).then((Response response) {
Uint8List bytes = response.bodyBytes;
tempFile = File("${widget.appDirectory?.path}/${appname}/audio/temp/${DateTime.now().microsecondsSinceEpoch}.wav");
if (response.statusCode == 200 && tempFile != null) {
tempFile!.create(recursive: true).then((File createdFileDescriptor) {
tempFile = createdFileDescriptor;
if (tempFile != null) {
tempFile!.writeAsBytes(bytes).then((_) {
if (mounted) {
widget.audioPlayer.play(tempFile!.path, isLocal: true)
.onError((error, stackTrace) {
print(error);
return 0;
});
}
});
}
});
}
});
}
And delete the file when it is no more needed:
@override
void dispose() {
if (tempFile != null && tempFile!.existsSync()) {
tempFile?.delete();
}
super.dispose();
}
For an urgent production repair, consider migrating => just_audio From just_audio README
var duration = await player.setUrl(
"https://foo.com/bar.mp3",
headers: {
"header1": "value1",
"header2": "value2"
}
);
It's an open source project. Feel free to fork and try to implement it :) I think it's a very special use case, which is not high priority :/
See #129