Closed andrei-pavel closed 3 years ago
Does the problem manifest with flutter run?
Yes
$ flutter run -d chrome
Launching lib/main.dart on Chrome in debug mode...
../../../.pub-cache/hosted/pub.dartlang.org/audio_service-0.16.0/lib/js/media_metadata.dart:7:7: Error:
JS interop class 'MediaMetadata' conflicts with natively supported class 'MediaMetadata' in
'dart:html'.
class MediaMetadata {
^
Waiting for connection from debug service on Chrome... 21.5s
Failed to compile application.
$ dart2js --version
Dart-to-JavaScript compiler (dart2js) version: 2.10.4
Hmm, strangely I'm not able to reproduce this:
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel beta, 1.25.0-8.1.pre, on Linux, locale en_AU.UTF-8)
Then flutter run -d chrome
ran without error. I wonder if some libraries are being resolved differently. Here are my pubspec.lock
files:
It could be interesting to compare them to your own in case there are any differences.
You're right, I must have skipped the beta when going through different channels. flutter run
and flutter build
work for web on the beta channel. This is good enough for me. Apologies! I'll leave it to you to close this issue if you wish. It will probably be fixed in newer flutter versions. There seems to be some effort in this direction done under https://github.com/dart-lang/sdk/issues/35084.
To answer the question, I had the same pubsec.lock
with beta. I had a different pubspec.lock
when running on dev
channel. Some packages had slightly higher versions. Not sure how package versions are tied to flutter channels.
Let's leave this issue open for the time being.
It's probably that the newer dart:html
library will include its own MediaMetadata
interoperability class at which point we can remove audio_service's own stand-in. Probably a good time to do that will be when the new version of dart:html
reaches the beta channel.
Interesting... Dart html already had support for MediaSession I just had to create an interop for functionality that didn't work in their implementation. Hopefully that actually works when this hits beta haha
Oh, hmm, it seems that it's already in beta now! I guess what has changed is something in the way the @JS
classes get compiled that causes a conflict in newer versions.
Looking at it a bit more, I guess that html.MediaSession
still has an issue, while html.MediaMetadata
seems fine. Specifically, html.MediaSession.setActionHandler
only accepts void callbacks, so we'll need to stick to the current solution. But, note that this will cause a compile conflict in dev and master, and assuming that whatever's causing that compiler conflict will eventually make its way into beta, it may be a good idea to submit an issue on dart2js.
@keaganhilliard , apparently the current recommendation is to not use js-interop if there is a conflicting native class, at least until they either delete the native classes (because they're known to be incomplete, and they would rather not maintain them) or some alternative way (e.g. extension methods) is made to allow developers to patch those incomplete native classes.
For more details, see: https://github.com/dart-lang/sdk/issues/42200
@ryanheise well that is not helpful at all. If I'm remembering correctly, I had to use the @JS MediaMetadata
class because the artwork would not load with the built in html.MediaMetadata
. So I guess we could roll back to only using the native stuff for now. It would just mean that artwork probably wouldn't work and seekTo
would not work either. Less than ideal for sure. I mean we could wrap the MediaSession
functions with some JavaScript and pass the functions through.
I'll take a stab at making something work.
The native implementation of MediaMetadata
seems like it should work. Maybe there will be a trick to how the constructor parameters need to be passed in as a map, especially since nested maps are involved.
From what I can tell from the documentation, this should work:
metadata = html.MediaMetadata(jsify({
'album': mediaItem.album,
'title': mediaItem.title,
'artist': mediaItem.artist,
'artwork': [
{
'src': artUri,
'sizes': '512x512',
},
],
}));
I would also point out that the conflict only occurs with the MediaMetadata
class. The way the new compiler checks work is that they only detect the conflict if you use @JS(...)
where ...
is a JS classname. At least for now, it seems that @JS(navigator.mediaSession)
is fine since that binds to the object rather than the class, and this is not checked. So fingers crossed, there may be a way to get it working by keeping navigator.mediaSession
in place but using the native MediaMetadata
.
Aside from that, the issue I linked to above says that until this JS Interop mess is sorted out, the only guaranteed way to get it to work is to use js_util.callMethod
directly.
@ryanheise Looks like this works:
session.metadata = html.MediaMetadata({
'album': mediaItem.album,
'title': mediaItem.title,
'artist': mediaItem.artist,
'artwork': [
{
'src': artUri,
'sizes': '512x512',
},
],
});
It throws an error if you jsify
the map.
So we should be able to just remove the MediaMetadata
class and the setter in the @JS
class.
@suragch is this affecting the beta
channel now?
@ryanheise It was affecting the beta and dev channels when I tried it a couple days ago (that is, when I tried to run the app from VS Code). It worked to run and build the web app on the command line though.
Can you try the latest commit?
After the latest commit the MediaMetadata conflict is gone so this appears to solve the problem described in this issue.
I'm getting a silent error, but it doesn't seem to prevent audio_service from working:
Error: XMLHttpRequest error.
dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 906:28 get current
packages/http/src/browser_client.dart 84:22 <fn>
dart-sdk/lib/async/zone.dart 1446:54 runUnary
dart-sdk/lib/async/future_impl.dart 150:18 handleValue
dart-sdk/lib/async/future_impl.dart 708:44 handleValueCallback
dart-sdk/lib/async/future_impl.dart 737:13 _propagateToListeners
dart-sdk/lib/async/future_impl.dart 532:7 [_complete]
dart-sdk/lib/async/stream_pipe.dart 61:11 _cancelAndValue
dart-sdk/lib/async/stream.dart 1302:7 <fn>
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 324:14 _checkAndCall
dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/operations.dart 329:39 dcall
dart-sdk/lib/html/dart2js/html_dart2js.dart 37307:58 <fn>
at Object.createErrorWithStack (http://localhost:53556/dart_sdk.js:5310:12)
at Object._rethrow (http://localhost:53556/dart_sdk.js:38850:16)
at async._AsyncCallbackEntry.new.callback (http://localhost:53556/dart_sdk.js:38844:13)
at Object._microtaskLoop (http://localhost:53556/dart_sdk.js:38676:13)
at _startMicrotaskLoop (http://localhost:53556/dart_sdk.js:38682:13)
at http://localhost:53556/dart_sdk.js:34209:9
This might me something related to my server or some other aspect of my client setup. I'll open a new issue if I can isolate it.
Maybe CORS related?
Very well could be. I had an earlier XMLHttpRequest error that I thought I had fixed by adjusting CORS headers on the server. I'll look into that some more.
There was a CORS issue with the service worker caching. Don't know if that's what you are seeing here, but when you set the art uri for the MediaMetadata
the service worker attempts to cache the image and I've never seen it actually work. It doesn't seem to have any ill effects other than the silent error.
@keaganhilliard does the artwork in the example show for you? For me it doesn't, although it used to show, at least for Chrome on desktop and Android.
It was working when I tried it with the code I posted above. Maybe we should remove the interop setter? This was the issue that caused me to create the JS interop for the Metadata
in the first place.
My mistake, the notification does seem to be working in the latest commit, it is only the Image widget within the app's UI that isn't loading.
@andrei-pavel , @suragch , @keaganhilliard , can you confirm whether the latest commit to master
works for you? I will try to push out a release once I'm confident this hasn't broken anything.
I tested the most resent commit. I think it works. I say "think" because I was getting some crashes at first but then I wasn't able to reliably reproduce them. In my last couple tries I haven't gotten any crashes. At any rate, none of the crashes were related to a conflict with MediaMetadata
.
Regarding artwork not loading, I'm wondering if this is a problem outside of audio_service. I'm handling artwork directly with cached_network_image and it also isn't loading them when I start chrome from VS Code (but they load ok when I start Chrome from the terminal).
I'd say you can go ahead and publish a release, close this issue, and open a new one if any other problems come up related to web.
Were the crashes pointing to a line of code in audio_service? Some other changes I worked on recently may have introduced a crash, or at least there is one that I'm aware of which I fixed this morning. It affected macOS and web if the audio service was started a second time, so you might just want to test that you are able to start and stop the service multiple times.
The image widget not loading does seem to be an unrelated issue, and possibly is the service worker issue @keaganhilliard referred to earlier.
I'll leave this issue open for let's say another 8 hours and if no further crashes are reported, I'll make a release.
The crashes were related to stopping and restarting audio_service but I don't recall if there was a particular line number referenced. I think it was related to the cancel or onCancel method if I recall correctly. I was getting ready to post the stack trace but then the error wouldn't return.
On Thu, Jan 28, 2021 at 12:54 PM ryanheise notifications@github.com wrote:
Were the crashes pointing to a line of code in audio_service? Some other changes I worked on recently may have introduced a crash, or at least there is one that I'm aware of which I fixed this morning. It affected macOS and web if the audio service was started a second time, so you might just want to test that you are able to start and stop the service multiple times.
The image widget not loading does seem to be an unrelated issue, and possibly is the service worker issue @keaganhilliard https://github.com/keaganhilliard referred to earlier.
I'll leave this issue open for let's say another 8 hours and if no further crashes are reported, I'll make a release.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ryanheise/audio_service/issues/574#issuecomment-768798834, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACOSWPESPOMS7QCIYNN547DS4DUX7ANCNFSM4VQOKYIA .
This fix has now been published in release 0.16.2.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs, or use StackOverflow if you need help with audio_service.
Which API doesn't behave as documented, and how does it misbehave? README.md shows that web should be supported, but when I
flutter build web
from the command line, I get a JS interop error.Minimal reproduction project The example
To Reproduce (i.e. user steps, not code)
flutter build web
Error messages
Expected behavior I would have expected no error and the
web
directory containing generated static files.Screenshots N/A
Runtime Environment (please complete the following information if relevant):
Flutter SDK version
Additional context Manifests on beta & dev flutter versions as well. Stable is not yet ready for web.