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

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

दूसरा, यह पता लगाने का कोई पक्का तरीका नहीं है कि SourceBuffer
कितना डेटा मैनेज कर सकता है.
अन्य ब्राउज़र में व्यवहार
इस लेख को लिखने के समय, Safari के कई बिल्ड में QuotaExceededError
नहीं दिखता. इसके बजाय, यह दो चरणों वाले एल्गोरिदम का इस्तेमाल करके फ़्रेम हटाता है. अगर appendBuffer()
को हैंडल करने के लिए ज़रूरत के मुताबिक जगह है, तो यह प्रोसेस रुक जाती है. सबसे पहले, यह मौजूदा समय से 30 सेकंड पहले के फ़्रेम को 30 सेकंड के हिस्सों में हटा देता है. इसके बाद, यह currentTime
के 30 सेकंड बाद से लेकर, वीडियो की अवधि के आखिर तक, 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()
को सही तरीके से लागू नहीं करते. असल में, इनकी वजह से गड़बड़ियां होती हैं, जिससे वीडियो चलाने में रुकावट आती है. सौभाग्य से, यहां और यहां, बग ट्रैकर खोले गए हैं. इस बीच, आपको इस समस्या को हल करना होगा. Shaka 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);
वीडियो चलाने का रिज़ॉल्यूशन कम करना
यह हाल ही का डेटा हटाने और फिर से जोड़ने जैसा ही है. असल में, दोनों को एक साथ किया जा सकता है. हालांकि, नीचे दिए गए उदाहरण में सिर्फ़ रिज़ॉल्यूशन को कम करने के बारे में बताया गया है.
इस तकनीक का इस्तेमाल करते समय, इन बातों का ध्यान रखें:
- आपको एक नया इनिशिएलाइज़ेशन सेगमेंट जोड़ना होगा. प्रॉडक्ट के विज़ुअल बदलने पर, आपको ऐसा करना होगा. नया शुरुआती सेगमेंट, इसके बाद आने वाले मीडिया सेगमेंट के लिए होना चाहिए.
- जोड़ा गया मीडिया, बफ़र में मौजूद डेटा के टाइमस्टैंप से मेल खाना चाहिए. हालांकि, यह ज़रूरी नहीं है कि वह डेटा के टाइमस्टैंप से आगे हो. ब्राउज़र के हिसाब से, बफ़र किए गए डेटा को ओवरलैप करने पर, वीडियो में रुकावट आ सकती है या कुछ समय के लिए वीडियो रुक सकता है. चाहे आपने जो भी जोड़ा हो, प्लेलिस्ट के हेड को ओवरलैप न करें. ऐसा करने पर, गड़बड़ियां दिखेंगी.
- वीडियो पर आगे-पीछे जाने से, प्लेबैक में रुकावट आ सकती है. हो सकता है कि आप किसी खास जगह पर जाएं और वहां से वीडियो चलाना जारी रखें. ध्यान रखें कि ऐसा करने पर, वीडियो का प्लेबैक तब तक रुक जाएगा, जब तक वीडियो को आगे या पीछे नहीं ले जाया जाता.