WebCodecs ہینڈ بک: براؤزرز میں بنیادی ویڈیو پروسیسنگ

اگر آپ نے کبھی براؤزر میں ویڈیو پر کارروائی کرنے کی کوشش کی ہے، جیسے کہ ویڈیو ایڈیٹنگ یا اسٹریمنگ ایپ، تو آپ یا تو سرور پر ویڈیو پر کارروائی کرنے کا انتخاب کرسکتے ہیں (مہنگا) یا ffmpeg.js (clunky) استعمال کریں۔ WebCodecs API کے ساتھ، اب ایسا کرنے کا ایک بہتر طریقہ موجود ہے۔

WebCodecs ایک نسبتاً نیا API ہے جو براؤزر ایپلی کیشنز کو انتہائی کم سطح کے کنٹرول کے ساتھ مؤثر طریقے سے ویڈیو پر کارروائی کرنے کی اجازت دیتا ہے۔

ماضی میں، اگر آپ ایک ویڈیو ایڈیٹنگ ایپ، لائیو اسٹریمنگ اسٹوڈیو، یا کوئی ایسی چیز بنانا چاہتے تھے جس کے لیے ‘ہیوی لفٹنگ’ کی ضرورت ہوتی ہو، تو آپ کو ایک بنیادی ڈیسک ٹاپ ایپلی کیشن بنانا پڑتا تھا۔ بہت سے SaaS ٹولز، جیسے Canva، نے اس مسئلے کو سرور سائیڈ ویڈیو پروسیسنگ کے ذریعے حل کیا ہے۔ یہ بہت بہتر UX فراہم کرتا ہے، لیکن زیادہ پیچیدہ اور مہنگا ہے۔

WebCodecs کے ساتھ، آپ اب ان ایپس کو مکمل طور پر براؤزر میں بنا سکتے ہیں، بغیر آپ کے صارفین کو کوئی سافٹ ویئر ڈاؤن لوڈ اور انسٹال کرنے، یا مہنگے اور پیچیدہ سرور انفراسٹرکچر کے بغیر۔

یہ نظریاتی نہیں ہے۔ ویڈیو ایڈیٹنگ ٹولز جیسے Capcut نے WebCodecs + WebAssembly پر سوئچ کرنے کے بعد ٹریفک میں 83% اضافہ دیکھا۔ [1]. یوٹیلیٹی ایپس جیسے Remotion Convert اور Free AI Video Upscaler (دونوں اوپن سورس) روزانہ ہزاروں ویڈیوز کو بغیر سرور کی لاگت کے اور کسی انسٹالیشن کی ضرورت کے بغیر پروسیس کرتی ہیں۔ [2].

WebCodecs کو مکمل طور پر نئے استعمال کے معاملات کے لیے بھی استعمال کیا جا رہا ہے، جیسے کہ پروگرام کے ذریعے ویڈیو بنانا۔ [3].

اگر آپ کسی بھی قسم کی ویڈیو ایپ بنا رہے ہیں، تو WebCodecs کے بارے میں جاننا ضروری ہے، کم از کم براؤزر میں ویڈیو کے ساتھ کام کرنے کے آپشن کے طور پر۔

اس گائیڈ میں آپ کریں گے:

  1. ویڈیو پروسیسنگ کی بنیادی باتوں کا جائزہ لیں۔

  2. WebCodecs API کا تعارف

  3. ویڈیو فائلوں کو پڑھنے اور لکھنے کے لیے مکسنگ + ڈیمکسنگ ڈسکشن

  4. ویڈیوز کو webm + mp4 کے درمیان تبدیل کرنے اور مقامی تبادلوں کو لاگو کرنے کے لیے اپنی ویڈیو کنورژن یوٹیلیٹی بنائیں۔

  5. پروڈکشن لیول کے کچھ مسائل کو طے کیا۔

  6. اضافی وسائل کی بحث

اس مضمون کا مقصد ایک عملی نقطہ آغاز اور سامنے والے ڈویلپرز کے لیے WebCodecs API کا تعارف ہے۔ یہ آپ کو سکھائے گا کہ API کیسے کام کرتا ہے اور آپ اس کے ساتھ کیا کر سکتے ہیں۔ میں فرض کرتا ہوں کہ آپ جاوا اسکرپٹ کی بنیادی باتیں جانتے ہیں، لیکن اس کی پیروی کرنے کے لیے آپ کو سینئر ڈویلپر یا ویڈیو انجینئر بننے کی ضرورت نہیں ہے۔

آخر میں، میں اضافی سیکھنے کے وسائل اور حوالہ جات کا ذکر کروں گا۔ مستقبل کے ٹیوٹوریلز میں، ہم مخصوص عنوانات کی گہرائی میں جائیں گے، جیسے کہ ویڈیو ایڈیٹر بنانا یا WebCodecs کا استعمال کرتے ہوئے لائیو سٹریمنگ کرنا۔ لیکن یہ ہینڈ بک آپ کو ایک ٹھوس نقطہ آغاز فراہم کرے گا کہ WebCodecs کیا ہے، یہ کیا کر سکتا ہے، اور WebCodecs کا استعمال کرتے ہوئے بنیادی ایپلی کیشنز کیسے بنائے جائیں۔

انڈیکس

شرطیں

ساتھ چلنے کے لیے آپ کو ویڈیو انجینئر بننے کی ضرورت نہیں ہے، لیکن آپ کو درج ذیل سے واقف ہونا چاہیے:

  • بنیادی JavaScript، بشمول async/await اور کال بیکس

  • مقامی براؤزر APIs جیسے fetch اور DOM

  • فائل آبجیکٹ کیا ہے اور HTML میں فائل ان پٹ کیسے کام کرتا ہے؟

  • HTML5 کیا ہے اس کی عمومی تفہیم (مختصر طور پر استعمال کیا جاتا ہے لیکن گہرائی میں نہیں)

ویڈیو پروسیسنگ، کوڈیکس، یا میڈیا APIs کے بارے میں پہلے سے علم کی ضرورت نہیں ہے۔ اس ہینڈ بک کے پہلے نصف میں ہم اس کا احاطہ کرتے ہیں۔

ویڈیو پروسیسنگ پرائمر

اس سے پہلے کہ ہم WebCodecs میں داخل ہوں، میں اس بات کو یقینی بنانا چاہتا ہوں کہ کوڈیک کیا ہے اس سے پہلے کہ آپ اسے ویب پر ڈالنے پر غور کریں۔

ویڈیو فریم

میرے خیال میں آپ جانتے ہیں کہ ویڈیو کیا ہے۔ ستم ظریفی یہ ہے کہ نیچے دی گئی ‘ویڈیو’ دراصل ایک GIF ہے، لیکن آپ کو خیال آتا ہے۔

بگ بک بنی، ایک اوپن سورس ویڈیو

ایک ویڈیو صرف تصاویر کا ایک سلسلہ ہے جو تیزی سے یکے بعد دیگرے دکھائے جاتے ہیں۔ ہر تصویر ہے۔ ویڈیو فریمہر فریم ٹائم اسٹیمپ سے منسلک ہوتا ہے۔ جب ویڈیو پلیئر ایک ویڈیو چلاتا ہے، تو یہ ہر ویڈیو فریم کو ٹائم اسٹیمپ کے ذریعہ اشارہ کردہ وقت پر دکھاتا ہے۔

ویڈیو فریم

ویڈیو کا ہر فریم پکسلز پر مشتمل ہوتا ہے، اور ایک 4K ویڈیو فریم تقریباً 8 ملین پکسلز (3840*2160 = 8294400) پر مشتمل ہوتا ہے۔

ویڈیو فریم میں پکسلز ہیں۔

ہر پکسل بذات خود اصل میں تین اجزاء پر مشتمل ہوتا ہے: سرخ، سبز اور نیلی قدریں (جسے آر جی بی ویلیوز بھی کہا جاتا ہے)۔

آر جی بی چینل

ہر R، G، اور B رنگ کی قدر 0 سے 255 کے درمیان ایک 8 بٹ انٹیجر کے طور پر ذخیرہ کی جاتی ہے، جس میں سرخ، سبز، یا نیلے رنگ کے اجزاء کی شدت کی نمائندگی کرنے والے نمبر ہوتے ہیں۔

uint8 رنگین چینل

R، G، اور B اجزاء میں سے ہر ایک کی طاقت کو ملا کر، ہم رنگین سپیکٹرم میں کسی بھی رنگ کی نمائندگی کر سکتے ہیں۔

آرجیبی کلر ویلیو کی مثال

لہذا ہر پکسل کو 3 بائٹس ڈیٹا کی ضرورت ہوتی ہے۔ ہر R, G, B رنگ کی قدر کے لیے 1 بائٹ (1 بائٹ = 8 بٹس) کی ضرورت ہوتی ہے۔ لہذا ایک 4K ویڈیو فریم میں ~25 MB ڈیٹا ہوتا ہے۔

آر جی بی چینل

