您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Allows you to select audio output device on any sites (except iframe)
当前为
// ==UserScript== // @name Universal Audio Device Selector // @name:zh-cn 音频输出切换器 // @name:ja ユニバーサル音声切替器 // @namespace Violentmonkey Scripts // @match *://*/* // @grant none // @version 1.0 // @author tiamed // @license MIT // @homepageURL https://github.com/tiamed/universal-audio-device-selector // @description Allows you to select audio output device on any sites (except iframe) // @description:zh-cn 可在任意网站切换音视频的音频输出设备(iframe除外) // @description:ja 「あらゆるウェブサイトで音声出力デバイスの選択を可能にするスクリプト ※iframe内のコンテンツは除外」 // @run-at document-end // ==/UserScript== (function() { 'use strict'; let devices = []; let currentDevice; const menu = document.createElement('div'); let isInitialized = false; let isMenuVisible = false; // 菜单样式 Object.assign(menu.style, { position: 'fixed', bottom: '60px', right: '20px', background: '#333', color: 'white', padding: '10px', borderRadius: '5px', zIndex: 999999, display: 'none', maxHeight: '60vh', overflowY: 'auto', boxShadow: '0 2px 10px rgba(0,0,0,0.2)', minWidth: '200px' }); async function initDevices() { try { // 只在首次点击时请求权限 if (!isInitialized) { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); stream.getTracks().forEach(track => track.stop()); isInitialized = true; } await updateDeviceList(); return true; } catch(e) { console.error('Device access error:', e); return false; } } async function updateDeviceList() { devices = (await navigator.mediaDevices.enumerateDevices()) .filter(d => d.kind === 'audiooutput' && d.deviceId !== 'default'); const saved = localStorage.getItem('audioDevice'); currentDevice = devices.find(d => d.deviceId === saved) || devices[0]; } function createDeviceList() { menu.innerHTML = ` <div style="margin-bottom:10px;font-weight:bold;padding:0 5px">音频输出设备</div> ${devices.map(d => ` <div class="device-item" data-device-id="${d.deviceId}" style="padding:8px 12px; cursor:pointer; background:${d.deviceId === currentDevice?.deviceId ? '#444' : 'transparent'}; border-radius:4px; margin:2px 0; transition:background 0.2s;"> ${d.label} </div> `).join('')} `; menu.querySelectorAll('.device-item').forEach(item => { item.addEventListener('click', async () => { const deviceId = item.dataset.deviceId; currentDevice = devices.find(d => d.deviceId === deviceId); localStorage.setItem('audioDevice', deviceId); await updateMediaElements(); createDeviceList(); toggleMenu(); }); }); } async function updateMediaElements() { const mediaElements = document.querySelectorAll('video, audio'); for (const media of mediaElements) { if (currentDevice && media.setSinkId) { try { await media.setSinkId(currentDevice.deviceId); } catch(e) { console.error('Failed to set sink:', e); } } } } function toggleMenu() { isMenuVisible = !isMenuVisible; menu.style.display = isMenuVisible ? 'block' : 'none'; } // 主入口 async function main() { if (window.self !== window.top) return; // 添加控制按钮 const btn = document.createElement('div'); btn.innerHTML = '🔊'; Object.assign(btn.style, { position: 'fixed', bottom: '20px', right: '20px', background: '#444', color: 'white', padding: '12px 15px', borderRadius: '50%', cursor: 'pointer', zIndex: '999999', fontSize: '18px', boxShadow: '0 2px 8px rgba(0,0,0,0.2)', transition: 'transform 0.2s' }); btn.addEventListener('mouseover', () => btn.style.transform = 'scale(1.1)'); btn.addEventListener('mouseout', () => btn.style.transform = 'scale(1)'); btn.addEventListener('click', async () => { if (!isInitialized) { const success = await initDevices(); if (!success) return; } if (!devices.length) await updateDeviceList(); createDeviceList(); toggleMenu(); }); document.body.appendChild(btn); document.body.appendChild(menu); new MutationObserver(updateMediaElements) .observe(document, { subtree: true, childList: true }); } // 点击外部关闭菜单 document.addEventListener('click', (e) => { if (!menu.contains(e.target) && !e.target.isEqualNode(btn)) { menu.style.display = 'none'; isMenuVisible = false; } }); window.addEventListener('load', main); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址