返回首頁 

Greasy Fork is available in English.

Netflix Enhanced Progress Bar

Netflixの動画にプログレスバーを追加します。

// ==UserScript==// @name                Netflix Enhanced Progress Bar// @name:en             Netflix Enhanced Progress Bar// @name:ja             Netflix Enhanced Progress Bar// @name:zh-CN          Netflix Enhanced Progress Bar// @name:ko             Netflix Enhanced Progress Bar// @name:ru             Netflix Enhanced Progress Bar// @name:de             Netflix Enhanced Progress Bar// @description         Netflixの動画にプログレスバーを追加します。// @description:en      Adds a progress bar to Netflix videos.// @description:ja      Netflixの動画にプログレスバーを追加します。// @description:zh-CN   为 Netflix 视频添加进度条。// @description:ko      Netflix 동영상에 진행 막대를 추가합니다.// @description:ru      Добавляет индикатор прогресса к видео на Netflix.// @description:de      Fügt einen Fortschrittsbalken zu Netflix-Videos hinzu.// @version             1.0.0// @author              Yos_sy// @match               *://*.netflix.com/*// @namespace           http://tampermonkey.net/// @icon                https://www.google.com/s2/favicons?sz=64&domain=netflix.com// @license             MIT// @grant               none// ==/UserScript==(function () {"use strict";// 定数定義const PROGRESS_UPDATE_INTERVAL = 1000; // プログレスバー更新間隔(ミリ秒)const VIDEO_CHECK_INTERVAL = 1000; // ビデオ要素チェック間隔(ミリ秒)class NetflixProgressBar {constructor() {this.progressBar = null; // カスタムプログレスバーの要素this.progress = null; // プログレスバーの進行状況を示す要素this.videoElement = null; // 現在のビデオ要素this.updateInterval = null; // プログレスバー更新のためのインターバルIDthis.videoCheckInterval = null; // ビデオ要素チェックのためのインターバルID}// 初期化メソッドinit() {this.addStyles(); // カスタムスタイルをページに追加this.startVideoCheck(); // ビデオ要素の存在を定期的にチェックthis.observeDOMChanges(); // DOMの変化を監視this.observeURLChanges(); // URLの変更を監視(SPA対応)}// スタイルを追加addStyles() {const style = document.createElement("style");style.textContent = `.netflixEnhancedProgressBar {position: absolute;bottom: 0;left: 0;width: 100%;height: 5px;background-color: rgba(128, 128, 128, 0.7);z-index: 9999;}.netflixEnhancedProgress {width: 0%;height: 100%;background-color: #e50914;transition: width 0.25s linear;}`;document.head.appendChild(style); // スタイルをheadに追加}// プログレスバー要素を作成createProgressBar() {this.progressBar = document.createElement("div");this.progressBar.className = "netflixEnhancedProgressBar"; // カスタムプログレスバーのクラス名を設定this.progress = document.createElement("div");this.progress.className = "netflixEnhancedProgress"; // プログレスバーの進行状況を示すクラス名を設定this.progressBar.appendChild(this.progress); // プログレスバーに進行状況を示す要素を追加return this.progressBar;}// プログレスバーの進行状況を更新updateProgress() {if (!this.videoElement || !this.progress) return; // ビデオ要素またはプログレスバーが存在しない場合は終了const percentage =(this.videoElement.currentTime / this.videoElement.duration) * 100; // 現在の再生時間を全体の再生時間で割り、パーセンテージを計算this.progress.style.width = `${percentage}%`; // プログレスバーの幅を更新}// プログレスバーの定期更新を開始startProgressUpdate() {this.stopProgressUpdate(); // 既存の更新を停止this.updateInterval = setInterval(() => this.updateProgress(),PROGRESS_UPDATE_INTERVAL); // プログレスバーの更新を定期的に実行}// プログレスバーの更新を停止stopProgressUpdate() {if (this.updateInterval) {clearInterval(this.updateInterval); // インターバルをクリアthis.updateInterval = null;}}// ビデオ要素の変更を処理handleVideoChange() {try {const newVideoElement = document.querySelector("video"); // 現在のページに存在するビデオ要素を取得if (newVideoElement !== this.videoElement) {this.cleanUp(); // 古いリソースをクリーンアップthis.videoElement = newVideoElement; // 新しいビデオ要素を設定if (this.videoElement) {this.createAndAttachProgressBar(); // プログレスバーを作成し、ビデオ要素に付加this.startProgressUpdate(); // プログレスバーの定期更新を開始}}} catch (error) {console.error("Error in handleVideoChange:", error); // エラーをコンソールに出力}}// プログレスバーを作成し、ビデオ要素に付加createAndAttachProgressBar() {if (!this.progressBar) {this.progressBar = this.createProgressBar(); // プログレスバーが存在しない場合、新規作成}this.videoElement.parentNode.appendChild(this.progressBar); // プログレスバーをビデオ要素の親要素に追加}// リソースのクリーンアップcleanUp() {this.stopProgressUpdate(); // プログレスバーの定期更新を停止if (this.progressBar && this.progressBar.parentNode) {this.progressBar.parentNode.removeChild(this.progressBar); // プログレスバーをDOMから削除}this.progressBar = null; // プログレスバーの参照をクリアthis.progress = null; // プログレスバーの進行状況要素の参照をクリア}// ビデオ要素の存在を定期的にチェックstartVideoCheck() {this.videoCheckInterval = setInterval(() => this.handleVideoChange(),VIDEO_CHECK_INTERVAL); // 定期的にビデオ要素の変更をチェック}// DOMの変化を監視observeDOMChanges() {const observer = new MutationObserver(() => this.handleVideoChange()); // DOM変化の監視を設定observer.observe(document.body, { childList: true, subtree: true }); // body要素以下の全ての変更を監視}// URLの変更を監視(SPA対応)observeURLChanges() {let lastUrl = location.href; // 最後に確認したURLを保存new MutationObserver(() => {const url = location.href;if (url !== lastUrl) {// URLが変更された場合lastUrl = url; // 新しいURLを保存this.handleVideoChange(); // ビデオ要素の変更を処理}}).observe(document, { subtree: true, childList: true }); // ドキュメント全体の変更を監視}}// プログレスバーのインスタンスを作成し、初期化const progressBar = new NetflixProgressBar();progressBar.init();})();