30 فریم فی سیکنڈ (ایک عام فریم ریٹ) پر، تقریباً ایک گھنٹہ 4K ویڈیو ممکن ہے۔ 746 جی بی ڈیٹا. اگر آپ نے کبھی کوئی بڑی ویڈیو ڈاؤن لوڈ کی ہے یا اپنے فون کے کیمرے سے HD ویڈیو ریکارڈ کی ہے، تو آپ جانتے ہیں کہ ویڈیو فائلیں بڑی ہو سکتی ہیں، لیکن وہ نہیں ہیں۔ کہ جسامت میں بڑا۔

درحقیقت، حقیقی ویڈیو فائلز جو آپ یوٹیوب پر دیکھ سکتے ہیں، اپنے فون کے کیمرے سے ریکارڈ کر سکتے ہیں، یا انٹرنیٹ سے ڈاؤن لوڈ کر سکتے ہیں، ان سے تقریباً 100 گنا چھوٹی ہیں۔ اصل ویڈیو فائل بہت چھوٹی کیوں ہے؟ ویڈیو کمپریشنیہ الگورتھم کا ایک انتہائی نفیس سویٹ ہے جو ڈیٹا کو ~100x تک کم کرنے میں مدد کرتا ہے۔

اس ویڈیو کمپریشن کے بغیر، آپ جدید ترین ہائی اینڈ سمارٹ فونز پر 10 منٹ سے زیادہ ویڈیو ریکارڈ نہیں کر پائیں گے، اور نہ ہی آپ اسے ہائی اینڈ ہوم انٹرنیٹ کنکشن پر HD میں سٹریم کر سکیں گے۔

اس سے کوئی فرق نہیں پڑتا ہے کہ آپ کے جدید آلات اور انٹرنیٹ کنیکشن کتنے ہی نفیس کیوں نہ ہوں، آپ جارحانہ ویڈیو کمپریشن کے بغیر HD میں کچھ بھی نہیں دیکھ سکیں گے، ریکارڈ نہیں کر سکیں گے یا اس کو اسٹریم نہیں کر سکیں گے۔

کوڈیک

کوئی راستہ نہیں کوڈیک یہ ویڈیو کمپریشن الگورتھم کے لیے صرف ایک فینسی لفظ ہے۔ کئی قائم کردہ کوڈیکس/کمپریشن الگورتھم ہیں:

  • h264: یہ سب سے عام کوڈیک ہے۔ اگر آپ کو ایک mp4 فائل نظر آتی ہے، تو یہ زیادہ تر ممکنہ طور پر h264 کوڈیک استعمال کر رہی ہے۔

  • vp9: ایک اوپن سورس کوڈیک جو عام طور پر YouTube اور ویڈیو کانفرنسنگ میں استعمال ہوتا ہے، جو اکثر webm فائلوں میں پایا جاتا ہے۔

  • av1: ایک نیا اوپن سورس کوڈیک جو YouTube اور Netflix جیسے پلیٹ فارمز پر تیزی سے استعمال ہو رہا ہے۔

یہ الگورتھم کیسے کام کرتے ہیں اتنا پیچیدہ ہے کہ یہ اس ہینڈ بک کے دائرہ کار سے باہر ہے۔ لیکن ایک بہت ہی اعلی سطح پر، یہ الگورتھم ویڈیو کو کمپریس کرنے کے کچھ اہم طریقے یہ ہیں:

تفصیلات کو حذف کریں۔

یہ تمام الگورتھم "تفصیلات کو ہٹانے” کے لیے Discrete Cosine Transform نامی تکنیک کا استعمال کرتے ہیں۔ جب آپ ویڈیو فریم سے "تفصیل” کو ہٹاتے ہیں، تو فریم "زیادہ دھندلا” نظر آنے لگتا ہے۔ لیکن یہ ٹیکنالوجی اتنی موثر ہے کہ انسانی آنکھ میں فرق نظر آنے سے پہلے ویڈیو فریموں کو 10 بار تک کمپریس کیا جا سکتا ہے۔

اگر آپ جاننا چاہتے ہیں تو کمپیوٹر فائل کی ویڈیو دیکھیں کہ DCT الگورتھم کیسے کام کرتا ہے۔

تفصیلات کو ہٹانے کے لیے DCT الگورتھم

انکوڈنگ فریم فرق

درحقیقت، اگر آپ ویڈیو فریموں کی ایک سیریز کو دیکھیں، تو آپ دیکھیں گے کہ وہ بصری طور پر بہت ملتے جلتے ہیں، جس میں حرکت کی ڈگری کے لحاظ سے ویڈیو کے صرف چھوٹے حصے تبدیل ہوتے ہیں۔

یہ کوڈیک/کمپریشن الگورتھم صرف فریموں کے درمیان فرق کو انکوڈ کرنے کے لیے جدید ترین ریاضی اور کمپیوٹر ویژن تکنیکوں کا استعمال کرتے ہیں۔

فریم فرق

لہذا آپ کو صرف پہلا فریم بھیجنے کی ضرورت ہے (a)۔ کلیدی فریم) – پھر آپ "فریم فرق” بھیج سکتے ہیں، جسے "فریم فرق” بھی کہا جاتا ہے، بعد کے فریموں کے لیے۔ ڈیلٹا فریمہر پورے فریم کو دوبارہ تشکیل دیں۔

کلیدی فریم اور ڈیلٹا فریم

حقیقت میں، ایک گھنٹہ طویل ویڈیو پر، آپ صرف پہلے فریم کو انکوڈ کرتے ہیں اور لاکھوں ڈیلٹا فریموں کو ذخیرہ نہیں کرتے ہیں۔ اس کے بجائے، الگورتھم ہر 60ویں فریم کو کلیدی فریم کے طور پر انکوڈ کرتا ہے، اور اگلے 59 فریم ڈیلٹا فریم ہیں۔

یہ ٹکنالوجی بھی بہت موثر ہے، 10 کے فیکٹر کے ذریعے استعمال ہونے والے ڈیٹا کو کم کرتی ہے۔ کلیدی فریم اور ڈیلٹا فریم یہ "یہ الگورتھم کیسے کام کرتے ہیں” کے چند حصوں میں سے ایک ہے جو آپ کو واقعی جاننے کی ضرورت ہے۔

ان کمپریشن الگورتھم اور کمپریشن تکنیک کے بارے میں بہت سی دیگر تفصیلات ہیں جو اس تعارفی مضمون کے دائرہ کار سے باہر ہیں۔

انکوڈنگ اور ڈی کوڈنگ

ویڈیو کمپریشن کے کام کرنے کے لیے، آپ کو ویڈیو کو کمپریس کرنے کے قابل ہونا چاہیے (خام ویڈیو کو کمپریسڈ بائنری ڈیٹا میں تبدیل کریں) اور ویڈیو کو ڈیکمپریس کریں (کمپریسڈ بائنری ڈیٹا کو دوبارہ خام ویڈیو فریموں میں تبدیل کریں)۔

خام ویڈیو فریموں کو کمپریسڈ بائنری ڈیٹا میں تبدیل کرنے کا مطالبہ کرتا ہے۔ انکوڈنگکمپریسڈ بائنری ڈیٹا کو خام ویڈیو فریموں میں تبدیل کرنے کے لیے ایک آپریشن کہا جاتا ہے۔ ضابطہ کشائی لفظ کوڈیک "انکوڈ ڈیکوڈ” کا مخفف۔

ویڈیو انکوڈر اور ویڈیو ڈیکوڈر

ایک عملی ڈویلپر کے نقطہ نظر سے، آپ کو یہ جاننے کی ضرورت نہیں ہے کہ یہ کوڈیکس کیسے کام کرتے ہیں، لیکن آپ کو درج ذیل جاننے کی ضرورت ہے:

  1. مختلف ویڈیو کوڈیکس ہیں، بشمول: h264, vp9اور av1

  2. کوڈیک کے ساتھ ویڈیو کو انکوڈنگ کرتے وقت، جیسے h264)، ایک ویڈیو چلانے کے لیے، آپ کو ایک ویڈیو پلیئر کی ضرورت ہے جو اسی کوڈیک کو سپورٹ کر سکے۔

  3. ویڈیو انکوڈنگ کے لیے ویڈیو ڈی کوڈنگ سے کہیں زیادہ کمپیوٹنگ کی ضرورت ہوتی ہے، اس لیے بجٹ فون پر 4K ویڈیو چلانا ٹھیک رہے گا، لیکن 4K ویڈیو کو انکوڈنگ کرنا بہت سست ہوگا۔

  4. زیادہ تر صارفین کے آلات (سیل فونز، لیپ ٹاپس) میں خاص طور پر ویڈیو انکوڈنگ اور ڈی کوڈنگ کے لیے ڈیزائن کردہ خصوصی چپس ہوتی ہیں، جو ایک باقاعدہ سافٹ ویئر پروگرام کی طرح CPU پر چلنے کے مقابلے میں انکوڈنگ/ڈی کوڈنگ کو زیادہ تیز کرتی ہیں۔ اسے کہتے ہیں۔ ہارڈ ویئر ایکسلریشن۔

