Skip to content

Commit

Permalink
Add timeoutMillis parameter to UriAudioSource (including Android impl…
Browse files Browse the repository at this point in the history
… change to respect it)
  • Loading branch information
Cris committed Dec 26, 2024
1 parent e0e2b19 commit 6f1b3a9
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 17 deletions.
5 changes: 5 additions & 0 deletions just_audio/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.9.44

* Add timeoutMillis parameter to UriAudioSource (@ctedgar).
* Android platform implementation completed

## 0.9.43

* Fix NPE in load on iOS/macOS.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -615,20 +615,20 @@ private MediaSource decodeAudioSource(final Object json) {
String id = (String)map.get("id");
switch ((String)map.get("type")) {
case "progressive":
return new ProgressiveMediaSource.Factory(buildDataSourceFactory(mapGet(map, "headers")), buildExtractorsFactory(mapGet(map, "options")))
return new ProgressiveMediaSource.Factory(buildDataSourceFactory(mapGet(map, "headers"), mapGet(map, "timeoutMillis")), buildExtractorsFactory(mapGet(map, "options")))
.createMediaSource(new MediaItem.Builder()
.setUri(Uri.parse((String)map.get("uri")))
.setTag(id)
.build());
case "dash":
return new DashMediaSource.Factory(buildDataSourceFactory(mapGet(map, "headers")))
return new DashMediaSource.Factory(buildDataSourceFactory(mapGet(map, "headers"), mapGet(map, "timeoutMillis")))
.createMediaSource(new MediaItem.Builder()
.setUri(Uri.parse((String)map.get("uri")))
.setMimeType(MimeTypes.APPLICATION_MPD)
.setTag(id)
.build());
case "hls":
return new HlsMediaSource.Factory(buildDataSourceFactory(mapGet(map, "headers")))
return new HlsMediaSource.Factory(buildDataSourceFactory(mapGet(map, "headers"), mapGet(map, "timeoutMillis")))
.createMediaSource(new MediaItem.Builder()
.setUri(Uri.parse((String)map.get("uri")))
.setMimeType(MimeTypes.APPLICATION_M3U8)
Expand Down Expand Up @@ -709,7 +709,7 @@ private void clearAudioEffects() {
audioEffectsMap.clear();
}

private DataSource.Factory buildDataSourceFactory(Map<?, ?> headers) {
private DataSource.Factory buildDataSourceFactory(Map<?, ?> headers, Integer timeoutMillis) {
final Map<String, String> stringHeaders = castToStringMap(headers);
String userAgent = null;
if (stringHeaders != null) {
Expand All @@ -727,6 +727,11 @@ private DataSource.Factory buildDataSourceFactory(Map<?, ?> headers) {
if (stringHeaders != null && stringHeaders.size() > 0) {
httpDataSourceFactory.setDefaultRequestProperties(stringHeaders);
}
//Default for both timeout setting is 8 seconds, so using timeoutMillis to control both
if(timeoutMillis!=null){
httpDataSourceFactory.setConnectTimeoutMs(timeoutMillis);
httpDataSourceFactory.setReadTimeoutMs(timeoutMillis);
}
return new DefaultDataSource.Factory(context, httpDataSourceFactory);
}

Expand Down
40 changes: 29 additions & 11 deletions just_audio/lib/just_audio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -681,20 +681,21 @@ class AudioPlayer {
/// This is equivalent to:
///
/// ```
/// setAudioSource(AudioSource.uri(Uri.parse(url), headers: headers, tag: tag),
/// setAudioSource(AudioSource.uri(Uri.parse(url), headers: headers, timeoutMillis: timeoutMillis, tag: tag),
/// initialPosition: Duration.zero, preload: true);
/// ```
///
/// See [setAudioSource] for a detailed explanation of the options.
Future<Duration?> setUrl(
String url, {
Map<String, String>? headers,
int? timeoutMillis,
Duration? initialPosition,
bool preload = true,
dynamic tag,
}) =>
setAudioSource(
AudioSource.uri(Uri.parse(url), headers: headers, tag: tag),
AudioSource.uri(Uri.parse(url), headers: headers, timeoutMillis: timeoutMillis, tag: tag),
initialPosition: initialPosition,
preload: preload);

Expand Down Expand Up @@ -2232,17 +2233,20 @@ abstract class AudioSource {
/// provided by that package. If you wish to have more control over the tag
/// for background audio purposes, consider using the plugin audio_service
/// instead of just_audio_background.
///
/// [timeoutMillis] can be used to adjust http connection timeout settings
/// (currently only supported for Android)
static UriAudioSource uri(Uri uri,
{Map<String, String>? headers, dynamic tag}) {
{Map<String, String>? headers, int? timeoutMillis, dynamic tag}) {
bool hasExtension(Uri uri, String extension) =>
uri.path.toLowerCase().endsWith('.$extension') ||
uri.fragment.toLowerCase().endsWith('.$extension');
if (hasExtension(uri, 'mpd')) {
return DashAudioSource(uri, headers: headers, tag: tag);
return DashAudioSource(uri, headers: headers, timeoutMillis: timeoutMillis, tag: tag);
} else if (hasExtension(uri, 'm3u8')) {
return HlsAudioSource(uri, headers: headers, tag: tag);
return HlsAudioSource(uri, headers: headers, timeoutMillis: timeoutMillis, tag: tag);
} else {
return ProgressiveAudioSource(uri, headers: headers, tag: tag);
return ProgressiveAudioSource(uri, headers: headers, timeoutMillis: timeoutMillis, tag: tag);
}
}

Expand Down Expand Up @@ -2329,9 +2333,10 @@ abstract class IndexedAudioSource extends AudioSource {
abstract class UriAudioSource extends IndexedAudioSource {
final Uri uri;
final Map<String, String>? headers;
final int? timeoutMillis;
Uri? _overrideUri;

UriAudioSource(this.uri, {this.headers, dynamic tag, Duration? duration})
UriAudioSource(this.uri, {this.headers, this.timeoutMillis, dynamic tag, Duration? duration})
: super(tag: tag, duration: duration);

/// If [uri] points to an asset, this gives us [_overrideUri] which is the URI
Expand Down Expand Up @@ -2423,12 +2428,16 @@ abstract class UriAudioSource extends IndexedAudioSource {
///
/// If headers are set, just_audio will create a cleartext local HTTP proxy on
/// your device to forward HTTP requests with headers included.
///
/// [timeoutMillis] can be used to adjust http connection timeout settings
/// (currently only supported for Android)
class ProgressiveAudioSource extends UriAudioSource {
final ProgressiveAudioSourceOptions? options;

ProgressiveAudioSource(
super.uri, {
super.headers,
super.timeoutMillis,
super.tag,
super.duration,
this.options,
Expand All @@ -2439,6 +2448,7 @@ class ProgressiveAudioSource extends UriAudioSource {
id: _id,
uri: _effectiveUri.toString(),
headers: _mergedHeaders,
timeoutMillis: timeoutMillis,
tag: tag,
options: options?._toMessage(),
);
Expand All @@ -2458,16 +2468,20 @@ class ProgressiveAudioSource extends UriAudioSource {
///
/// If headers are set, just_audio will create a cleartext local HTTP proxy on
/// your device to forward HTTP requests with headers included.
///
/// [timeoutMillis] can be used to adjust http connection timeout settings
/// (currently only supported for Android)
class DashAudioSource extends UriAudioSource {
DashAudioSource(Uri uri,
{Map<String, String>? headers, dynamic tag, Duration? duration})
: super(uri, headers: headers, tag: tag, duration: duration);
{Map<String, String>? headers, int? timeoutMillis, dynamic tag, Duration? duration})
: super(uri, headers: headers, timeoutMillis: timeoutMillis, tag: tag, duration: duration);

@override
AudioSourceMessage _toMessage() => DashAudioSourceMessage(
id: _id,
uri: _effectiveUri.toString(),
headers: _mergedHeaders,
timeoutMillis: timeoutMillis,
tag: tag,
);
}
Expand All @@ -2485,16 +2499,20 @@ class DashAudioSource extends UriAudioSource {
///
/// If headers are set, just_audio will create a cleartext local HTTP proxy on
/// your device to forward HTTP requests with headers included.
///
/// [timeoutMillis] can be used to adjust http connection timeout settings
/// (currently only supported for Android)
class HlsAudioSource extends UriAudioSource {
HlsAudioSource(Uri uri,
{Map<String, String>? headers, dynamic tag, Duration? duration})
: super(uri, headers: headers, tag: tag, duration: duration);
{Map<String, String>? headers, int? timeoutMillis, dynamic tag, Duration? duration})
: super(uri, headers: headers, timeoutMillis: timeoutMillis, tag: tag, duration: duration);

@override
AudioSourceMessage _toMessage() => HlsAudioSourceMessage(
id: _id,
uri: _effectiveUri.toString(),
headers: _mergedHeaders,
timeoutMillis: timeoutMillis,
tag: tag,
);
}
Expand Down
4 changes: 2 additions & 2 deletions just_audio/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: just_audio
description: A feature-rich audio player for Flutter. Loop, clip and concatenate any sound from any source (asset/file/URL/stream) in a variety of audio formats with gapless playback.
version: 0.9.43
version: 0.9.44
repository: https://github.com/ryanheise/just_audio/tree/minor/just_audio
issue_tracker: https://github.com/ryanheise/just_audio/issues
topics:
Expand All @@ -14,7 +14,7 @@ environment:
flutter: ">=3.10.0"

dependencies:
just_audio_platform_interface: ^4.3.0
just_audio_platform_interface: ^4.3.1
# just_audio_platform_interface:
# path: ../just_audio_platform_interface
just_audio_web: ^0.4.11
Expand Down
18 changes: 18 additions & 0 deletions just_audio/test/just_audio_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,20 @@ void runTests() {
exception = e;
}
expect(exception != null, equals(true));
try {
await player.setUrl('https://foo.foo/timeout.mp3');
exception = null;
} catch (e) {
exception = e;
}
expect(exception != null, equals(true));
try {
await player.setUrl('https://foo.foo/timeout.mp3', timeoutMillis: 11);
exception = null;
} catch (e) {
exception = e;
}
expect(exception == null, equals(true));
await player.dispose();
});

Expand Down Expand Up @@ -1479,6 +1493,10 @@ class MockAudioPlayer extends AudioPlayerPlatform {
throw PlatformException(code: '404', message: 'Not found');
} else if (audioSource.uri.contains('error')) {
throw PlatformException(code: 'error', message: 'Unknown error');
} else if (audioSource.uri.contains('timeout')){
if ((audioSource.timeoutMillis ?? 0) < 10) {
throw PlatformException(code: 'timeout', message: 'Timed out (because timeoutMillis setting is less than 10)');
}
}
_duration = audioSourceDuration;
} else if (audioSource is ClippingAudioSourceMessage) {
Expand Down

0 comments on commit 6f1b3a9

Please sign in to comment.