您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
English:"Add HTML5 player support in restricted browsers.";中文:“在受限制的浏览器中,添加html5播放器支持”
// ==UserScript== // @name HTML5 Player Simulation // @namespace [email protected] // @version a.1 // @description English:"Add HTML5 player support in restricted browsers.";中文:“在受限制的浏览器中,添加html5播放器支持” // @author xiaoxingxingboer31 // @match *://* // @grant none // @run-at document-start // @license Proprietary // ==/UserScript== (function () { 'use strict'; // 引入解码器库 const decoderScripts = [ 'https://cdn.jsdelivr.net/npm/[email protected]/Player/Decoder.js', // H.264 'https://cdn.jsdelivr.net/npm/[email protected]/libde265.js', // HEVC/H.265 'https://cdn.jsdelivr.net/npm/[email protected]/dav1d.js', // AV1 ]; decoderScripts.forEach(src => { const script = document.createElement('script'); script.src = src; document.head.appendChild(script); }); // 创建自定义的<video>元素 class CustomVideoPlayer extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); // 创建Canvas用于绘制视频帧 this.canvas = document.createElement('canvas'); this.canvas.style.width = '100%'; this.canvas.style.height = '100%'; this.canvas.style.backgroundColor = '#000'; this.shadowRoot.appendChild(this.canvas); // 创建基础控件 const controls = document.createElement('div'); controls.style.position = 'absolute'; controls.style.bottom = '0'; controls.style.left = '0'; controls.style.right = '0'; controls.style.backgroundColor = 'rgba(0, 0, 0, 0.7)'; controls.style.padding = '10px'; controls.style.display = 'flex'; controls.style.alignItems = 'center'; // 播放/暂停按钮 this.playPauseBtn = document.createElement('button'); this.playPauseBtn.innerText = '播放'; this.playPauseBtn.style.padding = '5px 10px'; this.playPauseBtn.style.marginRight = '10px'; this.playPauseBtn.addEventListener('click', () => this.togglePlay()); controls.appendChild(this.playPauseBtn); // 音量控制 this.volumeControl = document.createElement('input'); this.volumeControl.type = 'range'; this.volumeControl.min = '0'; this.volumeControl.max = '1'; this.volumeControl.step = '0.1'; this.volumeControl.value = '1'; this.volumeControl.style.flexGrow = '1'; this.volumeControl.addEventListener('input', () => this.volume = this.volumeControl.value); controls.appendChild(this.volumeControl); // 进度条 this.progressBar = document.createElement('progress'); this.progressBar.value = '0'; this.progressBar.max = '100'; this.progressBar.style.width = '100%'; this.progressBar.style.marginTop = '10px'; this.progressBar.addEventListener('click', (e) => this.seek(e)); controls.appendChild(this.progressBar); this.shadowRoot.appendChild(controls); // 初始化解码器 this.decoders = { 'avc': new Decoder({ rgb: true, webgl: true }), // H.264 'hevc': new libde265.Decoder(), // HEVC/H.265 'av1': new dav1d.Decoder(), // AV1 }; // 绑定解码器回调 this.decoders.avc.onPictureDecoded = this.decoders.hevc.onPictureDecoded = this.decoders.av1.onPictureDecoded = (buffer, width, height) => { const ctx = this.canvas.getContext('2d'); const imageData = new ImageData(new Uint8ClampedArray(buffer), width, height); ctx.putImageData(imageData, 0, 0); }; // 初始化状态 this._src = ''; this._currentTime = 0; this._paused = true; this._volume = 1; this._muted = false; this._playbackRate = 1; this._crossOrigin = null; this._autoplay = false; this._loop = false; this._preload = 'auto'; this._poster = ''; this._width = 0; this._height = 0; this._controls = false; this._controlsList = ''; this._disablePictureInPicture = false; this._playsInline = false; this._videoElement = null; this._audioContext = null; this._sourceNode = null; this._gainNode = null; // 绑定事件 this._timeupdateEvent = new Event('timeupdate'); this._playEvent = new Event('play'); this._pauseEvent = new Event('pause'); this._endedEvent = new Event('ended'); this._errorEvent = new Event('error'); this._progressEvent = new Event('progress'); this._seekedEvent = new Event('seeked'); } // 实现src属性 get src() { return this._src; } set src(value) { this._src = value; this.load(); } // 实现currentTime属性 get currentTime() { return this._currentTime; } set currentTime(value) { this._currentTime = value; this.dispatchEvent(this._timeupdateEvent); } // 实现paused属性 get paused() { return this._paused; } // 实现volume属性 get volume() { return this._volume; } set volume(value) { this._volume = value; if (this._gainNode) { this._gainNode.gain.value = value; } this.volumeControl.value = value; } // 实现muted属性 get muted() { return this._muted; } set muted(value) { this._muted = value; if (this._gainNode) { this._gainNode.gain.value = value ? 0 : this._volume; } } // 实现playbackRate属性 get playbackRate() { return this._playbackRate; } set playbackRate(value) { this._playbackRate = value; if (this._videoElement) { this._videoElement.playbackRate = value; } } // 实现crossOrigin属性 get crossOrigin() { return this._crossOrigin; } set crossOrigin(value) { this._crossOrigin = value; if (this._videoElement) { this._videoElement.crossOrigin = value; } } // 实现autoplay属性 get autoplay() { return this._autoplay; } set autoplay(value) { this._autoplay = value; if (this._videoElement) { this._videoElement.autoplay = value; } } // 实现loop属性 get loop() { return this._loop; } set loop(value) { this._loop = value; if (this._videoElement) { this._videoElement.loop = value; } } // 实现preload属性 get preload() { return this._preload; } set preload(value) { this._preload = value; if (this._videoElement) { this._videoElement.preload = value; } } // 实现poster属性 get poster() { return this._poster; } set poster(value) { this._poster = value; if (this._videoElement) { this._videoElement.poster = value; } } // 实现width属性 get width() { return this._width; } set width(value) { this._width = value; this.canvas.width = value; } // 实现height属性 get height() { return this._height; } set height(value) { this._height = value; this.canvas.height = value; } // 实现controls属性 get controls() { return this._controls; } set controls(value) { this._controls = value; controls.style.display = value ? 'flex' : 'none'; } // 切换播放/暂停 togglePlay() { if (this._paused) { this.play(); } else { this.pause(); } } // 实现play方法 play() { if (this._videoElement) { this._videoElement.play(); this._paused = false; this.playPauseBtn.innerText = '暂停'; this.dispatchEvent(this._playEvent); this._drawVideoFrame(); } } // 实现pause方法 pause() { if (this._videoElement) { this._videoElement.pause(); this._paused = true; this.playPauseBtn.innerText = '播放'; this.dispatchEvent(this._pauseEvent); } } // 加载视频并解码 load() { if (this._src) { fetch(this._src) .then(response => response.arrayBuffer()) .then(buffer => { const data = new Uint8Array(buffer); const codec = this._detectCodec(data); if (this.decoders[codec]) { this.decoders[codec].decode(data); // 解码视频帧 } else { console.error('不支持的视频编码格式:', codec); } }) .catch(error => { console.error('视频加载失败:', error); }); } } // 检测视频编码格式 _detectCodec(data) { if (data[4] === 0x68 && data[5] === 0x76 && data[6] === 0x63 && data[7] === 0x31) { return 'avc'; // H.264 } else if (data[4] === 0x68 && data[5] === 0x65 && data[6] === 0x76 && data[7] === 0x63) { return 'hevc'; // HEVC/H.265 } else if (data[4] === 0x61 && data[5] === 0x76 && data[6] === 0x30 && data[7] === 0x31) { return 'av1'; // AV1 } else { return 'unknown'; } } // 绘制视频帧 _drawVideoFrame() { if (!this._paused && this._videoElement) { const ctx = this.canvas.getContext('2d'); ctx.drawImage(this._videoElement, 0, 0, this.canvas.width, this.canvas.height); this.currentTime = this._videoElement.currentTime; this.progressBar.value = (this.currentTime / this._videoElement.duration) * 100; requestAnimationFrame(() => this._drawVideoFrame()); } } // 进度条跳转 seek(e) { const rect = this.progressBar.getBoundingClientRect(); const percent = (e.clientX - rect.left) / rect.width; this.currentTime = percent * this._videoElement.duration; } // 释放资源 _releaseResources() { if (this._audioContext) { this._audioContext.close(); this._audioContext = null; } if (this._videoElement) { URL.revokeObjectURL(this._videoElement.src); this._videoElement = null; } } } // 注册自定义元素 customElements.define('custom-video', CustomVideoPlayer); // 替换<video>标签 function replaceVideoElements() { const videoElements = document.querySelectorAll('video'); videoElements.forEach(video => { const customVideo = document.createElement('custom-video'); customVideo.src = video.src; // 设置其他属性... video.parentNode.replaceChild(customVideo, video); }); } // 监控DOM变化并替换<video>标签 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.tagName === 'VIDEO') { const customVideo = document.createElement('custom-video'); customVideo.src = node.src; // 设置其他属性... node.parentNode.replaceChild(customVideo, node); } }); }); }); // 在脚本加载完成后替换<video>标签 window.addEventListener('load', () => { replaceVideoElements(); observer.observe(document.body, { childList: true, subtree: true }); }); })();