حقیقت میں، صرف چند ویڈیو کوڈیکس موجود ہیں۔ اس کی وجہ یہ ہے کہ آئی فون پر ریکارڈ کی گئی ویڈیوز کو ونڈوز ڈیوائسز پر چلانے سے پہلے دنیا کو ایک معیار پر متفق ہونا ضروری ہے۔

کنٹینر

زیادہ تر لوگوں نے اس کے بارے میں کبھی نہیں سنا ہے۔ h264 یا vp9. جب آپ ویڈیو فائلوں کے بارے میں سوچتے ہیں، تو آپ عام طور پر MP4 یا MKV جیسے فائل فارمیٹس کے بارے میں سوچتے ہیں۔ یہ بھی متعلقہ ہیں، لیکن الگ الگ چیزیں جنہیں کنٹینرز کہتے ہیں۔

ویڈیو فائلوں میں عام طور پر انکوڈ شدہ آڈیو، انکوڈ شدہ ویڈیو، اور ویڈیو فائل کے بارے میں میٹا ڈیٹا ہوتا ہے۔ ایک فائل فارمیٹ، جیسے MP4، انکوڈ شدہ آڈیو اور ویڈیو ڈیٹا اور میٹا ڈیٹا کو ذخیرہ کرنے کے لیے ایک مخصوص فارمیٹ کی وضاحت کرتا ہے۔

ویڈیو کنٹینر

ویڈیو کمپریشن سوفٹ ویئر انکوڈ شدہ آڈیو/ویڈیو اور میٹا ڈیٹا کو فائل کی شکل/تصریحات کے مطابق فائلوں میں اسٹور کرتا ہے۔ اسے کہتے ہیں۔ ملٹی پلیکسنگ۔

اسی طرح، ویڈیو پلیئرز میٹا ڈیٹا پڑھتے ہیں اور فائل فارمیٹ کی تفصیلات کے مطابق انکوڈ شدہ آڈیو/ویڈیو تلاش کرتے ہیں۔ اسے کہتے ہیں۔ ملٹی پلیکسنگ.

ویڈیو فائلوں کو کمپریس کرتے وقت آپ کو دونوں کی ضرورت ہوتی ہے۔ انکوڈ اس کے ساتھ ملٹی پلیکسر (اس ترتیب میں)۔ یہ عمل میں دو الگ الگ مراحل ہیں۔ اسی طرح، ویڈیو فائلوں کو چلاتے وقت دونوں کی ضرورت ہوتی ہے۔ ڈیمو وہ اور پھر کھولنا (اس ترتیب میں)۔

جب ایک ویڈیو پلیئر ایک mp4 فائل کھولتا ہے، تو منطق کا بہاؤ اس طرح ہوتا ہے:

  • ٹھیک ہے فائل .mp4 پر ختم ہوتی ہے، اس لیے یہ ایک mp4 فائل ہونی چاہیے۔ آئیے mp4 فائلوں کو پارس کرنے کے لیے ایک لائبریری لوڈ کریں، فائل کو پارس کریں، اور پھر اسے پارس کریں۔

  • بہترین میں نے mp4 فائل کو پارس کیا۔ اب ہمارے پاس میٹا ڈیٹا ہے اور ہم جانتے ہیں کہ انکوڈ شدہ آڈیو اور ویڈیو حاصل کرنے کے لیے بائٹ آفسیٹ کہاں سے حاصل کرنا ہے۔

  • اسے پہلا انکوڈ شدہ ویڈیو فریم ملتا ہے، اسے ڈی کوڈ کرتا ہے، اور صارف کو ڈی کوڈ شدہ ویڈیو فریم دکھانا شروع کر دیتا ہے۔

اگر آپ کا ویڈیو پلیئر یہ پیغام دکھاتا ہے کہ "ویڈیو فائل کرپٹڈ ہے”، اس بات کا زیادہ امکان ہے کہ ویڈیو فائل فائل فارمیٹ کی وضاحتوں کی پیروی نہیں کرتی ہے اور ویڈیو کو پارس/ڈیملٹی پلیکس کرنے کی کوشش کے دوران ایک خرابی واقع ہوئی ہے۔

ویب کوڈیک کیا ہے؟

اب جبکہ ہم نے کوڈیک کا احاطہ کر لیا ہے، آئیے اسے ویب پر ڈالتے ہیں۔

ویب کوڈیکس = ویب + کوڈیکس

WebCodecs ایک API ہے جو فرنٹ اینڈ ڈویلپرز کو براؤزر میں انتہائی کم سطح کے کنٹرول (ایک فریم بہ فریم کی بنیاد پر انکوڈ/ڈی کوڈ) کے ساتھ براؤزر میں مؤثر طریقے سے ویڈیو کو انکوڈ اور ڈی کوڈ کرنے کی اجازت دیتا ہے۔

ہارڈویئر ایکسلریشن بٹ اہم ہے۔ اس کی وجہ یہ ہے کہ آپ صرف پولی کو نہیں بھر سکتے یا خود API کو دوبارہ نافذ نہیں کر سکتے۔ WebCodecs انکوڈنگ/ڈی کوڈنگ کے لیے خصوصی ہارڈ ویئر تک براہ راست رسائی فراہم کرکے ڈیسک ٹاپ ویڈیو ایپس کے ساتھ ساتھ پرفارم بھی کرتا ہے۔

ویب کوڈیک ٹرانسفر

WebCodecs کیوں موجود ہیں یہ سمجھنے میں ایک لمحہ لگانے کے قابل ہے۔ WebCodecs API کے موجود ہونے سے پہلے، براؤزر میں ویڈیو کے ساتھ کام کرنے کے لیے کئی متبادل دستیاب تھے۔

  • HTMLVideoElement: آپ ایک عنصر بنا سکتے ہیں اور اسے ویڈیو ڈی کوڈنگ کے لیے استعمال کر سکتے ہیں۔ یہ استعمال کرنا آسان ہے، لیکن فریم لیول کنٹرول کا فقدان ہے۔ واحد کنٹرول ‘video.currentTime’ پراپرٹی کو ترتیب دینا اور اسے بازیافت کرنے کا انتظار کرنا ہے، جس کے نتیجے میں اکثر فریم گر جاتے ہیں یا غائب ہوتے ہیں۔

  • میڈیا ریکارڈر API: بنیادی طور پر آپ کو کسی بھی کینوس عنصر یا ویڈیو اسٹریم کو ‘اسکرین ریکارڈ’ کرنے کی اجازت دیتا ہے۔ یہ کام کرنے کے دوران رینڈر پر کلک کرنے کے بجائے اسکرین ریکارڈنگ Adobe Premeire pro کے برابر ہے۔ منظرناموں میں ترمیم کرنے کے لیے، فریم کی سطح کا کنٹرول ختم ہو جاتا ہے اور ویڈیو پر صرف حقیقی وقت کی رفتار سے کارروائی کی جا سکتی ہے۔

  • FFMPEG.js: ffmpeg کی ایک بندرگاہ، ایک مقبول ویڈیو پروسیسنگ ٹول جو براؤزر میں ffmpeg چلاتا ہے۔ بہت سے ٹولز نے اسے ماضی میں استعمال کیا تھا، لیکن اس میں ہارڈویئر ایکسلریشن کا فقدان ہے اور یہ WebCodecs سے بہت سست ہے۔ مزید برآں، چونکہ یہ WebAssembly پر چلتا ہے، اس میں فائل کے سائز کی حدود ہیں، جس سے 100MB سے بڑی ویڈیوز کے ساتھ کام کرنا مشکل ہو جاتا ہے۔

WebCodecs کو 2021 میں بنایا اور جاری کیا گیا تھا تاکہ نچلی سطح، ہارڈویئر سے تیز رفتار ویڈیو ڈی کوڈنگ اور انکوڈنگ کو سپورٹ کیا جا سکے۔ اعلی کارکردگی والی سٹریمنگ اور ویڈیو ایڈیٹنگ کے لیے مثالی، ایسے کیسز کا استعمال کریں جو موجودہ APIs کے ذریعے اچھی طرح سے پیش نہیں کیے گئے ہیں۔

کور API

WebCodecs کا بنیادی API دو نئی "ڈیٹا اقسام” پر مشتمل ہے: ویڈیو فریم اور انکوڈ شدہ ویڈیو کے ٹکڑےہاں ویڈیو انکوڈر اور ویڈیو ڈیکوڈر انٹرفیس

ویڈیو فریم

جاوا اسکرپٹ ویڈیو فریم ایک آبجیکٹ تصوراتی طور پر ایک ویڈیو فریم کے لیے پکسل ڈیٹا اور میٹا ڈیٹا دونوں پر مشتمل ہوتا ہے۔

ویڈیو فریم آبجیکٹ

آپ واقعی کچھ نیا بنا سکتے ہیں۔ ویڈیو فریم کسی بھی تصویری ماخذ سے اشیاء، بشمول میٹا ڈیٹا:

const bitmapFrame = new VideoFrame(imgBitmap, {timestamp: 0});

const imageFrame = new VideoFrame(htmlImageEl, {timestamp: 0});

const videoFrame = new VideoFrame(htmlVideoEl, {timestamp: 0});

