您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Makes play buttons in Video Station generate VLC playlists rather than playing videos in the browser.
// ==UserScript== // @name VLC Station // @namespace VLCStation // @description Makes play buttons in Video Station generate VLC playlists rather than playing videos in the browser. // @include /^https?://[^/]*/.*[?&]launchApp=SYNO.SDS.VideoStation.AppInstance(?=[&#]|$).*$/ // @version 7 // @grant GM_registerMenuCommand // ==/UserScript== (function() { 'use strict'; var DSRequest; var FileServer; var Playlist; var Problem; var Thumbnail; var VLCStation; var Platform; Platform = { LINUX: navigator.platform.startsWith("Linux ") }; Problem = { MESSAGE__HEADING: "VLC Station Error", MESSAGE_INVALID_REQUEST: "An invalid request was made.", MESSAGE_NO_CONTACT: "Unable to contact the DiskStation.", MESSAGE_UNEXPECTED_RESPONSE_FORMAT: "Unexpected response structure.", MESSAGE_UNKNOWN_THUMBNAIL_TYPE: "Unknown thumbnail type.", MESSAGE_UNKNOWN_ITEM_FORMAT: "Unknown item format.", EXTRA_STATUS_CODE: "Status code", EXTRA_ERROR_CODE: "Error code", EXTRA_FIELD: "Field", EXTRA_PATH_ELEMENT: "Path element", EXTRA_INDEX: "Index", EXTRA_TYPE: "Type", PREFIX_EXTRA_SYNOLOGY: "Synology ", SEPARATOR_EXTRA: "\n", SEPARATOR_EXTRA_ITEM: ": ", SEPARATOR_SECTION: "\n\n", report: function(message, extra) { var index; var buffer; buffer = []; if(extra) for(index in extra) buffer.push(index + Problem.SEPARATOR_EXTRA_ITEM + extra[index]); alert([Problem.MESSAGE__HEADING, message, buffer.join(Problem.SEPARATOR_EXTRA)].join(Problem.SEPARATOR_SECTION) + Problem.SEPARATOR_SECTION); return; } }; (Thumbnail = function(element) { this._element = element; return; }).prototype = { _element: null, _thread: null, onload: null, id: null, token: null, type: null, _getImageURL: function() { return(this._element.style.backgroundImage || this._element.getAttribute(Thumbnail.ATTRIBUTE_URL)); }, _poll: function() { var url; url = this._getImageURL(); if(!this._element.classList.contains(Thumbnail.CLASS_LOADING) && url) { clearInterval(this._thread); this._parse(url); } return; }, _parse: function(url) { var index; var item; if(url.endsWith(Thumbnail.SUFFIX_CSS)) url = url.substr(0, url.length - Thumbnail.SUFFIX_CSS.length); if(url.indexOf(Thumbnail.SEPARATOR_PARAMETER_LIST) !== -1) { url = url.substr(url.indexOf(Thumbnail.SEPARATOR_PARAMETER_LIST) + Thumbnail.SEPARATOR_PARAMETER_LIST.length).split(Thumbnail.SEPARATOR_PARAMETER); index = url.length; while(index--) { item = url[index].split(Thumbnail.SEPARATOR_VALUE); this[Thumbnail.PARAMETER[item[0]] || Thumbnail.PARAMETER_DEFAULT] = item[1]; } } else Problem.report(Problem.MESSAGE_UNKNOWN_ITEM_FORMAT); if(this.onload) this.onload(this); return; }, load: function() { var url; url = this._getImageURL(); if(!url) this._thread = setInterval(this._poll.bind(this), Thumbnail.RATE_POLL); else this._parse(url); return; } }; Thumbnail.PARAMETER = { id: "id", SynoToken: "token", type: "type" }; Thumbnail.TYPE = { tvshow_episode: { api: "SYNO.VideoStation2.TVShowEpisode", infoContainer: "episode", preferredTitle: "tagline", episodic: true }, movie: { api: "SYNO.VideoStation2.Movie", infoContainer: "movie" }, home_video: { api: "SYNO.VideoStation2.HomeVideo", infoContainer: "video" } }; Thumbnail.SEPARATOR_PARAMETER_LIST = "?"; Thumbnail.SEPARATOR_PARAMETER = "&"; Thumbnail.SEPARATOR_VALUE = "="; Thumbnail.SUFFIX_CSS = "\")"; Thumbnail.PARAMETER_DEFAULT = "last"; Thumbnail.ATTRIBUTE_URL = "url"; Thumbnail.CLASS_LOADING = "loading"; Thumbnail.RATE_POLL = 50; (DSRequest = function(token) { this._request = new XMLHttpRequest(); this._request.onreadystatechange = this._handleStateChange.bind(this); this._request.open(DSRequest.TYPE_POST, location.origin + DSRequest.URL_ENTRY_POINT); this._request.setRequestHeader(DSRequest.HEADER_TOKEN, token); this._parameter = {}; return; }).prototype = { _request: null, _parameter: null, onsuccess: null, response: null, _handleStateChange: function() { var extra; var index; if(this._request.readyState === XMLHttpRequest.DONE) { if(this._request.status === DSRequest.STATUS_OK) { this.response = JSON.parse(this._request.responseText); if(this.response.success) { if(this.onsuccess) this.onsuccess(this); } else { extra = this.response.error.errors; for(index in extra) { extra[Problem.PREFIX_EXTRA_SYNOLOGY + index] = extra[index]; delete extra[index]; } extra[Problem.EXTRA_ERROR_CODE] = this.response.error.code; Problem.report(Problem.MESSAGE_INVALID_REQUEST, extra); } } else { extra = {}; extra[Problem.EXTRA_STATUS_CODE] = this._request.status; Problem.report(Problem.MESSAGE_NO_CONTACT, extra); } } return; }, setParameter: function(name, value) { this._parameter[name] = value; return; }, send: function() { var index; var buffer; buffer = []; for(index in this._parameter) buffer.push(encodeURIComponent(index) + DSRequest.SEPARATOR_VALUE + encodeURIComponent(this._parameter[index])); this._request.send(buffer.join(DSRequest.SEPARATOR_PARAMETER)); return; } }; DSRequest.HEADER_TOKEN = "X-SYNO-TOKEN"; DSRequest.URL_ENTRY_POINT = "/webapi/entry.cgi"; DSRequest.TYPE_POST = "POST"; DSRequest.SEPARATOR_VALUE = "="; DSRequest.SEPARATOR_PARAMETER = "&"; DSRequest.PARAMETER_ID = "id"; DSRequest.PARAMETER_ADDITIONAL = "additional"; DSRequest.PARAMETER_API = "api"; DSRequest.PARAMETER_METHOD = "method"; DSRequest.PARAMETER_VERSION = "version"; DSRequest.METHOD_GET_INFO = "getinfo"; DSRequest.ADDITION_FILE = "file"; DSRequest.STATUS_OK = 200; DSRequest.VERSION_API = "1"; (Playlist = function() { this.list = []; return; }).prototype = { list: null, add: function(filename, title) { this.list.push({filename: filename, title: title}); return; }, addVideoEntry: function(entry, type) { var index; var list; var listLength; list = entry.additional.file.concat(); list.sort(Playlist._compareSharepath); listLength = list.length; if(listLength > 1) for(index = 0; index < listLength; index++) this.add(Playlist._getVideoEntryFilename(list[index]), Playlist._getVideoEntryTitle(entry, type) + Playlist.PREFIX_TITLE_PART + (index + 1) + Playlist.SEPARATOR_TITLE_PART + listLength + Playlist.SUFFIX_TITLE_PART); else this.add(Playlist._getVideoEntryFilename(list[0]), Playlist._getVideoEntryTitle(entry, type)); return; }, addVideoEntryList: function(list, type) { var index; var listLength; listLength = list.length; for(index = 0; index < listLength; index++) this.addVideoEntry(list[index], type); return; }, getPLSText: function() { var result; var listLength; var index; listLength = this.list.length; result = [Playlist.HEADER_PLS, Playlist._getPLSRecord(Playlist.FIELD_PLS_ENTRY_COUNT, listLength)]; for(index = 0; index < listLength; index++) { result.push(Playlist._getPLSRecord(Playlist.PREIFX_PLS_FIELD_TITLE + (index + 1), this.list[index].title)); result.push(Playlist._getPLSRecord(Playlist.PREIFX_PLS_FIELD_FILE + (index + 1), this.list[index].filename)); } return(result.join(Playlist.SEPARATOR_PLS_RECORD) + Playlist.SEPARATOR_PLS_RECORD); } }; Playlist._compareSharepath = function(alpha, beta) { alpha = alpha.sharepath.toUpperCase(); beta = beta.sharepath.toUpperCase(); return(alpha < beta ? -1 : (alpha > beta ? 1 : 0)); }; Playlist._getPLSRecord = function(name, value) { return(name + Playlist.SEPARATOR_PLS_VALUE + value); }; Playlist._getVideoEntryTitle = function(entry, type) { var title; if(type.preferredTitle && entry[type.preferredTitle]) title = entry[type.preferredTitle]; else if(type.episodic) title = Playlist.PREFIX_TITLE_EPISODE + entry.episode; else title = entry.title; return(title); }; Playlist._getVideoEntryFilename = Platform.LINUX ? function(file) { return(Playlist.PREFIX_PATH_LINUX + location.hostname + file.sharepath); } : function(file) { return(Playlist.PREFIX_PATH_WINDOWS + (location.hostname + file.sharepath).replace(Playlist.PATTERN_PATH_SEPARATOR, Playlist.SEPARATOR_PATH)); }; Playlist.HEADER_PLS = "[playlist]"; Playlist.FIELD_PLS_ENTRY_COUNT = "NumberOfEntries"; Playlist.PREFIX_TITLE_PART = " ("; Playlist.PREFIX_TITLE_EPISODE = "Episode "; Playlist.PREFIX_PATH_WINDOWS = "\\\\"; Playlist.PREFIX_PATH_LINUX = "smb://"; Playlist.PREIFX_PLS_FIELD_TITLE = "Title"; Playlist.PREIFX_PLS_FIELD_FILE = "File"; Playlist.SEPARATOR_TITLE_PART = " of "; Playlist.SEPARATOR_PATH = "\\"; Playlist.SEPARATOR_PLS_RECORD = "\n"; Playlist.SEPARATOR_PLS_VALUE = "="; Playlist.SUFFIX_TITLE_PART = ")"; Playlist.PATTERN_PATH_SEPARATOR = new RegExp("/", "g"); FileServer = { FILENAME_DEFAULT: {}, ELEMENT_ANCHOR: "a", ELEMENT_IFRAME: "iframe", ATTRIBUTE_DOWNLOAD: "download", ATTRIBUTE_HREF: "href", ATTRIBUTE_SRC: "src", STYLE_VALUE_NONE: "none", DELAY_SAFE_REMOVAL: 1000, PROTOCOL_DATA: "data:", SEPARATOR_MIME: ";", SEPARATOR_PRAGMA: ",", PRAGMA_UTF8: "charset=utf-8", PRAGMA_BASE64: "base64", CONTENT_COMPANION: "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", MIME_PLAYLIST: "application/videolan", MIME_EXECUTABLE: "application/octet-stream", FILENAME_COMPANION: "vlc-full.exe", serve: function(filename, content, pragma, mime) { var element; var url; if(window.chrome || filename) { element = document.createElement(FileServer.ELEMENT_ANCHOR); element.style.display = FileServer.STYLE_VALUE_NONE; element.setAttribute(FileServer.ATTRIBUTE_HREF, FileServer._getDataURL(content, pragma, mime)); element.setAttribute(FileServer.ATTRIBUTE_DOWNLOAD, filename || FileServer.FILENAME_DEFAULT[mime]); document.body.appendChild(element); element.click(); document.body.removeChild(element); } else { filename = FileServer.FILENAME_DEFAULT[mime]; element = document.createElement(FileServer.ELEMENT_IFRAME); element.style.display = FileServer.STYLE_VALUE_NONE; document.body.appendChild(element); if(filename && window.File && window.URL) { url = URL.createObjectURL(new File([content], filename, {type: mime})); element.setAttribute(FileServer.ATTRIBUTE_SRC, url); } else element.setAttribute(FileServer.ATTRIBUTE_SRC, FileServer._getDataURL(content, pragma, mime)); setTimeout(this._cleanUpDownload.bind(this, element, url), FileServer.DELAY_SAFE_REMOVAL); } return; }, serveText: function(filename, text, mime) { this.serve(filename, text, FileServer.PRAGMA_UTF8, mime); return; }, serveCompanion: function() { this.serve(FileServer.FILENAME_COMPANION, FileServer.CONTENT_COMPANION, FileServer.PRAGMA_BASE64, FileServer.MIME_EXECUTABLE); return; } }; FileServer._cleanUpDownload = function(element, url) { document.body.removeChild(element); if(url) URL.revokeObjectURL(url); return; }; FileServer._getDataURL = function(content, pragma, mime) { return(FileServer.PROTOCOL_DATA + mime + FileServer.SEPARATOR_MIME + pragma + FileServer.SEPARATOR_PRAGMA + (pragma === FileServer.PRAGMA_BASE64 ? content : encodeURIComponent(content))); }; FileServer.FILENAME_DEFAULT[FileServer.MIME_PLAYLIST] = "playlist.vlc"; VLCStation = { start: function() { document.body.addEventListener(VLCStation.EVENT_CLICK, this, true); if(typeof(GM_registerMenuCommand) !== VLCStation.TYPE_UNDEFINED) GM_registerMenuCommand(VLCStation.MENU_ITEM_DOWNLOAD_COMPANION, FileServer.serveCompanion.bind(FileServer), VLCStation.MENU_ACCESS_DOWNLOAD_COMPANION); return; }, handleEvent: function(event) { var button; switch(event.type) { case VLCStation.EVENT_CLICK: button = event.target; if(!this.play(event, button)) { button = button.parentNode; if(button) { button = button.parentNode; if(button) this.play(event, button); } } break; } return; }, play: function(event, button) { var source; var valid; valid = button.classList.contains(VLCStation.CLASS_PLAY_BUTTON); if(valid) { source = new Thumbnail(button.parentNode); source.onload = this.requestPlaylist.bind(this); source.load(); event.stopPropagation(); } return(valid); }, requestPlaylist: function(thumbnail) { var playlist; var request; var type; type = Thumbnail.TYPE[thumbnail.type]; if(type) { request = new DSRequest(thumbnail.token); request.onsuccess = function(request) { var element; var extra; var field; var index; var pathLength; var response; var test; response = request.response; field = type.infoContainer; test = response; pathLength = VLCStation.PATH_TEST_PLAYLIST.length; for(index = 0; index < pathLength; index++) { element = VLCStation.PATH_TEST_PLAYLIST[index]; if(element === null) element = field; test = test[element]; if(!test) { extra = {}; extra[Problem.EXTRA_FIELD] = field; extra[Problem.EXTRA_PATH_ELEMENT] = VLCStation.PATH_TEST_PLAYLIST[index]; extra[Problem.EXTRA_INDEX] = index; Problem.report(Problem.MESSAGE_UNEXPECTED_RESPONSE_FORMAT, extra); break; } } if(index === pathLength) { playlist = new Playlist(); playlist.addVideoEntryList(response.data[field], type); FileServer.serveText(null, playlist.getPLSText(), FileServer.MIME_PLAYLIST); } return; }; request.setParameter(DSRequest.PARAMETER_ID, JSON.stringify([+thumbnail.id])); request.setParameter(DSRequest.PARAMETER_ADDITIONAL, JSON.stringify([DSRequest.ADDITION_FILE])); request.setParameter(DSRequest.PARAMETER_API, type.api); request.setParameter(DSRequest.PARAMETER_METHOD, DSRequest.METHOD_GET_INFO); request.setParameter(DSRequest.PARAMETER_VERSION, DSRequest.VERSION_API); request.send(); } else { extra = {}; extra[Problem.EXTRA_TYPE] = thumbnail.type; Problem.report(Problem.MESSAGE_UNKNOWN_THUMBNAIL_TYPE, extra); } return; } }; VLCStation.PATH_TEST_PLAYLIST = ["data", null, 0, "additional", "file", 0]; VLCStation.MENU_ACCESS_DOWNLOAD_COMPANION = "D"; VLCStation.MENU_ITEM_DOWNLOAD_COMPANION = "Download VLC Full Screen Launcher (Windows)"; VLCStation.CLASS_PLAY_BUTTON = "play"; VLCStation.EVENT_CLICK = "click"; VLCStation.TYPE_UNDEFINED = "undefined"; VLCStation.start(); return; })();