বাফারিং কোটা অতিক্রম করছে

জো মেডলি
Joe Medley

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

QuotaExceededError কি?

মূলত, QuotaExceededError হল আপনি যদি আপনার SourceBuffer অবজেক্টে খুব বেশি ডেটা যোগ করার চেষ্টা করেন তাহলে আপনি যা পাবেন। (একটি অভিভাবক MediaSource উপাদানে আরও SourceBuffer অবজেক্ট যুক্ত করাও এই ত্রুটিটি ফেলতে পারে৷ এটি এই নিবন্ধের সুযোগের বাইরে৷) যদি SourceBuffer এ খুব বেশি ডেটা থাকে, তাহলে SourceBuffer.appendBuffer() কল করলে Chrome কনসোল উইন্ডোতে নিম্নলিখিত বার্তাটি ট্রিগার হবে৷ .

কোটা কনসোল ত্রুটি।

এই বিষয়ে লক্ষ করার মতো কয়েকটি বিষয় রয়েছে। প্রথমে লক্ষ্য করুন যে QuotaExceededError নামটি মেসেজে কোথাও দেখা যাচ্ছে না। এটি দেখতে, এমন একটি স্থানে একটি ব্রেকপয়েন্ট সেট করুন যেখানে আপনি ত্রুটিটি ধরতে পারেন এবং এটি আপনার ঘড়ি বা স্কোপ উইন্ডোতে পরীক্ষা করতে পারেন। আমি নীচে এই দেখিয়েছি.

কোটা ঘড়ির জানালা।

দ্বিতীয়ত, SourceBuffer কতটা ডেটা পরিচালনা করতে পারে তা খুঁজে বের করার কোন নির্দিষ্ট উপায় নেই।

অন্যান্য ব্রাউজারে আচরণ

লেখার সময়, সাফারি এর অনেক বিল্ডে QuotaExceededError ফেলে না। পরিবর্তে এটি একটি দুই ধাপের অ্যালগরিদম ব্যবহার করে ফ্রেমগুলি সরিয়ে দেয়, যদি appendBuffer() পরিচালনা করার জন্য পর্যাপ্ত জায়গা থাকে তবে বন্ধ করে দেয়। প্রথমত, এটি বর্তমান সময়ের 0 থেকে 30 সেকেন্ডের মধ্যে ফ্রেমগুলিকে 30 সেকেন্ডের মধ্যে মুক্ত করে। এর পরে, এটি 30 সেকেন্ডের অংশে ফ্রেমগুলিকে মুক্ত করে সময়কাল থেকে currentTime পরে 30 সেকেন্ডের কাছাকাছি। আপনি 2014 থেকে একটি ওয়েবকিট পরিবর্তনসেটে এই সম্পর্কে আরও পড়তে পারেন।

সৌভাগ্যবশত, ক্রোম, এজ এবং ফায়ারফক্সের সাথে এই ত্রুটিটি নিক্ষেপ করে। আপনি যদি অন্য ব্রাউজার ব্যবহার করেন তবে আপনাকে নিজের পরীক্ষা করতে হবে। যদিও সম্ভবত আপনি বাস্তব জীবনের মিডিয়া প্লেয়ারের জন্য যা তৈরি করতে চান তা নয়, ফ্রাঙ্কোইস বিউফোর্টের উত্স বাফার সীমা পরীক্ষা অন্তত আপনাকে আচরণটি পর্যবেক্ষণ করতে দেয়।

আমি কত ডেটা যোগ করতে পারি?

সঠিক সংখ্যা ব্রাউজার থেকে ব্রাউজারে পরিবর্তিত হয়। যেহেতু আপনি বর্তমানে যুক্ত করা ডেটার পরিমাণের জন্য অনুসন্ধান করতে পারবেন না, তাই আপনি নিজেকে কতটা যুক্ত করছেন তার ট্র্যাক রাখতে হবে। কী দেখতে হবে, লেখার সময় আমি সংগ্রহ করতে পারি এমন সেরা ডেটা এখানে। ক্রোমের জন্য এই সংখ্যাগুলি ঊর্ধ্ব সীমা যার মানে সিস্টেম মেমরির চাপের সম্মুখীন হলে এগুলি ছোট হতে পারে৷

ক্রোম Chromecast* ফায়ারফক্স সাফারি প্রান্ত
ভিডিও 150MB 30MB 100MB 290MB অজানা
শ্রুতি 12MB 2MB 15MB 14MB অজানা
  • অথবা অন্যান্য সীমিত মেমরি ক্রোম ডিভাইস।

তাই আমি কি করতে পারি?