const canvasFrame = new VideoFrame(canvasEl, {timestamp: 0});

مثال کے طور پر، ایک ویڈیو ایڈیٹنگ ایپ میں، آپ عام طور پر کینوس پر ہر فریم پر امیج ایڈیٹنگ کا آپریشن کریں گے اور پھر ہر فریم کو بازیافت کریں گے۔ ویڈیو فریم کینوس پر۔

تم بھی ویڈیو فریم Canvas 2D رینڈرنگ سیاق و سباق کا استعمال کرتے ہوئے کینوس پر:

ctx.drawImage(frame, 0, 0);

آپ عام طور پر براؤزر میں ویڈیو پیش کرتے/چلاتے وقت ایسا کرتے ہیں۔

انکوڈ شدہ ویڈیو کے ٹکڑے

نہیں انکوڈ شدہ ویڈیو کے ٹکڑے یہ صرف کا ایک گاڑھا ورژن ہے۔ ویڈیو فریم، اس میں بائنری ڈیٹا کے ساتھ ساتھ فریم کے برابر میٹا ڈیٹا بھی ہوتا ہے۔

انکوڈ شدہ ویڈیو کے ٹکڑے

آپ عام طور پر حاصل کریں گے انکوڈ شدہ ویڈیو کے ٹکڑے لائبریری سے جو اسے نکالتی ہے۔ فائل اعتراض

import { getVideoChunks } from 'webcodecs-utils'

const chunks =  await getVideoChunks( file);

یا آؤٹ پٹ جس سے آپ حاصل کرتے ہیں: ویڈیو انکوڈر اعتراض

بہت زیادہ مفید چیزیں نہیں ہیں جو آپ کر سکتے ہیں۔ انکوڈ شدہ ویڈیو کے ٹکڑے – یہ صرف بائنری ڈیٹا ہے جسے آپ کسی فائل سے پڑھتے ہیں، فائل میں لکھتے ہیں، یا انٹرنیٹ پر اسٹریم کرتے ہیں۔

انکوڈنگ اور ڈی کوڈنگ کے ساتھ ویڈیو اسٹریمنگ

کی قدر انکوڈ شدہ ویڈیو کے ٹکڑے کیونکہ یہ اصل ویڈیو ڈیٹا سے تقریباً 100 گنا چھوٹا ہے۔ انکوڈ شدہ ویڈیو کے ٹکڑے سٹریمنگ کرتے وقت خام ویڈیو کی بجائے (اور فائلوں کو لکھنا)۔

ویڈیو انکوڈر

کوئی راستہ نہیں ویڈیو انکوڈر گردش ویڈیو فریم اعتراض انکوڈ شدہ ویڈیو کے ٹکڑے اشیاء

ویڈیو انکوڈر

بنیادی APIs ہیں: یہ وہ جگہ ہے جہاں ہم کال بیک کی وضاحت کرتے ہیں۔ ویڈیو انکوڈر رپورٹ انکوڈ شدہ ویڈیو کے ٹکڑے اشیاء

const encoder = new VideoEncoder({
    output: function(chunk: EncodedVideoChunk, meta: any){
        // Do something with the chunk
    },
    error: function(e: any)=> console.warn(e);
});

ذہن میں رکھیں کہ یہ ایک متضاد عمل ہے، اور یہ باقاعدہ غیر مطابقت پذیر عمل بھی نہیں ہے۔ آپ اسے فریم بہ فریم آپریشن کے طور پر نہیں کر سکتے۔

// Does not work like this
const frame  = await encoder.encode(chunk);

اس کی وجہ یہ ہے کہ ویڈیو انکوڈنگ دراصل اندرونی طور پر کیسے کام کرتی ہے۔ لہذا آپ کو یہ قبول کرنا ہوگا کہ آؤٹ پٹ کال بیک کے ذریعے واپس کیا جائے گا، اور جب آپ اسے حاصل کریں گے تو آپ کو آؤٹ پٹ ملے گا۔

ایک انکوڈر کی وضاحت کرنے کے بعد، آپ ترتیب دے سکتے ہیں: ویڈیو انکوڈر مطلوبہ کوڈیک کو منتخب کریں (ہم بعد میں اس کی وضاحت کریں گے) کے ساتھ ساتھ دیگر پیرامیٹرز جیسے چوڑائی، اونچائی، فریم کی شرح، اور بٹ ریٹ منتخب کریں۔

encoder.configure({
    'codec': 'vp9.00.10.08.00', // We'll get to this
     width: 1280,
     height: 720,
     bitrate: 1000000 //1 MBPS,
     framerate: 25
});

اس کے بعد آپ فریموں کو انکوڈنگ شروع کر سکتے ہیں۔ یہ فرض کرتا ہے کہ آپ کے پاس پہلے سے ہی ایک ہے۔ ویڈیو فریم ایک آبجیکٹ بنائیں اور اسے ہر 60ویں فریم پر چلائیں۔ کلیدی فریم.

for (let i=0; i < frames.length; frames++){
    encoder.encode(frames[i], {keyFrame: i%60 ==0})
}

ویڈیو ڈیکوڈر

ویڈیو ڈیکوڈر اس کے برعکس کرتے ہیں۔ انکوڈ شدہ ویڈیو کے ٹکڑے اعتراض ویڈیو فریم اشیاء

ویڈیو ڈیکوڈر

اسے ترتیب دینے کے طریقے کی ایک فوری مثال یہ ہے: ویڈیو ڈیکوڈر۔ سب سے پہلے انکوڈ شدہ ویڈیو کے ٹکڑے ویڈیو فائلوں کے لیے آبجیکٹ اور ڈیکوڈر کنفیگریشن۔ یہاں کوئی ترتیب کا انتخاب نہیں کیا گیا ہے۔ فائل کو انکوڈ کرنے والے شخص نے کنفیگریشن کا انتخاب کیا۔ ضابطہ کشائی کرتے وقت، کنفیگریشن فائل سے نکالی جاتی ہے۔

import { demuxVideo } from 'webcodecs-utils';

const {chunks, config} = await demuxVideo( file);

اگلا ہم ویڈیو ڈیکوڈر کال بیک کی وضاحت کرکے ویڈیو فریم config کا استعمال کرتے ہوئے ایک آبجیکٹ تخلیق اور ترتیب دیا جاتا ہے۔

const decoder = new VideoDecoder({
    output: function(frame: VideoFrame){
        //do something with the VideoFrame
    },
    error: function(e: any)=> console.warn(e);
});

decoder.configure(config)

دوبارہ، ویڈیو انکوڈرکال بیک ایک فریم لوٹاتا ہے۔ آخر میں، ہم ٹکڑوں کو ڈی کوڈ کرنا شروع کر سکتے ہیں۔

for (const chunk of chunks){
    decoder.decode(chunk);
}

سب کچھ ایک ساتھ ڈالنا

WebCodecs API کے مرکز میں ڈیٹا کی دو اقسام ہیں:انکوڈ شدہ ویڈیو چنک، ویڈیو فریم) اور ویڈیو انکوڈر اور ویڈیو ڈیکوڈر ایک انٹرفیس جو ڈیٹا کی دو اقسام کے درمیان بدلتا ہے۔

ویب کوڈیک کا بنیادی حصہ

WebCodecs API دراصل ویڈیو فائلوں کے ساتھ کام نہیں کرتا ہے۔ صرف انکوڈنگ اور ڈی کوڈنگ لاگو ہوتی ہے، انکوڈ شدہ ویڈیو کے ٹکڑے آبجیکٹ صرف بائنری ڈیٹا کی نمائندگی کرتے ہیں۔

ویڈیو فائلوں کو پڑھنا اور ویڈیو فائلوں کو لکھنا الگ الگ آپریشن ہیں جنہیں ملٹی پلیکسنگ/ڈیملٹی پلیکسنگ کہتے ہیں۔

ملٹی پلیکسنگ اور ملٹی پلیکسنگ

ویڈیو فائل میں لکھنے کے لیے آپ کو یہ بھی ضرورت ہو گی: ملٹی پلیکسر ویڈیو اور ویڈیو فائلوں کو چلانے کے لیے آپ کو ضرورت ہو گی: ڈیمو ویڈیو اس میں ویڈیو کنٹینر کے فائل فارمیٹ کی پیروی کرنا، ویڈیو فائل کو پارس کرنا (ڈی ملٹی پلیکسنگ کے لیے)، یا انکوڈ شدہ ویڈیو ڈیٹا کو ریکارڈ کی جا رہی فائل میں صحیح جگہ پر رکھنا (ڈی ملٹی پلیکسنگ کے لیے) شامل ہے۔

Muxing اور Demuxing WebCodecs API میں شامل نہیں ہیں، لہذا آپ کو Muxing اور Demuxing کو سنبھالنے کے لیے علیحدہ لائبریریوں کا استعمال کرنا چاہیے۔

ڈیمکسنگ

آپ کو اپنے براؤزر میں ویڈیو چلانے کے لیے دونوں کی ضرورت ہے۔ ڈیمو ویڈیو ڈیپارٹمنٹ کھولنا ویڈیو ترتیب میں۔

