প্লেয়ার আসলে কী
ফেচ, ডিমাক্স, ডিকোড, রেন্ডার আর A/V সিঙ্ক — একটা ভিডিও প্লেয়ারের পাঁচটা কাজ, কোনটা ব্রাউজার করে আর কোনটা আপনার JavaScript, আর প্লেয়ার লাইব্রেরিগুলোর মানচিত্র।
গল্পে বুঝি
খুলনার পুরনো একটা সিনেমা হলে প্রজেকশন রুমের দায়িত্বে হাইসাম। শো শুরুর আগে ডিস্ট্রিবিউটরের অফিস থেকে টিনের বাক্সে করে ফিল্মের রিল আসে, একেকটা বাক্সে বিশ মিনিটের মতো ছবি। হাইসাম প্রথম রিলটা প্রজেক্টরে পরায়, ফিল্ম আলোর সামনে দিয়ে টানা হয়, পর্দায় ছবি পড়ে। পাশেই একটা আলাদা সাউন্ড হেড ফিল্মের কিনারার সাউন্ডট্র্যাক পড়ে স্পিকারে পাঠায়। হাইসামের সবচেয়ে বড় ভয় একটাই: নায়কের ঠোঁট নড়ছে কিন্তু ডায়ালগ আধা সেকেন্ড পরে আসছে। দর্শক তখন হাসতে শুরু করে, আর পরের দিন হল খালি।
তাই হাইসাম তিনটা জিনিস সবসময় চোখে রাখে। প্রথমত, পরের রিল হাতের কাছে আছে কিনা: একটা রিল শেষ হওয়ার আগেই দ্বিতীয় প্রজেক্টরে পরেরটা পরানো থাকতে হবে, না হলে পর্দা কালো হয়ে যাবে। দ্বিতীয়ত, ছবি আর শব্দ একই তালে চলছে কিনা। তৃতীয়ত, রিল ছিঁড়ে গেলে বা বাক্সে ভুল রিল এলে কী করবে। হলের মালিক ফাতিমা আবার আরেকটা ব্যাপার জানেন: পাশের শহরের নতুন মাল্টিপ্লেক্সে একই ছবি চলছে ডিজিটাল প্রজেক্টরে, যেখানে সব কাজ মেশিন নিজেই করে, হাইসামের মতো কাউকে লাগে না। কিন্তু সেখানে কোন রিল কখন চলবে, বিরতি কোথায় হবে, অ্যাড কোথায় বসবে, সেটা হলের লোক বদলাতে পারে না। হাইসামের হলে সব হাতের মুঠোয়, কিন্তু সব দায়ও তার।
মিলিয়ে নিই: টিনের বাক্সে রিল আসা হলো ফেচ (সেগমেন্ট ডাউনলোড), রিল খুলে ছবির ফিল্ম আর সাউন্ডট্র্যাক আলাদা করে পড়া হলো ডিমাক্স, আলোর সামনে দিয়ে ফিল্ম টেনে ছবি বানানো হলো ডিকোড ও রেন্ডার, ঠোঁট আর ডায়ালগ মেলানো হলো A/V সিঙ্ক, দ্বিতীয় প্রজেক্টরে আগেই পরের রিল পরানো হলো বাফার, আর ছেঁড়া রিল সামলানো হলো এরর রিকভারি। হাইসামের হাতে চালানো হল হলো JavaScript প্লেয়ার (hls.js, Shaka), যেখানে সব নিয়ন্ত্রণ আপনার; মাল্টিপ্লেক্সের অটোমেটিক প্রজেক্টর হলো নেটিভ প্লেয়ার (Safari-র HLS, iOS-এর AVPlayer), যেটা নিজেই সব করে কিন্তু কম বদলানো যায়। বাস্তবে প্রতিটা স্ট্রিমিং সাইট এই দুইয়ের একটা বেছে নেয়, আর অনেকে দুটোই রাখে: যে ডিভাইসে যেটা ভালো চলে।
একটা প্লেয়ারের পাঁচটা কাজ
ভিডিও প্লেয়ার শুনলে আমরা প্লে বাটন, সিক বার আর ভলিউম স্লাইডার ভাবি। ওগুলো প্লেয়ারের সবচেয়ে ছোট অংশ। আসল প্লেয়ার হলো একটা পাইপলাইন যেটা নেটওয়ার্ক থেকে বাইট এনে স্ক্রিনে পিক্সেল আর স্পিকারে শব্দ বানায়, প্রতি সেকেন্ডে পঁচিশ থেকে ষাটবার, কোনো ফ্রেম না ফেলে।
- ফেচ। ম্যানিফেস্ট (HLS-এর
.m3u8বা DASH-এর.mpd) পড়ে ঠিক করা কোন সেগমেন্ট লাগবে, তারপর HTTP দিয়ে সেগুলো নামানো। কোন কোয়ালিটির সেগমেন্ট নামাবে সেটাই ABR-এর সিদ্ধান্ত। - ডিমাক্স। একটা সেগমেন্ট ফাইলে ভিডিও, অডিও, কখনো সাবটাইটেল একসাথে মোড়ানো থাকে। কন্টেইনার (fMP4, MPEG-TS) খুলে প্রতিটা ট্র্যাকের কম্প্রেসড ফ্রেম আলাদা করা হলো ডিমাক্স। কন্টেইনারের ভেতরটা কেমন, সেটা আছে Container আর transmuxing চ্যাপ্টারে।
- ডিকোড। H.264, HEVC, AV1-এর মতো কম্প্রেসড ফ্রেমকে কাঁচা পিক্সেলে ফেরানো। এটা ভারী কাজ, তাই প্রায় সব ডিভাইসে আলাদা হার্ডওয়্যার ডিকোডার চিপ থাকে।
- রেন্ডার। ডিকোড হওয়া ফ্রেমকে ঠিক সময়ে স্ক্রিনে বসানো, স্কেল করা, রঙ ঠিক রাখা।
- A/V সিঙ্ক। প্রতিটা ফ্রেমের গায়ে একটা টাইমস্ট্যাম্প (PTS) থাকে। প্লেয়ার একটা মাস্টার ক্লক ধরে, সাধারণত অডিও ক্লক, আর ভিডিও ফ্রেমকে সেই ক্লকের সাথে মিলিয়ে দেখায়। কারণ সহজ: একটা ফ্রেম এক মুহূর্ত দেরিতে দেখালে চোখ ধরতে পারে না, কিন্তু অডিওতে ফাঁক পড়লে কান সাথে সাথে ধরে। তাই অডিও নিজের গতিতে চলে, আর ভিডিও দরকারে একটা ফ্রেম ফেলে দিয়ে বা একটু ধরে রেখে তাল মেলায়।
এর উপরে আরও কয়েকটা দায়িত্ব আছে যেগুলো পাইপলাইনের অংশ না হলেও প্লেয়ারকেই সামলাতে হয়: ক্যাপশন দেখানো, একাধিক অডিও ট্র্যাক বদলানো, DRM লাইসেন্স আনা, অ্যাড বসানো, আর কী হলো সেটা অ্যানালিটিক্সে পাঠানো। এই ট্র্যাকের প্রতিটা চ্যাপ্টার এর একেকটা নিয়ে।
অডিও কেন মাস্টার ক্লক: ৩০ fps ভিডিওতে একটা ফ্রেম ৩৩ মিলিসেকেন্ড থাকে। একটা ফ্রেম ফেলে দিলে বেশিরভাগ মানুষ টেরই পায় না। কিন্তু অডিওতে ২০ মিলিসেকেন্ডের ফাঁক একটা স্পষ্ট “ক্লিক” শব্দ। তাই সিঙ্ক ঠিক রাখার দায় ভিডিওর ঘাড়ে।
হার্ডওয়্যার ডিকোড: কেন এটা প্লেয়ারের সবচেয়ে বড় সীমা
একটা 1080p H.264 স্ট্রিম সফটওয়্যারে ডিকোড করলে পুরনো ফোনের CPU গরম হয়ে যায়, ব্যাটারি গলে যায়। হার্ডওয়্যার ডিকোডার একই কাজ অল্প বিদ্যুতে করে। এর মানে দাঁড়ায়, কোন কোডেক চলবে সেটা মূলত ডিভাইসের চিপ ঠিক করে, প্লেয়ার নয়।
| পরিস্থিতি | কী হয় |
|---|---|
| কোডেকের হার্ডওয়্যার ডিকোডার আছে | মসৃণ, ঠান্ডা, ব্যাটারি বাঁচে |
| হার্ডওয়্যার নেই, সফটওয়্যার ডিকোডার আছে | চলে, কিন্তু বড় রেজোলিউশনে ফ্রেম ড্রপ, ফোন গরম |
| কোনো ডিকোডার নেই | ভিডিও চলেই না, অথবা শুধু অডিও চলে |
এজন্যই একটা প্লেয়ার প্লে করার আগে জিজ্ঞেস করে নেয় “এই কোডেক তুমি পারবে?” ব্রাউজারে এর জন্য আছে MediaSource.isTypeSupported() আর আরও বিস্তারিত উত্তরের জন্য navigator.mediaCapabilities.decodingInfo(), যেটা বলে দেয় শুধু “সাপোর্টেড” না, “মসৃণ” আর “পাওয়ার-এফিশিয়েন্ট” কিনা।
const info = await navigator.mediaCapabilities.decodingInfo({
type: 'media-source',
video: {
contentType: 'video/mp4; codecs="av01.0.08M.08"',
width: 1920,
height: 1080,
bitrate: 4_000_000,
framerate: 30
}
});
console.log(info); { supported: true, smooth: true, powerEfficient: false } এই উত্তরটা (উদাহরণ হিসেবে) বলছে: AV1 চলবে, মসৃণও চলবে, কিন্তু হার্ডওয়্যারে না, সফটওয়্যারে। ল্যাপটপে প্লাগ লাগানো থাকলে ঠিক আছে, ফোনে ব্যাটারিতে থাকলে প্লেয়ার হয়তো H.264 রেন্ডিশন বেছে নেবে। এই সিদ্ধান্তটাই প্লেয়ারের কাজ। কোন কোডেক কেন বেছে নেওয়া হয় তার পেছনের হিসাব আছে Codec আর compression চ্যাপ্টারে।
নেটিভ প্লেয়ার বনাম JavaScript প্লেয়ার
ব্রাউজারে ভিডিও চালানোর দুইটা মৌলিক উপায় আছে।
নেটিভ: video এলিমেন্টের src-এ সরাসরি একটা URL দিয়ে দেওয়া। একটা সাধারণ MP4 ফাইল হলে সব ব্রাউজার এটা পারে। HLS ম্যানিফেস্ট হলে পারে Safari (macOS, iOS, iPadOS), কারণ Apple-এর মিডিয়া স্ট্যাকের ভেতরেই HLS প্লেয়ার বসানো। তখন ম্যানিফেস্ট পড়া, সেগমেন্ট আনা, ABR, সব ব্রাউজার নিজে করে।
<video src="https://cdn.baytalhikma.org/lectures/42/master.m3u8" controls playsinline></video> JavaScript প্লেয়ার: ব্রাউজার শুধু ডিকোড আর রেন্ডার করে। ম্যানিফেস্ট পড়া, সেগমেন্ট আনা, কোয়ালিটি বাছাই, বাফার সামলানো সব করে আপনার পেজের JavaScript, আর বাইটগুলো ব্রাউজারকে খাওয়ায় Media Source Extensions (MSE) দিয়ে। hls.js, dash.js, Shaka Player সবাই এভাবেই কাজ করে। MSE কীভাবে কাজ করে, সেটা তৃতীয় চ্যাপ্টারে হাতে-কলমে দেখব।
| প্রশ্ন | নেটিভ | JavaScript (MSE) |
|---|---|---|
| ABR কে চালায় | ব্রাউজার, আপনার নিয়ন্ত্রণ সামান্য | আপনি, প্রতিটা প্যারামিটার বদলানো যায় |
| কোন ডিভাইসে লাগে | iOS-এ প্রায়ই একমাত্র উপায় | ডেস্কটপ, Android, স্মার্ট TV-র ব্রাউজার |
| এরর বোঝা | শুধু MediaError কোড, খুব কম তথ্য | কোন সেগমেন্ট, কোন HTTP স্ট্যাটাস, সব জানা যায় |
| পাওয়ার ও AirPlay | সবচেয়ে ভালো ইন্টিগ্রেশন | ব্রাউজার ভেদে সীমিত |
| অ্যানালিটিক্স | ইভেন্ট কম | প্রতিটা সেগমেন্টের টাইমিং |
| কাস্টম লজিক (অ্যাড, লো-লেটেন্সি টিউনিং) | কঠিন | সহজ |
বাস্তবে বেশিরভাগ প্রোডাকশন সাইট এভাবে বেছে নেয়: MSE থাকলে JavaScript প্লেয়ার, না থাকলে নেটিভ। তবে একটা সূক্ষ্ম ব্যাপার আছে: নতুন iPhone-এ Safari MSE-র একটা রূপ (ManagedMediaSource) সাপোর্ট করে, কিন্তু Apple-এর নিজের নির্দেশনা আর ব্যাটারির হিসাবে অনেকে iOS-এ এখনো নেটিভ HLS-ই রাখে। তৃতীয় চ্যাপ্টারে এর বিস্তারিত আছে।
ব্রাউজারের নাম দেখে সিদ্ধান্ত নেবেন না। navigator.userAgent-এ “Safari” লেখা আছে বলে নেটিভ HLS ধরে নেওয়া একটা পুরনো ভুল, কারণ Chrome-এর user agent-এও “Safari” শব্দটা থাকে। সবসময় ফিচার দেখে সিদ্ধান্ত নিন: video.canPlayType('application/vnd.apple.mpegurl') আর MediaSource.isTypeSupported(...)।
প্লেয়ার লাইব্রেরির মানচিত্র
২০২৬ সালের অক্টোবর অনুযায়ী ওয়েবে বহুল ব্যবহৃত ওপেন-সোর্স প্লেয়ারগুলো মোটামুটি এরকম (প্রতিটার রিপোজিটরিতে বর্তমান অবস্থা মিলিয়ে নিন):
| লাইব্রেরি | কী চালায় | কখন বেছে নেবেন |
|---|---|---|
| hls.js | শুধু HLS (TS ও fMP4 সেগমেন্ট, LL-HLS) | আপনার সব কন্টেন্ট HLS, আর একটা হালকা, ফোকাসড ইঞ্জিন চান |
| dash.js | MPEG-DASH, DASH-IF-এর রেফারেন্স প্লেয়ার | DASH-ভিত্তিক স্ট্যাক, স্ট্যান্ডার্ডের কাছাকাছি থাকতে চান |
| Shaka Player | DASH আর HLS দুটোই, DRM ও অফলাইন সহ | এক প্লেয়ারে দুই ফরম্যাট, DRM বেশি, স্মার্ট TV টার্গেট |
| Video.js | UI ফ্রেমওয়ার্ক; ভেতরে নিজের স্ট্রিমিং ইঞ্জিন (VHS) | রেডিমেড স্কিন আর প্লাগইন ইকোসিস্টেম চান |
খেয়াল করুন, hls.js, dash.js আর Shaka হলো ইঞ্জিন: এগুলোর কাজ বাইট এনে ব্রাউজারকে খাওয়ানো, UI খুব সামান্য বা নেই। Video.js-এর মতো লাইব্রেরি হলো স্কিন আর কাঠামো, যার ভেতরে একটা ইঞ্জিন বসানো। অনেক টিম নিজের UI বানিয়ে ভেতরে hls.js বা Shaka বসায়।
মোবাইল অ্যাপে আলাদা জগত: iOS-এ AVPlayer (Apple-এর নেটিভ), Android-এ Media3 ExoPlayer। দশম চ্যাপ্টারে এগুলো দেখব।
প্লেয়ারের দায়িত্ব বনাম সার্ভারের দায়িত্ব
প্লেয়ারের অনেক সমস্যা আসলে সার্ভারের ভুল, আর উল্টোটাও। কোনটা কার, এটা পরিষ্কার জানা থাকলে ডিবাগিং অর্ধেক সহজ হয়ে যায়।
| কাজ | কার দায়িত্ব | ভুল হলে কী দেখা যায় |
|---|---|---|
| সঠিক কোডেক স্ট্রিং ম্যানিফেস্টে লেখা | প্যাকেজার (সার্ভার) | প্লেয়ার রেন্ডিশন বাদ দেয় বা addSourceBuffer ফেল করে |
| কীফ্রেম দিয়ে সেগমেন্ট শুরু করা | এনকোডার (সার্ভার) | কোয়ালিটি বদলালে সবুজ ব্লক, ঝাপসা ছবি |
সঠিক Content-Type ও CORS হেডার | CDN/origin | ব্রাউজার রিকোয়েস্ট ব্লক করে, কনসোলে CORS এরর |
| কোন কোয়ালিটি নামাবে | প্লেয়ার (ABR) | বারবার বাফারিং বা অকারণে ঝাপসা |
| কতটা আগে থেকে বাফার রাখবে | প্লেয়ার | স্লো নেটওয়ার্কে থেমে থেমে চলা |
| নেটওয়ার্ক এররে রিট্রাই | প্লেয়ার | একটা সেগমেন্ট ফেল করলেই পুরো প্লেব্যাক বন্ধ |
| সেগমেন্টের ক্যাশিং | CDN | স্টার্টআপ ধীর, origin-এ চাপ |
প্যাকেজিং আর এনকোডিংয়ের দিকটা VOD ট্র্যাকে (এনকোডিং জব, প্যাকেজিং কৌশল) আর লাইভ স্ট্রিমিং ট্র্যাকে আছে। ক্যাশিংয়ের দিকটা CDN ট্র্যাকে।
DevTools দিয়ে একটা প্লেয়ারকে কাজ করতে দেখা
তত্ত্ব পড়ার চেয়ে একবার নিজের চোখে দেখা ভালো। যেকোনো ভিডিও সাইট খুলুন, DevTools-এর Network ট্যাবে যান, আর ফিল্টারে m3u8|mpd|m4s|ts|mp4 লিখুন। ভিডিও চালু করলে মোটামুটি এরকম একটা ক্রম দেখবেন (উদাহরণ, আসল নাম সাইট ভেদে আলাদা):
GET master.m3u8 200 1.2 KB 38 ms
GET 720p/index.m3u8 200 3.4 KB 41 ms
GET 720p/init.mp4 200 1.1 KB 35 ms
GET 720p/seg-00001.m4s 200 812 KB 210 ms
GET 720p/seg-00002.m4s 200 790 KB 188 ms
GET 1080p/index.m3u8 200 3.4 KB 39 ms
GET 1080p/init.mp4 200 1.2 KB 33 ms
GET 1080p/seg-00003.m4s 200 1.6 MB 402 ms এই আটটা লাইনেই পুরো পাইপলাইনের গল্প আছে: প্রথমে মাস্টার প্লেলিস্ট, তারপর একটা রেন্ডিশনের প্লেলিস্ট, তারপর init সেগমেন্ট (ডিকোডারকে কোডেকের পরিচয় দেয়), তারপর মিডিয়া সেগমেন্ট। তৃতীয় সেগমেন্টে প্লেয়ার দেখেছে নেটওয়ার্ক ভালো, তাই 1080p-তে উঠে গেছে; এজন্য নতুন প্লেলিস্ট আর নতুন init সেগমেন্ট আনতে হয়েছে।
Chrome-এ আরেকটা দারুণ জায়গা আছে: chrome://media-internals। এখানে প্রতিটা চলমান মিডিয়া প্লেয়ারের ভেতরের লগ দেখা যায়: কোন ডিকোডার বাছা হয়েছে (হার্ডওয়্যার না সফটওয়্যার), কোন কোডেক, ফ্রেম ড্রপ, আর এরর হলে আসল কারণ। Firefox-এ কাছাকাছি তথ্য পাওয়া যায় about:support-এর Media অংশে। এই দুইটা জায়গা পরের চ্যাপ্টারগুলোতে বারবার আসবে।
প্লেয়ার কখন “ভালো”
একটা প্লেয়ারকে চারটা প্রশ্নে বিচার করা হয়, আর এগুলোই QoE (Quality of Experience) মেট্রিক যা এগারো নম্বর চ্যাপ্টারে মাপব:
- কত দ্রুত শুরু হলো? প্লে চাপা থেকে প্রথম ফ্রেম পর্যন্ত সময়।
- কতবার আটকাল? রিবাফারিংয়ের সংখ্যা আর মোট সময়।
- কেমন দেখাল? গড় বিটরেট বা রেজোলিউশন, আর কতবার কোয়ালিটি ওঠানামা করল।
- কতবার পুরোপুরি ফেল করল? এরর রেট।
এই চারটা একে অপরের বিরুদ্ধে টানে। বড় বাফার রাখলে আটকানো কমে কিন্তু শুরু ধীর হয়। উঁচু কোয়ালিটিতে শুরু করলে দেখতে ভালো কিন্তু শুরু ধীর আর আটকানোর ঝুঁকি বেশি। প্লেয়ার ডিজাইন মানেই এই টানাপোড়েনে কোথায় দাঁড়াবেন সেটা ঠিক করা। ABR-এর তাত্ত্বিক দিকটা আছে Playback আর ABR চ্যাপ্টারে; এই ট্র্যাকের পঞ্চম চ্যাপ্টার দেখাবে আসল লাইব্রেরিতে সেটা কীভাবে টিউন করতে হয়।
ডিবাগিং: এই চ্যাপ্টারের সমস্যাগুলো
| লক্ষণ | কীভাবে নিশ্চিত হবেন | সমাধান |
|---|---|---|
| শুধু অডিও চলে, ছবি কালো | chrome://media-internals-এ ভিডিও ডিকোডারের এরর, অথবা mediaCapabilities.decodingInfo() এ supported: false | ওই কোডেকের পাশাপাশি H.264 রেন্ডিশন রাখুন; ম্যানিফেস্টের কোডেক স্ট্রিং ঠিক আছে কিনা দেখুন |
| ফোনে ভিডিও চলে কিন্তু ফোন গরম, ব্যাটারি দ্রুত শেষ | decodingInfo() এ powerEfficient: false | ওই ডিভাইসে হার্ডওয়্যার-ডিকোডযোগ্য কোডেক বা কম রেজোলিউশন বেছে নিন |
| ঠোঁট আর শব্দ মেলে না, সবসময় একই পরিমাণে | একটা ক্ল্যাপ বা বিপ সহ টেস্ট ভিডিও চালিয়ে দেখুন, আর ffprobe -show_streams দিয়ে অডিও ও ভিডিওর start_time তুলনা করুন | সমস্যা এনকোডিংয়ে; অডিও ট্র্যাকের অফসেট ঠিক করে আবার প্যাকেজ করুন |
| ঠোঁট আর শব্দ ধীরে ধীরে সরে যায় | লম্বা ভিডিওর শেষে বেশি সরে কিনা দেখুন; chrome://media-internals-এ ফ্রেম ড্রপ | ডিভাইস ডিকোড সামলাতে পারছে না; কম রেজোলিউশন বা হার্ডওয়্যার কোডেক |
| Safari-তে চলে, Chrome-এ চলে না (বা উল্টো) | video.canPlayType('application/vnd.apple.mpegurl') আর MediaSource.isTypeSupported(...) দুই ব্রাউজারে চালিয়ে তুলনা | নেটিভ HLS-এর উপর ভরসা না করে MSE থাকলে JavaScript প্লেয়ার চালান |
| এরর শুধু “MEDIA_ERR_SRC_NOT_SUPPORTED” | Network ট্যাবে ম্যানিফেস্ট আর সেগমেন্টের স্ট্যাটাস ও Content-Type দেখুন | প্রায়ই 404, CORS বা ভুল MIME টাইপ; এটা প্লেয়ারের না, সার্ভারের সমস্যা |
মূল শিক্ষা
- প্লেয়ার মানে একটা পাইপলাইন: ফেচ, ডিমাক্স, ডিকোড, রেন্ডার আর A/V সিঙ্ক। বাটনগুলো এর সবচেয়ে ছোট অংশ।
- অডিও সাধারণত মাস্টার ক্লক, কারণ অডিওর ফাঁক কানে ধরা পড়ে আর একটা ভিডিও ফ্রেম ফেলা চোখে প্রায় পড়ে না।
- কোন কোডেক চলবে সেটা ডিভাইসের হার্ডওয়্যার ঠিক করে।
mediaCapabilities.decodingInfo()দিয়ে শুধু “চলবে কিনা” না, “মসৃণ ও পাওয়ার-এফিশিয়েন্ট কিনা” জিজ্ঞেস করুন। - নেটিভ প্লেয়ার সব নিজে করে কিন্তু কম বদলানো যায়; JavaScript প্লেয়ার MSE দিয়ে সব আপনার হাতে দেয়। ফিচার দেখে বাছুন, ব্রাউজারের নাম দেখে না।
- hls.js, dash.js, Shaka ইঞ্জিন; Video.js-এর মতো লাইব্রেরি স্কিন আর কাঠামো।
- প্লেয়ারের অনেক “বাগ” আসলে সার্ভারের ভুল (কোডেক স্ট্রিং, কীফ্রেম, CORS)। কোন দায়িত্ব কার, সেটা জানা থাকলে ডিবাগিং অর্ধেক হয়ে যায়।
- DevTools-এর Network ট্যাব আর
chrome://media-internalsপ্লেয়ারের ভেতরটা দেখার দুইটা প্রধান জানালা।