Web Audio API برای تولید، پردازش و ترکیب صدا در مرورگر به کار میرود. اگر فقط پخش یک فایل لازم است، عنصر audio ممکن است کافی باشد؛ اگر تولید tone، کنترل gain یا تحلیل سیگنال لازم دارید، یک Audio Graph مفیدتر میشود. انتخاب باید از وظیفهٔ محصول بیاید. معرفی این API به معنی تبدیل هر سایت به استودیوی موسیقی یا تضمین تأخیر یکسان روی همهٔ دستگاهها نیست. سختافزار، مرورگر و پیچیدگی پردازش همچنان در نتیجه اثر دارند.
نسخهٔ قبلی مقاله چند سرویس را با مالکیت و صفت موفقیت معرفی میکرد، بدون اینکه تاریخ و منبع آنها روشن باشد. این بخش حذف شده است تا متن به مفاهیم و نمونهٔ قابل پیگیری بپردازد. مرجع Web Audio API در MDN ابزارهای تولید صدا و مسیر اتصال آنها را شرح میدهد. برای شروع، یک صدای کوتاه با کنترل مشخص، از فهرست امکاناتی که کاربردشان معلوم نیست آموزندهتر است.
Audio Graph را به مسیر سیگنال تبدیل کنید
در یک graph ساده، منبع صدا به node کنترل حجم وصل میشود و خروجی آن به مقصد شنیداری میرود. هر node نقش مشخص دارد. اگر یک node به مقصد وصل نباشد، لزوماً صدای قابل شنیدن تولید نمیشود؛ شاید برای تحلیل استفاده شود یا مسیر ناقص باشد. رسم مسیر منبع، پردازش و مقصد کمک میکند هنگام عیبیابی بدانیم کدام اتصال را باید بررسی کرد. این ترتیب از تغییر تصادفی تنظیمهای چند node روشنتر است.
AudioContext زمینهٔ اجرای همین graph را نگه میدارد. برای یک صفحهٔ کوچک، ایجاد Context تازه برای هر کلیک معمولاً قرارداد سادهای نمیسازد. بهتر است عمر Context و عمر منبع صدا را جدا ببینید. یک Context میتواند برای تعاملهای بعدی استفاده شود، در حالی که منبع کوتاه برای هر بار پخش ساخته میشود. نیاز دقیق به ساخت یا آزاد کردن منابع را با رفتار API بررسی کنید؛ نام مشترک «صدا» به معنی عمر یکسان همهٔ شیءها نیست.
نمونهٔ کامل یک tone کوتاه
نمونهٔ زیر یک فایل مستقل HTML است. آن را به نام audio-tone.html ذخیره کنید و با مرورگری که Web Audio API را پشتیبانی میکند باز کنید. فایل صدا، package، microphone یا API شبکه لازم نیست. با کلیک دکمه یک tone کوتاه تولید میشود. صدا فقط پس از درخواست کاربر شروع میشود و متن وضعیت نیز نتیجهٔ همان درخواست را نشان میدهد. این نمونهٔ آموزشی ساز موسیقی یا آزمون شنوایی نیست.
<!doctype html>
<html lang="fa" dir="rtl">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>نمونه صدای کوتاه</title>
<style>body{font-family:system-ui;max-width:36rem;margin:2rem auto;padding:1rem}button{font:inherit;padding:.7rem 1rem}button:focus-visible{outline:3px solid #2447a8}</style>
<h1>پخش صدای کوتاه</h1>
<button type="button" id="play-tone">پخش tone</button>
<p id="tone-status" role="status">صدا فقط پس از کلیک شروع میشود.</p>
<script>
let context;
const button = document.getElementById('play-tone');
const status = document.getElementById('tone-status');
button.addEventListener('click', async () => {
button.disabled = true;
try {
context ??= new AudioContext();
if (context.state === 'suspended') await context.resume();
const source = context.createOscillator();
const gain = context.createGain();
const start = context.currentTime;
source.type = 'sine';
source.frequency.value = 440;
gain.gain.setValueAtTime(0, start);
gain.gain.linearRampToValueAtTime(0.04, start + 0.02);
gain.gain.linearRampToValueAtTime(0, start + 0.3);
source.connect(gain).connect(context.destination);
source.addEventListener('ended', () => { source.disconnect(); gain.disconnect(); button.disabled = false; });
source.start(start);
source.stop(start + 0.32);
status.textContent = 'درخواست پخش صدای کوتاه انجام شد.';
} catch {
button.disabled = false;
status.textContent = 'پخش انجام نشد؛ دوباره تلاش کنید.';
}
});
</script>
</html>
تمام idهای استفادهشده در JavaScript در HTML وجود دارند. دکمهٔ play-tone عمل کاربر را دریافت میکند و tone-status پیام متنی را نشان میدهد. CSS نیز فقط همان ساختار را شکل میدهد. مقدار فرکانس و زمان برای یک مثال ساده ثابتاند. اگر خواستید آنها را تغییر دهید، دامنهٔ مجاز ورودی و روش نمایش را نیز مشخص کنید. دادهٔ ورودی دلخواه را بدون محدودیت به پارامتر صوتی وصل نکنید، مخصوصاً اگر رابط اجازهٔ حجم یا زمان طولانی میدهد.
در هر پخش، Oscillator تازه ساخته میشود. مرجع OscillatorNode نقش این منبع تناوبی را توضیح میدهد. برنامه پس از پایان، اتصال nodeهای همان پخش را آزاد میکند. Context برای کلیک بعدی باقی میماند. این تفاوت عمر، در کد عمداً دیده میشود تا خواننده تصور نکند یک منبع پایانیافته را باید برای هر درخواست دوباره start کند. قرارداد start و stop را مطابق همان نوع منبع بخوانید.
تغییر gain را با شروع و پایان صدا هماهنگ کنید
تغییر ناگهانی مقدار سیگنال میتواند در بعضی موقعیتها صدای کلیک ایجاد کند. در نمونه، gain از مقدار پایین شروع میشود، کمی بالا میرود و دوباره پایین میآید. مرجع GainNode نقش کنترل دامنه را توضیح میدهد. این envelope کوچک برای فهم شروع و پایان است، نه یک تنظیم عمومی مناسب تمام صداها. اگر محصول با فایل موسیقی یا صدای گفتار کار میکند، نیاز و کیفیت خروجی باید جدا بررسی شود.
کم بودن مقدار gain نیز تضمین بلندی صدای واقعی در همهٔ دستگاهها نیست. حجم سیستم، هدفون و شکل موج در شنیدن اثر دارند. برای محصول، کنترل قابل فهم صدا و امکان توقف لازم است. یک صدای طولانی نباید فقط با بستن تب متوقف شود. نمونهٔ کوتاه این مقاله خودبهخود پایان مییابد، ولی این رفتار را به پخشهای طولانی تعمیم ندهید. قرارداد تجربه باید با مدت و نقش صدا هماهنگ باشد.
Autoplay را بخشی از محیط مرورگر بدانید
مرورگرها برای شروع صدا بدون تعامل کاربر سیاست دارند. راهنمای Autoplay این زمینه را توضیح میدهد. اگر Context در حالت suspended باشد، نمونه پس از کلیک resume میکند. این رفتار با فرض شروع خودکار هنگام بارگذاری فرق دارد. برای کاربر، دکمه و پیام باید روشن کنند چه چیزی قرار است شنیده شود. دریافت اجازهٔ microphone نیز موضوع دیگری است و این نمونه به آن نیاز ندارد.
اگر پخش شکست خورد، پیام نمونه موفقیت نشان نمیدهد. در محصول، وضعیت فنی را با زبانی قابل استفاده توضیح دهید و راه دوباره تلاش کردن را داشته باشید. خطایی که فقط در console دیده شود، به کاربر نمیگوید چرا سکوت میشنود. این نکته در کنترلهای صوتی اهمیت دارد، چون نبود صدا چند علت ممکن دارد: وضعیت مرورگر، حجم دستگاه یا خطای برنامه. رابط نباید بدون اطلاعات لازم یکی از آنها را قطعی اعلام کند.
AudioWorklet برای پردازش سفارشی
وقتی پردازش سفارشی سیگنال لازم باشد، AudioWorklet ابزار مرتبطی است. مرجع AudioWorklet محیط اجرای آن را توضیح میدهد. به یک tone ساده نیازی به افزودن این لایه نیست. ابتدا مشخص کنید nodeهای موجود چه بخشی از نیاز را پاسخ میدهند و کجا پردازش تازه لازم است. فایل Worklet و شرایط اجرای آن باید در نمونهٔ آموزشی معرفی شوند؛ یک تابع پردازش جدا بدون روش بارگذاری، مثال کامل نیست.
محاسبهٔ سنگین و ساخت مکرر داده در مسیر پردازش میتواند کیفیت را تحت تأثیر قرار دهد. انتخاب الگوریتم باید با بودجهٔ زمانی صدا هماهنگ باشد. نتیجهٔ یک دستگاه سریع، وضعیت همهٔ مخاطبان را توضیح نمیدهد. برای ارزیابی، تعداد nodeها، نرخ نمونهبرداری و مسیر ورودی را ثبت کنید. یک عدد کلی «بلادرنگ» بدون این زمینه معلوم نمیکند محصول در چه شرایطی پاسخ مناسب دارد و چه محدودیتهایی باقی ماندهاند.
صدا تنها مسیر پیام نباشد
اگر برنامه با tone موفقیت یک عملیات را اعلام میکند، همان نتیجه باید در متن یا نشانهٔ قابل مشاهده نیز وجود داشته باشد. ممکن است دستگاه بیصدا باشد یا کاربر صدا را نشنود. در نمونه، پیام متنی کنار پخش قرار دارد، اما این پیام صرفاً اجرای درخواست tone را توصیف میکند. برای یک عملیات تجاری، متن باید نتیجهٔ همان عملیات را از پاسخ معتبر بگیرد. صدای خوشایند بهتنهایی ثبت موفق سفارش را ثابت نمیکند.
نمایش waveform یا نمودار فرکانس نیز باید نقش روشن داشته باشد. اگر فقط تزئینی است، نباید خواندن کنترلها را سخت کند. اگر برای تحلیل لازم است، برچسب و واحد باید دقیق باشند. تصویری که با موسیقی حرکت میکند، الزاماً نمودار اندازهگیریشده با معنای علمی نیست. برای شروع طراحی رابط، بحث Microinteractions به انتخاب بازخورد مرتبط کمک میکند. نقش هر نمایش و هر صدا را پیش از اضافه کردن جلوهها مشخص کنید.
قدم بعدی را با نیاز محصول انتخاب کنید
اگر صدا از محتوای کاربران میآید، اندازه و نوع فایل و رفتار شکست دریافت را مشخص کنید. عنوان فایل و مجوز استفاده نیز بخشی از قرارداد محتواست. نمایش یک کنترل پخش برای فایلی که هنوز آماده نیست باید وضعیت روشنی داشته باشد. جدا کردن مرحلهٔ دریافت از مرحلهٔ پخش کمک میکند کاربر سکوت ناشی از انتظار را با پایان فایل یا خطای دستگاه اشتباه نگیرد.
پس از فهم tone، میتوان مسیر ورودی فایل، فیلتر یا تحلیل را جدا بررسی کرد. هر مرحله باید ساختار، dependency و رفتار خطای خود را داشته باشد. راهنمای بهترین رویههای Web Audio برای نگهداری این مسیر مفید است. ابتدا یک وظیفهٔ محدود را کامل تعریف کنید؛ مثلاً پخش قابل توقف یک فایل یا تولید صدای کوتاه پس از عمل کاربر. همین تعریف، ابزار لازم را از فهرست کلی قابلیتها جدا میکند.
هنوز دیدگاهی ثبت نشده
اولین نفری باشید که نظر میدهد!