Skip to content

Commit

Permalink
Migrated to package:web
Browse files Browse the repository at this point in the history
  • Loading branch information
ali2236 authored and ryanheise committed Jan 25, 2025
1 parent 2994f08 commit e8c4c42
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 166 deletions.
2 changes: 1 addition & 1 deletion audio_service/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Demonstrates how to use the audio_service plugin.
publish_to: 'none'

environment:
sdk: ">=2.14.0 <4.0.0"
sdk: ">=3.3.0 <4.0.0"
flutter: ">=3.0.0"

dependencies:
Expand Down
14 changes: 3 additions & 11 deletions audio_service/example/web/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<!DOCTYPE html>
<html>
<head>
<base href="$FLUTTER_BASE_HREF">

<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
Expand All @@ -18,16 +20,6 @@
<link rel="manifest" href="manifest.json">
</head>
<body>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<script>
if ('serviceWorker' in navigator) {
window.addEventListener('load', function () {
navigator.serviceWorker.register('flutter_service_worker.js');
});
}
</script>
<script src="main.dart.js" type="application/javascript"></script>
<script src="flutter_bootstrap.js" async></script>
</body>
</html>
2 changes: 1 addition & 1 deletion audio_service/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ topics:
- background

environment:
sdk: ">=2.14.0 <4.0.0"
sdk: ">=3.3.0 <4.0.0"
flutter: ">=3.0.0"

dependencies:
Expand Down
4 changes: 4 additions & 0 deletions audio_service_web/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.1.4

* Migrated to package:web (@ali2236)

## 0.1.3

* Support rxdart 0.28.x.
Expand Down
112 changes: 64 additions & 48 deletions audio_service_web/lib/audio_service_web.dart
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
import 'dart:async';
import 'dart:html' as html;
import 'dart:js' as js;
import 'dart:js_util';
import 'dart:js_interop' as js;
import 'dart:js_interop_unsafe';

import 'package:audio_service_platform_interface/audio_service_platform_interface.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
import 'package:web/web.dart' as web;

import 'js/media_session_web.dart';

