Skip to content

Commit

Permalink
Added ResolvingAudioSource
Browse files Browse the repository at this point in the history
From the PR ryanheise#800
  • Loading branch information
Jorge-Anton authored May 31, 2024
1 parent cb70aa4 commit 925e751
Showing 1 changed file with 83 additions and 0 deletions.
83 changes: 83 additions & 0 deletions just_audio/lib/just_audio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2832,6 +2832,89 @@ abstract class StreamAudioSource extends IndexedAudioSource {
id: _id, uri: _uri.toString(), headers: null, tag: tag);
}

typedef ResolveSoundUrl = Future<Uri?> Function(String uniquidId);

//An [AudioSource] likes [UriAudioSource] but resolve http url in time.
class ResolvingAudioSource extends StreamAudioSource {
final String uniqueId;
final ResolveSoundUrl resolveSoundUrl;
final Map<String, String>? headers;

var _hasRequestedSoundUrl = false;
final _soundUrlCompleter = Completer<Uri?>();

Future<Uri?> get _soundUrl => _soundUrlCompleter.future;

HttpClient? _httpClient;

HttpClient get httpClient => _httpClient ?? (_httpClient = HttpClient());

ResolvingAudioSource(
{required this.uniqueId,
required this.resolveSoundUrl,
this.headers,
dynamic tag})
: super(tag: tag);

@override
Future<StreamAudioResponse> request([int? start, int? end]) async {
if (!_hasRequestedSoundUrl) {
_hasRequestedSoundUrl = true;
final soundUrl = await resolveSoundUrl(uniqueId);
_soundUrlCompleter.complete(soundUrl);
}
final soundUrl = await _soundUrl;
if (soundUrl == null) {
return StreamAudioResponse(
sourceLength: null,
contentLength: null,
offset: null,
stream: const Stream.empty(),
contentType: '');
}
final request = await httpClient.getUrl(soundUrl);
for (var entry in headers?.entries ?? <MapEntry<String, String>>[]) {
request.headers.set(entry.key, entry.value);
}
if (_player?._userAgent != null) {
request.headers.set(HttpHeaders.userAgentHeader, _player!._userAgent!);
}
if (start != null || end != null) {
request.headers
.set(HttpHeaders.rangeHeader, 'bytes=${start ?? ""}-${end ?? ""}');
}
final response = await request.close();
final acceptRangesHeader =
response.headers.value(HttpHeaders.acceptRangesHeader);
final contentRange = response.headers.value(HttpHeaders.contentRangeHeader);
int? offset;
if (contentRange != null) {
int offsetEnd = contentRange.indexOf('-');
if (offsetEnd >= 6) {
offset = int.tryParse(contentRange.substring(6, offsetEnd));
}
}
final contentLength =
response.headers.value(HttpHeaders.contentLengthHeader);
final contentType = response.headers.value(HttpHeaders.contentTypeHeader);
return StreamAudioResponse(
rangeRequestsSupported:
acceptRangesHeader != null && acceptRangesHeader != 'none',
sourceLength: null,
contentLength:
contentLength == null ? null : int.tryParse(contentLength),
offset: offset,
stream: response.asBroadcastStream(),
contentType: contentType ?? "");
}

@override
AudioSourceMessage _toMessage() {
return ProgressiveAudioSourceMessage(
id: _id, uri: _uri.toString(), headers: headers, tag: tag);
}
}

/// The response for a [StreamAudioSource]. This API is experimental.
@experimental
class StreamAudioResponse {
Expand Down

0 comments on commit 925e751

Please sign in to comment.