Skip to content
·45 min read

ভিডিও মাস্টারি — পর্ব ৬: Mux কীভাবে করে

জাস্ট-ইন-টাইম ট্রান্সকোডিং, নিউরাল নেটওয়ার্ক দিয়ে মিলিসেকেন্ডে পার-টাইটেল ল্যাডার, কোয়ালিটি টিয়ার, ওয়েবহুক-চালিত API, LL-HLS, আর ClickHouse-এ চলা QoE অ্যানালিটিক্স — সাথে তিন প্রোভাইডারের তুলনা।

জাস্ট-ইন-টাইম ট্রান্সকোডিং, নিউরাল নেটওয়ার্ক দিয়ে মিলিসেকেন্ডে পার-টাইটেল ল্যাডার, কোয়ালিটি টিয়ার, ওয়েবহুক-চালিত API, LL-HLS, আর ClickHouse-এ চলা QoE অ্যানালিটিক্স — সাথে তিন প্রোভাইডারের তুলনা।


Mux-এর সমস্যাটা তৃতীয় রকম

নেটফ্লিক্স নিজের কনটেন্ট নিজে দেখায়। Vimeo ব্যবহারকারীর কনটেন্ট নিজে দেখায়। Mux অন্য ডেভেলপারদের জন্য পুরো পাইপলাইনটাই একটা API বানিয়ে দেয় — মানে পর্ব ২ আর ৩-এ আমরা যা বানিয়েছিলাম, সেটার বাণিজ্যিক সংস্করণ।

এই ব্যবসায়িক মডেলটা তিনটা সীমাবদ্ধতা তৈরি করে:

  • কনটেন্ট কী আসবে, আগে থেকে জানার উপায় নেই। ওয়েবিনার, গেমিং ক্লিপ, ড্রোন ফুটেজ, ৪ ঘণ্টার লেকচার — একই সিস্টেমে।
  • সময় নেওয়া যাবে না। কেউ আপলোড করে বসে আছে; নেটফ্লিক্সের মতো “রিলিজের আগে তিন দিন এনকোড করব” বিলাসিতা নেই।
  • খরচ প্রতি মিনিটে দাম হয়ে ফিরে আসে। এনকোডিংয়ে যা খরচ করবে, সেটা সরাসরি প্রাইস লিস্টে দেখা যায়।

তাই Mux-এর প্রায় প্রতিটা প্রকৌশলগত সিদ্ধান্তের পেছনে একটাই প্রশ্ন: নেটফ্লিক্স-মানের কোয়ালিটি কি সেকেন্ডে দেওয়া যায়?


১. জাস্ট-ইন-টাইম ট্রান্সকোডিং

প্রচলিত প্রবাহ এরকম:

আপলোড → স্টোরেজ → ট্রান্সকোড (শেষ হওয়া পর্যন্ত অপেক্ষা) → স্টোরেজ → CDN → দর্শক

এখানে ট্রান্সকোডিং একটা বাধা — শেষ না হলে কিছুই দেখা যায় না। সাধারণ ট্রান্সকোডারে সময় লাগে ভিডিওর দৈর্ঘ্যের প্রায় অর্ধেক, মানে ১০ মিনিটের ভিডিওতে ~৫ মিনিট।

Mux দুটো কাজ একসাথে করে এই বাধাটা ভেঙে ফেলে।

প্রথমত, চাংকিং। প্রতিটা ভিডিওকে ছোট টুকরোয় (ধরো ১০ সেকেন্ড) ভাগ করে সমান্তরালে প্রসেস করা। এটা আমাদের চেনা — পর্ব ৩-এ আমরাও এটাই করেছি।

দ্বিতীয়ত, শেষ হওয়ার আগেই সার্ভ করা। এনকোডার থেকে ফ্রেম বেরোনোর সাথে সাথে সেগুলো স্ট্রিম করে দেওয়া হয় — মানে ভিডিওটা ট্রান্সকোড হওয়ার সময়েই দেখা শুরু করা যায়

Mux-এর নিজের ভাষায়, এটা সমস্যাটার সমাধান না — সমস্যাটাকে পাশ কাটিয়ে যাওয়া, আগে থেকে ট্রান্সকোড করার প্রয়োজনটাই মুছে দিয়ে।