ڈیمکسنگ اور ڈی کوڈنگ

ایسی کئی لائبریریاں ہیں جنہیں آپ ویڈیو کو ڈیمکس کرنے کے لیے استعمال کر سکتے ہیں، بشمول MediaBunny یا web-demuxer۔ اس ٹیوٹوریل کے مقاصد کے لیے، ہم نے ان لائبریریوں کے گرد ایک بہت ہی آسان ریپر رکھا ہے اور اسے webcodecs-utils پیکج کے سامنے لایا ہے، جس سے ڈیمکسنگ کو ایک بہت ہی آسان 2 لائن بنایا گیا ہے۔

import { demuxVideo } from 'webcodecs-utils'
const {chunks, config} = await demuxVideo(file);

اس کی وجہ سے پوری ویڈیو میموری میں پڑھی جائے گی، لہذا ایسا نہ کریں۔ تاہم، یہ ویب کوڈیکس کے لیے ایک سادہ اور پڑھنے کے قابل ہیلو ورلڈ بنانے میں مدد کرتا ہے۔

مندرجہ ذیل ٹکڑا ایک ویڈیو فائل دکھاتا ہے (فائل اعتراض)، اسے ڈی کوڈ کریں، اور نتیجہ کو کینوس کی طرف کھینچیں۔ یہاں ہم آؤٹ پٹ کال بیک سے فریم حاصل کرتے ہیں اور ڈرا کال کو براہ راست کال بیک سے انجام دیتے ہیں۔

import { demuxVideo } from 'webcodecs-utils'

async function playFile(file: File){

    const {chunks, config} = await demuxVideo(file);
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    const decoder = new VideoDecoder({
        output(frame: VideoFrame) {
            ctx.drawImage(frame, 0, 0);
            frame.close()
        },
        error(e) {}
    });


    decoder.configure(config);

    for (const chunk of chunks){
        decoder.decode(chunk)
    }

}

اصل ویڈیو چلانے کے لیے یہاں ایک سپر بیئر بونز ڈیمو ہے:

اگر آپ ڈیملٹی پلیکسنگ کی مزید 'درست' مثال دیکھنا چاہتے ہیں، تو یہ ہے کہ میڈیا بنی کا استعمال کرتے ہوئے ڈیملٹی پلیکسنگ کیسا لگتا ہے، جو تکراری طریقے سے ٹکڑوں کو نکال سکتا ہے:

import { EncodedPacketSink, Input, ALL_FORMATS, BlobSource } from 'mediabunny';

const input = new Input({
  formats: ALL_FORMATS,
  source: new BlobSource( file),
});

const videoTrack = await input.getPrimaryVideoTrack();
const sink = new EncodedPacketSink(videoTrack);

for await (const packet of sink.packets()) {
  const chunk =  packet.toEncodedVideoChunk();
}

ملٹی پلیکسنگ

ویڈیو فائل بنانے میں صرف انکوڈنگ سے زیادہ شامل ہے ( ویڈیو انکوڈر) آپ کو بھی چاہئے ملٹی پلیکسر کہ اس میں انکوڈ شدہ ٹکڑوں کو لینا اور آؤٹ پٹ بائنری فائل میں صحیح جگہ پر رکھنا شامل ہے جس پر آپ لکھ رہے ہیں۔

ملٹی پلیکسنگ اور انکوڈنگ

ایک بار پھر، آپ کو ویڈیو کو ملٹی پلیکس کرنے کے لیے ایک لائبریری (MediaBunny) کی ضرورت ہوگی، لیکن میں نے ڈیمو مقاصد کے لیے ایک بہت ہی آسان ریپر بنایا ہے۔ یہاں ہم ایک بہت ہی بنیادی مثال Muxer کی وضاحت کرتے ہیں۔

import { ExampleMuxer } from 'webcodecs-utils'

const muxer = new ExampleMuxer('video');

for (const chunk of encodedChunks){
    muxer.addChunk(chunk);
}

const outputBlob = await muxer.finish();

ایک مکمل انکوڈنگ + ملٹی پلیکسنگ ڈیمو کے طور پر، آئیے ایک انکوڈر بنائیں اور اسے آؤٹ پٹ انکوڈنگ کے ٹکڑوں کے واپس آتے ہی ملٹی پلیکس کرنے کے لیے سیٹ کریں۔

const encoder = new VideoEncoder({
    output: function(chunk, meta){
        muxer.addChunk(chunk, meta);
    },
    error: function(e){}
})

encoder.configure({
    'codec': 'avc1.4d0034', // We'll get to this
     width: 1280,
     height: 720,
     bitrate: 1000000 //1 MBPS,
     framerate: 25
});

پھر چیک کریں کہ آیا یہ ایک کینوس اینیمیشن کی وضاحت کرکے کام کرتا ہے جو موجودہ فریم نمبر کو اسکرین پر کھینچتا ہے۔

const canvas = new OffscreenCanvas(640, 360);
const ctx = canvas.getContext('2d');
const TOTAL_FRAMES=300;
let frameNumber = 0;
let chunksMuxed = 0;
const fps = 30;


function renderFrame(){
    ctx.fillStyle="#000";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle="white";
    ctx.font = `bold ${Math.min(canvas.width / 10, 72)}px Arial`;
    ctx.textAlign = 'center';
    ctx.textBaseline="middle";
    ctx.fillText(`Frame ${frameNumber}`, canvas.width / 2, canvas.height / 2);
}

آخر میں، ہم ایک انکوڈنگ لوپ بناتے ہیں جو موجودہ فریم کو کھینچتا ہے اور پھر اسے انکوڈ کرتا ہے۔


let flushed = false;

async function encodeLoop(){

    renderFrame();

    const frame = new VideoFrame(canvas, {timestamp: frameNumber/fps*1e6});
    encoder.encode(frame, {keyFrame: frameNumber %60 ===0});
    frame.close();

    frameNumber++;

    if(frameNumber === TOTAL_FRAMES) {
        if (!flushed) encoder.flush();
    }
    else return requestAnimationFrame(encodeLoop);
}

ان سب کو ایک ساتھ رکھ کر، آپ کینوس کی اینیمیشنز کو فریم لیول کی درستگی کے ساتھ ویڈیو فائلوں میں انکوڈ کر سکتے ہیں۔

آپ ویڈیو ڈاؤن لوڈ کر سکتے ہیں اور یہ یقینی بنانے کے لیے کہ اس میں ہر ایک فریم نمبر موجود ہے۔

فریم لیول کی درستگی کا ویڈیو

یہ ان اہم فرقوں میں سے ایک ہے جو اسے دوسرے ویب APIs سے الگ کرتا ہے، جیسے کہ MediaRecorder، جو ویڈیو کو انکوڈ کر سکتا ہے لیکن فریم لیول کی درستگی کے بغیر۔ WebCodecs آپ کو ہر فریم کی مستقل مزاجی کو کنٹرول کرنے اور یقینی بنانے کی اجازت دیتا ہے۔

آخر میں، یہاں MediaBunny کا استعمال کرتے ہوئے ایک مناسب مکمل ملٹی پلیکسنگ مثال ہے:

import {
  EncodedPacket,
  EncodedVideoPacketSource,
  BufferTarget,
  Mp4OutputFormat,
  Output
} from 'mediabunny';

async function muxChunks(chunks: EncodedVideoChunk[]): Promise {

    const output = new Output({
        format: new Mp4OutputFormat(),
        target: new BufferTarget(),
    });

    const source = new EncodedVideoPacketSource('avc');
    output.addVideoTrack(source);

    await output.start();

    for (const chunk of chunks){
        source.add(EncodedPacket.fromEncodedChunk(chunk))
    }

    await output.finalize();
    const buffer =  output.target.buffer;
    return new Blob([buffer], { type: 'video/mp4' });

});

ویڈیو کنورٹر یوٹیلیٹی بنانا

اب جبکہ ہم نے WebCodecs اور Muxing کی بنیادی باتوں کا احاطہ کر لیا ہے، ہم واقعی ایک مفید MVP بنانے کی طرف بڑھیں گے: ایک ویڈیو کنورٹر یوٹیلیٹی۔ ہم اسے mp4 اور webm کے درمیان تبدیل کرنے اور کچھ بنیادی کارروائیوں کو انجام دینے کے لیے استعمال کر سکتے ہیں جیسے کہ ویڈیوز کا سائز تبدیل کرنا اور پلٹنا۔

ٹرانس کوڈنگ

سائز تبدیل کرنے اور پلٹنے سے پہلے، آئیے پہلے بنیادی تبدیلی کو سنبھال لیں، جس میں ویڈیو کو ڈی کوڈ کرنا اور اسے ایک نئے فارمیٹ میں انکوڈنگ کرنا شامل ہے۔ اسے ٹرانس کوڈنگ کہتے ہیں۔