class AudioServiceWeb extends AudioServicePlatform {
static void registerWith(Registrar registrar) {
AudioServicePlatform.instance = AudioServiceWeb();
}

web.MediaSession get _mediaSession => web.window.navigator.mediaSession;

final _mediaSessionSupported = _SupportChecker(
() => js.context.hasProperty('MediaSession'),
() => js.globalContext.hasProperty('MediaSession'.toJS).toDart,
"MediaSession is not supported in this browser, so plugin is no-op",
);
final _setPositionStateSupported = _SupportChecker(
() => hasProperty(html.window.navigator.mediaSession!, 'setPositionState'),
() => web.window.navigator.mediaSession
.hasProperty('setPositionState'.toJS)
.toDart,
"MediaSession.setPositionState is not supported in this browser",
);

Expand All @@ -39,82 +44,94 @@ class AudioServiceWeb extends AudioServicePlatform {
final state = request.state;

if (state.processingState == AudioProcessingStateMessage.idle) {
MediaSession.playbackState = MediaSessionPlaybackState.none;
_mediaSession.playbackState = MediaSessionPlaybackState.none;
} else {
if (state.playing) {
MediaSession.playbackState = MediaSessionPlaybackState.playing;
_mediaSession.playbackState = MediaSessionPlaybackState.playing;
} else {
MediaSession.playbackState = MediaSessionPlaybackState.paused;
_mediaSession.playbackState = MediaSessionPlaybackState.paused;
}
}

for (final control in state.controls) {
switch (control.action) {
case MediaActionMessage.play:
MediaSession.setActionHandler(
_mediaSession.setActionHandler(
MediaSessionActions.play,
(details) => handlerCallbacks?.play(const PlayRequest()),
((MediaSessionActionDetails details) {
handlerCallbacks?.play(const PlayRequest());
}).toJS,
);
break;
case MediaActionMessage.pause:
MediaSession.setActionHandler(
_mediaSession.setActionHandler(
MediaSessionActions.pause,
(details) => handlerCallbacks?.pause(const PauseRequest()),
((MediaSessionActionDetails details) {
handlerCallbacks?.pause(const PauseRequest());
}).toJS,
);
break;
case MediaActionMessage.skipToPrevious:
MediaSession.setActionHandler(
_mediaSession.setActionHandler(
MediaSessionActions.previoustrack,
(details) =>
handlerCallbacks?.skipToPrevious(const SkipToPreviousRequest()),
((MediaSessionActionDetails details) {
handlerCallbacks?.skipToPrevious(const SkipToPreviousRequest());
}).toJS,
);
break;
case MediaActionMessage.skipToNext:
MediaSession.setActionHandler(
_mediaSession.setActionHandler(
MediaSessionActions.nexttrack,
(details) =>
handlerCallbacks?.skipToNext(const SkipToNextRequest()),
((MediaSessionActionDetails details) {
handlerCallbacks?.skipToNext(const SkipToNextRequest());
}).toJS,
);
break;
case MediaActionMessage.rewind:
MediaSession.setActionHandler(
_mediaSession.setActionHandler(
MediaSessionActions.seekbackward,
(details) => handlerCallbacks?.rewind(const RewindRequest()),
((MediaSessionActionDetails details) {
handlerCallbacks?.rewind(const RewindRequest());
}).toJS,
);
break;
case MediaActionMessage.fastForward:
MediaSession.setActionHandler(
_mediaSession.setActionHandler(
MediaSessionActions.seekforward,
(details) =>
handlerCallbacks?.fastForward(const FastForwardRequest()),
((MediaSessionActionDetails details) {
handlerCallbacks?.fastForward(const FastForwardRequest());
}).toJS,
);
break;
case MediaActionMessage.stop:
MediaSession.setActionHandler(
_mediaSession.setActionHandler(
MediaSessionActions.stop,
(details) => handlerCallbacks?.stop(const StopRequest()),
((MediaSessionActionDetails details) {
handlerCallbacks?.stop(const StopRequest());
}).toJS,
);
break;
default:
// no-op
// no-op
break;
}
}

for (final message in state.systemActions) {
switch (message) {
case MediaActionMessage.seek:
MediaSession.setActionHandler('seekto',
(MediaSessionActionDetails details) {
// Browsers use seconds
handlerCallbacks?.seek(SeekRequest(
position:
_mediaSession.setActionHandler(
'seekto',
((MediaSessionActionDetails details) {
// Browsers use seconds
handlerCallbacks?.seek(SeekRequest(
position:
Duration(milliseconds: (details.seekTime * 1000).round()),
));
});
));
}).toJS);
break;
default:
// no-op
// no-op
break;
}
}
Expand All @@ -128,7 +145,7 @@ class AudioServiceWeb extends AudioServicePlatform {
final position = _minDuration(state.updatePosition, duration);

// Browsers expect for seconds
MediaSession.setPositionState(MediaSessionPositionState(
_mediaSession.setPositionState(web.MediaPositionState(
duration: duration.inMilliseconds / 1000,
playbackRate: state.speed,
position: position.inMilliseconds / 1000,
Expand All @@ -151,26 +168,24 @@ class AudioServiceWeb extends AudioServicePlatform {
final album = mediaItem!.album;
final artUri = mediaItem!.artUri;

MediaSession.metadata = html.MediaMetadata(<String, dynamic>{
'title': mediaItem!.title,
if (artist != null) 'artist': artist,
if (album != null) 'album': album,
'artwork': [
{
'src': artUri,
'sizes': '512x512',
}
],
});
_mediaSession.metadata = web.MediaMetadata(
web.MediaMetadataInit(
title: mediaItem!.title,
artist: artist.toString(),
album: album.toString(),
artwork: [
web.MediaImage(src: artUri.toString(), sizes: '512x512'),
].toJS,
),
);
}

@override
Future<void> stopService(StopServiceRequest request) async {
if (!_mediaSessionSupported.check()) {
return;
}
final session = html.window.navigator.mediaSession!;
session.metadata = null;
_mediaSession.metadata = null;
mediaItem = null;
}

Expand All @@ -193,6 +208,7 @@ class _SupportChecker {
_SupportChecker(this._checkCallback, this._warningMessage);

bool _logged = false;

bool check() {
final result = _checkCallback();
if (!_logged && !result) {
Expand Down
Loading

0 comments on commit e8c4c42

Please sign in to comment.