Chrome 64, Web Audio API में एक ऐसी नई सुविधा है जिसका इंतज़ार किया जा रहा था - AudioWorklet. यहां आप वीडियो बनाने के कॉन्सेप्ट और उनके इस्तेमाल के बारे में जानेंगे JavaScript कोड के साथ कस्टम ऑडियो प्रोसेसर. इन बातों पर ध्यान दें: लाइव डेमो भी देख सकते हैं. सीरीज़ का अगला लेख, ऑडियो वर्कलेट डिज़ाइन पैटर्न, यह एक बेहतर ऑडियो ऐप्लिकेशन बनाने के लिए एक दिलचस्प लेख हो सकता है.
बैकग्राउंड: ScriptProcessorNode
Web Audio API में ऑडियो प्रोसेसिंग, मुख्य थ्रेड से अलग थ्रेड में चलती है यूज़र इंटरफ़ेस (यूआई) थ्रेड, ताकि यह आसानी से काम करे. इसमें कस्टम ऑडियो प्रोसेसिंग चालू करने के लिए JavaScript, Web Audio API ने Scriptप्रोसेसरनोड का प्रस्ताव दिया, जिसमें इस सुविधा का इस्तेमाल किया गया था इवेंट हैंडलर का इस्तेमाल करके, उपयोगकर्ता स्क्रिप्ट को मुख्य यूज़र इंटरफ़ेस (यूआई) थ्रेड में शुरू किया जा सकता है.
इस डिज़ाइन में दो समस्याएं हैं: इवेंट मैनेज करने की प्रोसेस एसिंक्रोनस है
डिज़ाइन के मुताबिक बनाया जाता है और कोड को मुख्य थ्रेड पर प्रोसेस किया जाता है. पहला
बाद में, इंतज़ार के समय को कम करता है और बाद वाली प्रोसेस, मुख्य थ्रेड पर दबाव डालती है
इनमें अक्सर कई यूज़र इंटरफ़ेस (यूआई) और डीओएम से जुड़े टास्क होते हैं, जिनकी वजह से यूज़र इंटरफ़ेस (यूआई) है
"जैंक" के लिए या "ग्लिच" ऑडियो हो. डिज़ाइन की इस बुनियादी गलती की वजह से,
ScriptProcessorNode
को स्पेसिफ़िकेशन में शामिल नहीं किया गया है और
AudioWorklet से बदला गया.
कॉन्सेप्ट
ऑडियो वर्कलेट की मदद से, उपयोगकर्ता से मिले JavaScript कोड को
ऑडियो प्रोसेस करने से जुड़ा थ्रेड. इसका मतलब है कि इसे मुख्य साइट पर जाने की ज़रूरत नहीं है
ऑडियो प्रोसेस करने के लिए थ्रेड. इसका मतलब है कि उपयोगकर्ता से मिला स्क्रिप्ट कोड काम करता है
ऑडियो रेंडरिंग थ्रेड (AudioWorkletGlobalScope
) के साथ-साथ
बिल्ट-इन AudioNodes
, जो बिना किसी अतिरिक्त इंतज़ार के समय और सिंक को पक्का करता है
रेंडरिंग.
रजिस्ट्रेशन और इंस्टैंशिएट करना
ऑडियो वर्कलेट के दो हिस्से होते हैं: AudioWorkletProcessor
और
AudioWorkletNode
. इसमें Scriptप्रोसेसरनोड का इस्तेमाल करने के मुकाबले ज़्यादा अहम भूमिका होती है.
हालांकि, डेवलपर को उनकी पसंद के मुताबिक ऑडियो
प्रोसेस चल रही है. AudioWorkletProcessor
असल ऑडियो प्रोसेसर के बारे में बताता है
JavaScript कोड में लिखा होता है और AudioWorkletGlobalScope
में मौजूद होता है.
AudioWorkletNode
, AudioWorkletProcessor
का प्रतिरूप है और यह
मुख्य थ्रेड में अन्य AudioNodes
के कनेक्शन और उससे जुड़े कनेक्शन की यह
मुख्य ग्लोबल स्कोप में दिखाया गया है और यह सामान्य AudioNode
की तरह काम करता है.
यहां कोड स्निपेट का एक जोड़ा दिया गया है, जो इंस्टैंशिएट करना.
// The code in the main global scope.
class MyWorkletNode extends AudioWorkletNode {
constructor(context) {
super(context, 'my-worklet-processor');
}
}
let context = new AudioContext();
context.audioWorklet.addModule('processors.js').then(() => {
let node = new MyWorkletNode(context);
});
AudioWorkletNode
बनाने के लिए, आपको AudioContext जोड़ना होगा
ऑब्जेक्ट और प्रोसेसर के नाम को स्ट्रिंग के रूप में शामिल करें. प्रोसेसर की डेफ़िनिशन
नए ऑडियो वर्कलेट ऑब्जेक्ट के addModule()
कॉल से लोड और रजिस्टर किया गया.
ऑडियो वर्कलेट के साथ वर्कलेट एपीआई सिर्फ़ इसमें उपलब्ध हैं:
सुरक्षित संदर्भ का इस्तेमाल करते हैं, इसलिए
उनका इस्तेमाल करने वाले पेज को एचटीटीपीएस पर दिखाया जाना चाहिए, हालांकि http://localhost
इसे स्थानीय टेस्ट के लिए सुरक्षित माना जाता है.
तय करने के लिए, AudioWorkletNode
को सब-क्लास में शामिल किया जा सकता है
वर्कलेट पर चल रहे प्रोसेसर की मदद से बनाया गया कस्टम नोड.
// This is the "processors.js" file, evaluated in AudioWorkletGlobalScope
// upon audioWorklet.addModule() call in the main global scope.
class MyWorkletProcessor extends AudioWorkletProcessor {
constructor() {
super();
}
process(inputs, outputs, parameters) {
// audio processing code here.
}
}
registerProcessor('my-worklet-processor', MyWorkletProcessor);
AudioWorkletGlobalScope
में registerProcessor()
तरीके को
रजिस्टर किए जाने वाले प्रोसेसर के नाम और क्लास की परिभाषा के लिए स्ट्रिंग.
ग्लोबल स्कोप में स्क्रिप्ट कोड का आकलन पूरा होने के बाद,
AudioWorklet.addModule()
में किए गए प्रॉमिस का समाधान, उपयोगकर्ताओं को सूचना देने के लिए हो जाएगा
कि क्लास डेफ़िनिशन मुख्य ग्लोबल स्कोप में इस्तेमाल किए जाने के लिए तैयार है.
कस्टम ऑडियो पैरामीटर
ऑडियो नोड के बारे में सबसे काम की चीज़ों में से एक है शेड्यूल किया जा सकने वाला पैरामीटर
AudioParam
की मदद से ऑटोमेशन का इस्तेमाल किया. AudioWorkletNodes इनका इस्तेमाल इन कामों के लिए कर सकते हैं
ऐसे पैरामीटर जो ऑडियो की दर पर अपने-आप कंट्रोल हो सकते हैं.
उपयोगकर्ता के तय किए गए ऑडियो पैरामीटर, AudioWorkletProcessor
में तय किए जा सकते हैं
AudioParamDescriptor
का सेट सेट अप करके क्लास की परिभाषा देखें. कॉन्टेंट बनाने
मौजूद WebAudio इंजन इस जानकारी को
AudioWorkletNode का बनाया जा सकता है. इसके बाद, लिंक जोड़कर
AudioParam
ऑब्जेक्ट को उसी हिसाब से नोड में ले जाएं.
/* A separate script file, like "my-worklet-processor.js" */
class MyWorkletProcessor extends AudioWorkletProcessor {
// Static getter to define AudioParam objects in this custom processor.
static get parameterDescriptors() {
return [{
name: 'myParam',
defaultValue: 0.707
}];
}
constructor() { super(); }
process(inputs, outputs, parameters) {
// |myParamValues| is a Float32Array of either 1 or 128 audio samples
// calculated by WebAudio engine from regular AudioParam operations.
// (automation methods, setter) Without any AudioParam change, this array
// would be a single value of 0.707.
const myParamValues = parameters.myParam;
if (myParamValues.length === 1) {
// |myParam| has been a constant value for the current render quantum,
// which can be accessed by |myParamValues[0]|.
} else {
// |myParam| has been changed and |myParamValues| has 128 values.
}
}
}
AudioWorkletProcessor.process()
तरीका
ऑडियो को प्रोसेस करने के लिए, यहां दिए गए process()
कॉलबैक तरीके का इस्तेमाल किया जाता है:
AudioWorkletProcessor
. इसे क्लास के किसी उपयोगकर्ता को ही लागू करना होगा
परिभाषा शामिल नहीं है. Webऑडियो इंजन इस फ़ंक्शन को आइसोक्रोनस में शुरू करता है
इनपुट और पैरामीटर को फ़ीड करने और आउटपुट पाने के लिए फ़ैशन.
/* AudioWorkletProcessor.process() method */
process(inputs, outputs, parameters) {
// The processor may have multiple inputs and outputs. Get the first input and
// output.
const input = inputs[0];
const output = outputs[0];
// Each input or output may have multiple channels. Get the first channel.
const inputChannel0 = input[0];
const outputChannel0 = output[0];
// Get the parameter value array.
const myParamValues = parameters.myParam;
// if |myParam| has been a constant value during this render quantum, the
// length of the array would be 1.
if (myParamValues.length === 1) {
// Simple gain (multiplication) processing over a render quantum
// (128 samples). This processor only supports the mono channel.
for (let i = 0; i < inputChannel0.length; ++i) {
outputChannel0[i] = inputChannel0[i] * myParamValues[0];
}
} else {
for (let i = 0; i < inputChannel0.length; ++i) {
outputChannel0[i] = inputChannel0[i] * myParamValues[i];
}
}
// To keep this processor alive.
return true;
}
इसके अलावा, process()
तरीके की रिटर्न वैल्यू का इस्तेमाल इन कामों के लिए किया जा सकता है
AudioWorkletNode
की लाइफ़टाइम गतिविधि को कंट्रोल करें, ताकि डेवलपर
इस्तेमाल किया जा सकता है. process()
मेथड मार्क से false
मिलता है
प्रोसेसर इनऐक्टिव हो जाता है और WebAudio
इंजन
तरीका. प्रोसेसर को चालू रखने के लिए, इस तरीके से true
दिखना चाहिए.
असल में, नोड और प्रोसेसर का जोड़ा वह कचरा है जिसे सिस्टम इकट्ठा करता है
आखिरकार.
MessagePort की मदद से दो-तरफ़ा बातचीत
कभी-कभी, पसंद के मुताबिक बनाया गया AudioWorkletNode
ऐसे कंट्रोल दिखाना चाहता है जो
AudioParam
के लिए मैप, जैसे कि स्ट्रिंग पर आधारित type
एट्रिब्यूट
का इस्तेमाल कस्टम फ़िल्टर को कंट्रोल करने के लिए किया जाता है. इस मक़सद से और आगे,
AudioWorkletNode
और AudioWorkletProcessor
,
दो-तरफ़ा बातचीत के लिए MessagePort
. किसी भी तरह का कस्टम डेटा
इस चैनल से लेन-देन किया जा सकता है.
MessagePort को नोड और दोनों पर .port
एट्रिब्यूट के साथ ऐक्सेस किया जा सकता है
प्रोसेसर. नोड की port.postMessage()
विधि
संबंधित प्रोसेसर का port.onmessage
हैंडलर और रिवर्स.
/* The code in the main global scope. */
context.audioWorklet.addModule('processors.js').then(() => {
let node = new AudioWorkletNode(context, 'port-processor');
node.port.onmessage = (event) => {
// Handling data from the processor.
console.log(event.data);
};
node.port.postMessage('Hello!');
});
/* "processors.js" file. */
class PortProcessor extends AudioWorkletProcessor {
constructor() {
super();
this.port.onmessage = (event) => {
// Handling data from the node.
console.log(event.data);
};
this.port.postMessage('Hi!');
}
process(inputs, outputs, parameters) {
// Do nothing, producing silent output.
return true;
}
}
registerProcessor('port-processor', PortProcessor);
MessagePort
में ट्रांसफ़र किया जा सकता है. इससे आपको यह सुविधा मिलती है
डेटा स्टोरेज या WASM मॉड्यूल को थ्रेड की सीमा पर ट्रांसफ़र कर सकता है. इससे यह खुलता है
ऑडियो वर्कलेट सिस्टम के इस्तेमाल की अनगिनत संभावनाएँ हैं.
आगे बढ़ें: गैननोड बनाएं
यहां नीचे के सबसे ऊपर बने GanNode का पूरा उदाहरण दिया गया है
AudioWorkletNode
और AudioWorkletProcessor
.
index.html
फ़ाइल:
<!doctype html>
<html>
<script>
const context = new AudioContext();
// Loads module script with AudioWorklet.
context.audioWorklet.addModule('gain-processor.js').then(() => {
let oscillator = new OscillatorNode(context);
// After the resolution of module loading, an AudioWorkletNode can be
// constructed.
let gainWorkletNode = new AudioWorkletNode(context, 'gain-processor');
// AudioWorkletNode can be interoperable with other native AudioNodes.
oscillator.connect(gainWorkletNode).connect(context.destination);
oscillator.start();
});
</script>
</html>
gain-processor.js
फ़ाइल:
class GainProcessor extends AudioWorkletProcessor {
// Custom AudioParams can be defined with this static getter.
static get parameterDescriptors() {
return [{ name: 'gain', defaultValue: 1 }];
}
constructor() {
// The super constructor call is required.
super();
}
process(inputs, outputs, parameters) {
const input = inputs[0];
const output = outputs[0];
const gain = parameters.gain;
for (let channel = 0; channel < input.length; ++channel) {
const inputChannel = input[channel];
const outputChannel = output[channel];
if (gain.length === 1) {
for (let i = 0; i < inputChannel.length; ++i)
outputChannel[i] = inputChannel[i] * gain[0];
} else {
for (let i = 0; i < inputChannel.length; ++i)
outputChannel[i] = inputChannel[i] * gain[i];
}
}
return true;
}
}
registerProcessor('gain-processor', GainProcessor);
इसमें ऑडियो वर्कलेट सिस्टम की बुनियादी बातें शामिल हैं. लाइव डेमो उपलब्ध हैं Chrome WebAudio टीम की GitHub रिपॉज़िटरी पर मिलेगी.
फ़ीचर ट्रांज़िशन: एक्सपेरिमेंटल से स्टेबल
ऑडियो वर्कलेट, Chrome 66 या उसके बाद के वर्शन के लिए डिफ़ॉल्ट रूप से चालू होता है. Chrome 64 और 65 में, यह सुविधा एक्सपेरिमेंटल फ़्लैग के पीछे थी.