ms.ts 2.9 KB

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