2012-04-19 37 views
18

मैं HTML5 वीडियो प्रबंधित करने के लिए एक jQuery प्लगइन का निर्माण कर रहा हूं। मैं कैनप्ले और कैप्चरथ्रू घटनाओं को पकड़ने की कोशिश कर रहा हूं। क्रोम में, घटना बिना किसी समस्या के निकाल दी जाती है। फ़ायरफ़ॉक्स में, कभी-कभी यह ट्रिगर होता है, कभी-कभी यह नहीं होता है।एक HTML5 वीडियो के लिए कैप्प्ले/कैप्प्लेथ्रू ईवेंट फ़ायरफ़ॉक्स पर नहीं कहा जाता है। क्यूं कर?

मैं अपने कोड को सरल बनाने रहा हूँ यहाँ एक छोटे से:

$('#my_video').on('canplay canplaythrough', function(){ 
    console.log('canplay event fired'); 
}); 

मैं भी देशी जावास्क्रिप्ट .addEventListener साथ की कोशिश की() है और यह काम नहीं कर रहा।

कोई विचार क्यों फ़ायरफ़ॉक्स पर ईवेंट नहीं कहा जाता है और इसे कैसे ठीक किया जाए?

नोट: कृपया मुझे पहले से ही उपलब्ध प्लगइन जैसे जेप्लेयर और वीडियो-जेएस का उपयोग करने के लिए न कहें, मुझे पता है कि वे मौजूद हैं और अच्छी तरह से काम करते हैं, लेकिन मुझे इन-हाउस समाधान बनाना है।

उत्तर

36

समस्या यह है कि आपके video तत्व ने ईवेंट हैंडलर पंजीकृत करने से पहले canplaythrough ईवेंट ट्रिगर किया है।

जैसा कि आपने अपने उत्तर में बताया है, आप अपनी स्क्रिप्ट <head> में डाल सकते हैं, लेकिन यह आपके पृष्ठ के प्रदर्शन के लिए खराब है।

आपकी समस्या को ठीक करने के लिए एक बेहतर तरीका readystate विशेषता की जाँच करें और उस मामले में मैन्युअल रूप से अपने कार्य निष्पादित करने के लिए है:

var $video = $('video'), 
    videoElement = $video[0]; 

$video.on('canplaythrough', callback); 

// If the video is in the cache of the browser, 
// the 'canplaythrough' event might have been triggered 
// before we registered the event handler. 
if (videoElement.readyState > 3) { 
    callback(); 
} 
+0

सर्वश्रेष्ठ उत्तर! वीडियो तैयार करने की जांच करें, और अगर तैयार हो तो ईवेंट श्रोता जोड़ें ' टी '4' या उच्चतर। – peirix

+0

कमाल का जवाब! यह वही है। धन्यवाद !!!! @ गैब्रियल आपको इसे – 30secondstosam

+0

के उत्तर के रूप में चिह्नित करना चाहिए क्योंकि सिर में नहीं स्क्रिप्ट डालना बुरा है: लिपियों को समग्र रूप से लिखना और दिखाता है मानकों को समझने की कमी: 'defer' विशेषता का उपयोग करें, सिर में स्क्रिप्ट रखें और अभी भी वही प्रदर्शन करें। – John

4

यहां तक ​​कि अगर मेरे सवाल का कोई ध्यान भी नहीं मिला, मुझे लगता है कि यह एक अच्छा विचार है लोग हैं, जो भविष्य में इस पर ठोकर सकता है के लिए एक स्पष्टीकरण देने के लिए ...

समस्या

वास्तव में अजीब है: अगर jQuery कोर को पाद लेख में शामिल किया गया है, कुछ वीडियो ईवेंट काम नहीं करते हैं। यदि jQuery कोर दस्तावेज़ के शीर्ष में शामिल है, तो सभी घटनाओं को सही ढंग से बुलाया जाता है।

तो समाधान एचटीएमएल हेड में jQuery कोर को शामिल करना है, भले ही ऑप्टिमाइज़ेशन के लिए "सर्वोत्तम प्रथाओं" तेजी से लोडिंग समय के लिए शरीर के अंत में सभी स्क्रिप्ट रखने की सिफारिश करें।

+3