প্রচলিত বনাম JIT

সংখ্যায়

Mux-এর প্রকাশিত হিসাব:

  • সাধারণ ১০ মিনিটের ভিডিও প্রকাশিত হতে ৯ সেকেন্ড
  • ৬০ মিনিটের সাধারণ ইনপুট ফাইলে মধ্যমা ২৬.৭ সেকেন্ড
  • তবে ৬০ মিনিটের কনটেন্টে ৯৫তম পার্সেন্টাইল ১১ মিনিট

শেষ সংখ্যাটা কেন গুরুত্বপূর্ণ, সেটা বলা দরকার। মধ্যমা ২৭ সেকেন্ড, কিন্তু p95 ১১ মিনিট — মানে কিছু ইনপুট অনেক কঠিন। অদ্ভুত কোডেক, ভাঙা টাইমস্ট্যাম্প, বিশাল বিটরেট, ভেরিয়েবল ফ্রেমরেট। পর্ব ৩-এ আমরা যে “ভাঙা ইনপুটই আসল শত্রু” বলেছিলাম, এই সংখ্যাটা তার প্রমাণ।

বাড়তি যা যা পাওয়া যায়

চাহিদামতো ট্রান্সকোড করতে পারার ক্ষমতাটা কিছু ফিচার প্রায় বিনা খরচে খুলে দেয়:

  • তাৎক্ষণিক থাম্বনেইল যেকোনো টাইমস্ট্যাম্পে
  • GIF বানানো চাহিদামতো
  • লাইভ ক্লিপিং
  • খরচ সাশ্রয়, কারণ যে অংশ কেউ দেখে না, সেটা প্রসেস করারই দরকার নেই

শেষ পয়েন্টটা লক্ষ করার মতো: চার ঘণ্টার একটা ভিডিওর যদি কেউ শুধু প্রথম দশ মিনিট দেখে, তাহলে বাকি ২১০ মিনিটের ছয়টা ধাপ এনকোড করার কোনো মানে নেই।


২. মিলিসেকেন্ডে পার-টাইটেল ল্যাডার

পর্ব ৪-এ আমরা দেখেছি কনভেক্স হাল কীভাবে বের করা হয় — অনেকগুলো ট্রায়াল এনকোড, প্রতিটার কোয়ালিটি মাপা, তারপর সেরা সীমারেখাটা নেওয়া। নেটফ্লিক্সের স্কেলে এই খরচটা যুক্তিসঙ্গত।

Mux-এর জন্য না। ওরা তিনটা প্রচলিত পদ্ধতি বিশ্লেষণ করে দেখিয়েছে কেন কোনোটাই চলে না:

পদ্ধতিকীভাবেসমস্যা
ব্রুট ফোর্সপ্রতি ক্লিপে ৩০০+ এনকোড, সব সমন্বয় পরীক্ষাসমান্তরাল করা যায়, কিন্তু কম্পিউটের বিশাল অপচয়
হাল ধরে হাঁটাপ্রতিটা বিটরেটে দুটো রেজলিউশন তুলনা করে এগোনো; বিটরেট প্রতি মাত্র ২–৩টা এনকোড (~৫৪টা বিটরেট)সমান্তরাল করা যায় না — ধাপে ধাপে এগোতে হয়, তাই ধীর; আর চমৎকার রেট কন্ট্রোল লাগে
CRF-ভিত্তিক স্কেলিংদ্রুত আর সহজMux VMAF-এর সাথে নির্ভরযোগ্য ম্যাপিং বের করতে পারেনি

সমস্যাটা আসলেই বড়

Mux-এর মাপা ফল, যেটা দেখায় ল্যাডার ঠিক করাটা কেন গুরুত্বপূর্ণ:

  • ৮৪% টেস্ট ভিডিওতে স্থির ল্যাডারের চেয়ে অপটিমাইজ করা হাল ভালো ফল দিয়েছে
  • সরল কনটেন্টে কম বিটরেটে প্রায় ১০ VMAF পয়েন্ট পর্যন্ত লাভ