যেহেতু সমর্থিত ডেটার পরিমাণ ব্যাপকভাবে পরিবর্তিত হয় এবং আপনি একটি SourceBuffer এ ডেটার পরিমাণ খুঁজে পাচ্ছেন না, তাই আপনাকে অবশ্যই QuotaExceededError পরিচালনা করে পরোক্ষভাবে এটি পেতে হবে। এখন আসুন এটি করার কয়েকটি উপায় দেখি।

QuotaExceededError মোকাবেলা করার জন্য বিভিন্ন পন্থা রয়েছে। বাস্তবে এক বা একাধিক পদ্ধতির সংমিশ্রণ সর্বোত্তম। আপনি HTMLMediaElement.currentTime বাইরে কতটা আনছেন এবং যোগ করার চেষ্টা করছেন এবং QuotaExceededError উপর ভিত্তি করে সেই আকারটি সামঞ্জস্য করার জন্য আপনার পদ্ধতির ভিত্তি হওয়া উচিত। এছাড়াও কিছু ধরণের ম্যানিফেস্ট ব্যবহার করে যেমন একটি mpd ফাইল (MPEG-DASH) বা একটি m3u8 ফাইল (HLS) আপনাকে বাফারে যে ডেটা যুক্ত করছেন তার ট্র্যাক রাখতে সাহায্য করতে পারে।

এখন, QuotaExceededError মোকাবেলা করার জন্য বিভিন্ন পদ্ধতির দিকে নজর দেওয়া যাক।

  • অপ্রয়োজনীয় ডেটা সরান এবং পুনরায় যুক্ত করুন।
  • ছোট টুকরা যোগ করুন.
  • প্লেব্যাক রেজোলিউশন কম করুন।

যদিও তারা সংমিশ্রণে ব্যবহার করা যেতে পারে, আমি সেগুলিকে একবারে কভার করব।

অপ্রয়োজনীয় ডেটা সরান এবং পুনরায় যুক্ত করুন

সত্যিই এটিকে বলা উচিত, "কম-সম্ভাব্য-টু-ব্যবহৃত-শীঘ্রই ডেটা সরান, এবং তারপরে-সম্ভাব্য-ব্যবহৃত-শীঘ্রই ডেটা যুক্ত করার চেষ্টা করুন।" এটি একটি শিরোনাম খুব দীর্ঘ ছিল. তোমাকে শুধু মনে রাখতে হবে আমি আসলে কি বলতে চাইছি।

সাম্প্রতিক ডেটা সরানো SourceBuffer.remove() কল করার মতো সহজ নয়। SourceBuffer থেকে ডেটা অপসারণ করতে, এটির আপডেট করা পতাকা অবশ্যই মিথ্যা হতে হবে। যদি তা না হয়, কোনো ডেটা অপসারণের আগে SourceBuffer.abort() এ কল করুন।

SourceBuffer.remove() কল করার সময় কয়েকটি বিষয় মাথায় রাখতে হবে।

  • এটি প্লেব্যাকের উপর নেতিবাচক প্রভাব ফেলতে পারে। উদাহরণস্বরূপ, আপনি যদি ভিডিওটি শীঘ্রই রিপ্লে বা লুপ করতে চান তবে আপনি ভিডিওর শুরুটি সরাতে নাও চাইতে পারেন। একইভাবে, যদি আপনি বা ব্যবহারকারী ভিডিওর এমন একটি অংশ খোঁজেন যেখানে আপনি ডেটা সরিয়েছেন, সেই অনুসন্ধানটি পূরণ করতে আপনাকে আবার সেই ডেটা যোগ করতে হবে।
  • যতটা সম্ভব রক্ষণশীলভাবে সরান। currentTime সময়ে বা তার আগে কীফ্রেমে শুরু হওয়া ফ্রেমের বর্তমান প্লেয়িং গ্রুপটি সরানোর বিষয়ে সতর্ক থাকুন কারণ এটি করার ফলে প্লেব্যাক স্টল হতে পারে। ম্যানিফেস্টে উপলভ্য না থাকলে এই ধরনের তথ্যকে ওয়েব অ্যাপের দ্বারা বাইটস্ট্রিম থেকে পার্স করার প্রয়োজন হতে পারে। একটি মিডিয়া ম্যানিফেস্ট বা মিডিয়াতে কীফ্রেম ব্যবধানের অ্যাপ জ্ঞান বর্তমানে প্লে করা মিডিয়া অপসারণ রোধ করতে আপনার অ্যাপের অপসারণের ব্যাপ্তির পছন্দকে গাইড করতে সাহায্য করতে পারে। আপনি যাই মুছে ফেলুন না কেন, বর্তমানে বাজানো ছবির গ্রুপ বা এর বাইরেও প্রথম কয়েকটিকে সরিয়ে ফেলবেন না। সাধারণত, বর্তমান সময়ের বাইরে সরিয়ে ফেলবেন না যদি না আপনি নিশ্চিত হন যে মিডিয়ার আর প্রয়োজন নেই। আপনি যদি প্লেহেডের কাছাকাছি সরান তাহলে আপনি একটি স্টল হতে পারে।
  • Safari 9 এবং Safari 10 সঠিকভাবে SourceBuffer.abort() প্রয়োগ করে না । প্রকৃতপক্ষে, তারা এমন ত্রুটি নিক্ষেপ করে যা প্লেব্যাককে থামিয়ে দেবে। ভাগ্যক্রমে এখানে এবং এখানে খোলা বাগ ট্র্যাকার আছে। এই সময়ের মধ্যে, আপনাকে এটিকে একরকম কাজ করতে হবে। শাকা প্লেয়ার সাফারির সেই সংস্করণগুলিতে একটি খালি abort() ফাংশন স্টাব করে এটি করে।