मैं अपने वास्तव में एक दौड़ शर्त दांव लगाना होगा setTimout :-(। नहीं सच में सुंदर के साथ "रेडी-राज्य 'का एक चेक के साथ समाप्त हो गया है, लेकिन यह मेरे लिए काम करता है।, और 'कैप्ले' और 'कैप्लेथ्रू' घटनाओं को निकाल दिया जा रहा है _before_ jQuery घटना श्रोताओं को जोड़ता है। संपादित करें: बस ध्यान दें कि क्लेटन गुलिक ने नीचे दिए गए मुद्दे पर चर्चा की। –

10

सबसे अधिक संभावित कारण यह है कि आप इसे देख रहे हैं शायद समय के मुद्दों के साथ करना है। आपने अपने स्वीकृत उत्तर में कहा है कि पाद लेख की बजाय jQuery में सिर डालने से समस्या हल हो जाती है। यह मुझे बताता है कि समस्या डीओएम पार्सिंग और स्क्रिप्ट निष्पादन आदेश है। सबसे संभावित अपराधी यह है कि "कैप्ले" और "कैप्प्लेथ्रू" घटनाओं को jquery से पहले निकाल दिया जा रहा था और आपकी पेज स्क्रिप्ट को पार्स किया गया था और ईवेंट हैंडलर जोड़े गए थे - लेकिन कभी-कभी नेटवर्क यातायात और लोड समय के आधार पर। स्क्रिप्ट को सिर में डालकर, आपने डीओएम तत्वों के निर्माण से पहले अपने ईवेंट को बाध्यकारी करने के लिए मजबूर कर दिया, जिससे यह सुनिश्चित किया जा सके कि आपने किसी भी घटना को याद नहीं किया है।

एक तरफ, पृष्ठ के निचले भाग में स्क्रिप्ट तत्व डालने का प्रदर्शन लाभ बहस योग्य है। यदि आप वास्तव में पेज प्रदर्शन को ट्विक करना चाहते हैं, तो समानांतर स्क्रिप्ट लोडिंग प्रबंधित करने के लिए LABjs जैसे कुछ का उपयोग करें।

3

मुझे यह भी लगता है कि यह दौड़ की स्थिति है। जिस तरह से मैं इसके आसपास आया वह निम्नानुसार है:

वीडियो तत्व के HTML में विशेषता प्रीलोड = "मेटाडाटा" - केवल वीडियो मेटाडेटा को प्रीलोड करने के लिए जोड़ें। तो:

<video id="myVideo" width="640" height="480" preload="metadata" /> 

इसके बाद, जे एस के अंदर:

var $vid = $("#myVideo"); 
$vid.bind("canplaythrough", console.log("can play through full video")); 
$vid.get(0).load(); 

यह क्रोम में मेरे लिए संदेश लॉग इन - कहीं और परीक्षण नहीं किया।

2

आप आप तो load को गति प्रदान करने के बाद यह होगा फ़ायरफ़ॉक्स पूरे ऑडियो लोड करने के लिए आशा करते हैं ऐसा मत करो। यह loadstart को आग लगाएगा लेकिन कुछ भी डाउनलोड नहीं करेगा। नहीं progress घटनाओं को निकाल दिया जाएगा। और यह वास्तव में उस फ़ाइल के लिए कोई अनुरोध नहीं करेगा। आप फायरबग में यह व्यवहार देख सकते हैं।

फ़ायरफ़ॉक्स केवल 'play` को ट्रिगर करने के बाद फ़ाइल लोड करना शुरू कर देगा।

Proof। कंसोल आउटपुट देखें।

+0

वास्तव में, इस व्यवहार की अपेक्षा की जाती है और वीडियो –

+0

@NamanGoel पर प्रीलोड विशेषता के साथ नियंत्रित किया जा सकता है 'प्रीलोड विशेषता निर्दिष्ट करती है कि लेखक क्या सोचता है और कैसे ** ** पृष्ठ लोड होने पर ऑडियो फ़ाइल लोड की जानी चाहिए। 'जहां तक ​​मैं इसे प्राप्त कर सकता हूं' प्रीलोड 'के पास 'audio.load()' से कुछ लेना देना नहीं है।इसके बजाए यह ऑडियो व्यवहार के साथ कोई कार्रवाई नहीं होने पर ब्राउज़र व्यवहार को बदल देता है। अगर मैं गलत हूं तो कृपया मुझे दस्तावेज़ीकरण पर इंगित करें। क्या लोड होने पर ऑडियो लोड करने के लिए संभव है जब लोड लोड होता है और 'लोड() 'ट्रिगर होने पर पूरी तरह से लोड होने के बजाय? – Kolyunya

+0

मैं अभी एक लिंक ठीक नहीं कर सकता। लेकिन जो मुझे पता है, ब्राउजर तब तक ऑडियो लोड नहीं करना चाहिए जब तक कि इसमें 'प्रीलोड' एटीआर न हो। कुछ ब्राउज़रों को लगता है कि वैसे भी ऑडियो/वीडियो preload preload। –

0

जोड़ना:

var video = $('video'); 
video.trigger('load'); 

बाद canplaythrough घटना श्रोता फ़ायरफ़ॉक्स और सफारी पर मेरे लिए यह तय जोड़ने।

2

मेरे मामले में, यह तत्व के लिए निर्दिष्ट preload विशेषता द्वारा निर्धारित किया गया था। मैंने यह बिल्कुल निर्दिष्ट नहीं किया था, इसलिए अलग-अलग ब्राउज़र अलग-अलग चीजों को करने का विकल्प चुन रहे थे।

एक बार मैंने preload="auto" निर्दिष्ट किया, on("canplay") ईवेंट हैंडलर ने ठीक/अपेक्षित काम किया।

0

यहां से (वेनिला में) विभिन्न दृष्टिकोणों की कोशिश करने के 1.5 दिनों के बाद। AddEventListner के साथ "कैप्ले" और "कैनप्लेथ्रू" ईवेंट एज में काम नहीं करते हैं। वे हर दूसरे ब्राउज़र में ठीक काम करते हैं। इसलिए मैं

Controller.prototype.backGroundControl = function() { 
var vid = document.querySelector('#bgvid'); 
var bgImg = document.querySelector('#bgimg'); 
_this = this; 

if (vid.readyState === 4){ 
    bgImg.style.opacity = "0" 
} else{ 
    setTimeout(function(){ 
     _this.backGroundControl(); 
    },500) 
} 

}

संबंधित मुद्दे