ওদের উদাহরণটাও পরিষ্কার: নৌকা আর পানির জটিল ফুটেজে বেশি বিটরেটেও নিচু রেজলিউশনই জেতে; আবার ড্রোনের সরল ফুটেজ অল্প বিটরেটেই 1080p-তে পৌঁছে যায়।

Halfpipe — predict করা, হিসাব করা না

Mux-এর উত্তর: হালটা বের করার বদলে অনুমান করো।

ওরা একটা নিউরাল নেটওয়ার্ক (নাম Halfpipe) ট্রেন করেছে, যেটা ভিডিও দেখে সরাসরি কনভেক্স হাল অনুসরণ করা ল্যাডারটা বলে দেয়।

প্রেডিকশন ধাপ (মিলিসেকেন্ড): ভিডিও ঢোকার সময় কিছু ফ্রেম বের করে RGB অ্যারেতে ডিকোড করা হয়, সেগুলো Halfpipe-এ পাঠানো হয়, আর নেটওয়ার্ক আউটপুট দেয় রেজলিউশন-বিটরেট-কোয়ালিটির হাল ধরে চলা একটা ল্যাডার।

ট্রেনিং ধাপ (চলমান): যেসব ভিডিওর বৈশিষ্ট্য নতুন, সেগুলোতে পুরো পার-টাইটেল বিশ্লেষণ চালানো হয়, আর ফল ফেরত যায় মডেলে। মানে সিস্টেমটা নতুন ধরনের কনটেন্টের সাথে নিজেকে মানিয়ে নেয়।

মডেলটা কীভাবে বানানো হলো:

  • ৫০০টা ভিডিও ক্লিপ-এর গ্রাউন্ড ট্রুথ হাল বের করা হয়েছে — সেটাই লেগেছে ১৪০ দিনের প্রসেসিং
  • Inception আর YouTube-8M ডেটাসেট থেকে ট্রান্সফার লার্নিং
  • একটা LSTM ব্যবহার করা হয়েছে এটা নিশ্চিত করতে যে বিটরেট বাড়লে রেজলিউশন যেন কখনো কমে না (মনোটনিক থাকে) — নইলে ল্যাডারটা অর্থহীন হয়ে যেত

ফলাফল, তুলনায়

“নিখুঁত” ল্যাডার (পুরো হাল হিসাব করে বের করা) থেকে গড়ে কতটা দূরে:

VMAF ক্ষতি২ ঘণ্টার ভিডিওতে সময়২ ঘণ্টার ভিডিওতে খরচ
Mux (Halfpipe)০.৩০ পয়েন্ট৩ মিনিট$২.৪০
পুরো কনভেক্স হাল০ (সংজ্ঞামতে)৭০০+ মিনিট$১০০+
স্থির Apple ল্যাডার১.৯৯ পয়েন্ট৪০ মিনিট

আর ৪১.৫% এনকোডে স্থির ল্যাডারের চেয়ে ১ VMAF পয়েন্টের বেশি ভালো ফল।

মডেলটা যে সত্যিই শেখে, তার একটা উদাহরণও ওরা দিয়েছে: ব্রডকাস্ট কনটেন্ট দেখার আগে RMSE ছিল ০.৭৩; কয়েক মিনিটের ব্রডকাস্ট কনটেন্ট খাওয়ানোর পর সেটা নেমে আসে ০.৫০-এ।

ট্রেড-অফটা পরিষ্কার করে দেখা দরকার। ০.৩০ VMAF পয়েন্ট হারিয়ে ২৩৩ গুণ কম সময় আর ৪০ গুণ কম খরচ। ০.৩০ VMAF চোখে ধরা পড়ার ধারেকাছেও না। এটা প্রকৌশলের একটা আদর্শ সিদ্ধান্ত — নিখুঁততার শেষ ১% বিসর্জন দিয়ে পুরো জিনিসটাকে বাস্তবসম্মত বানানো।


৩. কোয়ালিটি টিয়ার — এক মাপ সবার জন্য না

Mux তিনটা কোয়ালিটি স্তর দেয়, আর তিনটাতেই পার-টাইটেল এনকোডিং চলে; পার্থক্যটা সীমার:

