Show Subtitle/Audio Names for Plex

Add the subtitle and audio track titles to the Plex Web app.

目前为 2020-03-09 提交的版本,查看 最新版本

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