IOS AVPlayer को कम करने के लिए देरी कैसे शुरू करें


115

नीचे दिए गए प्रश्न के लिए ध्यान दें: सभी संपत्ति डिवाइस पर स्थानीय हैं - कोई नेटवर्क स्ट्रीमिंग नहीं हो रही है। वीडियो में ऑडियो ट्रैक हैं।

मैं एक iOS एप्लिकेशन पर काम कर रहा हूं जिसमें वीडियो क्लिप को शुरू करने के लिए न्यूनतम देरी के साथ वीडियो फ़ाइलों को चलाने की आवश्यकता होती है। दुर्भाग्य से हम नहीं जानते हैं कि विशिष्ट वीडियो क्लिप तब तक क्या है जब तक हमें वास्तव में इसे शुरू करने की आवश्यकता नहीं है। विशेष रूप से: जब एक वीडियो क्लिप चल रहा होता है, तो हम जानेंगे कि 10 वीडियो क्लिप का अगला सेट (मोटे तौर पर) क्या है, लेकिन हम यह नहीं जानते कि कौन सा वास्तव में है, जब तक कि यह अगली क्लिप को 'तुरंत' खेलने का समय नहीं आता है।

मैंने वास्तविक शुरुआत देरी को देखने के लिए क्या किया है addBoundaryTimeObserverForTimes, वीडियो प्लेयर पर कॉल करने के लिए एक मिलीसेकंड की समयावधि के साथ यह देखना है कि वीडियो वास्तव में कब खेलना शुरू हुआ, और मैं उस समय के अंतर को पहले स्थान के साथ मोहर लेता हूं कोड जो इंगित करता है कि किस परिसंपत्ति को खेलना शुरू करना है।

मैंने इस प्रकार जो देखा है, उससे मैंने पाया है कि AVAssetलोडिंग के संयोजन का उपयोग करना , और फिर AVPlayerItemउस से एक बार तैयार होने के बाद, और फिर AVPlayerStatusReadyToPlayमैं कॉल प्ले करने से पहले प्रतीक्षा करना शुरू करने के लिए 1 और 3 सेकंड के बीच ले जाता हूं। क्लिप।

जब से मुझे लगता है कि मैं लगभग बराबर हो गया हूँ: मैंने फोन किया [AVPlayerItem playerItemWithURL:]और AVPlayerItemStatusReadyToPlayखेलने की प्रतीक्षा कर रहा था। मोटे तौर पर वही प्रदर्शन।