ویڈیو کو ٹرانس کوڈ کرنے کے لیے، آپ کو درج ذیل عمل کے ساتھ ایک پائپ لائن ترتیب دینے کی ضرورت ہے:

  • ڈیمکسنگ: پڑھیں انکوڈ شدہ ویڈیو کے ٹکڑے ویڈیو فائل سے

  • ضابطہ کشائی: تبدیل کرنا انکوڈ شدہ ویڈیو کے ٹکڑے کو ویڈیو فریم

  • انکوڈنگ: تبدیل کرنا ویڈیو فریم نیا انکوڈ شدہ ویڈیو کے ٹکڑے

  • ملٹی پلیکسنگ: لکھنا انکوڈ شدہ ویڈیو کے ٹکڑے ایک نئی ویڈیو فائل میں

ہماری پائپ لائن مندرجہ ذیل ہے:

ٹرانس کوڈنگ پائپ لائن

اب تک اس مضمون میں شامل ہر چیز کا استعمال کرتے ہوئے، آپ اس طرح ایک مکمل ورکنگ ڈیمو بنا سکتے ہیں: ویڈیو انکوڈر اور ویڈیو ڈیکوڈر جیسا کہ بحث کی گئی ہے۔ تاہم، ریاستی انتظام اور ٹریکنگ فریم پیچیدہ اور غلطی کا شکار ہو جاتے ہیں۔

اگر ہم Streams API کا استعمال کرتے ہوئے ایک اور تجرید شامل کرتے ہیں، تو ہماری پائپ لائن اس طرح نظر آئے گی: یہ پائپ لائن کے ذہنی ماڈل سے براہ راست تعلق رکھتی ہے اور متعدد تفصیلات جیسے ریاستی انتظام کو آسان بناتی ہے۔

const transcodePipeline = demuxerReader
    .pipeThrough(new VideoDecoderStream(videoDecoderConfig))
    .pipeThrough(new VideoEncoderStream(videoEncoderConfig))
    .pipeTo(createMuxerWriter(muxer));

await transcodePipeline;

ایسا کرنے کے لیے، ہم ایک TransformStream بناتے ہیں۔ ویڈیو ڈیکوڈر اور ویڈیو انکوڈر۔

class VideoDecoderStream extends TransformStream<{ chunk: EncodedVideoChunk; index: number }, { frame: VideoFrame; index: number }> {
  constructor(config: VideoDecoderConfig) {
    let pendingIndices: number[] = [];
    super(
      {
        start(controller) {
          decoder = new VideoDecoder({
            output: (frame) => {
              const index = pendingIndices.shift()!;
              controller.enqueue({ frame, index });
            },
            error: (e) => controller.error(e),
          });

          decoder.configure(config);
        },

        async transform(item, controller) {
          pendingIndices.push(item.index);
          decoder.decode(item.chunk);
        },

        async flush(controller) {
          await decoder.flush();
          if decoder.state !== 'closed' decoder.close();
        },
      }
    );
  }
}

میں آپ کو مکمل کوڈ کے ساتھ بور نہیں کروں گا، لیکن میں نے ان یوٹیلیٹیز کو webcodecs-utils پیکیج میں پیک کیا ہے، جسے آپ اس طرح استعمال کر سکتے ہیں:

import {
  SimpleDemuxer,
  VideoDecodeStream,
  VideoEncodeStream,
  SimpleMuxer,
} from "webcodecs-utils";

فائل کو ٹرانس کوڈ کرنے کا کوڈ یہ ہے:

const demuxer = new SimpleDemuxer(videoFile);
await demuxer.load();
const decoderConfig = await demuxer.getVideoDecoderConfig();

const encoderConfig = {/*Whatever we decide*/};

// Set up muxer
const muxer = new SimpleMuxer({ video: "avc" });

// Build the upscaling pipeline
await demuxer.videoStream()
  .pipeThrough(new VideoDecodeStream(decoderConfig))
  .pipeThrough(new VideoEncodeStream(encoderConfig))
  .pipeTo(muxer.videoSink());

// Get output
const blob = await muxer.finalize();

