ms.ts 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* eslint-disable-next-line no-redeclare */
  2. /* global MediaMetadata */
  3. export default {
  4. mediaSessionData: {},
  5. listeners: {},
  6. audio: null,
  7. ytReady: false,
  8. playSuccessful: false,
  9. loopInterval: null,
  10. setYTReady(ytReady) {
  11. if (ytReady)
  12. setTimeout(() => {
  13. this.ytReady = true;
  14. }, 1000);
  15. else this.ytReady = false;
  16. },
  17. setListeners(priority, listeners) {
  18. this.listeners[priority] = listeners;
  19. },
  20. removeListeners(priority) {
  21. delete this.listeners[priority];
  22. },
  23. setMediaSessionData(priority, playing, title, artist, album, artwork) {
  24. this.mediaSessionData[priority] = {
  25. playing, // True = playing, false = paused
  26. mediaMetadata: new MediaMetadata({
  27. title,
  28. artist,
  29. album,
  30. ...(artwork ? { artwork: [{ src: artwork }] } : null)
  31. })
  32. };
  33. },
  34. removeMediaSessionData(priority) {
  35. delete this.mediaSessionData[priority];
  36. },
  37. // Gets the highest priority media session data and updates the media session
  38. updateMediaSession() {
  39. const highestPriority = this.getHighestPriority();
  40. if (typeof highestPriority === "number") {
  41. const mediaSessionDataObject =
  42. this.mediaSessionData[highestPriority];
  43. navigator.mediaSession.metadata =
  44. mediaSessionDataObject.mediaMetadata;
  45. if (
  46. mediaSessionDataObject.playing ||
  47. !this.ytReady ||
  48. !this.playSuccessful
  49. ) {
  50. navigator.mediaSession.playbackState = "playing";
  51. this.audio
  52. .play()
  53. .then(() => {
  54. if (this.audio.currentTime > 1.0) {
  55. this.audio.muted = true;
  56. }
  57. this.playSuccessful = true;
  58. })
  59. .catch(() => {
  60. this.playSuccessful = false;
  61. });
  62. } else {
  63. this.audio.pause();
  64. navigator.mediaSession.playbackState = "paused";
  65. }
  66. } else {
  67. this.audio.pause();
  68. navigator.mediaSession.playbackState = "none";
  69. navigator.mediaSession.metadata = null;
  70. }
  71. },
  72. getHighestPriority() {
  73. return Object.keys(this.mediaSessionData)
  74. .map(priority => Number(priority))
  75. .sort((a, b) => a - b)
  76. .reverse()[0];
  77. },
  78. init() {
  79. this.audio = new Audio("/assets/15-seconds-of-silence.mp3");
  80. this.audio.loop = true;
  81. this.audio.volume = 0.1;
  82. navigator.mediaSession.setActionHandler("play", () => {
  83. this.listeners[this.getHighestPriority()].play();
  84. });
  85. navigator.mediaSession.setActionHandler("pause", () => {
  86. this.listeners[this.getHighestPriority()].pause();
  87. });
  88. navigator.mediaSession.setActionHandler("nexttrack", () => {
  89. this.listeners[this.getHighestPriority()].nexttrack();
  90. });
  91. this.loopInterval = setInterval(() => {
  92. this.updateMediaSession();
  93. }, 100);
  94. }
  95. };