Show Subtitle/Audio Names and Media File Name for Plex

Add the subtitle, video, audio track titles and media version filename to the Plex Web app.

当前为 2020-05-13 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Show Subtitle/Audio Names and Media File Name for Plex
  3. // @version 2.5
  4. // @grant none
  5. // @include https://app.plex.tv/*
  6. // @description Add the subtitle, video, audio track titles and media version filename to the Plex Web app.
  7. // @namespace https://greasyfork.org/users/456605
  8. // @license MIT; https://spdx.org/licenses/MIT.html#licenseText
  9. // ==/UserScript==
  10.  
  11. function main () {
  12. function getMediaTitle(media) {
  13. let parts = media.Part;
  14. for (let k = 0; k < parts.length; k++) {
  15. if (!parts[k].hasOwnProperty("file")) continue;
  16. const format = parts[k].file.match(".*[\\\\/]+([^\\\\/]\+)$");
  17. if (format != null) return format[1];
  18. }
  19. return "Unknown";
  20. }
  21. function intercept(url, responseText) {
  22. if (url.indexOf("/library/metadata/") == -1 && url.indexOf("/status/sessions") == -1) return responseText;
  23. let response = JSON.parse(responseText);
  24. if (!response.hasOwnProperty("MediaContainer") ||
  25. !response.MediaContainer.hasOwnProperty("Metadata")) return responseText;
  26. const meta = response.MediaContainer.Metadata;
  27. for (let i = 0; i < meta.length; i++) {
  28. if (!meta[i].hasOwnProperty("Media")) continue;
  29. let medias = meta[i].Media;
  30. for (let j = 0; j < medias.length; j++) {
  31. if (!medias[j].hasOwnProperty("Part")) continue;
  32. if (!medias[j].hasOwnProperty("title")) medias[j].title = getMediaTitle(medias[j]);
  33. let parts = medias[j].Part;
  34. for (let k = 0; k < parts.length; k++) {
  35. if (!parts[k].hasOwnProperty("Stream")) continue;
  36. let streams = parts[k].Stream;
  37. for (let l = 0; l < streams.length; l++) {
  38. if (!streams[l].hasOwnProperty("displayTitle") || !streams[l].hasOwnProperty("title")) continue;
  39. streams[l].displayTitle = streams[l].displayTitle + " (" + streams[l].title + ")";
  40. }
  41. }
  42. }
  43. }
  44. return JSON.stringify(response);
  45. }
  46.  
  47. // From https://stackoverflow.com/questions/26447335/
  48. (function() {
  49. // create XMLHttpRequest proxy object
  50. var oldXMLHttpRequest = XMLHttpRequest;
  51.  
  52. // define constructor for my proxy object
  53. XMLHttpRequest = function() {
  54. var actual = new oldXMLHttpRequest();
  55. var self = this;
  56.  
  57. this.onreadystatechange = null;
  58.  
  59. // this is the actual handler on the real XMLHttpRequest object
  60. actual.onreadystatechange = function() {
  61. if (this.readyState == 4 && (actual.responseType == '' || actual.responseType == 'text')) {
  62. try {
  63. self._responseText = intercept(actual.responseURL, actual.responseText);
  64. } catch (err) {
  65. console.error(err);
  66. }
  67. }
  68. if (self.onreadystatechange) {
  69. return self.onreadystatechange();
  70. }
  71. };
  72.  
  73. // add all proxy getters/setters
  74. ["status", "statusText", "responseType", "response", "readyState", "responseXML",
  75. "upload", "ontimeout, timeout", "withCredentials", "onload", "onerror", "onprogress"].forEach(function(item) {
  76. Object.defineProperty(self, item, {
  77. get: function() {return actual[item];},
  78. set: function(val) {actual[item] = val;}
  79. });
  80. });
  81.  
  82. // add all proxy getters/setters
  83. ["responseText"].forEach(function(item) {
  84. Object.defineProperty(self, item, {
  85. get: function() {
  86. if (self.hasOwnProperty("_" + item)) {
  87. return self["_" + item];
  88. } else {
  89. return actual[item];
  90. }
  91. },
  92. set: function(val) {actual[item] = val;}
  93. });
  94. });
  95.  
  96. // add all pure proxy pass-through methods
  97. ["addEventListener", "send", "open", "abort", "getAllResponseHeaders",
  98. "getResponseHeader", "overrideMimeType", "setRequestHeader"].forEach(function(item) {
  99. Object.defineProperty(self, item, {
  100. value: function() {return actual[item].apply(actual, arguments);}
  101. });
  102. });
  103. }
  104. })();
  105. }
  106.  
  107. // From https://stackoverflow.com/questions/2303147/
  108. var script = document.createElement('script');
  109. script.appendChild(document.createTextNode('('+ main +')();'));
  110. (document.body || document.head || document.documentElement).appendChild(script);