স্তররেজলিউশনবিটরেটের নীতিকার জন্য
Basicলাইভে 1080p পর্যন্তকম বিটরেটের সীমাসরল কনটেন্ট — সাক্ষাৎকার, সংবাদ সম্মেলন
Plusলাইভে 1080p পর্যন্তমাঝারি সীমাসাধারণ ব্যবহার
PremiumVOD-তে 4K, লাইভে 1080pবেশি বিটরেট ও বাড়তি অপটিমাইজেশনজটিল কনটেন্ট — খেলা, সিনেমা

Premium-এ একটা সূক্ষ্ম ব্যাপার আছে: সর্বোচ্চ বিটরেট যখন এত বেশি হয়ে যায় যে অনেক দর্শকের নেট সেটা টানতে পারবে না, তখন সিস্টেম নিজে থেকে মাঝখানে বাড়তি ধাপ যোগ করে। নইলে ল্যাডারে বড় ফাঁক তৈরি হতো, আর নেট একটু নড়লেই দর্শক অনেক নিচে পড়ে যেত।

দাম: Premium-এর খরচ Plus-এর ১.৫ গুণ — এনকোডিং, স্টোরেজ আর ডেলিভারি, তিনটাতেই। তবে এটা প্রতি অ্যাসেটে আলাদা করে দেওয়া যায়, তাই যে ভিডিওটার দরকার শুধু সেটাতেই।

আর কনটেন্টের ধরন কেউ হাতে ট্যাগ করে না — Mux কনটেন্টে এনকোড হওয়া তথ্যের জটিলতা মেপে সেটা মডেলে দেয়, আর তুমি যে স্তর বেছেছ তার সীমার ভেতরে সিদ্ধান্তটা নেওয়া হয়।


৪. API-টা দেখতে কেমন

এটা দেখা দরকার, কারণ এটাই ওদের আসল পণ্য — আর আমরা পর্ব ৩-এ নিজেরা যে ইন্টারফেসটা ডিজাইন করেছিলাম, তার সাথে তুলনা করার সুযোগ।

একটা অ্যাসেট বানানো:

// POST /video/v1/assets
{
	"inputs": [{ "url": "https://storage.example.com/ibn-sina-lecture.mp4" }],
	"playback_policies": ["public"],
	"video_quality": "premium",
	"static_renditions": [{ "resolution": "720p" }, { "resolution": "audio-only" }]
}

উত্তর আসে সাথে সাথে, কিন্তু ভিডিও তখনো তৈরি হয়নি:

{
	"data": {
		"status": "preparing",
		"playback_ids": [{ "policy": "public", "id": "TXjw00EgPBPS6acv7gBUEJ14PEr5XNWOe" }],
		"video_quality": "basic",
		"mp4_support": "none",
		"id": "01itgOBvgjAbES7Inwvu4kEBtsQ44HFL6",
		"created_at": "1607876845"
	}
}

তিনটা জিনিস খেয়াল করো:

status একটা স্টেট মেশিনpreparingready → (বা) errored। পর্ব ৩-এ আমরা ঠিক এটাই বানিয়েছিলাম।

playback_id অ্যাসেট আইডি থেকে আলাদা। এটা গুরুত্বপূর্ণ ডিজাইন — অ্যাসেট আইডি তোমার ভেতরের পরিচয়, আর playback ID সেই জিনিস যেটা URL-এ যায়:

https://stream.mux.com/{PLAYBACK_ID}.m3u8

আলাদা রাখার কারণে একই অ্যাসেটের একাধিক playback ID থাকতে পারে (কোনোটা পাবলিক, কোনোটা সাইন করা), আর একটা বাতিল করলে অ্যাসেটটা হারায় না।

static_renditions — HLS-এর বাইরে সাধারণ MP4 ফাইল, ডাউনলোড বা পুরনো ডিভাইসের জন্য। Vimeo যেটা Artax দিয়ে চলার পথে বানায়, Mux সেটা চাইলে আগে থেকে বানিয়ে রাখে।

সাইন করা প্লেব্যাক

