وقتی صوت بهصورت بایتهای تدریجی میرسد، مرزِ هر تکهٔ دریافتی لزوماً مرزِ فریمِ برنامه نیست. ممکن است سرآیند نصف شود یا دو فریم در یک تکه باشند. این راهنما یک قراردادِ آموزشیِ اصیل و parser افزایشی میسازد؛ شبکه، میکروفن یاپخشِ صوت را اجرا نمیکند و فرمتِ API اپرا نیست.
قرارداد را پیش از اتصالِ بایتها بنویسیم
سرآیندِ ۲۰ بایتی شامل نشانِ PCM1، نوع ۱، نسخه ۱، تککانال، عرضِ نمونه ۲ بایت، نرخ ۱۶۰۰۰، شمارهٔترتیب و طولِ payload است. عددهایِ چندبایتی و نمونههایِ PCM16 در این قرارداد little-endian اند. شماره ازصفر شروع میشود و هر فریم دقیقاً یکی اضافه میکند. payload باید ۲ تا ۴۰۹۶ بایت و مضربِ دو باشد.
این سرآیند اختراعِ تمرین است، نه RFC6455 یا RTP. WebSocket میتواند دادهٔمتنی و باینری داشته باشد، اما محتوایِ باینری را قراردادِ برنامه تفسیر میکند. تقسیمِ دلخواهِ جریانِ بایت در این آزمون را هم با API رویدادِ message مرورگر یا مرزِ بستهٔشبکه یکی فرض نمیکنیم.
بافرِ ناقص را تا رسیدنِ اطلاعاتِ کافی نگه داریم
تا وقتی ۲۰ بایتِ سرآیند نداریم، خروجی تولید نمیشود. پس از خواندنِ سرآیند، نوع، نسخه، مشخصات، ترتیب و طول کنترل میشوند. اگر payload کامل نرسیده باشد، فریمِ جزئی در بافر میماند؛ فقط فریمِ کامل به فهرستِ خروجی میرود. حلقه میتواند چند فریمِ کاملِ داخلِ یک feed را پشتِ سرهم بردارد.
برای نمونه، فریمِ صفر سه مقدار[۱۰۰، −۱۰۰، ۰]و فریمِ یک چهار مقدار[۳۲۷۶۷، −۳۲۷۶۸، ۲۳، ۰]دارد. مجموعِ سرآیندها و داده ۵۴ بایت است. فایل JSONhex همین جریان و قراردادِ فیلدها را میدهد؛ PCM را رشتهٔUTF-8 یا متنِ JSON فرض نکردهایم.
هر محلِ شکستِ این نمونه واقعاً آزموده شد
کد جریانِ ۵۴ بایتی را درتمامِ ۵۵ مرزِ ممکن به دو تکه تقسیم میکند وهر بارهمان دو فریم و هفت مقداررا پس میگیرد. درآزمونِ جدا، تکتکِ بایتها feed میشوند و باز هم خروجی یکسان است. این شاهدِ پایداریِ parser برایهمین fixture در برابرِ محلِ شکست است؛ بارِ عملیاتیِ نامحدود یا نبودِ تمامِ خطاهایِ پروتکل را ثابت نمیکند.
| کنترل | نتیجهٔ موردانتظارِ اجراشده |
|---|---|
| ۵۵ تقسیمِ دوتکه | دو فریمِ یکسان، بهترتیب ۰ و ۱ |
| feed بایتبهبایت | همان هفت مقدارِ PCM16 |
| پایانِ ناقص | خطا در finish؛ فریمِ کاملِ جعلی نمیسازد |
| شروع بافریمِ ۱ | خطایِ ترتیب؛ صفرِ گمشده حدس زده نمیشود |
طول و وضعیتِ ردشده را مهار کنیم
هفت حالتِ رد واقعاً داریم: حذفِ بایتِ آخر، ترتیبِ غلط، طولِ بیشازحد، طولِ فرد، نوعِ سرآیندِ نامعتبر، رشتهٔJSON بهجای bytes و feed بیشازسقفِ بافر. سقفِ بافرِ محلی ۸۲۳۲ بایت است؛ این عدد محدودیتِ سرویس یااندازهٔپیشنهادیِ بستهٔتلفنی نیست. پس ازخطا، parser متوقف میماند تا دادهٔناقص با ادامهٔظاهراًسالم قاطی نشود.
این نسخه بازیابیِ پسازقطع، تأییدِ دریافت، زمانِ واقعی، چندکانال، احرازِ هویت یا jitterbuffer ندارد. به جریانِ ناشناسِ واقعی وصلش نکردهایم؛ تنظیماتِ نمونه و schema متنی را ازبایتِ صوت جدا نگه دارید و قبل ازاستفادهٔواقعی قراردادِ همان سرویس را بخوانید.
این کار با اتصالِ فایل یا متنِ موقت فرق دارد
چسباندنِ WAV هایِ سازگار ظرفهایِ کامل دارد؛ اینجا سرآیند و payload ممکن است نصف برسند. مدیریتِ متنِ موقت و نهاییِ ASR نیز قراردادِ رویدادِ متنی است، نه parserِ PCM. اگر به پیادهسازیِ زنده در اپرانگار نیاز دارید، آن را برای بررسیِ روشِ قابلارائه مطرح کنید؛ این نمونه وجودِ API استریم، فرمتِ PCM1 یاپشتیبانیِ آن در محصول را اعلام نمیکند.
فایل تمرین و منبع
parser بایتی با بافرِ جزئی، ترتیب، حدِ طول و پایانِ ناقص · قراردادِ ۲۰ بایتی و hex دو فریمِ اصیل، جدا ازمتنِ JSON
منابع در ۳ نوامبر ۲۰۲۶ خوانده شدند؛ این تاریخ، تاریخ انتشار منبع نیست. مثالها و فایلهای این راهنما آموزشی و ساختهٔ تحریریهاند.