2012-06-11 15 views
5

मेरे पास एक छिपी हुई <audio> ऑब्जेक्ट वाला पृष्ठ है जिसे जावास्क्रिप्ट के माध्यम से एक कस्टम बटन का उपयोग करके शुरू किया जा रहा है और बंद कर दिया गया है। (कारण मैं बटन को कस्टमाइज़ करना चाहता हूं, और एक ऑडियो प्लेयर ड्राइंग करना किसी भी तरह से आईपैड पर प्रतिपादन प्रदर्शन को नष्ट करना प्रतीत होता है)। एक सरल उदाहरण (coffeescript में):एचटीएमएल 5 ऑडियो ऑब्जेक्ट आईपैड पर नहीं चलाया जाता है (जब सेटटाइम से कहा जाता है)

// Works fine on all browsers 

constructor: (@_button, @_audio) -> 
    @_button.on 'click', @_play   // Bind button's click event with jQuery 

_play: (e) => 
    @_audio[0].play()     // Call play() on audio element 

ऑडियो ठीक खेलता है जब एक समारोह एक click घटना के लिए बाध्य से शुरू हो रहा है, लेकिन मैं वास्तव में फ़ाइल से पहले तो निभाता है मैं एक setTimeout अंदर .play() डाल एक एनीमेशन पूरा करना चाहते हैं। हालांकि मैं सिर्फ यह काम करने के लिए नहीं मिल सकता है:

// Will not play on iPad 

constructor: (@_button, @_audio) -> 
    @_button.on 'click', @_play   // Bind button's click event with jQuery 

_play: (e) => 
    setTimeout (=>      // Declare a 300ms timeout 
    @_audio[0].play()     // Call play() on audio element 
), 300 

मैं देख लिया है कि @_audio (this._audio) दायरे में और उसके play() विधि मौजूद है कि है। यह आईपैड पर क्यों काम नहीं करता है?

संपादित: ऐसा होता है, वास्तव में ऊपर सरलीकृत परीक्षण का मामला काम करता है। नीचे @apsillers का उत्तर और इस पर मेरी टिप्पणियां देखें।

+0

बस जोड़ने के लिए मैंने सिम्युलेटर _and_ पर एक वास्तविक आईपैड पर इसका परीक्षण किया है। –

+0

मुझे लगता है कि आप एक स्पष्ट उपयोगकर्ता कार्रवाई के बिना आईपैड/आईफोन में एक वीडियो/ऑडियो नहीं चला सकते हैं ... बैंडविड्थ खपत – fcalderan

+0

के लिए, मैंने प्ले विधि के आसपास 'कोशिश/पकड़' रखा है और वहां नहीं है प्रतीत होता है कि कोई त्रुटि फेंक दिया गया है। –

उत्तर

10

एक घटना के लिए सफारी चेकों लगता Apple's iOS considerations guide देखें:

... जावास्क्रिप्ट play() और load() उपयोगकर्ता तब भी निष्क्रिय होते हैं जब तक उपयोगकर्ता प्लेबैक शुरू नहीं करता है, जब तक play() या load() विधि उपयोगकर्ता क्रिया द्वारा ट्रिगर नहीं की जाती है। दूसरे शब्दों में, उपयोगकर्ता द्वारा शुरू किया गया प्ले बटन काम करता है, लेकिन onLoad="play()" ईवेंट नहीं करता है।

ऐसा लगता है कि आपके setTimeout() कॉलबैक तथ्य यह है कि setTimeout() अपने आप में एक उपयोगकर्ता द्वारा शुरू किए समारोह में किया गया था के बावजूद, उपयोगकर्ता आरंभ की गई कार्रवाई के रूप में योग्य नहीं है।

सुझाव: मेरे पास परीक्षण करने के लिए कोई आईओएस डिवाइस नहीं है, लेकिन जब उपयोगकर्ता बटन दबाता है तो प्रारंभिक प्ले/रोक सकता है, इस प्रतिबंध को राहत देगा। यही है, आप play() पर कॉल करें और फिर इसे एक बार में रोकें, फिरplay() कॉल के साथ setTimeout() फ़ंक्शन को एनिमेट करने के लिए कॉल करें और कॉल करें। यह उपयोगकर्ता द्वारा शुरू किए गए फ़ंक्शन को आईओएस को यह बताता है कि भविष्य में इस वीडियो को लोड और चलाने के लिए ठीक है।