ব্যক্তিগত ভিডিওর জন্য URL-এ একটা JWT জোড়া হয়:

https://stream.mux.com/{PLAYBACK_ID}.m3u8?token={JWT}

JWT তৈরি হয় তোমার সার্ভারে। পর্ব ৩-এ আমরা যে সইসহ URL-এর কথা বলেছিলাম, একই ধারণা — গোপন চাবি কখনো ব্রাউজারে যায় না, আর টোকেনের মেয়াদ থাকে।

ওয়েবহুক, পোলিং না

কাজ শেষ হলে Mux তোমার সার্ভারে ইভেন্ট পাঠায়:

export async function handleMuxWebhook(req, res) {
	const event = req.body; // সই যাচাই করার পর

	if (event.type === 'video.asset.ready') {
		const { id, playback_ids, duration } = event.data;
		await db.videos.update({
			where: { muxAssetId: id },
			data: { status: 'ready', playbackId: playback_ids[0].id, duration }
		});
	}

	res.json({ received: true });
}

গুরুত্বপূর্ণ ইভেন্টগুলো:

  • video.asset.ready — চালানোর জন্য প্রস্তুত; পেলোডে duration, resolution_tier, aspect_ratio, playback_ids
  • video.asset.errored — ব্যর্থ
  • video.upload.errored — আপলোড নিজেই ব্যর্থ; সবচেয়ে সাধারণ কারণ, ব্যবহারকারী ভিডিও নয় এমন ফাইল দিয়েছে
  • video.asset.static_renditions.ready — MP4 ফাইলগুলো তৈরি

পোলিং লুপ বনাম ওয়েবহুক — এই পার্থক্যটা ছোট মনে হলেও না। পোলিং মানে তোমার সিস্টেমকে প্রতি কয়েক সেকেন্ডে প্রশ্ন করতে হবে “হয়েছে?”, আর ভুলে গেলে ভিডিও চিরকাল “প্রসেসিং” দেখাবে। ওয়েবহুক মানে ঘটনাটা তোমার কাছে আসে, আর তার পেছনে ক্যাপশন তৈরি, থাম্বনেইল, CMS আপডেট — সব চেইন করে বসানো যায়।

লাইভ আর লেটেন্সি

লাইভ স্ট্রিম বানানো:

// POST /video/v1/live-streams
{
	"latency_mode": "low",
	"reconnect_window": 60,
	"playback_policies": ["public"],
	"new_asset_settings": { "playback_policies": ["public"] }
}

latency_mode: "low" অ্যাপলের LL-HLS স্পেক ব্যবহার করে, লেটেন্সি নামে ৫ সেকেন্ড পর্যন্ত। তুলনায় সাধারণ HLS-এ সাধারণত ৩০ সেকেন্ড

reconnect_window হলো সম্প্রচারকের নেট কেটে গেলে কত সেকেন্ড অপেক্ষা করা হবে স্ট্রিমটা শেষ ঘোষণা করার আগে। আর new_asset_settings মানে লাইভ শেষ হলে রেকর্ডিংটা নিজে থেকেই একটা VOD অ্যাসেট হয়ে যাবে।


৫. দর্শকের দিকটা মাপা — Mux Data

Mux-এর দ্বিতীয় পণ্যটা এনকোডিং না, মাপা। আর এটাই সবচেয়ে বেশি অনুকরণযোগ্য জিনিস — কারণ তুমি যেই দিয়েই ভিডিও চালাও, দর্শকের অভিজ্ঞতা মাপা লাগবেই।

যে মেট্রিকগুলো আসলে গুরুত্বপূর্ণ

Video Startup Time — প্লে চাপা থেকে প্রথম ফ্রেম দেখানো পর্যন্ত সময়। দর্শক ধরে রাখার জন্য একক সবচেয়ে প্রভাবশালী সংখ্যা; ২ সেকেন্ডের বেশি হলে উল্লেখযোগ্য পরিমাণ দর্শক ছেড়ে চলে যায়। মধ্যমা দেখা হয়, গড় না।

Rebuffer Percentage — মোট চাওয়া সময়ের কত শতাংশ বাফারিংয়ে গেল। ৫% মানে প্রতি ৬০ সেকেন্ড দেখায় ৩ সেকেন্ড আটকে থাকা।