یہ انٹرمیڈیٹ ڈیمو پہلے سے بنی فائلوں کو ڈاؤن لوڈ کرنے اور ایم پی 4 فائلوں کو آؤٹ پٹ کرنے کے لیے ایک ٹوگل متعارف کرایا ہے تاکہ ٹرانس کوڈنگ کو اصل میں کام کیا جا سکے (استعمال کرتے ہوئے: h264) یا ویب ایم فائل (استعمال کریں۔ vp9

ہم استعمال کریں گے avc1.4d0034 h264 (سب سے زیادہ تعاون یافتہ h264 کوڈیک سٹرنگ) اور vp09.00.40.08.00 vp9 کے لیے (سب سے زیادہ تعاون یافتہ vp9 سٹرنگ)۔

یہاں CodePen سے ایک بنیادی ٹرانس کوڈنگ ڈیمو ہے:

تبدیلی

اگر آپ ویڈیو ٹرانسفارمیشن کرنا چاہتے ہیں جیسے پلٹنا، کراپ کرنا، گھومنا، سائز تبدیل کرنا، وغیرہ، تو صرف خالص آپریشن ہی کام نہیں کریں گے۔ ویڈیو فریم اشیاء

اس کو حاصل کرنے کا سب سے آسان طریقہ یہ ہے کہ ایک کینوس عنصر متعارف کرایا جائے جو 2D کینوس سیاق و سباق کو سورس فریم میں ہیرا پھیری کرنے اور اسے کینوس پر کھینچنے کے لیے استعمال کرتا ہے۔

const canvas = new OffscreenCanvas(width, height);
const ctx = canvas.getContext('2d');

// Very easy to do transformations
ctx.drawImage(sourceFrame, 0, 0);

اس کے بعد ہم آؤٹ پٹ ویڈیو فریموں کے لیے کینوس کو سورس امیج کے طور پر استعمال کرتے ہیں۔

const outFrame = new VideoFrame(canvas, {timestamp: sourceFrame.timestamp});

سائز تبدیل کرنے کے عمل کو لاگو کرنے کے لیے، پہلے کینوس کا سائز آؤٹ پٹ کی اونچائی اور چوڑائی پر سیٹ کریں۔

const canvas = new OffscreenCanvas(outputWidth, outputHeight);
const ctx = canvas.getContext('2d');

// Resize sourceFrame to fit output dimensions
ctx.drawImage(sourceFrame, 0, 0, outputWidth, outputHeight);

canvas2d کا استعمال کرتے ہوئے افقی فلپ آپریشن کو لاگو کرنے کے لیے آپ درج ذیل کام کر سکتے ہیں:

ctx.scale(-1, 1);
ctx.translate(-outputWidth, 0);
ctx.drawImage(sourceFrame, 0, 0, outputWidth, outputHeight);

آپ ایک مکمل رینڈرنگ فنکشن تشکیل دے سکتے ہیں جو درج ذیل کی طرح تبدیلیوں کا اطلاق کرتا ہے۔

function render(videoFrame, outW, outH, flipped) {

  canvas.width  = outW;
  canvas.height = outH;

  if (flipped) {
    ctx.scale(-1, 1);
    ctx.translate(-outW, 0);
  }
  ctx.drawImage(videoFrame, 0, 0, outW, outH);

}

ذیل میں ایک انٹرایکٹو ڈیمو ہے جس میں دکھایا گیا ہے کہ یہ تبدیلی کیسی دکھتی ہے۔

تبدیلی پائپ لائن

ان تبدیلیوں کے لیے آپ کو تبدیلی کے مراحل کو شامل کرنے کے لیے اپنی پائپ لائن کو ڈھالنے کی ضرورت ہوتی ہے۔ یہ لے جائے گا ویڈیو فریمتبدیلی کو لاگو کرتا ہے اور تبدیل شدہ فریم کو لوٹاتا ہے۔

ٹرانسفارمز کا استعمال کرتے ہوئے ٹرانس کوڈنگ پائپ لائن

webcodecs-utils پیکیج میں اس مقصد کے لیے ایک VideoProcessStream آبجیکٹ ہے۔ ویڈیو فریم اور پھر ویڈیو فریم:

import { VideoProcessStream} from "webcodecs-utils";
 
new VideoProcessStream(async (frame) => {
      // Apply transformations
      return procesedFrame;
    }),

لہذا اگر آپ تبدیلی کا اطلاق کرنا چاہتے ہیں تو آپ اسے اس طرح ترتیب دے سکتے ہیں:

import { VideoProcessStream} from "webcodecs-utils";
 

const canvas = new OffscreenCanvas(outW, outH);
const ctx = canvas.getContext('2d');

const processStream = new VideoProcessStream(async (frame) => {
  
  if (flipped) {
    ctx.scale(-1, 1);
    ctx.translate(-outW, 0);
  }
  ctx.drawImage(frame, 0, 0, outW, outH);

  return new VideoFrame(canvas, {timestamp: frame.timestamp});

});

پھر مکمل پائپ لائن اس طرح نظر آئے گی:

const demuxer = new SimpleDemuxer(videoFile);
await demuxer.load();
const decoderConfig = await demuxer.getVideoDecoderConfig();

const encoderConfig = {/*Whatever we decide*/};

// Set up muxer
const muxer = new SimpleMuxer({ video: "avc" });

// Build the upscaling pipeline
await demuxer.videoStream()
  .pipeThrough(new VideoDecodeStream(decoderConfig))
  .pipeThrough(processStream) // Just defined this
  .pipeThrough(new VideoEncodeStream(encoderConfig))
  .pipeTo(muxer.videoSink());

// Get output
const blob = await muxer.finalize();

پروسیس پائپ لائن کا استعمال کرتے ہوئے یہاں ایک مکمل ورکنگ ڈیمو ہے:

مکمل ڈیمو

اب آئیے پورے ٹول میں کچھ بڑی تبدیلیاں کرتے ہیں۔

  • آپ اپنی ویڈیوز اپ لوڈ کر سکتے ہیں۔

  • تبدیلی کا پیش نظارہ کرنے کے لیے فریم نکالیں۔

  • آئیے ترقی کی پیمائش شامل کریں۔

ان پٹ کے لیے یہ آسان ہے:


فریم پیش نظارہ کے لیے، آپ پیش نظارہ بنانے کے لیے WebCodecs کا استعمال کر سکتے ہیں، لیکن چونکہ پیش نظارہ کے لیے فریم کی سطح کی درستگی یا اعلیٰ کارکردگی کی ضرورت نہیں ہوتی ہے، اس لیے HTML5 VideoElement کا استعمال کرتے ہوئے سورس فائل سے ویڈیو فریم حاصل کرنا آسان ہے۔

async function getFirstFrame(file) {
  const video = document.createElement("video");
  video.src = URL.createObjectURL(file);
  video.muted = true;

  await new Promise((resolve) => video.addEventListener("loadeddata", resolve, { once: true }));
  video.currentTime = 0;
  await new Promise((resolve) => video.addEventListener("seeked", resolve, { once: true }));

  return new VideoFrame(video, {timestamp: 0});
}

آخر میں، فریم ٹائم اسٹیمپ/ویڈیو کا دورانیہ پروسیس فنکشن کی پیشرفت کا حساب لگانے کے لیے استعمال کیا جا سکتا ہے۔

const {duration} = await demuxer.getMediaInfo();


const processStream = new VideoProcessStream(async (frame) => {
  
  if (flipped) {
    ctx.scale(-1, 1);
    ctx.translate(-outW, 0);
  }
  ctx.drawImage(frame, 0, 0, outW, outH);

   // Frame timestamps are in microseconds, duration in seconds
  const progress = frame.timestamp/(duration*1e6); 

  return new VideoFrame(canvas, {timestamp: frame.timestamp});

});

ان سب کو ایک ساتھ رکھتے ہوئے، ہم آخر کار ایک بہترین کام کرنے والی ویڈیو کنورٹر افادیت کو اکٹھا کر سکتے ہیں۔

اور بس! ہم نے WebCodecs پر Demuxing، Decoding، Canvas Transforms، Encoding اور Muxing کے ساتھ واقعی ایک مفید MVP بنایا ہے۔

اس میں اور Capcut جیسے مکمل براؤزر ایڈیٹنگ سویٹ کے درمیان فرق صرف تبدیلی کا پیمانہ اور دائرہ کار ہے۔ تاہم، ویڈیو پروسیسنگ منطق تقریبا ایک جیسی ہے۔

پیداوار کے مسائل

مجھے خوشی ہے کہ ہم کچھ کارآمد بنانے میں کامیاب ہوئے، لیکن اس کو سمیٹنے سے پہلے پیداواری سطح کے چند مسائل کو حل کرنا ضروری ہے۔

کوڈیک

آپ کو اس طرح کے تار مل سکتے ہیں: vp09.00.10.08 ڈیمو نے تفصیلات پر روشنی ڈالی۔ آئیے اب اس سے نمٹتے ہیں۔

پہلے، WebCodecs مخصوص کوڈیک تاروں کے ساتھ کام کرتا ہے: vp09.00.10.08، 'ہاںvp9' مندرجہ ذیل کام نہیں کرتا:

const codec = VideoEncoder({
    codec: 'vp9', //This won't work!
    //...
})

جیسا کہ پہلے بیان کیا گیا ہے، آپ ویڈیو کو ڈی کوڈ کرتے وقت اصل میں کوڈیک کا انتخاب نہیں کر سکتے۔ چونکہ ویڈیو پہلے ہی انکوڈ شدہ ہے، ہمیں ویڈیو سے کوڈیک حاصل کرنے کی ضرورت ہے جیسا کہ پچھلے ڈیمو میں دکھایا گیا ہے۔

ذکر کردہ ڈیملٹی پلیکسنگ لائبریری صحیح کوڈیک سٹرنگ کی نشاندہی کرے گی لہذا آپ کو اس کے بارے میں فکر کرنے کی ضرورت نہیں ہے۔

const decoderConfig = await demuxer.getVideoDecoderConfig();
//decoderConfig.codec = exact codec string for the video

ویڈیو کو انکوڈنگ کرتے وقت آپ کوڈیک کا انتخاب کر سکتے ہیں۔ کچھ لوگ کوڈیک کے انتخاب پر بہت زیادہ توجہ دیتے ہیں، لیکن ایک بہت ہی عملی اور عملی نقطہ نظر سے، درج ذیل اصولوں کا اطلاق زیادہ تر ڈویلپرز پر ہونا چاہیے:

  • اگر آپ چاہتے ہیں کہ صارفین وہ ویڈیو ڈاؤن لوڈ کریں جو آپ کی ایپ تیار کرتی ہے، یا mp4 فائل آؤٹ پٹ کریں، تو استعمال کریں: h264.

  • اگر تیار کردہ ویڈیو اندرونی استعمال کے لیے ہے، یا آپ ویڈیو پلے بیک کو کنٹرول کرنا چاہتے ہیں اور فارمیٹ سے متعلق نہیں ہیں، تو استعمال کریں: vp9 ویب ایم (اوپن سورس، بہتر کمپریشن، سب سے زیادہ تعاون یافتہ کوڈیک) استعمال کریں۔

  • زیادہ تر ایپس کے لیے، یہ دو اختیارات لاگو ہوتے ہیں۔ گہرا کوڈیک انتخاب ایک خرگوش سوراخ ہے جسے آپ کو ابھی نیچے نہیں جانا ہے۔

کوڈیک فیملی کو منتخب کرنے کے بعد، آپ کو ایک مخصوص کوڈیک سٹرنگ کا انتخاب کرنا ہوگا: avc1.42001f.

سٹرنگ میں دیگر نمبر مخصوص کوڈیک پیرامیٹرز کی وضاحت کرتے ہیں جو ڈویلپر کے نقطہ نظر سے کم اہم ہیں۔ اگر آپ کا مقصد زیادہ سے زیادہ مطابقت ہے، تو یہاں ایک دھوکہ دہی کی شیٹ ہے جس کے لیے کوڈیک سٹرنگز استعمال کرنے ہیں:

h264 (mp4 فائلوں کے لیے)
  • avc1.42001f - ڈیفالٹ پروفائل، سب سے زیادہ مطابقت رکھتا ہے، 720p تک (99.6٪ سپورٹ) کو سپورٹ کرتا ہے۔

  • avc1.4d0034 - مین پروفائل، لیول 5.2 (4K سپورٹ تک) (98.9% سپورٹ)

  • avc1.42003e - بنیادی پروفائل، سطح 6.2 (8k تک تعاون یافتہ) (86.8% تعاون یافتہ)

  • avc1.64003e - ہائی پروفائل - لیول 6.2 (8k سپورٹ تک) (85.9% سپورٹ)

vp9 (ویب ایم فائلوں کے لیے)

آپ بھی استعمال کر سکتے ہیں: getCodecString webcodecs-utils پیکیج کی خصوصیات:

import { getCodecString } from 'webcodecs-utils'

const codec_string = getCodecString('vp9', width, height, bitrate)

آپ ویب کوڈیکس میں دستیاب کوڈیکس اور کوڈیک سٹرنگز کی مکمل فہرست یہاں حاصل کر سکتے ہیں۔

بٹ کی شرح

اونچائی اور چوڑائی (مواد کے ذریعہ اشارہ کیا گیا ہے) اور کوڈیک سٹرنگ (جس پر ہم نے ابھی بات کی ہے) کے علاوہ، آپ کو ویڈیو کو انکوڈنگ کرتے وقت بٹ ریٹ بھی بتانا ہوگا۔

ویڈیو کمپریشن الگورتھم معیار اور فائل کے سائز کے درمیان توازن برقرار رکھتے ہیں۔ آپ کے پاس بڑی فائل سائز کے ساتھ اعلیٰ معیار کی ویڈیو ہو سکتی ہے، یا آپ کے پاس چھوٹی فائل سائز کے ساتھ کم معیار کی ویڈیو ہو سکتی ہے۔

1080p ویڈیو کے لیے مختلف بِٹریٹس پر انکوڈ کیے گئے مختلف کوالٹی لیولز کا فوری تصور یہاں ہے۔

300kbps

300kbps فریم

1Mbps

1 ایم بی پی ایس فریم

3Mbps

3Mbps فریم

10Mbps

10Mbps فریم

یہاں بٹریٹ کے رہنما خطوط کے لئے ایک فوری تلاش کی میز ہے:

حل بٹریٹ (30fps) بٹریٹ (60fps)
4K 13~20Mbps 20-30Mbps
1080ص 4.5~6Mbps 6~9Mbps
720ص 2~4Mbps 3~6Mbps
480ص 1.5~2Mbps 2-3Mbps
360ص 0.5-1Mbps 1~1.5Mbps
240ص 300~500kbps 500-800kbps

آپ اس یوٹیلیٹی فنکشن کو اپنی ایپس میں ایک فوری تخمینہ کے طور پر بھی استعمال کر سکتے ہیں۔

function getBitrate(width, height, fps, quality = 'good') {
    const pixels = width * height;

    const qualityFactors = {
      'low': 0.05,
      'good': 0.08,
      'high': 0.10,
      'very-high': 0.15
    };

    const factor = qualityFactors[quality] || qualityFactors['good'];

    // Returns bitrate in bits per second
    return pixels * fps * factor;
  }

یہی فعالیت webcodecs-utils پیکیج میں بھی دستیاب ہے۔

import { getBitrate } from 'webcodecs-utils'

GPU بمقابلہ CPU

زیادہ تر صارف کے آلات میں کچھ قسم کے گرافکس کارڈ ہوتے ہیں (جسے عام طور پر مربوط گرافکس کہا جاتا ہے)۔ یہ مخصوص سلکان فن تعمیر کے ساتھ خصوصی چپس ہیں جو بنیادی گرافکس کے ساتھ ساتھ ویڈیو انکوڈنگ اور ڈی کوڈنگ کے لیے موزوں ہیں۔

جب آپ "GPU" کا لفظ سنتے ہیں تو آپ AI ڈیٹا سینٹرز اور گیمرز کے بارے میں سوچ سکتے ہیں۔ لیکن جب بات ویب ایپلیکیشنز کی ہو تو تقریباً ہر ایک کے پاس GPU ہوتا ہے۔

یہ اہم ہے کیونکہ زیادہ تر فرنٹ اینڈ ڈیولپمنٹ تقریباً خصوصی طور پر CPUs کے ساتھ ہوتی ہے، لیکن WebCodec اور ویڈیو پروسیسنگ بنیادی طور پر GPUs پر کام کرتی ہے۔

یہاں ایک فوری گائیڈ ہے کہ کس قسم کا ڈیٹا کہاں ذخیرہ کیا جاتا ہے۔

ڈیٹا کی قسم مقام
ویڈیو فریم جی پی یو
انکوڈ شدہ ویڈیو کے ٹکڑے سی پی یو
تصویر کا بٹ میپ جی پی یو
صف بفر سی پی یو
فائل CPU + ڈسک

ڈیٹا منتقل کرنے کی کارکردگی کی لاگت ہوتی ہے، جو میموری کے انتظام کے لیے بھی اہم ہے۔

یادداشت

ویڈیو فریم اشیاء کافی بڑی ہو سکتی ہیں، 4K ویڈیو کے لیے 30 MB تک۔ آپ کا گرافکس کارڈ عام طور پر RAM کا ایک حصہ "ویڈیو میموری" یا "VRAM" کے لیے محفوظ رکھتا ہے۔ ویڈیو فریم اعتراض محفوظ ہو گیا ہے۔

لہذا اگر کسی صارف کے پاس 8 جی بی ریم ہے، تو اس کے پاس عام طور پر 2 جی بی VRAM ہوگی (آپریٹنگ سسٹم کے ذریعہ کتنا طے ہوتا ہے)۔

اگر ویڈیو ڈیٹا کی مقدار VRAM سے زیادہ ہو جائے تو ایپلیکیشن کریش ہو جائے گی۔ اس کا مطلب یہ ہے کہ اوسط صارف کے لیے، اگر میموری میں 67 4K فریم (ویڈیو کے 2 سیکنڈ تک) سے زیادہ ہوں تو پروگرام کریش ہو جائے گا۔

جب ویڈیو فریم بنتا ہے۔

ویڈیو فریم آبجیکٹ ہے۔ new VideoFrame(source) لیکن یہ بھی VideoDecoderخاص طور پر آؤٹ پٹ کال بیک۔ جب بھی فریم بنتا ہے، میموری کا استعمال بڑھ جاتا ہے۔

ویڈیو فریم کو کیسے ہٹایا جائے۔

آپ VideoFrame اشیاء کے لیے معیاری کوڑا کرکٹ جمع کرنے پر انحصار نہیں کر سکتے۔ مکمل ہونے پر، آپ کو واضح طور پر بند () کو فریم پر کال کرنا چاہیے۔

frame.close()

پہلے دکھائے گئے اسٹریمز/پائپ لائن کوڈ اور ڈیمو میں، فریم انکوڈ ہوتے ہی اصل میں بند ہو جاتے ہیں۔ ویڈیو عمل کا سلسلہ اور ویڈیو انکوڈ اسٹریم انٹرفیس

اسٹریمز سے WebCodecs کو فائدہ پہنچانے کی ایک اور وجہ ہے۔ highWaterMark اس پراپرٹی کی ڈیفالٹ ویلیو 10 ہے۔ اس کا مطلب یہ ہے کہ جب آپ چلاتے ہیں:

await demuxer.videoStream()
  .pipeThrough(new VideoDecodeStream(decoderConfig))
  .pipeThrough(processStream) 
  .pipeThrough(new VideoEncodeStream(encoderConfig))
  .pipeTo(muxer.videoSink());

اس بات کو یقینی بناتا ہے کہ کسی بھی وقت 10 سے زیادہ ویڈیو فریم میموری میں نہ ہوں۔ اسٹریمز API آپ کو اس حد کی وضاحت کرنے کی اجازت دیتا ہے جب کہ براؤزر خود اس منطق کو سنبھالتا ہے کہ اسے کیسے کرنا ہے۔

اگر آپ Streams API استعمال نہیں کر رہے ہیں، تو آپ کو اپنی میموری کی حدود اور کھلے ویڈیو فریموں کی تعداد کو خود ٹریک کرنا ہوگا۔

اضافی وسائل

اس مضمون کے ذریعے، ہم نے ویڈیو پروسیسنگ کی بنیادی باتوں کو دریافت کیا، WebCodecs API کے بنیادی تصورات کو متعارف کرایا، اور اپنی ویڈیو کنورٹر یوٹیلیٹی کا MVP بنایا۔ یہ دراصل ایک آسان ترین ڈیمو ہے جو API کے تمام حصوں کا احاطہ کرتا ہے۔ ہم نے کچھ بنیادی پیداواری مسائل کا بھی احاطہ کیا۔

یہ صرف ایک تعارف ہے اور صرف WebCodecs کی سطح کا احاطہ کرتا ہے۔ یہ دیکھنے کے لیے کہ API کتنا آسان ہے، ایک مناسب، پروڈکشن کے لیے تیار WebCodecs ایپلی کیشن کو صرف ہیلو ورلڈ ڈیمو سے زیادہ کی ضرورت ہے۔

WebCodecs کے بارے میں مزید جاننے کے لیے، MDN اور WebCodecsFundamentals دیکھیں، ایک جامع آن لائن درسی کتاب جو WebCodecs کے بارے میں بہت زیادہ گہرائی میں جاتی ہے۔

آپ موجودہ، پروڈکشن ٹیسٹ شدہ ایپس کے ماخذ کوڈ کا بھی جائزہ لے سکتے ہیں، جیسے کہ Remotion Convert (ماخذ کوڈ) جو ہم نے احاطہ کیا ڈیمو ایپ سے زیادہ مشابہت رکھتا ہے، اور Free AI Video Upscaler (ماخذ کوڈ، پروسیسنگ پائپ لائن)، جس نے یہاں پیش کردہ ڈیزائن پیٹرن کو متاثر کیا اور webcodecs-utils میں لاگو کیا ہے۔

آخر میں، WebCodecs لگتا ہے اس سے زیادہ مشکل ہے، لیکن MediaBunny جیسی لائبریریوں کا استعمال جو بہت سی تفصیلات کو آسان بناتا ہے جیسے کہ میموری کا انتظام، فائل I/O، اور دیگر تفصیلات آپ کی زندگی کو بہت آسان بنا سکتی ہیں۔ میں اسے اپنی پروڈکشن WebCodecs ایپلی کیشن میں استعمال کرتا ہوں۔

چاہے آپ واقعی ایک مکمل پروڈکشن گریڈ WebCodecs ایپلی کیشن بنائیں یا نہیں، آپ جانتے ہیں کہ اب یہ ایک آپشن ہے۔ یہ نسبتاً نیا ہے، سرور کی کم قیمت پر بہتر UX پیش کرتا ہے، اور اس کے فوائد کی وجہ سے بڑے ویڈیو ایپلی کیشنز جیسے Capcut اور Descript کے ذریعے اسے تیزی سے اپنایا جا رہا ہے۔

اوپر تک سکرول کریں۔