+0

आप काफी सही @apsillers हैं, जो मैं कर रहा था वह 'उपयोगकर्ता द्वारा शुरू की गई कार्रवाई' के रूप में योग्य नहीं था। हालांकि एक समाधान है - मैंने कुछ और खुदाई की और यह इंगित करना महत्वपूर्ण है कि जब मैंने अपने प्रश्न में सरलीकृत परीक्षण केस लिखा था तो मैं गलत था - यह वास्तव में काम करता है _does_। क्यों मेरा जवाब नीचे के लिए देखें। –

+0

मेरे मूल प्रश्न का समाधान मेरे जटिल कई-टाइमआउट-गहरे एनीमेशन अनुक्रम का उपयोग करना जारी रखना था, लेकिन उपयुक्त लंबी अवधि के साथ '.play()' विधि के लिए एक-टाइमआउट-गहरी फ़ंक्शन चलाएं। यह तब 'समानांतर' चलाता है। स्पष्ट रूप से यह मूर्खतापूर्ण नहीं है, क्योंकि एनीमेशन अनुक्रम में टाइमर स्पॉट पर नहीं हो सकते हैं और 'play()' को जल्दी कहा जा सकता है। लेकिन ऐसा लगता है कि मेरे मामले में ठीक काम करता है। –

1

कुछ डिवाइस जो आप ऑडियो सिस्टम चलाने के लिए कॉल को स्वचालित नहीं कर सकते हैं, आपने बटन का उपयोग करने की कोशिश की है और यह देखने के लिए क्लिक करें कि अगर यह काम करता है तो यह कैसे काम करता है यह ऑडियो प्लेयर को चलाने के लिए खोलता है अगर आपको स्वचालित करने की अनुमति नहीं है मीडिया इस वीडियो टैग जैसा ही है खेलने अगर मैं सही ढंग से याद

मैं ऑडियो इसलिए आग क्यों क्लिक काम करता है

1

@apsillers उनके जवाब में सुझाव देते हैं कि मैं आईपैड की 'उपयोगकर्ता द्वारा शुरू की गई कार्रवाई' आवश्यकता को पूरा करने के लिए अपना कोड पुनर्व्यवस्थित कर सकता हूं। मैंने कुछ खुदाई की है और यह सच साबित हुआ है। (- मैं मूल रूप से play() कई setTimeout गहरा था इसलिए, सरल उदाहरण मैं मूल प्रश्न में दे दी है काम करता है)

आवश्यकता है कि play() कॉल केवल भीतर एकsetTimeout हो सकता है लगता है।

तो यह होगा काम:

constructor: (@_button, @_audio) -> 
    @_button.on 'click', @_play 

_play: (e) => 
    setTimeout (=> 
    @_audio[0].play()     // play() is only inside one setTimeout 
), 300 

और यह भी काम करेगा:

constructor: (@_button, @_audio) -> 
    @_button.on 'click', => 
    setTimeout ((e) => 
     @_play(e) 
    ), 300 

_play: (e) => 
    @_audio[0].play()     // Still only inside one setTimeout 

लेकिन यह काम नहीं करेगा:

constructor: (@_button, @_audio) -> 
    @_button.on 'click', @_play 

_play: (e) => 
    setTimeout (=> 
    // Something useful 
    setTimeout (=> 
     @_audio[0].play()    // play() is inside two setTimeouts 
    ), 300 
), 300 

न ही यह (अपने मूल होगा सेटअप):

constructor: (@_button, @_audio) -> 
    @_button.on 'click', @_play 

_play: (e) => 

    @_button 
    .animate { prop: value }, 300, => 

     setTimeout (=> 
     @_audio[0].play()    // play() still 'too deep' 
    ), 300 

पिछले उदाहरण में, ऐसा लगता है कि jQuery के animate कॉलबैक एक और setTimeout पुस्तकालय को आंतरिक से कहा जाता है तो play() फिर से 'बहुत गहरा' है।

+0

ध्यान दें कि यह केवल 300ms या उससे कम होने पर ही काम करता है। – gkiely

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