ছোট টুকরা যোগ করুন

আমি নীচের পদ্ধতিটি দেখিয়েছি। এটি প্রতিটি ক্ষেত্রে কাজ নাও করতে পারে, তবে এটির সুবিধা রয়েছে যে ছোট অংশগুলির আকার আপনার প্রয়োজন অনুসারে সামঞ্জস্য করা যেতে পারে। এটি নেটওয়ার্কে ফিরে যাওয়ারও প্রয়োজন নেই যা কিছু ব্যবহারকারীর জন্য অতিরিক্ত ডেটা খরচ বহন করতে পারে।

const pieces = new Uint8Array([data]);
(function appendFragments(pieces) {
    if (sourceBuffer.updating) {
    return;
    }
    pieces.forEach(piece => {
    try {
        sourceBuffer.appendBuffer(piece);
    }
    catch e {
        if (e.name !== 'QuotaExceededError') {
        throw e;
        }

        // Reduction schedule: 80%, 60%, 40%, 20%, 16%, 12%, 8%, 4%, fail.
        const reduction = pieces[0].byteLength * 0.8;
        if (reduction / data.byteLength < 0.04) {
        throw new Error('MediaSource threw QuotaExceededError too many times');
        }
        const newPieces = [
        pieces[0].slice(0, reduction),
        pieces[0].slice(reduction, pieces[0].byteLength)
        ];
        pieces.splice(0, 1, newPieces[0], newPieces[1]);
        appendBuffer(pieces);  
    }
    });
})(pieces);

প্লেব্যাক রেজোলিউশন কম করুন

এটি সাম্প্রতিক ডেটা অপসারণ এবং পুনরায় সংযুক্ত করার অনুরূপ। প্রকৃতপক্ষে, দুটি একসাথে করা যেতে পারে, যদিও নীচের উদাহরণটি শুধুমাত্র রেজোলিউশন কমিয়ে দেখায়।

এই কৌশলটি ব্যবহার করার সময় কিছু জিনিস মাথায় রাখতে হবে:

  • আপনাকে অবশ্যই একটি নতুন ইনিশিয়ালাইজেশন সেগমেন্ট যোগ করতে হবে। আপনি যে কোনো সময় উপস্থাপনা পরিবর্তন করতে হলে আপনাকে অবশ্যই এটি করতে হবে। নতুন প্রারম্ভিক সেগমেন্ট অবশ্যই অনুসরণ করা মিডিয়া সেগমেন্টের জন্য হতে হবে।
  • সংযোজিত মিডিয়ার উপস্থাপনা টাইমস্ট্যাম্প যতটা সম্ভব বাফারে থাকা ডেটার টাইমস্ট্যাম্পের সাথে মিলিত হওয়া উচিত, তবে এগিয়ে যাবে না। বাফার করা ডেটা ওভারল্যাপ করার ফলে ব্রাউজারের উপর নির্ভর করে একটি স্তব্ধতা বা সংক্ষিপ্ত স্টল হতে পারে। আপনি যা যুক্ত করুন না কেন, প্লেহেডকে ওভারল্যাপ করবেন না কারণ এটি ত্রুটিগুলি ফেলবে।
  • চাওয়া প্লেব্যাক ব্যাহত হতে পারে. আপনি একটি নির্দিষ্ট অবস্থান খোঁজার এবং সেখান থেকে প্লেব্যাক পুনরায় শুরু করতে প্রলুব্ধ হতে পারেন। সতর্ক থাকুন যে অনুসন্ধানটি সম্পূর্ণ না হওয়া পর্যন্ত এটি প্লেব্যাক বাধা সৃষ্টি করবে৷