Skip to content

Commit

Permalink
Add MappingAudioSource with Web implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
hacker1024 committed Jul 23, 2022
1 parent 0e8376f commit fc9e498
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 6 deletions.
34 changes: 28 additions & 6 deletions just_audio/lib/just_audio.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2144,6 +2144,9 @@ abstract class IndexedAudioSource extends AudioSource {
@override
void _shuffle({int? initialIndex}) {}

@override
IndexedAudioSourceMessage _toMessage();

@override
List<IndexedAudioSource> get sequence => [this];

Expand Down Expand Up @@ -2245,7 +2248,7 @@ class ProgressiveAudioSource extends UriAudioSource {
: super(uri, headers: headers, tag: tag, duration: duration);

@override
AudioSourceMessage _toMessage() => ProgressiveAudioSourceMessage(
IndexedAudioSourceMessage _toMessage() => ProgressiveAudioSourceMessage(
id: _id, uri: _effectiveUri.toString(), headers: headers, tag: tag);
}

Expand All @@ -2269,7 +2272,7 @@ class DashAudioSource extends UriAudioSource {
: super(uri, headers: headers, tag: tag, duration: duration);

@override
AudioSourceMessage _toMessage() => DashAudioSourceMessage(
IndexedAudioSourceMessage _toMessage() => DashAudioSourceMessage(
id: _id, uri: _effectiveUri.toString(), headers: headers, tag: tag);
}

Expand All @@ -2292,7 +2295,7 @@ class HlsAudioSource extends UriAudioSource {
: super(uri, headers: headers, tag: tag, duration: duration);

@override
AudioSourceMessage _toMessage() => HlsAudioSourceMessage(
IndexedAudioSourceMessage _toMessage() => HlsAudioSourceMessage(
id: _id, uri: _effectiveUri.toString(), headers: headers, tag: tag);
}

Expand All @@ -2312,10 +2315,29 @@ class SilenceAudioSource extends IndexedAudioSource {
}) : super(tag: tag, duration: duration);

@override
AudioSourceMessage _toMessage() =>
IndexedAudioSourceMessage _toMessage() =>
SilenceAudioSourceMessage(id: _id, duration: duration);
}

class MappingAudioSource<T> extends IndexedAudioSource {
final T identifier;
final Future<IndexedAudioSource> Function(T identifier) createAudioSource;

MappingAudioSource(
this.identifier,
this.createAudioSource, {
dynamic tag,
Duration? duration,
}) : super(tag: tag, duration: duration);

@override
IndexedAudioSourceMessage _toMessage() => MappingAudioSourceMessage<T>(
id: _id,
createAudioSourceMessage: () => createAudioSource(identifier)
.then((audioSource) => audioSource._toMessage()),
);
}

/// An [AudioSource] representing a concatenation of multiple audio sources to
/// be played in succession. This can be used to create playlists. Playback
/// between items will be gapless on Android, iOS and macOS, while there will
Expand Down Expand Up @@ -2562,7 +2584,7 @@ class ClippingAudioSource extends IndexedAudioSource {
}

@override
AudioSourceMessage _toMessage() => ClippingAudioSourceMessage(
IndexedAudioSourceMessage _toMessage() => ClippingAudioSourceMessage(
id: _id,
child: child._toMessage() as UriAudioSourceMessage,
start: start,
Expand Down Expand Up @@ -2634,7 +2656,7 @@ abstract class StreamAudioSource extends IndexedAudioSource {
Future<StreamAudioResponse> request([int? start, int? end]);

@override
AudioSourceMessage _toMessage() => ProgressiveAudioSourceMessage(
IndexedAudioSourceMessage _toMessage() => ProgressiveAudioSourceMessage(
id: _id, uri: _uri.toString(), headers: null, tag: tag);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,26 @@ class SilenceAudioSourceMessage extends IndexedAudioSourceMessage {
};
}

/// Information about a mapping audio source to be communicated with the
/// platform implementation.
class MappingAudioSourceMessage<T> extends IndexedAudioSourceMessage {
/// The closure can only be used by platform implementations that pass by
/// reference.
final Future<IndexedAudioSourceMessage> Function() createAudioSourceMessage;

MappingAudioSourceMessage({
required String id,
required this.createAudioSourceMessage,
dynamic tag,
}) : super(id: id, tag: tag);

@override
Map<dynamic, dynamic> toMap() => <dynamic, dynamic>{
'type': 'mapping',
'id': id,
};
}

/// Information about a concatenating audio source to be communicated with the
/// platform implementation.
class ConcatenatingAudioSourceMessage extends AudioSourceMessage {
Expand Down
55 changes: 55 additions & 0 deletions just_audio_web/lib/just_audio_web.dart
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,16 @@ class Html5AudioPlayer extends JustAudioPlayer {
} else if (audioSourceMessage is HlsAudioSourceMessage) {
return HlsAudioSourcePlayer(this, audioSourceMessage.id,
Uri.parse(audioSourceMessage.uri), audioSourceMessage.headers);
} else if (audioSourceMessage is MappingAudioSourceMessage) {
return MappingAudioSourcePlayer(
this,
audioSourceMessage.id,
() async {
final innerMessage =
await audioSourceMessage.createAudioSourceMessage();
return decodeAudioSource(innerMessage) as IndexedAudioSourcePlayer;
},
);
} else if (audioSourceMessage is ConcatenatingAudioSourceMessage) {
return ConcatenatingAudioSourcePlayer(
this,
Expand Down Expand Up @@ -698,6 +708,51 @@ class HlsAudioSourcePlayer extends UriAudioSourcePlayer {
: super(html5AudioPlayer, id, uri, headers);
}

class MappingAudioSourcePlayer extends IndexedAudioSourcePlayer {
final Future<IndexedAudioSourcePlayer> Function() _generateInnerPlayer;
IndexedAudioSourcePlayer? _innerPlayer;

MappingAudioSourcePlayer(
Html5AudioPlayer html5AudioPlayer, String id, this._generateInnerPlayer)
: super(html5AudioPlayer, id);

@override
Future<Duration?> load([int? initialPosition]) async =>
(_innerPlayer = await _generateInnerPlayer()).load(initialPosition);

@override
List<IndexedAudioSourcePlayer> get sequence => [this];

@override
List<int> get shuffleIndices => [0];

@override
Future<void> play() => _innerPlayer!.play();

@override
Future<void> pause() => _innerPlayer!.pause();

@override
Future<void> seek(int position) => _innerPlayer!.seek(position);

@override
Future<void> complete() => _innerPlayer!.complete();

@override
Future<void> timeUpdated(double seconds) async =>
_innerPlayer?.timeUpdated(seconds);

@override
Duration? get duration => _innerPlayer?.duration;

@override
Duration get position => _innerPlayer?.position ?? Duration.zero;

@override
Duration get bufferedPosition =>
_innerPlayer?.bufferedPosition ?? Duration.zero;
}

/// A player for a [ConcatenatingAudioSourceMessage].
class ConcatenatingAudioSourcePlayer extends AudioSourcePlayer {
/// The players for each child audio source.
Expand Down

0 comments on commit fc9e498

Please sign in to comment.