PlayerFM PWA

Enables PWA features in PlayerFM web.

  1. // ==UserScript==
  2. // @name PlayerFM PWA
  3. // @namespace net.englard.shmuelie
  4. // @version 1.3.4
  5. // @description Enables PWA features in PlayerFM web.
  6. // @author Shmuelie
  7. // @match https://player.fm/*
  8. // @grant none
  9. // @website https://github.com/shmuelie/user-scripts/blob/main/src/PlayerFMPWA.user.js
  10. // @supportURL https://github.com/shmuelie/user-scripts/issues
  11. // @noframes
  12. // ==/UserScript==
  13.  
  14. (function() {
  15. 'use strict';
  16.  
  17. if (window.player && navigator.mediaSession) {
  18. const p = window.player;
  19. const ms = navigator.mediaSession;
  20.  
  21. function onPlay() {
  22. ms.playbackState = "playing";
  23. ms.metadata = new MediaMetadata({
  24. album: p.currentEpisode.series.title,
  25. artist: p.currentEpisode.series.network.name || p.currentEpisode.series.owner,
  26. artwork: [
  27. {
  28. src: p.currentEpisode.series.imageModel.url
  29. }
  30. ],
  31. title: p.currentEpisode.title
  32. });
  33. document.title = "PlayerFM: " + p.currentEpisode.series.title + " - " + p.currentEpisode.title;
  34. }
  35.  
  36. function onPause() {
  37. ms.playbackState = "paused";
  38. }
  39.  
  40. function onEnded() {
  41. ms.playbackState = "none";
  42. }
  43.  
  44. function onTimeupdate() {
  45. if (ms.setPositionState) {
  46. ms.setPositionState({
  47. duration: p.getDuration(),
  48. position: p.getCurrentTime(),
  49. playbackRate: p.getSpeed()
  50. });
  51. }
  52. updatePlaylist();
  53. }
  54.  
  55. function onSeekForward() {
  56. p.seekIncrement(p.getForwardJumpDuration());
  57. }
  58.  
  59. function onSeekBackward() {
  60. p.seekIncrement(-p.getBackwardJumpDuration());
  61. }
  62.  
  63. function onNextTrack() {
  64. p.gotoNext(false);
  65. }
  66.  
  67. function onPreviousTrack() {
  68. p.gotoPrev();
  69. }
  70.  
  71. function updatePlaylist() {
  72. if (p.currentPlaylist) {
  73. if (p.currentPlaylist.index > 0) {
  74. ms.setActionHandler("previoustrack", onPreviousTrack);
  75. } else {
  76. ms.setActionHandler("previoustrack", null);
  77. }
  78. if (p.currentPlaylist.index < p.currentPlaylist.length() - 1) {
  79. ms.setActionHandler("nexttrack", onNextTrack);
  80. } else {
  81. ms.setActionHandler("nexttrack", null);
  82. }
  83. } else {
  84. ms.setActionHandler("nexttrack", null);
  85. ms.setActionHandler("previoustrack", null);
  86. }
  87. }
  88.  
  89. p.listen("play", onPlay);
  90. p.listen("pause", onPause);
  91. p.listen("ended", onEnded);
  92. p.listen("timeupdate", onTimeupdate);
  93. p.listen("playing", onPlay);
  94.  
  95. ms.setActionHandler("pause", function () {
  96. p.togglePlayback(false);
  97. });
  98. ms.setActionHandler("play", function() {
  99. p.togglePlayback(true);
  100. });
  101. ms.setActionHandler("seekforward", onSeekForward);
  102. ms.setActionHandler("seekbackward", onSeekBackward);
  103. updatePlaylist();
  104. }
  105. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址