Video Quality Score — এটা চতুর। এটা VMAF-এর মতো ছবির ভেতরটা দেখে না; এটা দেখে স্ট্রিমের রেজলিউশন বনাম প্লেয়ারের আকার। ৩৬০p-র স্ট্রিম যদি ফুল স্ক্রিনে টেনে বড় করা হয়, স্কোর নামে — কারণ দর্শক আসলে ঝাপসা ছবিই দেখছে।

Exits Before Video Start — লোড হওয়ার সময়েই যারা চলে গেল।

Playback Failures — যেসব ত্রুটির পর আর চালানোই যায় না।

Viewer Experience Score — উপরের চারটা দিক (প্লেব্যাক ব্যর্থতা, রিবাফারিং, স্টার্টআপ সময়, ভিডিও কোয়ালিটি) মিলিয়ে একটা সংখ্যা।

লাইভের জন্য বাড়তি: Live Stream Latency — ক্যামেরা থেকে দর্শকের স্ক্রিন পর্যন্ত সময়, মাপা হয় ম্যানিফেস্টের EXT-X-PROGRAM-DATE-TIME ট্যাগ দিয়ে। যারা লাইভ প্রান্ত থেকে ৫ মিনিটের বেশি পিছিয়ে, তাদের হিসাব থেকে বাদ দেওয়া হয় (কারণ ওরা তো আসলে লাইভ দেখছে না)।

CCV (Current Concurrent Viewers) — এই মুহূর্তে কতজন দেখছে; যারা লোড হচ্ছে, রিবাফার করছে বা ত্রুটিতে আছে তারাও গোনা হয়, কিন্তু যারা পজ করে রেখেছে বা টানা ৫ মিনিট ধরে রিবাফার করছে তারা বাদ।

ভাগ করে দেখাটাই আসল কাজ

মেট্রিকগুলো ভাগ করে দেখা যায় ASN, CDN, অপারেটিং সিস্টেম, প্লেয়ার, অঞ্চল, স্ট্রিমের ধরন, ভিডিও টাইটেল ইত্যাদি দিয়ে।

এটাই সবচেয়ে দামি অংশ। “রিবাফারিং ৩%” — এই সংখ্যাটা দিয়ে কিছু করার নেই। কিন্তু ”এই ISP-তে, এই CDN-এ, অ্যান্ড্রয়েডে রিবাফারিং ১২%” — এটা একটা টিকিট, যেটা সমাধান করা যায়।

মনিটরিং ড্যাশবোর্ডে ডেটা আসে ২০ সেকেন্ডের কম বিলম্বে, ২৪ ঘণ্টা পর্যন্ত।

এই পাইপলাইনটা নিজেই একটা গল্প

কোটি কোটি প্লেয়ার থেকে আসা বিকন প্রসেস করাটা নিজেই একটা কঠিন সিস্টেম সমস্যা, আর Mux তাদের সমাধান বদলানোর কথা লিখে গেছে।

আগে: CDN লগ আর অভ্যন্তরীণ ইভেন্ট → Kafka → একটা Apache Flink অ্যাপ (exactly-once প্রসেসিং আর এনরিচমেন্টের জন্য) → PostgreSQL

এখন: ClickHouse একাই দুটো কাজ করে — স্ট্রিম প্রসেসর আর স্থায়ী ডেটা স্টোর। Flink আর Postgres, দুটোই সরে গেছে।

কৌশলটা: Kafka Table Engine দিয়ে সরাসরি Kafka থেকে টানা, তারপর ক্যাসকেডিং ম্যাটেরিয়ালাইজড ভিউ আর Null টেবিলের একটা সিরিজের ভেতর দিয়ে ডেটাকে কয়েক ধাপে প্রি-অ্যাগ্রিগেট ও রূপান্তর করে রোলআপ টেবিলে ফেলা।

(Null টেবিল হলো ClickHouse-এর একটা কৌশল — টেবিলটা কিছুই সংরক্ষণ করে না, কিন্তু তার উপর বসানো ম্যাটেরিয়ালাইজড ভিউগুলো চলে। মানে রূপান্তরের মধ্যবর্তী ধাপগুলো ডিস্কে জায়গা নেয় না।)

