2

according to this JavaScript detecting play/pause keyboard (virtual) key , it is possible to detect the play/pause, next and previous (Hardware Media Key Handling) keys using javascript but only in chrome. is there any similar thing in electron ? PS: it is for an audio player.

2 Answers2

2

I'm answering my question ! using the media keys with EvenListener is not an effective way to do that. not all Browsers support the Media Session API. Checkout this for more information about the API : https://developer.mozilla.org/en-US/docs/Web/API/Media_Session_API. Example for usign media session API:

if ('mediaSession' in navigator) {
//setting the metadata
  navigator.mediaSession.metadata = new MediaMetadata({
    title: 'Unforgettable',
    artist: 'Nat King Cole',
    album: 'The Ultimate Collection (Remastered)',
    artwork: [
      { src: 'https://dummyimage.com/96x96',   sizes: '96x96',   type: 'image/png' },
      { src: 'https://dummyimage.com/128x128', sizes: '128x128', type: 'image/png' },
      { src: 'https://dummyimage.com/192x192', sizes: '192x192', type: 'image/png' },
      { src: 'https://dummyimage.com/256x256', sizes: '256x256', type: 'image/png' },
      { src: 'https://dummyimage.com/384x384', sizes: '384x384', type: 'image/png' },
      { src: 'https://dummyimage.com/512x512', sizes: '512x512', type: 'image/png' },
    ]
  });

  navigator.mediaSession.setActionHandler('play', function() { /* Code excerpted. */ });
  navigator.mediaSession.setActionHandler('pause', function() { /* Code excerpted. */ });
  navigator.mediaSession.setActionHandler('stop', function() { /* Code excerpted. */ });
  navigator.mediaSession.setActionHandler('seekbackward', function() { /* Code excerpted. */ });
  navigator.mediaSession.setActionHandler('seekforward', function() { /* Code excerpted. */ });
  navigator.mediaSession.setActionHandler('seekto', function() { /* Code excerpted. */ });
  navigator.mediaSession.setActionHandler('previoustrack', function() { /* Code excerpted. */ });
  navigator.mediaSession.setActionHandler('nexttrack', function() { /* Code excerpted. */ });
  navigator.mediaSession.setActionHandler('skipad', function() { /* Code excerpted. */ });
}

Now for Electron, if you using the latest version then probably you could use the media session API (in the renderer process) and it would work just fine as chrome when playing Youtube videos (you can play/pause, go to next & previous media...). But we still can face problems when another application starts using the media keys befor our Electron app (like Chrome), this problem can't be solved using the media session API. In Electron we have globalShortcut from Electron package for setting shortcuts Example:

const { app, globalShortcut } = require('electron')

app.whenReady().then(() => {
  globalShortcut.register('Alt+CommandOrControl+I', () => {
    console.log('Electron loves global shortcuts!')
  })
}).then(createWindow)

This would work just fine with all shortcuts, but not effectivly with the media keys ! the reason why is because Linux keys are by default stolen by dbus, so we need os level control (a package that interacts with dbus directly). i searched for that and i found some incoming packeges (not finished) that uses the dbus for linux to handle media keys. https://www.npmjs.com/package/electron-media-service or you can use the dbus package your self :D (i'm not sure but i think for electron you gonna need to use native-packages => native-dbus) I welcome any improvments on this answer.

issue that helped me https://github.com/electron/electron/issues/5268

1

Should work in chrome/electron

document.addEventListener('keyup', ({ key }) => { 
  const mediaKey = [
    'MediaTrackNext', 
    'MediaTrackPrevious', 
    'MediaPlayPause', 
    'MediaStop'].includes(key)
    
  mediaKey && console.log(key)
})
syarul
  • 2,161
  • 2
  • 20
  • 22
  • 1
    [`Array.prototype.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes) would have sufficed though – Tibebes. M Nov 09 '20 at 12:42
  • i don't know what is wrong but it didn't work for me, i tried it in chrome and electron nothing was detected, and there was no errors... – abdeslam chettout Nov 09 '20 at 15:15
  • check your keys, if it needs extra key, i.e ``FN`` + key to activate, or you can ``log`` all keys to see if it return a different key – syarul Nov 09 '20 at 15:20
  • yes, i checked them, and they are working correctly but still not detected ! bro i think it is impossible to catch media keys with eventListener, if you read this article and this one you will find out that thess keys are not considered as "normal" keys from your keyboard, but as a different hardware, and we need a special feature to access it from a browser, and what we need is mediaSession API, i tested the demo code offered and it works for chrom but not electron. – abdeslam chettout Nov 09 '20 at 16:04
  • i tried to log all pressed keys and i had a result, for the media keys the event is never fired in time, and needs to click randomly on the media keys so the event fires... i don't know why... – abdeslam chettout Nov 09 '20 at 17:49