MediaWiki:Gadget-PrintOptions.js:修订间差异
外观
小无编辑摘要 |
小无编辑摘要 |
||
| 第1行: | 第1行: | ||
// ==UserScript== | // ==UserScript== | ||
// @name | // @name Safe Web Audio Implementation | ||
// @namespace https://github.com/ | |||
// @namespace https://github.com | // @version 1.0 | ||
// @version | // @description Proper AudioContext initialization with full error handling | ||
// @author You | |||
// @match *://*/* | // @match *://*/* | ||
// @grant none | // @grant none | ||
// @require https:// | // @require https://cdn.jsdelivr.net/npm/web-audio-api-shim@0.2.6/build/WebAudioAPI.min.js | ||
// ==/UserScript== | // ==/UserScript== | ||
| 第12行: | 第13行: | ||
'use strict'; | 'use strict'; | ||
// | // 🔊 Audio Context Manager Class | ||
class AudioSystem { | |||
constructor(options = {}) { | |||
this.options = { | |||
latencyHint: 'interactive', | |||
sampleRate: 44100, | |||
...options | |||
}; | |||
this.context = null; | |||
this.init(); | |||
} | } | ||
// | // 🔍 Detect supported AudioContext class | ||
static getAudioContextClass() { | |||
const prefixes = ['', 'webkit', 'moz', 'ms']; | |||
for (const prefix of prefixes) { | |||
const name = prefix ? `${prefix}AudioContext` : 'AudioContext'; | |||
if (window[name]) return window[name]; | |||
name | |||
} | } | ||
return null; | |||
} | |||
// | // 🏗️ Initialize audio system | ||
init() { | init() { | ||
const | const AudioContextClass = AudioSystem.getAudioContextClass(); | ||
if (! | if (!AudioContextClass) { | ||
console.warn(' | console.warn('Web Audio API not supported'); | ||
return; | return; | ||
} | } | ||
try { | |||
. | this.context = new AudioContextClass(this.options); | ||
this.setupEventListeners(); | |||
this.log('AudioContext created'); | |||
} catch (error) { | |||
console.error('AudioContext initialization failed:', error); | |||
} | } | ||
} | } | ||
// 🎛️ Setup state management | |||
setupEventListeners() { | |||
if (!this.context) return; | |||
// | // Monitor state changes | ||
this.context.onstatechange = () => { | |||
this.log(`State changed: ${this.context.state}`); | |||
if (this.context.state === 'suspended') { | |||
this.addActivationTriggers(); | |||
} | } | ||
}; | }; | ||
// | // Initial activation check | ||
if (this.context.state === 'suspended') { | |||
this.addActivationTriggers(); | |||
} | } | ||
} | |||
// 🖱️ Add user interaction triggers | |||
const | addActivationTriggers() { | ||
const events = ['click', 'keydown', 'touchstart']; | |||
const handler = () => { | |||
if ( | if (this.context && this.context.state === 'suspended') { | ||
this. | this.context.resume() | ||
.then(() => this.log('Audio resumed successfully')) | |||
.catch(err => console.error('Resume failed:', err)); | |||
} | } | ||
}); | |||
} | // Remove after first activation | ||
events.forEach(e => document.removeEventListener(e, handler)); | |||
}; | |||
events.forEach(e => document.addEventListener(e, handler)); | |||
} | |||
// | // 📝 Logging helper | ||
log(message) { | |||
console.log(`[AudioSystem] ${message}`); | |||
} | |||
// 🎵 Safe audio playback | |||
playBuffer(buffer) { | |||
if (!this.context || this.context.state !== 'running') { | |||
console.warn('Audio not ready'); | |||
return null; | |||
} | |||
if ( | |||
const | try { | ||
const source = this.context.createBufferSource(); | |||
source.buffer = buffer; | |||
source.connect(this.context.destination); | |||
source.start(); | |||
return source; | |||
} catch (error) { | |||
console.error('Playback failed:', error); | |||
return null; | |||
} | } | ||
} | } | ||
}; | } | ||
// 🚀 Startup sequence | |||
document.addEventListener('DOMContentLoaded', () => { | |||
const audioSystem = new AudioSystem({ | |||
latencyHint: 'balanced', | |||
sampleRate: 48000 | |||
}); | |||
// Example usage | |||
setTimeout(() => { | |||
if (audioSystem.context) { | |||
// Load and play dummy sound | |||
const buffer = audioSystem.context.createBuffer( | |||
1, | |||
audioSystem.context.sampleRate * 0.5, | |||
audioSystem.context.sampleRate | |||
); | |||
audioSystem.playBuffer(buffer); | |||
} | |||
}, 3000); | |||
}); | }); | ||
})(); | })(); | ||
2025年11月1日 (六) 20:36的版本
// ==UserScript==
// @name Safe Web Audio Implementation
// @namespace https://github.com/
// @version 1.0
// @description Proper AudioContext initialization with full error handling
// @author You
// @match *://*/*
// @grant none
// @require https://cdn.jsdelivr.net/npm/web-audio-api-shim@0.2.6/build/WebAudioAPI.min.js
// ==/UserScript==
(function() {
'use strict';
// 🔊 Audio Context Manager Class
class AudioSystem {
constructor(options = {}) {
this.options = {
latencyHint: 'interactive',
sampleRate: 44100,
...options
};
this.context = null;
this.init();
}
// 🔍 Detect supported AudioContext class
static getAudioContextClass() {
const prefixes = ['', 'webkit', 'moz', 'ms'];
for (const prefix of prefixes) {
const name = prefix ? `${prefix}AudioContext` : 'AudioContext';
if (window[name]) return window[name];
}
return null;
}
// 🏗️ Initialize audio system
init() {
const AudioContextClass = AudioSystem.getAudioContextClass();
if (!AudioContextClass) {
console.warn('Web Audio API not supported');
return;
}
try {
this.context = new AudioContextClass(this.options);
this.setupEventListeners();
this.log('AudioContext created');
} catch (error) {
console.error('AudioContext initialization failed:', error);
}
}
// 🎛️ Setup state management
setupEventListeners() {
if (!this.context) return;
// Monitor state changes
this.context.onstatechange = () => {
this.log(`State changed: ${this.context.state}`);
if (this.context.state === 'suspended') {
this.addActivationTriggers();
}
};
// Initial activation check
if (this.context.state === 'suspended') {
this.addActivationTriggers();
}
}
// 🖱️ Add user interaction triggers
addActivationTriggers() {
const events = ['click', 'keydown', 'touchstart'];
const handler = () => {
if (this.context && this.context.state === 'suspended') {
this.context.resume()
.then(() => this.log('Audio resumed successfully'))
.catch(err => console.error('Resume failed:', err));
}
// Remove after first activation
events.forEach(e => document.removeEventListener(e, handler));
};
events.forEach(e => document.addEventListener(e, handler));
}
// 📝 Logging helper
log(message) {
console.log(`[AudioSystem] ${message}`);
}
// 🎵 Safe audio playback
playBuffer(buffer) {
if (!this.context || this.context.state !== 'running') {
console.warn('Audio not ready');
return null;
}
try {
const source = this.context.createBufferSource();
source.buffer = buffer;
source.connect(this.context.destination);
source.start();
return source;
} catch (error) {
console.error('Playback failed:', error);
return null;
}
}
}
// 🚀 Startup sequence
document.addEventListener('DOMContentLoaded', () => {
const audioSystem = new AudioSystem({
latencyHint: 'balanced',
sampleRate: 48000
});
// Example usage
setTimeout(() => {
if (audioSystem.context) {
// Load and play dummy sound
const buffer = audioSystem.context.createBuffer(
1,
audioSystem.context.sampleRate * 0.5,
audioSystem.context.sampleRate
);
audioSystem.playBuffer(buffer);
}
}, 3000);
});
})();