ফল:

  • প্রায় ৫ লাখ রাইট প্রতি সেকেন্ডে
  • ৬০ vCPU, ৪টা নোডে
  • কনজিউমার ল্যাগ সাধারণত এক মিনিটের নিচে
  • ডেটার সতেজতা কয়েক ঘণ্টা থেকে সবচেয়ে খারাপ ক্ষেত্রেও কয়েক মিনিটে

আর শর্তটা ছিল কঠিন: বিলিং সঠিক রাখতে exactly-once নিশ্চয়তা লাগবে, আর কোয়েরি উইন্ডো কয়েক মিনিট থেকে ৩০+ দিন পর্যন্ত।

Flink সরানোর যুক্তিটা প্রকৌশলের চেয়ে সাংগঠনিক বেশি, আর Mux সেটা স্বীকার করেছে: Flink শক্তিশালী কিন্তু জটিল, অনেক প্রতিষ্ঠানে পুরো একটা টিম শুধু Flink ক্লাস্টার চালায়। Mux-এ ClickHouse-এর বিশেষজ্ঞ ছিল। টিম যা ভালো চালাতে পারে, সেটাই প্রায়ই সঠিক প্রযুক্তি।


৬. অবকাঠামো

Mux-এর ইনফ্রার যেটুকু ওরা প্রকাশ করেছে:

  • Google Cloud আর AWS, দুটোতেই চলে
  • Kubernetes নিজেরা চালায়, ম্যানেজড সার্ভিস না — কারণ দুই ক্লাউডে একই পরিবেশ, একই লগিং আর মেট্রিক চাই
  • একাধিক রিজিয়ন জুড়ে প্রায় ৯০টা মাইক্রোসার্ভিস
  • সব রিজিয়নে পুরো ক্লাস্টার রোলআউট এক ঘণ্টারও কম সময়ে
  • ডেভেলপমেন্ট পরিবেশ তৈরি কয়েক ঘণ্টা থেকে নেমে ১৫ মিনিটের কম

Kubernetes বাছার মূল কারণটাও ভিডিও-নির্দিষ্ট: লাইভ ইভেন্টে দর্শক সংখ্যা সেকেন্ডে শূন্য থেকে লাখে যেতে পারে, তাই খুব দ্রুত উপরে-নিচে স্কেল করতে পারা দরকার।


৭. তিনজনের তুলনা

তিনটা পর্ব একসাথে রাখলে ছবিটা এরকম দাঁড়ায়:

নেটফ্লিক্সVimeoMux
ক্যাটালগসীমিত, ভিউ বিশালবিশাল, ভিউ কমগ্রাহকের, অনির্দেশ্য
প্রধান শত্রুব্যান্ডউইথ ও কোয়ালিটিখরচ ও গতিলেটেন্সি ও সরলতা
ল্যাডারপার-শট, পুরো কনভেক্স হাল হিসাব করেপ্রোফাইল + বিটরেট ক্যাপ, VMAF দিয়ে নজরদারিনিউরাল নেটওয়ার্কে হাল অনুমান
এনকোডিংয়ের এককশট (কয়েকটা জড়ো করে ~৩ মিনিটের চাংক)~১ মিনিটের চাংক, কি-ফ্রেমে কাটা~১০ সেকেন্ডের চাংক
কম্পিউটঅন্য সার্ভিসের ফেলে রাখা ক্ষমতাস্পট ইনস্ট্যান্স + Quickset বিন-প্যাকিংমাল্টি-ক্লাউড, নিজেদের Kubernetes
কোয়ালিটি মেট্রিকVMAF (নিজেরা বানানো), অপটিমাইজেশনের লক্ষ্যVMAF, এনকোডারের ভেতর থেকে নমুনায়VMAF মডেল ট্রেনিংয়ে; দর্শকের দিকে VES
ডেলিভারিনিজের CDN (Open Connect), আগেভাগে ফিলক্লাউড স্টোরেজ + CDNমাল্টি-CDN
প্রকাশের গতিদিন (রিলিজের আগে)মিনিটসেকেন্ড

