您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
为指定视频添加可移动的进度条、音量控制器、重新加载按钮和悬浮窗功能和去黑边
- // ==UserScript==
- // @name Video Control with Reload and Floating Window
- // @namespace http://tampermonkey.net/
- // @version 1.5
- // @description 为指定视频添加可移动的进度条、音量控制器、重新加载按钮和悬浮窗功能和去黑边
- // @match https://app.kosmi.io/*
- // @grant none
- // @license MIT
- // ==/UserScript==
- (function() {
- 'use strict';
- let videoElement = null;
- let controller = null;
- let isDragging = false;
- let initialX = 0,
- initialY = 0;
- let lastX = 0,
- lastY = 0;
- let buttonCreated = false;
- let floatingWindow = null;
- function createController() {
- controller = document.createElement('div');
- controller.id = 'video-controller';
- controller.style.cssText = `
- position: fixed;
- bottom: 20px;
- left: 50%;
- transform: translateX(-50%);
- background-color: rgba(0, 0, 0, 0.7);
- color: white;
- padding: 10px;
- border-radius: 5px;
- z-index: 9999;
- cursor: move;
- user-select: none;
- width: 300px;
- height: 233px;
- transition: width 0.3s, height 0.3s;
- display: none;
- `;
- controller.innerHTML = `
- <progress id="progress-bar" value="0" max="100" style="width: 100%; height: 10px; background-color: #444; cursor: pointer;"></progress>
- <div id="time-display" style="text-align: center; margin-top: 5px;">0:00 / 0:00</div>
- <div id="volume-container" style="display: flex; align-items: center; margin-top: 10px; cursor: pointer;">
- <span id="volume-icon" style="margin-right: 10px;">🔊</span>
- <input type="range" id="volume-slider" min="0" max="1" step="0.1" value="1" style="flex-grow: 1; cursor: pointer;">
- </div>
- <button id="reload-button" style="width: 100%; margin-top: 10px; padding: 5px; background-color: #4CAF50; border: none; color: white; cursor: pointer;">重新加载视频控制</button>
- <button id="float-video-button" style="width: 100%; margin-top: 10px; padding: 5px; background-color: #2196F3; border: none; color: white; cursor: pointer;">创建悬浮视频窗口</button>
- <button id="video-remove-black" style="width: 100%; margin-top: 10px; padding: 5px; background-color: #FFA500; border: none; color: white; cursor: pointer;">视频去黑边</button>
- <div style="display: flex; justify-content: space-between; margin-top: 10px;">
- <button class="size-button" data-action="increase-width" style="cursor: pointer;">宽度+</button>
- <button class="size-button" data-action="decrease-width" style="cursor: pointer;">宽度-</button>
- <button class="size-button" data-action="increase-height" style="cursor: pointer;">高度+</button>
- <button class="size-button" data-action="decrease-height" style="cursor: pointer;">高度-</button>
- </div>
- `;
- document.body.appendChild(controller);
- return controller;
- }
- function createToggleButton() {
- if (!buttonCreated) {
- const button = document.createElement('button');
- button.textContent = '🎥';
- button.style.cssText = `
- position: fixed;
- left: 10px;
- top: 50%;
- transform: translateY(-50%);
- padding: 5px;
- font-size: 20px;
- background-color: rgba(0, 0, 0, 0.5);
- color: white;
- border: none;
- border-radius: 50%;
- cursor: move;
- z-index: 9999;
- `;
- document.body.appendChild(button);
- let pos1 = 0,
- pos2 = 0;
- button.onmousedown = function(e) {
- e.preventDefault();
- isDragging = true;
- initialX = e.clientX;
- initialY = e.clientY;
- lastX = initialX;
- lastY = initialY;
- document.onmouseup = closeDragElement;
- document.onmousemove = throttle(buttonDrag, 16);
- };
- function buttonDrag(e) {
- if (!isDragging) return;
- e.preventDefault();
- pos1 = lastX - e.clientX;
- pos2 = lastY - e.clientY;
- lastX = e.clientX;
- lastY = e.clientY;
- button.style.top = (button.offsetTop - pos2) + "px";
- button.style.left = (button.offsetLeft - pos1) + "px";
- }
- function closeDragElement() {
- document.onmouseup = null;
- document.onmousemove = null;
- isDragging = false;
- }
- button.addEventListener('click', function() {
- if (controller.style.display === 'none') {
- controller.style.display = 'block';
- } else {
- controller.style.display = 'none';
- }
- });
- let isClicking = false;
- button.addEventListener('touchstart', function(e) {
- e.preventDefault();
- if (e.touches.length === 1) {
- isClicking = true;
- setTimeout(() => {
- if (isClicking) {
- if (controller.style.display === 'none' || controller.style.display === '') {
- controller.style.display = 'block';
- } else {
- controller.style.display = 'none';
- }
- }
- }, 200);
- } else {
- isClicking = false;
- }
- const touch = e.touches[0];
- initialX = touch.clientX - button.offsetLeft;
- initialY = touch.clientY - button.offsetTop;
- isDragging = true;
- });
- button.addEventListener('touchmove', function(e) {
- e.preventDefault();
- if (!isDragging) return;
- isClicking = false;
- const touch = e.touches[0];
- const newX = touch.clientX - initialX;
- const newY = touch.clientY - initialY;
- button.style.left = newX + 'px';
- button.style.top = newY + 'px';
- });
- button.addEventListener('touchend', function() {
- isDragging = false;
- });
- }
- buttonCreated = true;
- }
- // 让元素能在手机拖动
- function makeDraggable(element) {
- console.log('progressContainer1');
- let pos1 = 0,
- pos2 = 0,
- pos3 = 0,
- pos4 = 0;
- let isDragging = false;
- element.onmousedown = dragMouseDown;
- element.ontouchstart = dragTouchStart;
- function dragMouseDown(e) {
- console.log('progressContainer2');
- if (e.target.tagName === 'BUTTON' || e.target.tagName === 'INPUT') return;
- e.preventDefault();
- pos3 = e.clientX;
- pos4 = e.clientY;
- document.onmouseup = closeDragElement;
- document.onmousemove = elementDrag;
- isDragging = true;
- }
- function dragTouchStart(e) {
- console.log(e.target.tagName);
- console.log(e);
- if (e.target.tagName === 'BUTTON' || e.target.tagName === 'PROGRESS' || e.target.tagName === 'INPUT') return;
- e.preventDefault();
- const touch = e.touches[0];
- pos3 = touch.clientX;
- pos4 = touch.clientY;
- document.ontouchend = closeDragElement;
- document.ontouchmove = elementTouchDrag;
- isDragging = true;
- }
- function elementDrag(e) {
- console.log('progressContainer');
- if (!isDragging) return;
- e.preventDefault();
- pos1 = pos3 - e.clientX;
- pos2 = pos4 - e.clientY;
- pos3 = e.clientX;
- pos4 = e.clientY;
- element.style.top = (element.offsetTop - pos2) + "px";
- element.style.left = (element.offsetLeft - pos1) + "px";
- }
- function elementTouchDrag(e) {
- console.log('progressContainer4');
- if (!isDragging) return;
- e.preventDefault();
- const touch = e.touches[0];
- pos1 = pos3 - touch.clientX;
- pos2 = pos4 - touch.clientY;
- pos3 = touch.clientX;
- pos4 = touch.clientY;
- element.style.top = (element.offsetTop - pos2) + "px";
- element.style.left = (element.offsetLeft - pos1) + "px";
- }
- function closeDragElement() {
- console.log('progressContainer5');
- isDragging = false;
- document.onmouseup = null;
- document.onmousemove = null;
- document.ontouchend = null;
- document.ontouchmove = null;
- }
- }
- function throttle(func, limit) {
- let lastFunc;
- let lastRan;
- return function() {
- const context = this;
- const args = arguments;
- if (!lastRan) {
- func.apply(context, args);
- lastRan = Date.now();
- } else {
- clearTimeout(lastFunc);
- lastFunc = setTimeout(function() {
- if ((Date.now() - lastRan) >= limit) {
- func.apply(context, args);
- lastRan = Date.now();
- }
- }, limit - (Date.now() - lastRan));
- }
- };
- }
- function formatTime(seconds) {
- const minutes = Math.floor(seconds / 60);
- seconds = Math.floor(seconds % 60);
- return `${minutes}:${seconds.toString().padStart(2, '0')}`;
- }
- function createFloatingWindow() {
- videoElement = document.querySelector('video[src^="blob:https://app.kosmi.io/"]');
- if (videoElement) {
- if (floatingWindow) {
- floatingWindow.remove();
- }
- floatingWindow = document.createElement('div');
- floatingWindow.style.cssText = `
- position: fixed;
- top: 50px;
- left: 01px;
- width: 320px;
- height: 240px;
- background-color: #000;
- border: 0px solid #000;
- z-index: 10000;
- resize: both;
- cursor: move;
- overflow: hidden;
- `;
- const closeButton = document.createElement('button');
- closeButton.textContent = 'X';
- closeButton.style.cssText = `
- position: absolute;
- top: 5px;
- right: 5px;
- background-color: grey;
- color: white;
- border: none;
- cursor: pointer;
- z-index: 10001;
- opacity: 0.1;
- `;
- closeButton.onclick = () => {
- // 停止播放视频
- videoElement.pause();
- videoElement.load();
- // 移除浮窗
- floatingWindow.remove();
- };
- floatingWindow.appendChild(closeButton);
- document.body.appendChild(floatingWindow);
- // 保存视频的原始尺寸
- const originalWidth = videoElement.offsetWidth;
- const originalHeight = videoElement.offsetHeight;
- // 调整视频大小以适应悬浮窗
- videoElement.style.width = '100%';
- videoElement.style.height = '100%';
- // 将视频添加到悬浮窗中
- floatingWindow.appendChild(videoElement);
- // 添加悬浮窗到body
- document.body.appendChild(floatingWindow);
- makeDraggable(floatingWindow);
- }
- }
- function removeVideoBlack() {
- videoElement = document.querySelector('video[src^="blob:https://app.kosmi.io/"]');
- if (videoElement) {
- videoElement.style.width = '100%';
- videoElement.style.height = '100%';
- videoElement.style.objectFit = 'cover';
- }
- }
- function main() {
- const existingController = document.getElementById('video-controller');
- const existingButton = document.getElementById('toggle-button');
- if (existingController) {
- existingController.remove();
- }
- if (existingButton) {
- existingButton.remove();
- }
- videoElement = document.querySelector('video[src^="blob:https://app.kosmi.io/"]');
- if (!videoElement) {
- console.log('未找到指定视频');
- return;
- }
- controller = createController();
- makeDraggable(controller);
- createToggleButton();
- const progressBar = document.getElementById('progress-bar');
- const timeDisplay = document.getElementById('time-display');
- const volumeSlider = document.getElementById('volume-slider');
- const volumeIcon = document.getElementById('volume-icon');
- const reloadButton = document.getElementById('reload-button');
- const floatVideoButton = document.getElementById('float-video-button');
- const videoRemoveBlack = document.getElementById('video-remove-black');
- const sizeButtons = document.querySelectorAll('.size-button');
- function updateProgress() {
- const progress = (videoElement.currentTime / videoElement.duration) * 100;
- progressBar.value = progress; // 设置进度条的value属性
- const current = formatTime(videoElement.currentTime);
- const total = formatTime(videoElement.duration);
- timeDisplay.textContent = `${current} / ${total}`;
- }
- // 添加点击事件监听器以改变视频播放位置
- progressBar.addEventListener('click', function(e) {
- if (isDragging) return;
- // 获取进度条的位置
- const rect = progressBar.getBoundingClientRect();
- const pos = (e.clientX - rect.left) / rect.width;
- // 设置视频播放位置
- videoElement.currentTime = pos * videoElement.duration;
- });
- volumeSlider.addEventListener('input', function() {
- videoElement.volume = this.value;
- updateVolumeIcon(this.value);
- });
- function updateVolumeIcon(volume) {
- if (volume > 0.5) {
- volumeIcon.textContent = '🔊';
- } else if (volume > 0) {
- volumeIcon.textContent = '🔉';
- } else {
- volumeIcon.textContent = '🔇';
- }
- }
- volumeSlider.value = videoElement.volume;
- updateVolumeIcon(videoElement.volume);
- reloadButton.addEventListener('click', function() {
- videoElement.removeEventListener('timeupdate', updateProgress);
- videoElement.removeEventListener('loadedmetadata', updateProgress);
- main();
- videoElement.addEventListener('timeupdate', updateProgress);
- videoElement.addEventListener('loadedmetadata', updateProgress);
- });
- floatVideoButton.addEventListener('click', createFloatingWindow);
- videoRemoveBlack.addEventListener('click', removeVideoBlack);
- sizeButtons.forEach(button => {
- button.addEventListener('click', function() {
- if (!floatingWindow) return;
- const action = this.dataset.action;
- const step = 20;
- switch (action) {
- case 'increase-width':
- floatingWindow.style.width = (floatingWindow.offsetWidth + step) + 'px';
- break;
- case 'decrease-width':
- floatingWindow.style.width = Math.max(160, floatingWindow.offsetWidth - step) + 'px';
- break;
- case 'increase-height':
- floatingWindow.style.height = (floatingWindow.offsetHeight + step) + 'px';
- break;
- case 'decrease-height':
- floatingWindow.style.height = Math.max(120, floatingWindow.offsetHeight - step) + 'px';
- break;
- }
- });
- });
- videoElement.addEventListener('timeupdate', updateProgress);
- videoElement.addEventListener('loadedmetadata', updateProgress);
- }
- function waitForVideo() {
- const video = document.querySelector('video[src^="blob:https://app.kosmi.io/"]');
- if (video) {
- main();
- } else {
- setTimeout(waitForVideo, 1000);
- }
- }
- waitForVideo();
- })();