एक बात जो मैं देख रहा हूँ, वह यह है कि पहला AVPlayer आइटम लोड बाकी की तुलना में धीमा है। लगता है कि पहले वीडियो को चलाने की कोशिश करने से पहले एक छोटी / खाली संपत्ति के साथ AVPlayer को प्री-फ्लाइट करना अच्छा व्यवहार हो सकता है। [ AVAudioPlayer के लिए धीमी शुरुआत जब पहली बार ध्वनि बजाई जाती है

मुझे वीडियो को जितना संभव हो सके शुरू करने में अच्छा लगेगा, और प्रयोग करने के लिए चीजों के कुछ विचार होंगे, लेकिन किसी से कुछ मार्गदर्शन चाहते हैं जो मदद करने में सक्षम हो।

अपडेट: विचार 7, नीचे, जैसा कि कार्यान्वित किया गया है, लगभग 500 एमएस के स्विचिंग समय में पैदावार देता है। यह एक सुधार है, लेकिन इसे और भी तेजी से प्राप्त करना अच्छा होगा।

विचार 1: N AVPlayers का उपयोग करें (काम नहीं करेगा)

~ 10 AVPPlayerऑब्जेक्ट्स का उपयोग करना और सभी ~ 10 क्लिप को स्टार्ट-एंड-पॉज़ करना, और एक बार हमें पता चल जाता है कि हमें वास्तव में किस चीज़ की ज़रूरत है, सही स्विच करें और अन-पॉज़ करें AVPlayerऔर अगले चक्र के लिए फिर से शुरू करें।

मुझे नहीं लगता कि यह काम करता है, क्योंकि मैंने पढ़ा है कि AVPlayer'sआईओएस में लगभग 4 सक्रिय की सीमा है । वहाँ कोई StackOverflow पर यहाँ के बारे में पूछ रहा था, और 4 AVPlayer सीमा के बारे में पता चला: फास्ट-स्विचिंग-बीच-वीडियो-उपयोग-एवफ़ाउंडेशन

विचार 2: AVQueuePlayer (काम नहीं करेगा) का उपयोग करें

मुझे विश्वास नहीं है कि 10 AVPlayerItemsमें shoving एक AVQueuePlayerपूर्व लोड होगा उन सभी को सहज शुरुआत के लिए। AVQueuePlayerएक कतार है, और मुझे लगता है कि यह वास्तव में कतार में अगले वीडियो को तत्काल प्लेबैक के लिए तैयार करता है। मुझे नहीं पता कि ~ 10 वीडियो में से कौन सा हम वापस खेलना चाहते हैं, जब तक कि उस एक को शुरू करने का समय नहीं है। ios-avplayer-वीडियो-पहले से लोड होने

विचार 3: लोड करें, खेलें, और AVPlayerItemsपृष्ठभूमि में बनाए रखें (100% अभी तक निश्चित नहीं है - लेकिन अच्छा नहीं लग रहा है)

मैं देख रहा हूं कि क्या पृष्ठभूमि में प्रत्येक वीडियो क्लिप के पहले सेकंड को लोड करने और चलाने के लिए कोई लाभ है (वीडियो और ऑडियो आउटपुट को दबाएं), और प्रत्येक के लिए एक संदर्भ रखें AVPlayerItem, और जब हम जानते हैं कि किस आइटम के लिए खेला जाना चाहिए वास्तविक, उस एक को स्वैप करें और सक्रिय के साथ पृष्ठभूमि AVPlayer को स्वैप करें। धोये और दोहराएं।

सिद्धांत यह होगा कि हाल ही में खेला गया AVPlayer/AVPlayerItemअभी भी कुछ तैयार संसाधनों को पकड़ सकता है जो बाद के प्लेबैक को तेज करेगा। अब तक, मैंने इससे लाभ नहीं देखा है, लेकिन मेरे पास AVPlayerLayerपृष्ठभूमि के लिए सेटअप ठीक से नहीं है । मुझे संदेह है कि यह वास्तव में चीजों को सुधार देगा जो मैंने देखा है।

विचार 4: एक अलग फ़ाइल प्रारूप का उपयोग करें - हो सकता है कि लोड करने में तेज़ हो?

मैं वर्तमान में उपयोग कर रहा हूँ .M4v (वीडियो-एमपीईजी 4) एच .264 प्रारूप। H.264 में बहुत सारे अलग-अलग कोडेक विकल्प हैं, इसलिए यह संभव है कि कुछ विकल्प दूसरों की तुलना में तेजी से पसंद करते हैं। मैंने पाया है कि अधिक उन्नत सेटिंग्स का उपयोग करने से फ़ाइल का आकार छोटा हो जाता है, जो कि समय को बढ़ाता है, लेकिन ऐसा कोई विकल्प नहीं मिला है जो दूसरे रास्ते पर जाता हो।

विचार 5: दोषरहित वीडियो प्रारूप + AVQueuePlayer का संयोजन

यदि एक वीडियो प्रारूप है जो लोड करने के लिए तेज़ है, लेकिन हो सकता है कि फ़ाइल का आकार पागल है, तो एक विचार प्रत्येक वीडियो क्लिप के पहले 10 सेकंड को एक संस्करण के साथ तैयार करने के लिए हो सकता है जो फूला हुआ है लेकिन लोड करने के लिए तेज़ है, लेकिन वापस उस संपत्ति के साथ जो H.264 में एन्कोडेड है। एक AVQueuePlayer का उपयोग करें, और पहले 10 सेकंड को असम्पीडित फ़ाइल प्रारूप में जोड़ें, और उस एक का पालन करें जो कि H.264 में है जो तैयार / प्रीलोड समय के 10 सेकंड तक हो जाता है। इसलिए मुझे दोनों दुनियाओं का 'सर्वश्रेष्ठ' मिलेगा: तेज शुरुआत समय, लेकिन अधिक कॉम्पैक्ट प्रारूप से भी लाभ होगा।

विचार 6: एक गैर-मानक AVPlayer का उपयोग करें / मेरा स्वयं लिखें / किसी और का उपयोग करें

मेरी जरूरतों को देखते हुए, शायद मैं AVPlayer का उपयोग नहीं कर सकता, लेकिन AVAssetReader का सहारा लेना होगा, और पहले कुछ सेकंड (संभवतः डिस्क पर कच्ची फ़ाइल लिखना) को डिकोड करना होगा, और जब यह प्लेबैक की बात आती है, तो इसे खेलने के लिए कच्चे प्रारूप का उपयोग करें। वापस तेजी से। मेरे लिए एक बड़ी परियोजना की तरह लगता है, और अगर मैं इसके बारे में एक भोली तरीके से जाना, यह स्पष्ट नहीं है / यह भी बेहतर काम करने की संभावना नहीं है। प्रत्येक डिकोड और असम्पीडित वीडियो फ्रेम 2.25 एमबी है। Naively बोल - अगर हम वीडियो के लिए ~ 30 एफपीएस के साथ जाते हैं, तो मैं ~ 60 एमबी / एस की रीड-से-डिस्क आवश्यकता के साथ समाप्त करूंगा, जो शायद असंभव है / इसे धक्का दे रहा है। जाहिर है हम छवि संपीड़न के कुछ स्तर (शायद देशी ओपन / PVRTC के माध्यम से सम्पीडन प्रारूप) करना होगा ... लेकिन यह दयालु है। शायद वहाँ एक पुस्तकालय है जो मैं उपयोग कर सकता हूं?

आइडिया 7: सब कुछ एक ही फिल्म की संपत्ति में मिलाएं, और तलाश करें

एक विचार जो ऊपर दिए गए कुछ की तुलना में आसान हो सकता है, वह है सब कुछ एक ही फिल्म में संयोजित करना, और चाहने वालों का उपयोग करना। बात यह है कि हम सभी जगह कूद पड़ेंगे। फिल्म में अनिवार्य रूप से यादृच्छिक अभिगम। मुझे लगता है कि यह वास्तव में ठीक काम कर सकता है: एविलेर-मूवी-प्लेइंग-लैग-इन-आईओएस 5

आपको कौन सा दृष्टिकोण सबसे अच्छा लगेगा? अब तक, मैंने लैग को कम करने के मामले में उतनी प्रगति नहीं की है।


इसके लायक क्या है, मैं आइडिया 7 के साथ जा रहा हूं। यह अभी भी धीमा है, लेकिन अन्य विकल्पों की तरह अप्रत्याशित रूप से धीमा नहीं है। अगला प्रश्न मेरे पास है - क्या कोडेक विकल्प, रिज़ॉल्यूशन, और की-फ्रेम फ़्रीक्वेंसी का साधक के समय पर प्रभाव पड़ता है?
बर्नट हर्मिएर

खेल के लिए देर हो चुकी है, लेकिन यह जितनी जल्दी हो सके वीडियो स्विच करने के लायक हो सकता है (यानी नए के तुरंत बाद खेलना शुरू हो जाता है) और एप्लिकेशन को यह देखने के लिए प्रोफाइल करना कि वह अपना अधिकांश सीपीयू समय कहां खर्च करता है।
टीसी

1
लगभग एक साल बाद अब आपको इस बारे में क्या पता चला?
lnafziger

1
मैं विकल्प 7 के साथ गया, और 300ms और 500ms के बीच किसी जगह पर पहुंच गया। एक बात मुझे पता है कि mp4 कोडेक विकल्प के इच्छुक हैं धीमी गति चाहने वाले। कुछ वीडियो संपीड़न विकल्प हैं जो बेहतर संपीड़न की अनुमति देते हैं और वीडियो की गुणवत्ता बनाए रखते हैं, लेकिन डिकोडिंग समय को मारते हैं।
बर्नट हेबरमियर

2
यह एक उचित लगने वाला अनुरोध है, लेकिन वास्तव में विकल्प 7 को लागू करने के लिए, पोस्ट करने के लिए कार्यान्वयन में बहुत अधिक पहलू हैं। विचार करें: (ए) वीडियो परिसंपत्तियों को मर्ज करने के लिए एक उपकरण श्रृंखला बनाएं, (बी) सुनिश्चित करें कि आप वीडियो सेगमेंट ऑफ़सेट का ट्रैक रखते हैं, (सी) किसी विशेष क्लिप को खेलने के लिए अनुरोध आने पर ऑफ़सेट देखते हैं, (डी) ऐडपेरियोडाइरेक्टेनऑब्स्वरवरफ़ॉरइंटरवाल्टर का उपयोग करने के लिए जाँच करें यदि आप एक वीडियो क्लिप से भागते हैं और तदनुसार प्रतिक्रिया करते हैं (इस पद्धति का उपयोग करें बनाम एकल-शॉट ऐड-बाउंडरी टाइमऑर्ब्जवरफ़ोरटाइम्स क्योंकि मैंने पाया है कि उत्तरार्द्ध कभी-कभी ट्रिगर नहीं होता है ... कुल मिलाकर, यह खुद को चिपकाने वाले कोड के लिए उधार नहीं देता है।
बर्नट हेबरमियर

जवाबों:


4

IOS 10.x के लिए और AVPlayer को कम करने के लिए अधिक से अधिक मैं सेट शुरू करने में देरी करता हूं: avplayer.automaticallyWaitsToMinimizeStalling = false; और यह मेरे लिए इसे ठीक करने के लिए लग रहा था। इसके अन्य परिणाम हो सकते हैं, लेकिन मैंने अभी तक उन पर प्रहार नहीं किया है।

मुझे इसके लिए विचार मिला: https://stackoverflow.com/a/50598525/9620547


मुझे देरी में 6-7 सेकंड की कमी मिली। लेकिन मेरा यहां एक सवाल है, क्या यह ऐप के प्रदर्शन पर असर डालेगा?
कल्प

@ हमलोगों ने इस कोड का उपयोग एक उत्पादन ऐप में एक वर्ष से अधिक समय तक बिना किसी नकारात्मक प्रभाव के किया है। हम ज्यादातर अमेरिका में श्रोताओं के लिए 20-60 मिनट की ऑडियो फाइलें खेलते हैं, जहां मोबाइल डेटा कवरेज आमतौर पर तेज है। आपका उपयोग मामला हालांकि अलग हो सकता है।
grizzb

जानकारी के लिए धन्यवाद। @ ग्रिज़ब
कल्प

1

आपके द्वारा बनाए जाने के बाद परिसंपत्ति तैयार नहीं हो सकती है, यह फिल्म की अवधि की तरह गणना कर सकती है, फ़ाइल में मूवी के सभी मेटाडेटा को शामिल करना सुनिश्चित करें।


1

आपको पहले # 7 विकल्प का प्रयास करना चाहिए, बस यह देखने के लिए कि क्या आपको वह काम मिल सकता है। मुझे संदेह है कि यह वास्तव में आपकी आवश्यकताओं के लिए काम नहीं करेगा क्योंकि क्लिप के बीच आपको सहज स्विच देने के लिए तलाश का समय काफी तेजी से संभव नहीं होगा। यदि आप ऐसा करने की कोशिश करते हैं और यह विफल रहता है, तो मैं आपको सलाह दूंगा कि आप विकल्प 4/6 करें और इस उद्देश्य के लिए विशेष रूप से डिज़ाइन किए गए मेरे iOS पुस्तकालय पर एक नज़र डालें, बस और अधिक जानकारी प्राप्त करने के लिए AVAnimator पर एक त्वरित Google खोज करें। मेरी लाइब्रेरी सहज लूप को लागू करना और एक क्लिप से दूसरे में स्विच करना संभव बनाती है, यह बहुत तेज़ है क्योंकि वीडियो को हाथ से पहले फ़ाइल में डिकोड किया जाना है। आपके मामले में, शुरू होने से पहले सभी 10 वीडियो क्लिप फ़ाइलों में डिकोड हो जाएंगे, लेकिन फिर उनके बीच स्विच करना तेज़ होगा।


वीडियो के ऑडियो हिस्से के बारे में क्या? मुझे वीडियो और ऑडियो को सिंक्रनाइज़ करने की आवश्यकता है।
बर्नट हेबरमियर

हां, ऑडियो पहले से ही ऑडियो ट्रैक और वीडियो क्लिप के बीच बहुत तंग सिंक के साथ हैंडल किया जाता है। उदाहरण देखें xcode प्रोजेक्ट्स। यह पहले से ही लागू है, आपको बस इसे डाउनलोड करने और आज़माने की आवश्यकता है।
MoDJ

क्या AVAimimator का उपयोग करके नेटवर्क वीडियो चलाने की संभावना है?
रिचर्ड टोपची

नहीं, यह स्थानीय फाइलों पर काम करता है, नेटवर्क वीडियो स्ट्रीमिंग एक पूरी तरह से अलग चीज है।
MoDJ

0

आपके विचारों और अनुभवों के आधार पर अतीत में इस तरह का कुछ भी किए बिना, मैं 7 और 1 के संयोजन की कोशिश करूँगा: 10 वीडियो का अनुसरण करने वाले 10 सेकंड के पहले जोड़े के साथ एक एवीप्लेयर को प्रीलोड करें। फिर स्किपिंग बहुत कम डेटा के कारण तेजी से और अधिक विश्वसनीय होगी। जब आप चुने हुए टुकड़े को खेल रहे होते हैं, तो आपके पास पृष्ठभूमि में बाकी चयनित अनुवर्ती वीडियो के लिए AVPlayer तैयार करने के लिए पर्याप्त समय होता है। जब शुरुआत पूरी हो जाती है, तो आप तैयार किए गए AVPlayer पर जाते हैं। तो कुल मिलाकर, आप किसी भी समय अधिकतम 2 AVPlayers लोड करते हैं।

बेशक मुझे नहीं पता कि स्विचिंग को इतनी आसानी से किया जा सकता है कि यह प्लेबैक को डिस्टर्ब न करे।

(यदि मैं कर सकता हूं तो एक टिप्पणी के रूप में इसे जोड़ा जाएगा।)

सर्वश्रेष्ठ, पीटर


मुझे एक AVPlayer पर श्रृंखला में 10 संपत्ति लोड करने का कोई लाभ नहीं मिला है। इसके अलावा, मैं आपके सुझाव को नहीं समझता, क्योंकि मुझे विकल्प (1) और (7) परस्पर अनन्य लगते हैं। विकल्प 7 सभी वीडियो परिसंपत्तियों को एक संपत्ति में विलय करता है - इस प्रकार अवधि को लोड करने के लिए केवल एक ही संपत्ति होती है। यह वही है जो मैं आज कर रहा हूं, और इसके लायक मैं वास्तविक शुरुआत / खेलने के समय पर लगभग 500 एमएस देरी से प्राप्त कर रहा हूं। यह ध्यान देने योग्य है कि वास्तविक पहला फ्रेम की तुलना में सीकैटो तेजी से पूरा होता है, इसलिए सही शुरुआत के समय के लिए, मैं मापता हूं कि पहला फ्रेम वास्तव में समयबद्ध कॉलबैक के माध्यम से वापस खेल रहा है या नहीं।
बजे बर्नट हेबरमीयर

बस अपने विचार को स्पष्ट करने के लिए: मेरा विचार एक परिसंपत्ति को दो भागों में विभाजित करना था: पहले कुछ सेकंड और बाकी। अब आपने एक से दो संपत्ति बना ली हैं। आप जिन 10 शुरुआतओं में शामिल होंगे, वे स्किप का उपयोग करेंगे और शुरुआत के दौरान आप बाकी को लोड करेंगे। इसके बाद सुझाव 8 शामिल होता है जो आपकी सूची में जुड़ जाता है।
ilmiacs

लेकिन जैसा कि मैंने आपकी पिछली टिप्पणी से समझा है, इस बीच आपने शोध को आगे बढ़ाया है जो अच्छा है, और समाधान 7 भी काम नहीं करता है। ऐसा लगता है जैसे ए वी मौलिक रूप से आपके रास्ते में रहता है और आपके लिए एकमात्र तरीका शायद यह है कि आपकी परिसंपत्तियों पर अधिक नियंत्रण पाने के लिए, जो कि कोर मीडिया के नीचे की तकनीक का उपयोग करता है। पीटर।
ilmiacs

ओह, मैं आपके विचार को अब बेहतर समझता हूं। धन्यवाद। यह जांच करना दिलचस्प होगा कि क्या आपको लघु वीडियो क्लिप के लिए तेजी से तलाश-बार मिलता है। मैंने अभी तक ऐसा प्रयास नहीं किया है, लेकिन यह एक विचार के लायक होगा। कोर मीडिया के उपयोग के बारे में - मुझे उस एपीआई पर कोई अच्छी संदर्भ सामग्री नहीं मिली है। क्या आपके पास एक अच्छा संसाधन है जो आप मुझे बता सकते हैं?
बर्नट हेबरमीयर

नहीं माफ़ करो। जैसा कि मैंने कहा, मैं एवी या कोर मीडिया का विशेषज्ञ नहीं हूं। बस अपने प्रश्न पढ़ें और कुछ विचार थे कि मैं व्यक्तिगत रूप से कैसे आगे बढ़ूंगा और उन्हें साझा करना चाहता हूं। पीटर
ilmiacs

0

अगर मैंने आपके मुद्दे को सही ढंग से समझा, तो ऐसा लगता है कि आपके पास एक निरंतर वीडियो है, जिसके लिए आपको एक पल के नोटिस पर ऑडियो ट्रैक लोड करने की आवश्यकता है।

अगर ऐसा है तो मैं BASS में देखना चाहता हूं । BASS AVPlayer की तरह एक ऑडियो लाइब्रेरी है जो आपको (अपेक्षाकृत) iOS में AudioUnits ढांचे के निम्न-स्तरीय एपीआई के लिए (अपेक्षाकृत) आसान पहुँच प्रदान करता है। आपके लिए क्या मतलब है? इसका मतलब है कि एक छोटे से बफर हेरफेर के साथ (आपको इसकी आवश्यकता भी नहीं हो सकती है, यह इस बात पर निर्भर करता है कि आप कितना छोटा चाहते हैं) आप तुरंत संगीत बजाना शुरू कर सकते हैं।

सीमाएँ वीडियो तक फैली हुई हैं, जैसा कि मैंने कहा, यह एक ऑडियो लाइब्रेरी है इसलिए किसी भी वीडियो हेरफेर को अभी भी AVPlayer के साथ करना होगा। हालाँकि, -seekToTime:toleranfeBefore:toleranceAfter:जब तक आप सभी आवश्यक विकल्पों के साथ प्रीरोल नहीं करते, तब तक आपको वीडियो के भीतर तेज़ी से प्राप्त करने में सक्षम होना चाहिए।

यदि आप कई उपकरणों में समन्वयित कर रहे हैं (जो आपका आवेदन सुझाव दे सकता है) बस एक टिप्पणी छोड़ दो और मुझे अपना उत्तर संपादित करने में खुशी होगी।

पुनश्च: B यह सी-जैसे प्रारूप के कारण पहली बार में कठिन लग सकता है, लेकिन वास्तव में इसका उपयोग करने के लिए वास्तव में आसान है।


-2

एवीएसेटसेट वर्ग द्वारा प्रदान की जाने वाली कई संपत्तियां और विधियां हैं जो मदद कर सकती हैं:

- (void)_pu_setCachedDuration:(id)arg1;
- (id)pu_cachedDuration; 
- (struct
 { 
   long long x1; 
   int x2;
   unsigned int x3; 
   long long x4; 
})pu_duration;
- (void)pu_loadDurationWithCompletionHandler:(id /* block */)arg1;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.