দুটো বড় শিক্ষা এই টেবিল থেকে বেরিয়ে আসে।

এক — চাংকের আকার আসলে একটা ব্যবসায়িক সিদ্ধান্ত। নেটফ্লিক্স ৩ মিনিটের চাংক নেয় কারণ কম্প্রেশন দক্ষতা তাদের কাছে সবচেয়ে দামি। Mux ১০ সেকেন্ডের নেয় কারণ প্রকাশের গতি তাদের পণ্য। Vimeo মাঝামাঝি ১ মিনিটে, কারণ ওদের লক্ষ্য স্পট মেশিনে সস্তায় কাজ চালানো। এটা কোনো “সঠিক উত্তর” নয় — এটা তোমার সীমাবদ্ধতার প্রতিফলন।

দুই — তিনজনই একই মৌলিক কাঠামোয় এসে দাঁড়িয়েছে। টুকরো করো → সমান্তরালে এনকোড করো → জোড়া দাও → প্যাকেজ করো → CDN থেকে দাও → দর্শকের দিকটা মাপো। পর্ব ৩-এ আমরা যেটা বানিয়েছিলাম, সেটার সাথে এর পার্থক্য মাত্রার, ধরনের না।


৮. তুমি কী করবে

ছয়টা পর্বের শেষে সবচেয়ে ব্যবহারিক প্রশ্নটা: নিজে বানাবে, নাকি কিনবে?

কিনে নাও যদি — ভিডিও তোমার পণ্যের অংশ, কিন্তু তোমার মূল ব্যবসা না। প্রতি মিনিটের দামটা প্রথমে বেশি মনে হবে, কিন্তু এর ভেতরে আছে ভাঙা ইনপুট সামলানো, কোডেক আপগ্রেড, প্লেয়ার বাগ, DRM, CDN চুক্তি, আর ২টার সময় ফোন আসা। পর্ব ৩-এর ব্যর্থতার তালিকাটা আরেকবার পড়ো — ওগুলোর প্রতিটা তোমাকে নিজে সমাধান করতে হবে।

নিজে বানাও যদি — ভিডিওই তোমার ব্যবসা, ভলিউম বিশাল, বা এমন কিছু দরকার যেটা কোনো প্রোভাইডার দেয় না (বিশেষ কোডেক, নির্দিষ্ট দেশে ডেটা রাখার বাধ্যবাধকতা, অদ্ভুত ওয়ার্কফ্লো)।

মাঝামাঝি পথটাও আছে, আর অনেক ক্ষেত্রে সেটাই সেরা: প্যাকেজিং, স্টোরেজ আর ডেলিভারি নিজে চালাও (এগুলো তুলনামূলক স্থির আর বোঝা সহজ), কিন্তু এনকোডিংয়ের ল্যাডার সিদ্ধান্তটা সরল রাখো — কনটেন্টের ধরন অনুযায়ী দু-তিনটা প্রি-সেট ল্যাডার, নিখুঁত পার-টাইটেল অপটিমাইজেশন না।

আর যা-ই করো, দর্শকের দিকটা মাপো। স্টার্টআপ টাইম, রিবাফার শতাংশ, ব্যর্থতার হার — এই তিনটা সংখ্যা ISP আর ডিভাইস ধরে ভাগ করে দেখা। এটা যেকোনো স্কেলে করা যায়, আর এটাই সবচেয়ে বেশি ফেরত দেয়। কারণ সব সিদ্ধান্তের শেষে প্রশ্নটা একই — সমরকন্দে বাসে বসে থাকা মানুষটা প্লে চাপল, সে কি ভিডিওটা দেখতে পেল?


সূত্র

পরের দুই পর্বেপর্ব ৭: লাইভ, যেখানে সময়ের বাজেট শূন্য বলে এই সিরিজের প্রায় সব কৌশল বাতিল হয়ে যায়; আর পর্ব ৮: প্লেয়ার, যেখানে এই পর্বের startup time আর rebuffer শতাংশের সংখ্যাগুলো আসলে তৈরি হয়।