-
-
Notifications
You must be signed in to change notification settings - Fork 236
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(playback): add functions to handle mediasession inputs #595
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also implement seekforward, seekbackward and seekto, so this is finally 100% complete?
Imo we should at this point also create the store that handles playbacksettings (even if not configurable yet), just so we store the seekforward and backward values there, alongside for the ones for the video player, instead of having numbers scattered all around.
Updated. |
Codecov Report
@@ Coverage Diff @@
## master #595 +/- ##
==========================================
- Coverage 10.28% 10.15% -0.13%
==========================================
Files 105 105
Lines 2908 2945 +37
Branches 444 449 +5
==========================================
Hits 299 299
- Misses 2593 2630 +37
Partials 16 16
Continue to review full report at Codecov.
|
@camc314 I might be able to test them on Edge Android. Hopefully I can do it tomorrow, if nobody else comes first. I'll report you back with my results 👍🏻. |
I got out an old android phone, should all work properly now. |
Seems like this is an issue since MediaSession is only a working drive w3c/mediasession#228 . We don't check if it is supported in web. I guess we could wrap it in a try catch block? |
@camc314 I would say we should wrap each action handler in its own try/catch block, so handlers that are down in the chain but still compatible can still be used. |
Saw something like this used, which should reduce the number of lines nicely: const actionHandlers = [
['play', () => { /* ... */ }],
['pause', () => { /* ... */ }],
['previoustrack', () => { /* ... */ }],
['nexttrack', () => { /* ... */ }],
['stop', () => { /* ... */ }],
['seekbackward', (details) => { /* ... */ }],
['seekforward', (details) => { /* ... */ }],
['seekto', (details) => { /* ... */ }],
];
for (const [action, handler] of actionHandlers) {
try {
navigator.mediaSession.setActionHandler(action, handler);
} catch (error) {
console.log(`The media session action "${action}" is not supported yet.`);
}
} |
Also note we should unset them when playback ends, with this: navigator.mediaSession.setActionHandler("nexttrack", null); |
@@ -388,6 +391,33 @@ export default Vue.extend({ | |||
} | |||
} | |||
}, | |||
addMediaHandlers(): void { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to also set play
and pause
here, just to ensure everything is handled the same across browser, and making sure to set navigator.mediaSession.playbackState
.
bd9a97e
to
6477b1f
Compare
components/Players/PlayerManager.vue
Outdated
'play', | ||
async (): Promise<void> => { | ||
await this.play(); | ||
if (navigator.mediaSession) { | ||
navigator.mediaSession.playbackState = 'playing'; | ||
} | ||
} | ||
], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'play', | |
async (): Promise<void> => { | |
await this.play(); | |
if (navigator.mediaSession) { | |
navigator.mediaSession.playbackState = 'playing'; | |
} | |
} | |
], | |
'play', | |
(): void => { | |
this.unpause(); | |
if (navigator.mediaSession) { | |
navigator.mediaSession.playbackState = 'playing'; | |
} | |
} | |
], |
I think this is what you want instead
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yeah I get confused with this.play
vs this.unpause
components/Players/PlayerManager.vue
Outdated
@@ -341,8 +343,11 @@ export default Vue.extend({ | |||
'setPreviousTrack', | |||
'setLastItemIndex', | |||
'playPause', | |||
'pause', | |||
'play', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'play', | |
'unpause', |
See my other comment
components/Players/PlayerManager.vue
Outdated
navigator.mediaSession.setActionHandler(action, handler); | ||
} catch (error) { | ||
// eslint-disable-next-line no-console | ||
console.log(`Error removing "${action}".`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
console.log(`Error removing "${action}".`); | |
console.log(`Error removing mediaSession action: "${action}".`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two things:
-
Not possible to go back. At first press it restarts the song as usual, at the second it goes back to the previous song. However, the track that it's reported in MediaSession it's still the same
-
We should disable previous/next buttons to avoid console errors, undefined items and also better experience (right now you press on it and it does nothing, and that's not good UX imo). Set a watcher for getPreviousItem and getNextItem and nullify the next/previous handlers there.
This is fixed.
I couldn't find a way to disable the buttons short of setting them to null - which hides them, which is even worse if we have got buttons disappearing and reappearing. So now, when pressing prev, it will go to the beginning of the item, and when pressed a second time to the previous item (if it exists). Pressing next will go to the next song, or end playback if there are no more items in the queue. |
@camc314 Imo it's better to have them disappear than do anything. Basically because all the desktop media controls I've used (Windows, Mac, elementaryOS), if I recall correctly, disables the buttons. Only mobile devices tend to make them disappear. Although we should keep in mind those devices, Android for instance is going native route and I think the majority of the users that use web will always be in desktop, so it's a matter of priorities imo. Buttons appearing/disappearing in something that's hidden in a notification panel it's not, in my opinion, such a big deal. Here's a Windows screenshot for reference: With this said, back to testing this Edit: Just checked and Spotify changed its behaviour (single item in queue): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you check again? This is working for me (chrome) |
2a980fc
to
bb67dd0
Compare
I rebased to see if CI passes (as your branch is still without the SSR bits). Back to testing |
|
||
this.removeMediaHandlers(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, it works now, but this makes the controls blink:
2021-02-04.12-20-03.mp4
I would create a updateMetadata
method that updates the metadata instead of plain removing the handlers and clearing the metadata. I don't see why we need a resetMetadata
one, that updateMetadata
method should clear the metadata that's missing of the item, but if we want to clear up everything, it's because the playing session ended, so we're better calling removeMediaHandlers
and that's it.
That updateMetadata
method can also take handle of removing the actions of the previous/next track if there's no next/previous track in the queue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't remove or read the media handlers when we navigate between tracks, only when playback is stopped, not we navigate between tracks
I can't seem to reproduce this. I have tested in both Chrome and Brave.
Does this still still occur in other browsers?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@camc314 True, GH code preview confusing me a bit with the collapses. See how Spotify app works:
spoty.mp4
I added console.log calls to removeMediaHandler
and updateMetadata
and I can confirm that updateMetadata
is called only once per track change and removeMediaHandler
is also called only when stopping.
Tested Chrome 88 in browserstacks and I can't reproduce the issue, so this does seem indeed and Edge Chromium bug.
Filed a bug report for this.
Kudos, SonarCloud Quality Gate passed!
|
Before

After

Unfortunately chrome desktop cannot seek through media tracks however it should not be too difficult to add: