बफ़रिंग का कोटा खत्म हो गया है

Joe Medley
Joe Medley

अगर मीडिया सोर्स एक्सटेंशन (एमएसई) का इस्तेमाल किया जा रहा है, तो आपको आखिर में एक समस्या का सामना करना पड़ेगा. यह समस्या, बफ़र के भर जाने से जुड़ी होगी. ऐसा होने पर, आपको QuotaExceededError मिलेगा. इस लेख में, हम इस समस्या से निपटने के कुछ तरीकों के बारे में बताएंगे.

QuotaExceededError क्या है?

आम तौर पर, QuotaExceededError तब मिलता है, जब SourceBuffer ऑब्जेक्ट में बहुत ज़्यादा डेटा जोड़ने की कोशिश की जाती है. (किसी पैरंट MediaSource एलिमेंट में ज़्यादा SourceBuffer ऑब्जेक्ट जोड़ने पर भी यह गड़बड़ी दिख सकती है. यह इस लेख के दायरे से बाहर है.) अगर SourceBuffer में बहुत ज़्यादा डेटा है, तो SourceBuffer.appendBuffer() को कॉल करने पर, Chrome कंसोल विंडो में यह मैसेज ट्रिगर होगा.

कोटा कंसोल में गड़बड़ी.

इस बारे में कुछ बातें ध्यान में रखें. सबसे पहले, ध्यान दें कि QuotaExceededError नाम, मैसेज में कहीं नहीं दिख रहा है. यह देखने के लिए, उस जगह पर ब्रेकपॉइंट सेट करें जहां गड़बड़ी हो सकती है. इसके बाद, अपनी वॉच या स्कोप विंडो में जाकर, गड़बड़ी की जांच करें. मैंने इसे यहां दिखाया है.

स्मार्टवॉच के लिए कोटा.

दूसरी बात, यह पता लगाने का कोई तय तरीका नहीं है कि SourceBuffer कितना डेटा मैनेज कर सकता है.

अन्य ब्राउज़र में काम करने का तरीका

इस लेख को लिखने के समय, Safari के कई बिल्ड में QuotaExceededError नहीं दिखता. इसके बजाय, यह दो चरणों वाले एल्गोरिदम का इस्तेमाल करके फ़्रेम हटाता है. अगर appendBuffer() को हैंडल करने के लिए ज़रूरत के मुताबिक जगह है, तो यह प्रोसेस रुक जाती है. पहला, यह 30 सेकंड के हिस्से में मौजूदा समय से 0 से 30 सेकंड पहले के फ़्रेम को खाली करता है. इसके बाद, यह फ़्रेम को 30 सेकंड के हिस्सों से मुफ़्त में बांट देता है. साथ ही, फ़्रेम को पीछे की ओर से लेकर currentTime के बाद तक 30 सेकंड के बराबर कर देता है. इस बारे में ज़्यादा जानने के लिए, 2014 से Webkit के बदलाव सेट में जाएं.

अच्छी बात यह है कि Chrome, Edge, और Firefox के साथ-साथ यह गड़बड़ी होती है. अगर किसी दूसरे ब्राउज़र का इस्तेमाल किया जा रहा है, तो आपको खुद ही जांच करनी होगी. ऐसा हो सकता है कि आप असल मीडिया प्लेयर के लिए ऐसा न बनाएं, लेकिन फ़्रांकोइस बफ़ोर का सोर्स बफ़र की सीमा का टेस्ट, आपको कम से कम इसकी परफ़ॉर्मेंस को देखने की सुविधा देता है.

मैं कितना डेटा जोड़ सकता/सकती हूं?

यह संख्या, ब्राउज़र के हिसाब से अलग-अलग होती है. फ़िलहाल, जोड़े गए डेटा की संख्या के बारे में क्वेरी नहीं की जा सकती. इसलिए, आपको खुद ही यह पता लगाना होगा कि आपने कितना डेटा जोड़ा है. इस बारे में कि क्या देखना है, यहां सबसे अच्छा डेटा दिया गया है. Chrome के लिए ये संख्याएं ऊपरी सीमाएं होती हैं. इसका मतलब है कि जब सिस्टम को मेमोरी का दबाव महसूस होता है, तो ये संख्याएं कम हो सकती हैं.

Chrome Chromecast* Firefox Safari Edge
वीडियो 150 एमबी 30 एमबी 100MB 290 एमबी अज्ञात
ऑडियो 12 एमबी 2 एमबी 15 एमबी 14 एमबी अज्ञात
  • या कम मेमोरी वाले किसी दूसरे Chrome डिवाइस पर.

मैं क्या करूं?

काम करने वाले डेटा की संख्या काफ़ी अलग-अलग होती है और आपको 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() को सही तरीके से लागू नहीं किया जाता. असल में, इनकी वजह से गड़बड़ियां होती हैं, जिससे वीडियो चलाने में रुकावट आती है. सौभाग्य से, यहां और यहां, गड़बड़ी की जानकारी देने वाले ट्रैकर मौजूद हैं. इस बीच, आपको इस समस्या को हल करना होगा. Shka Player ऐसा करता है इसके लिए, Safari के उन वर्शन में एक खाली 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);

वीडियो चलाने का रिज़ॉल्यूशन कम करना

यह हाल ही का डेटा हटाने और फिर से जोड़ने जैसा ही है. असल में, दोनों को एक साथ किया जा सकता है. हालांकि, नीचे दिए गए उदाहरण में सिर्फ़ रिज़ॉल्यूशन को कम करने के बारे में बताया गया है.

इस तकनीक का इस्तेमाल करते समय, इन बातों का ध्यान रखें:

  • आपको एक नया इनिशिएलाइज़ेशन सेगमेंट जोड़ना होगा. प्रॉडक्ट के विज़ुअल बदलने पर, आपको ऐसा करना होगा. नया शुरुआती सेगमेंट, इसके बाद आने वाले मीडिया सेगमेंट के लिए होना चाहिए.
  • जोड़ा गया मीडिया, बफ़र में मौजूद डेटा के टाइमस्टैंप से मेल खाना चाहिए. हालांकि, यह ज़रूरी नहीं है कि वह डेटा के टाइमस्टैंप से आगे हो. बफ़र किए गए डेटा को ओवरलैप करने से, ब्राउज़र के हिसाब से समस्याएं आ सकती हैं या थोड़ी रुकावट आ सकती है. चाहे आपने जो भी जोड़ा हो, उसे प्लेलिस्ट के हेड के साथ ओवरलैप न करें. ऐसा करने पर, गड़बड़ियां दिखेंगी.
  • वीडियो पर आगे-पीछे जाने से, प्लेबैक में रुकावट आ सकती है. हो सकता है कि आप किसी खास जगह पर जाएं और वहां से वीडियो चलाना जारी रखें. ध्यान रखें कि इससे सीक पूरा होने तक वीडियो चलाने में रुकावट आएगी.