- "Cleartext HTTP traffic not permitted" ত্রুটিগুলির সমাধান
- "SSLHandshakeException", "CertPathValidatorException" এবং "ERR_CERT_AUTHORITY_INVALID" ত্রুটিগুলির সমাধান
- কেন কিছু মিডিয়া ফাইল খোঁজা যায় না?
- কিছু MP3 ফাইলে অনুসন্ধান (seeking) কেন নির্ভুল হয় না?
- আমার ভিডিওতে খোঁজাখুঁজি ধীর কেন?
- কেন কিছু MPEG-TS ফাইল প্লে হয় না?
- কিছু MPEG-TS ফাইলে সাবটাইটেল পাওয়া যায় না কেন?
- কেন কিছু MP4/FMP4 ফাইল ঠিকমতো চলে না?
- কেন কিছু স্ট্রিম HTTP রেসপন্স কোড 301 বা 302 এর কারণে ব্যর্থ হয়?
- কেন কিছু স্ট্রিম UnrecognizedInputFormatException-এর কারণে ব্যর্থ হয়?
- কিছু ডিভাইসে setPlaybackParameters কেন সঠিকভাবে কাজ করে না?
- "Player is accessed on wrong thread" ত্রুটিগুলোর অর্থ কী?
- আমি "Unexpected status line: ICY 200 OK" সমস্যাটি কীভাবে সমাধান করতে পারি?
- যে স্ট্রিমটি প্লে করা হচ্ছে সেটি একটি লাইভ স্ট্রিম কিনা, তা আমি কীভাবে জানতে পারব?
- আমার অ্যাপ ব্যাকগ্রাউন্ডে গেলেও কীভাবে অডিও চালু রাখব?
- কেন ExoPlayer আমার কন্টেন্ট সাপোর্ট করে কিন্তু ExoPlayer Cast লাইব্রেরি করে না?
- কেন কন্টেন্টটি প্লে হয় না, কিন্তু কোনো ত্রুটি দেখানো হয় না?
- আমি কীভাবে একটি ডিকোডিং লাইব্রেরি লোড করে প্লেব্যাকের জন্য ব্যবহার করতে পারি?
- আমি কি সরাসরি ExoPlayer দিয়ে ইউটিউব ভিডিও চালাতে পারি?
- ভিডিও প্লেব্যাক আটকে আটকে যাচ্ছে
- অস্থিতিশীল এপিআই লিন্ট ত্রুটি
"Cleartext HTTP traffic not permitted" ত্রুটিগুলির সমাধান
আপনার অ্যাপের নেটওয়ার্ক নিরাপত্তা কনফিগারেশন অনুমতি না দেওয়া সত্ত্বেও যদি এটি ক্লিয়ারটেক্সট HTTP ট্র্যাফিকের (অর্থাৎ, https http:// এর পরিবর্তে https:// ) জন্য অনুরোধ করে, তাহলে এই ত্রুটিটি ঘটবে। আপনার অ্যাপটি যদি অ্যান্ড্রয়েড ৯ (এপিআই লেভেল ২৮) বা তার উচ্চতর সংস্করণকে টার্গেট করে, তাহলে ডিফল্ট কনফিগারেশন দ্বারা ক্লিয়ারটেক্সট HTTP ট্র্যাফিক নিষ্ক্রিয় থাকে।
আপনার অ্যাপকে যদি ক্লিয়ারটেক্সট HTTP ট্র্যাফিক নিয়ে কাজ করতে হয়, তাহলে আপনাকে এমন একটি নেটওয়ার্ক সিকিউরিটি কনফিগারেশন ব্যবহার করতে হবে যা এর অনুমতি দেয়। বিস্তারিত জানতে অ্যান্ড্রয়েডের নেটওয়ার্ক সিকিউরিটি ডকুমেন্টেশন দেখুন। সমস্ত ক্লিয়ারটেক্সট HTTP ট্র্যাফিক চালু করতে, আপনি আপনার অ্যাপের AndroidManifest.xml ফাইলের application এলিমেন্টে android:usesCleartextTraffic="true" যোগ করতে পারেন।
ExoPlayer ডেমো অ্যাপটি ডিফল্ট নেটওয়ার্ক সিকিউরিটি কনফিগারেশন ব্যবহার করে, এবং তাই এটি ক্লিয়ারটেক্সট HTTP ট্র্যাফিকের অনুমতি দেয় না। আপনি উপরের নির্দেশাবলী ব্যবহার করে এটি সক্রিয় করতে পারেন।
"SSLHandshakeException", "CertPathValidatorException" এবং "ERR_CERT_AUTHORITY_INVALID" ত্রুটিগুলির সমাধান
SSLHandshakeException , CertPathValidatorException এবং ERR_CERT_AUTHORITY_INVALID সবগুলোই সার্ভারের SSL সার্টিফিকেটে কোনো সমস্যা নির্দেশ করে। এই ত্রুটিগুলো শুধু ExoPlayer-এর জন্য নির্দিষ্ট নয়। আরও বিস্তারিত জানতে Android-এর SSL ডকুমেন্টেশন দেখুন।
কেন কিছু মিডিয়া ফাইল খোঁজা যায় না?
ডিফল্টরূপে, ExoPlayer এমন মিডিয়াতে সিকিং সমর্থন করে না, যেখানে সঠিক সিক অপারেশন করার একমাত্র উপায় হলো প্লেয়ারের পুরো ফাইলটি স্ক্যান ও ইন্ডেক্স করা। ExoPlayer এই ধরনের ফাইলকে 'আনসিকেবল' (অসিকযোগ্য) হিসেবে বিবেচনা করে। বেশিরভাগ আধুনিক মিডিয়া কন্টেইনার ফরম্যাটে সিকিং-এর জন্য মেটাডেটা (যেমন স্যাম্পল ইন্ডেক্স) অন্তর্ভুক্ত থাকে, একটি সুনির্দিষ্ট সিক অ্যালগরিদম থাকে (উদাহরণস্বরূপ, Ogg-এর জন্য ইন্টারপোলেটেড বাইসেকশন সার্চ), অথবা তাদের কন্টেন্ট যে কনস্ট্যান্ট বিটরেটের, তা নির্দেশ করে। এইসব ক্ষেত্রে দক্ষ সিক অপারেশন সম্ভব এবং ExoPlayer তা সমর্থন করে।
আপনার যদি সিকিং-এর প্রয়োজন হয় কিন্তু আপনার মিডিয়াটি সিকিং-এর অযোগ্য হয়, তাহলে আমরা আপনার কন্টেন্টকে আরও উপযুক্ত কন্টেইনার ফরম্যাটে রূপান্তর করার পরামর্শ দিই। MP3, ADTS এবং AMR ফাইলগুলির জন্য, আপনি সিকিং সক্ষম করতে পারেন এই শর্তে যে ফাইলগুলির একটি স্থির বিটরেট রয়েছে, যেমনটি এখানে বর্ণনা করা হয়েছে।
কিছু MP3 ফাইলে অনুসন্ধান (seeking) কেন নির্ভুল হয় না?
যেসব ক্ষেত্রে সুনির্দিষ্ট সিকিং প্রয়োজন হয়, সেসব ক্ষেত্রে ভ্যারিয়েবল বিটরেট (VBR) MP3 ফাইল মৌলিকভাবে অনুপযুক্ত। এর দুটি কারণ রয়েছে:
- সঠিক সিকিং-এর জন্য, একটি কন্টেইনার ফরম্যাটের হেডারে একটি সুনির্দিষ্ট টাইম-টু-বাইট ম্যাপিং থাকা আদর্শ। এই ম্যাপিং একটি প্লেয়ারকে অনুরোধ করা সিক টাইমকে সংশ্লিষ্ট বাইট অফসেটের সাথে মেলাতে এবং সেই অফসেট থেকে মিডিয়া অনুরোধ, পার্সিং ও প্লে করা শুরু করতে সাহায্য করে। দুর্ভাগ্যবশত, MP3-তে এই ম্যাপিং নির্দিষ্ট করার জন্য উপলব্ধ হেডারগুলো (যেমন XING হেডার) প্রায়শই নির্ভুল হয় না।
- যেসব কন্টেইনার ফরম্যাট সুনির্দিষ্ট টাইম-টু-বাইট ম্যাপিং (বা কোনো টাইম-টু-বাইট ম্যাপিং) প্রদান করে না, সেগুলোর ক্ষেত্রেও একটি সঠিক সিক (seek) করা সম্ভব, যদি কন্টেইনারটি স্ট্রিমে অ্যাবসোলিউট স্যাম্পল টাইমস্ট্যাম্প অন্তর্ভুক্ত করে। এই ক্ষেত্রে, একটি প্লেয়ার সিক টাইমকে সংশ্লিষ্ট বাইট অফসেটের একটি সম্ভাব্য অনুমানের সাথে ম্যাপ করতে পারে, সেই অফসেট থেকে মিডিয়া অনুরোধ করা শুরু করতে পারে, প্রথম অ্যাবসোলিউট স্যাম্পল টাইমস্ট্যাম্পটি পার্স করতে পারে এবং সঠিক স্যাম্পলটি খুঁজে না পাওয়া পর্যন্ত মিডিয়ার মধ্যে কার্যকরভাবে একটি গাইডেড বাইনারি সার্চ চালাতে পারে। দুর্ভাগ্যবশত, MP3 স্ট্রিমে অ্যাবসোলিউট স্যাম্পল টাইমস্ট্যাম্প অন্তর্ভুক্ত করে না, তাই এই পদ্ধতিটি সম্ভব নয়।
এইসব কারণে, একটি VBR MP3 ফাইলে নির্ভুলভাবে অনুসন্ধান (seek) করার একমাত্র উপায় হলো পুরো ফাইলটি স্ক্যান করা এবং প্লেয়ারে ম্যানুয়ালি একটি টাইম-টু-বাইট ম্যাপিং তৈরি করা। এই কৌশলটি FLAG_ENABLE_INDEX_SEEKING ব্যবহার করে সক্রিয় করা যেতে পারে, যা একটি DefaultExtractorsFactory তে setMp3ExtractorFlags ব্যবহার করে সেট করা যায়। মনে রাখবেন যে এটি বড় MP3 ফাইলের ক্ষেত্রে ভালোভাবে কাজ করে না, বিশেষ করে যদি ব্যবহারকারী প্লেব্যাক শুরু করার কিছুক্ষণ পরেই স্ট্রিমের প্রায় শেষের দিকে অনুসন্ধান করার চেষ্টা করেন, কারণ সেক্ষেত্রে অনুসন্ধান করার আগে প্লেয়ারকে পুরো স্ট্রিমটি ডাউনলোড এবং ইনডেক্স করা পর্যন্ত অপেক্ষা করতে হয়। ExoPlayer-এ, আমরা এই ক্ষেত্রে নির্ভুলতার চেয়ে গতিকে প্রাধান্য দেওয়ার সিদ্ধান্ত নিয়েছি এবং তাই FLAG_ENABLE_INDEX_SEEKING ডিফল্টরূপে নিষ্ক্রিয় থাকে।
আপনি যে মিডিয়াটি চালাচ্ছেন তা যদি আপনার নিয়ন্ত্রণে থাকে, তবে আমরা আপনাকে MP4-এর মতো আরও উপযুক্ত একটি কন্টেইনার ফরম্যাট ব্যবহার করার জন্য দৃঢ়ভাবে পরামর্শ দিই। আমাদের জানা মতে এমন কোনো ব্যবহারের ক্ষেত্র নেই যেখানে MP3 মিডিয়া ফরম্যাট হিসেবে সেরা পছন্দ।
আমার ভিডিওতে খোঁজাখুঁজি ধীর কেন?
যখন প্লেয়ার কোনো ভিডিওতে নতুন প্লেব্যাক অবস্থানে যেতে চায়, তখন তাকে দুটি কাজ করতে হয়:
- নতুন প্লেব্যাক পজিশনের সাথে সঙ্গতিপূর্ণ ডেটা বাফারে লোড করুন (যদি এই ডেটা ইতিমধ্যেই বাফার করা থাকে তবে এটি করার প্রয়োজন নাও হতে পারে)।
- বেশিরভাগ ভিডিও কম্প্রেশন ফরম্যাটে ব্যবহৃত ইন্ট্রা-ফ্রেম কোডিং- এর কারণে, ভিডিও ডিকোডারটি ফ্লাশ করুন এবং নতুন প্লেব্যাক পজিশনের আগের আই-ফ্রেম (কীফ্রেম) থেকে ডিকোডিং শুরু করুন। সিক-এর নির্ভুলতা নিশ্চিত করার জন্য (অর্থাৎ, প্লেব্যাক যেন ঠিক সিক পজিশন থেকেই শুরু হয়), পূর্ববর্তী আই-ফ্রেম এবং সিক পজিশনের মধ্যবর্তী সমস্ত ফ্রেম ডিকোড করে অবিলম্বে বাতিল করে দিতে হবে (স্ক্রিনে না দেখিয়ে)।
(1) দ্বারা সৃষ্ট লেটেন্সি প্লেয়ার দ্বারা মেমরিতে বাফার করা ডেটার পরিমাণ বাড়িয়ে, অথবা ডেটা ডিস্কে প্রি-ক্যাশ করে প্রশমিত করা যেতে পারে।
(2) দ্বারা সৃষ্ট লেটেন্সি ExoPlayer.setSeekParameters ব্যবহার করে সিক-এর নির্ভুলতা হ্রাস করে, অথবা আরও ঘন ঘন I-ফ্রেম অন্তর্ভুক্ত করার জন্য ভিডিওটি পুনরায় এনকোড করে প্রশমিত করা যেতে পারে (যার ফলে একটি বৃহত্তর আউটপুট ফাইল তৈরি হবে)।
কেন কিছু MPEG-TS ফাইল প্লে হয় না?
কিছু MPEG-TS ফাইলে অ্যাক্সেস ইউনিট ডিলিমিটার (AUD) থাকে না। ডিফল্টরূপে, ExoPlayer সস্তায় ফ্রেমের সীমানা শনাক্ত করতে AUD-এর উপর নির্ভর করে। একইভাবে, কিছু MPEG-TS ফাইলে IDR কীফ্রেম থাকে না। ডিফল্টরূপে, ExoPlayer শুধুমাত্র এই ধরনের কীফ্রেমগুলোই বিবেচনা করে।
যখন কোনো MPEG-TS ফাইল প্লে করতে বলা হয় যেটিতে AUD বা IDR কীফ্রেম নেই, তখন ExoPlayer বাফারিং অবস্থায় আটকে আছে বলে মনে হবে। যদি আপনার এই ধরনের ফাইল প্লে করার প্রয়োজন হয়, তবে আপনি যথাক্রমে FLAG_DETECT_ACCESS_UNITS এবং FLAG_ALLOW_NON_IDR_KEYFRAMES ব্যবহার করে তা করতে পারেন। এই ফ্ল্যাগগুলি একটি DefaultExtractorsFactory তে setTsExtractorFlags ব্যবহার করে অথবা একটি DefaultHlsExtractorFactory তে কনস্ট্রাক্টর ব্যবহার করে সেট করা যেতে পারে। AUD ভিত্তিক ফ্রেম বাউন্ডারি ডিটেকশনের তুলনায় গণনাগতভাবে ব্যয়বহুল হওয়া ছাড়া FLAG_DETECT_ACCESS_UNITS ব্যবহারের অন্য কোনো পার্শ্বপ্রতিক্রিয়া নেই। কিছু MPEG-TS ফাইল প্লে করার সময়, FLAG_ALLOW_NON_IDR_KEYFRAMES ব্যবহারের ফলে প্লেব্যাকের শুরুতে এবং সিক (seek) করার ঠিক পরেই সাময়িকভাবে ভিজ্যুয়াল বিকৃতি ঘটতে পারে।
কিছু MPEG-TS ফাইলে সাবটাইটেল পাওয়া যায় না কেন?
কিছু MPEG-TS ফাইলে CEA-608 ট্র্যাক অন্তর্ভুক্ত থাকে কিন্তু কন্টেইনার মেটাডেটাতে সেগুলো ঘোষণা করা হয় না, ফলে ExoPlayer সেগুলো শনাক্ত করতে পারে না। আপনি DefaultExtractorsFactory তে প্রত্যাশিত সাবটাইটেল ফরম্যাটের একটি তালিকা প্রদান করে ম্যানুয়ালি যেকোনো সাবটাইটেল ট্র্যাক নির্দিষ্ট করতে পারেন, যার মধ্যে MPEG-TS স্ট্রিমে সেগুলোকে শনাক্ত করার জন্য ব্যবহৃত অ্যাক্সেসিবিলিটি চ্যানেলগুলোও অন্তর্ভুক্ত থাকবে:
কোটলিন
val extractorsFactory = DefaultExtractorsFactory() .setTsSubtitleFormats( listOf( Format.Builder() .setSampleMimeType(MimeTypes.APPLICATION_CEA608) .setAccessibilityChannel(accessibilityChannel) // Set other subtitle format info, such as language. .build() ) ) val player: Player = ExoPlayer.Builder(context, DefaultMediaSourceFactory(context, extractorsFactory)).build()
জাভা
DefaultExtractorsFactory extractorsFactory = new DefaultExtractorsFactory() .setTsSubtitleFormats( ImmutableList.of( new Format.Builder() .setSampleMimeType(MimeTypes.APPLICATION_CEA608) .setAccessibilityChannel(accessibilityChannel) // Set other subtitle format info, such as language. .build())); Player player = new ExoPlayer.Builder(context, new DefaultMediaSourceFactory(context, extractorsFactory)) .build();
কেন কিছু MP4/FMP4 ফাইল ঠিকমতো চলে না?
কিছু MP4/FMP4 ফাইলে এডিট লিস্ট থাকে যা স্যাম্পলের তালিকা বাদ দিয়ে, সরিয়ে বা পুনরাবৃত্তি করে মিডিয়া টাইমলাইনকে নতুন করে লেখে। ExoPlayer-এ এডিট লিস্ট প্রয়োগ করার আংশিক সমর্থন রয়েছে। উদাহরণস্বরূপ, এটি একটি সিনক্রোনাইজেশন স্যাম্পল থেকে শুরু হওয়া স্যাম্পলের গ্রুপকে বিলম্বিত বা পুনরাবৃত্তি করতে পারে, কিন্তু এটি অডিও স্যাম্পল ছোট করে না বা এমন এডিটের জন্য মিডিয়া প্রি-রোল করে না যা সিনক্রোনাইজেশন স্যাম্পল থেকে শুরু হয় না।
যদি আপনি দেখেন যে মিডিয়ার কোনো অংশ অপ্রত্যাশিতভাবে অনুপস্থিত বা পুনরাবৃত্ত হচ্ছে, তাহলে Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS অথবা FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS সেট করার চেষ্টা করুন, যা এক্সট্র্যাক্টরকে এডিট লিস্ট সম্পূর্ণরূপে উপেক্ষা করতে বাধ্য করবে। এগুলি একটি DefaultExtractorsFactory তে setMp4ExtractorFlags অথবা setFragmentedMp4ExtractorFlags ব্যবহার করে সেট করা যেতে পারে।
কেন কিছু স্ট্রিম HTTP রেসপন্স কোড 301 বা 302 এর কারণে ব্যর্থ হয়?
HTTP রেসপন্স কোড 301 এবং 302 উভয়ই রিডাইরেকশন নির্দেশ করে। উইকিপিডিয়াতে এর সংক্ষিপ্ত বিবরণ পাওয়া যাবে। যখন ExoPlayer একটি রিকোয়েস্ট করে এবং স্ট্যাটাস কোড 301 বা 302 সহ একটি রেসপন্স পায়, তখন এটি সাধারণত রিডাইরেক্ট অনুসরণ করে এবং স্বাভাবিকভাবে প্লেব্যাক শুরু করে। একমাত্র যে ক্ষেত্রে এটি ডিফল্টভাবে ঘটে না, তা হলো ক্রস-প্রোটোকল রিডাইরেক্ট। একটি ক্রস-প্রোটোকল রিডাইরেক্ট হলো এমন একটি রিডাইরেক্ট যা HTTPS থেকে HTTP-তে বা এর বিপরীতে (অথবা কম ক্ষেত্রে, অন্য কোনো প্রোটোকলের জোড়ার মধ্যে) রিডাইরেক্ট করে। একটি URL ক্রস-প্রোটোকল রিডাইরেক্ট ঘটায় কিনা তা আপনি নিম্নলিখিতভাবে wget কমান্ড লাইন টুল ব্যবহার করে পরীক্ষা করতে পারেন:
wget "https://yourserver.example.com/test.mp3" 2>&1 | grep Location
আউটপুটটি দেখতে অনেকটা এইরকম হবে:
Location: https://secondserver.example.net/test.mp3 [following]
Location: http://thirdserver.example.org/test.mp3 [following]
এই উদাহরণে, দুটি রিডাইরেক্ট রয়েছে। প্রথম রিডাইরেক্টটি হলো https://yourserver.example.com/test.mp3 থেকে https://secondserver.example.net/test.mp3 এ। উভয়ই HTTPS, এবং তাই এটি একটি ক্রস-প্রোটোকল রিডাইরেক্ট নয়। দ্বিতীয় রিডাইরেক্টটি হলো https://secondserver.example.net/test.mp3 থেকে http://thirdserver.example.org/test.mp3 এ। এটি HTTPS থেকে HTTP-তে রিডাইরেক্ট করে এবং তাই এটি একটি ক্রস-প্রোটোকল রিডাইরেক্ট। ExoPlayer তার ডিফল্ট কনফিগারেশনে এই রিডাইরেক্টটি অনুসরণ করবে না, যার অর্থ প্লেব্যাক ব্যর্থ হবে।
প্রয়োজন হলে, আপনার অ্যাপ্লিকেশনে ব্যবহৃত DefaultHttpDataSource.Factory ইনস্ট্যান্সগুলো তৈরি করার সময় ক্রস-প্রোটোকল রিডাইরেক্ট অনুসরণ করার জন্য আপনি ExoPlayer-কে কনফিগার করতে পারেন। নেটওয়ার্ক স্ট্যাক নির্বাচন এবং কনফিগার করার বিষয়ে এখানে জানুন।
কেন কিছু স্ট্রিম UnrecognizedInputFormatException-এর কারণে ব্যর্থ হয়?
এই প্রশ্নটি নিম্নলিখিত ধরনের প্লেব্যাক ব্যর্থতা সম্পর্কিত:
UnrecognizedInputFormatException: None of the available extractors
(MatroskaExtractor, FragmentedMp4Extractor, ...) could read the stream.
এই ব্যর্থতার দুটি সম্ভাব্য কারণ রয়েছে। সবচেয়ে সাধারণ কারণ হলো, আপনি DASH (mpd), HLS (m3u8), বা SmoothStreaming (ism, isml) কন্টেন্ট চালানোর চেষ্টা করছেন, কিন্তু প্লেয়ারটি এটিকে একটি প্রগ্রেসিভ স্ট্রিম হিসেবে চালাতে চায়। এই ধরনের স্ট্রিম চালানোর জন্য, আপনাকে সংশ্লিষ্ট ExoPlayer মডিউলের উপর নির্ভর করতে হবে। যেসব ক্ষেত্রে স্ট্রিম URI-এর শেষে স্ট্যান্ডার্ড ফাইল এক্সটেনশন থাকে না, সেসব ক্ষেত্রে আপনি স্ট্রিমের ধরন স্পষ্টভাবে নির্দিষ্ট করার জন্য MediaItem.Builder এর setMimeType এ MimeTypes.APPLICATION_MPD , MimeTypes.APPLICATION_M3U8 বা MimeTypes.APPLICATION_SS পাস করতে পারেন।
দ্বিতীয় এবং তুলনামূলকভাবে কম প্রচলিত কারণটি হলো, আপনি যে মিডিয়াটি চালানোর চেষ্টা করছেন, ExoPlayer তার কন্টেইনার ফরম্যাটটি সাপোর্ট করে না। এক্ষেত্রে, এই ত্রুটিটি প্রত্যাশিতভাবেই ঘটছে, তবুও আপনি কন্টেইনার ফরম্যাটের বিবরণ এবং একটি টেস্ট স্ট্রিম সহ আমাদের ইস্যু ট্র্যাকারে একটি ফিচার রিকোয়েস্ট জমা দিতে পারেন। নতুন কোনো ফিচার রিকোয়েস্ট জমা দেওয়ার আগে অনুগ্রহ করে বিদ্যমান কোনো রিকোয়েস্ট খুঁজে দেখুন।
কিছু ডিভাইসে setPlaybackParameters কেন সঠিকভাবে কাজ করে না?
অ্যান্ড্রয়েড এম এবং তার পূর্ববর্তী সংস্করণগুলিতে আপনার অ্যাপের ডিবাগ বিল্ড চালানোর সময়, setPlaybackParameters API ব্যবহার করতে গিয়ে আপনি অমসৃণ পারফরম্যান্স, শ্রাব্য ত্রুটি এবং উচ্চ সিপিইউ ব্যবহারের মতো সমস্যার সম্মুখীন হতে পারেন। এর কারণ হলো, অ্যান্ড্রয়েডের এই সংস্করণগুলিতে চালিত ডিবাগ বিল্ডগুলির জন্য এই API-এর একটি গুরুত্বপূর্ণ অপটিমাইজেশন নিষ্ক্রিয় করা থাকে।
এটা মনে রাখা গুরুত্বপূর্ণ যে, এই সমস্যাটি শুধুমাত্র ডিবাগ বিল্ডকে প্রভাবিত করে। এটি রিলিজ বিল্ডকে প্রভাবিত করে না , যেগুলোর জন্য অপটিমাইজেশন সর্বদা সক্রিয় থাকে। সুতরাং, আপনি শেষ ব্যবহারকারীদের যে রিলিজগুলো প্রদান করেন, সেগুলো এই সমস্যা দ্বারা প্রভাবিত হওয়ার কথা নয়।
"Player is accessed on wrong thread" ত্রুটিগুলোর অর্থ কী?
শুরু করার পৃষ্ঠায় থ্রেডিং সম্পর্কিত একটি নোট দেখুন।
আমি "Unexpected status line: ICY 200 OK" সমস্যাটি কীভাবে সমাধান করতে পারি?
সার্ভারের রেসপন্সে HTTP-সম্মত স্ট্যাটাস লাইনের পরিবর্তে যদি একটি ICY স্ট্যাটাস লাইন থাকে, তাহলে এই সমস্যাটি দেখা দিতে পারে। ICY স্ট্যাটাস লাইন এখন আর ব্যবহার করা হয় না এবং এর ব্যবহার উচিত নয়। তাই, সার্ভারটি যদি আপনার নিয়ন্ত্রণে থাকে, তবে HTTP-সম্মত রেসপন্স দেওয়ার জন্য আপনার এটি আপডেট করা উচিত। আপনি যদি এটি করতে না পারেন, তবে ExoPlayer OkHttp লাইব্রেরি ব্যবহার করলে সমস্যাটির সমাধান হয়ে যাবে, কারণ এটি ICY স্ট্যাটাস লাইন সঠিকভাবে পরিচালনা করতে সক্ষম।
যে স্ট্রিমটি প্লে করা হচ্ছে সেটি একটি লাইভ স্ট্রিম কিনা, তা আমি কীভাবে জানতে পারব?
You can query the player's isCurrentWindowLive method. In addition, you can check isCurrentWindowDynamic to find out whether the window is dynamic (that is, still updating over time).
আমার অ্যাপ ব্যাকগ্রাউন্ডে গেলেও কীভাবে অডিও চালু রাখব?
আপনার অ্যাপ ব্যাকগ্রাউন্ডে থাকলেও অডিওর নিরবচ্ছিন্ন প্লেব্যাক নিশ্চিত করতে এই ধাপগুলো অনুসরণ করুন:
- আপনার একটি চলমান ফোরগ্রাউন্ড সার্ভিস থাকা প্রয়োজন। এটি সিস্টেমকে রিসোর্স খালি করার জন্য আপনার প্রসেসটি বন্ধ করে দেওয়া থেকে বিরত রাখে।
- You need to hold a
WifiLockand aWakeLock. These ensure that the system keeps the WiFi radio and CPU awake. This can be easily done if usingExoPlayerby callingsetWakeMode, which will automatically acquire and release the required locks at the correct times.
এটা গুরুত্বপূর্ণ যে, অডিও বাজানো বন্ধ হওয়ার সাথে সাথেই আপনি লকগুলো রিলিজ করবেন (যদি setWakeMode ব্যবহার না করেন) এবং সার্ভিসটি বন্ধ করে দেবেন।
কেন ExoPlayer আমার কন্টেন্ট সাপোর্ট করে কিন্তু ExoPlayer Cast লাইব্রেরি করে না?
হতে পারে যে আপনি যে কন্টেন্টটি চালানোর চেষ্টা করছেন তা CORS এনাবল করা নেই। Cast ফ্রেমওয়ার্ক অনুযায়ী কোনো কন্টেন্ট চালানোর জন্য সেটিকে CORS এনাবল করা আবশ্যক।
কেন কন্টেন্টটি প্লে হয় না, কিন্তু কোনো ত্রুটি দেখানো হয় না?
হতে পারে যে, আপনি যে ডিভাইসে কন্টেন্টটি চালাচ্ছেন সেটি একটি নির্দিষ্ট মিডিয়া স্যাম্পল ফরম্যাট সাপোর্ট করে না। আপনার প্লেয়ারে লিসেনার হিসেবে একটি EventLogger যোগ করে এবং লগক্যাটে (Logcat) এই ধরনের একটি লাইন খুঁজে দেখে এটি সহজেই নিশ্চিত করা যায়:
[ ] Track:x, id=x, mimeType=mime/type, ... , supported=NO_UNSUPPORTED_TYPE
NO_UNSUPPORTED_TYPE অর্থ হলো, ডিভাইসটি mimeType দ্বারা নির্দিষ্ট মিডিয়া স্যাম্পল ফরম্যাটটি ডিকোড করতে সক্ষম নয়। সমর্থিত স্যাম্পল ফরম্যাট সম্পর্কে তথ্যের জন্য অ্যান্ড্রয়েড মিডিয়া ফরম্যাট ডকুমেন্টেশন দেখুন। প্লেব্যাকের জন্য আমি কীভাবে একটি ডিকোডিং লাইব্রেরি লোড এবং ব্যবহার করতে পারি? এই প্রশ্নটিও সহায়ক হতে পারে।
আমি কীভাবে একটি ডিকোডিং লাইব্রেরি লোড করে প্লেব্যাকের জন্য ব্যবহার করতে পারি?
- বেশিরভাগ ডিকোডার লাইব্রেরির ডিপেন্ডেন্সিগুলো চেক আউট এবং বিল্ড করার জন্য ম্যানুয়াল ধাপ থাকে, তাই নিশ্চিত হয়ে নিন যে আপনি প্রাসঙ্গিক লাইব্রেরির README-তে দেওয়া ধাপগুলো অনুসরণ করেছেন। উদাহরণস্বরূপ, ExoPlayer FFmpeg লাইব্রেরির জন্য libraries/decoder_ffmpeg/README.md- এ দেওয়া নির্দেশাবলী অনুসরণ করা আবশ্যক, যার মধ্যে আপনি যে ফরম্যাটগুলো চালাতে চান সেগুলোর জন্য ডিকোডার সক্রিয় করতে কনফিগারেশন ফ্ল্যাগ পাস করাও অন্তর্ভুক্ত।
- যেসব লাইব্রেরিতে নেটিভ কোড আছে, সেগুলোর ক্ষেত্রে README-তে উল্লেখিত Android NDK-এর সঠিক সংস্করণটি ব্যবহার করছেন কিনা তা নিশ্চিত করুন এবং কনফিগারেশন ও বিল্ড করার সময় কোনো ত্রুটি দেখা দিলে সেদিকে খেয়াল রাখুন। README-তে দেওয়া ধাপগুলো অনুসরণ করার পর, প্রতিটি সমর্থিত আর্কিটেকচারের জন্য লাইব্রেরির পাথের
libsসাবডিরেক্টরিতে.soফাইলগুলো দেখতে পাবেন। - ডেমো অ্যাপ্লিকেশনে লাইব্রেরিটি ব্যবহার করে প্লেব্যাক পরীক্ষা করার জন্য, 'enableing bundled decoders' অংশটি দেখুন। আপনার নিজের অ্যাপ থেকে লাইব্রেরিটি ব্যবহারের নির্দেশাবলীর জন্য এর README ফাইলটি দেখুন।
- আপনি যদি
DefaultRenderersFactoryব্যবহার করেন, তাহলে ডিকোডার লোড হওয়ার সময় Logcat-এ "Loaded FfmpegAudioRenderer"-এর মতো একটি তথ্য-স্তরের লগ লাইন দেখতে পাওয়ার কথা। যদি সেটি না থাকে, তবে নিশ্চিত করুন যে অ্যাপ্লিকেশনটির ডিকোডিং লাইব্রেরির উপর একটি নির্ভরতা রয়েছে। - যদি আপনি Logcat-এ
LibraryLoaderথেকে সতর্কতামূলক স্তরের লগ দেখতে পান, তাহলে এটি নির্দেশ করে যে লাইব্রেরির নেটিভ কম্পোনেন্ট লোড করা ব্যর্থ হয়েছে। এমনটি ঘটলে, যাচাই করুন যে আপনি লাইব্রেরির README-তে দেওয়া ধাপগুলো সঠিকভাবে অনুসরণ করেছেন এবং নির্দেশাবলী অনুসরণ করার সময় কোনো ত্রুটি দেখা দেয়নি।
ডিকোডিং লাইব্রেরি ব্যবহার করতে গিয়ে যদি আপনার এখনও সমস্যা হয়, তবে প্রাসঙ্গিক সাম্প্রতিক কোনো সমস্যার জন্য অনুগ্রহ করে Media3 ইস্যু ট্র্যাকারটি দেখুন। যদি আপনাকে একটি নতুন সমস্যা জানাতে হয় এবং সেটি লাইব্রেরির নেটিভ অংশ বিল্ড করা সম্পর্কিত হয়, তবে সমস্যাটি নির্ণয়ে আমাদের সাহায্য করার জন্য অনুগ্রহ করে README নির্দেশাবলী চালানোর সম্পূর্ণ কমান্ড লাইন আউটপুট অন্তর্ভুক্ত করুন।
আমি কি সরাসরি ExoPlayer দিয়ে ইউটিউব ভিডিও চালাতে পারি?
না, ExoPlayer ইউটিউব থেকে ভিডিও চালাতে পারে না, যেমন https://www.youtube.com/watch?v=... এই ধরনের URL। এর পরিবর্তে, আপনার ইউটিউব আইফ্রেম প্লেয়ার এপিআই (YouTube IFrame Player API) ব্যবহার করা উচিত, যা অ্যান্ড্রয়েডে ইউটিউব ভিডিও চালানোর আনুষ্ঠানিক উপায়।
ভিডিও প্লেব্যাক আটকে আটকে যাচ্ছে
উদাহরণস্বরূপ, কন্টেন্টের বিটরেট বা রেজোলিউশন ডিভাইসের সক্ষমতা ছাড়িয়ে গেলে ডিভাইসটি হয়তো কন্টেন্টটি যথেষ্ট দ্রুত ডিকোড করতে পারবে না। এই ধরনের ডিভাইসে ভালো পারফরম্যান্স পেতে আপনাকে নিম্নমানের কন্টেন্ট ব্যবহার করতে হতে পারে।
আপনার ডিভাইসে যদি অ্যান্ড্রয়েড ৬.০ (এপিআই লেভেল ২৩) থেকে শুরু করে অ্যান্ড্রয়েড ১১ (এপিআই লেভেল ৩০) পর্যন্ত কোনো ভার্সন চলে এবং ভিডিও চলার সময় তা আটকে যায়, বিশেষ করে ডিআরএম-সুরক্ষিত বা উচ্চ-ফ্রেম-রেটের কন্টেন্ট চালানোর সময়, তাহলে আপনি অ্যাসিঙ্ক্রোনাস বাফার কিউইং চালু করে দেখতে পারেন।
অস্থিতিশীল এপিআই লিন্ট ত্রুটি
Media3 এপিআই সারফেসের একটি উপসেটের জন্য বাইনারি সামঞ্জস্যের নিশ্চয়তা দেয়। যে অংশগুলো বাইনারি সামঞ্জস্যের নিশ্চয়তা দেয় না, সেগুলোকে @UnstableApi দিয়ে চিহ্নিত করা হয়। এই পার্থক্যটি স্পষ্ট করার জন্য, অস্থিতিশীল এপিআই সিম্বলের ব্যবহার একটি লিন্ট এরর তৈরি করে, যদি না সেগুলোকে @OptIn দিয়ে টীকাযুক্ত করা হয়।
@UnstableApi অ্যানোটেশনটি কোনো API-এর গুণমান বা পারফরম্যান্স সম্পর্কে কিছুই বোঝায় না, শুধু এইটুকুই বোঝায় যে এটি "API-ফ্রোজেন" নয়।
অস্থিতিশীল এপিআই লিন্ট ত্রুটিগুলি পরিচালনা করার জন্য আপনার কাছে দুটি বিকল্প রয়েছে:
- এমন একটি স্থিতিশীল এপিআই ব্যবহার করা শুরু করুন যা একই ফলাফল দেয়।
- পরবর্তীতে দেখানো অনুযায়ী, অস্থিতিশীল এপিআই ব্যবহার করতে থাকুন এবং এর ব্যবহারে
@OptInটীকা যুক্ত করুন।
@OptIn টীকা যোগ করুন
অ্যান্ড্রয়েড স্টুডিও আপনাকে অ্যানোটেশন যোগ করতে সাহায্য করতে পারে:

আপনি নির্দিষ্ট ব্যবহারের স্থানগুলি ম্যানুয়ালিও টীকাযুক্ত করতে পারেন:
কোটলিন
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
@OptIn(UnstableApi::class)
fun functionUsingUnstableApi() { ... }
জাভা
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
@OptIn(markerClass = UnstableApi.class)
private void methodUsingUnstableApis() { ... }
Whole packages can be opted-in by adding a package-info file:
কোটলিন
// In your package-info.kt
@OptIn(UnstableApi::class)
package name.of.your.package
import androidx.annotation.OptIn
import androidx.media3.common.util.UnstableApi
জাভা
// In your package-info.java
@OptIn(markerClass = UnstableApi.class)
package name.of.your.package;
import androidx.annotation.OptIn;
import androidx.media3.common.util.UnstableApi;
সম্পূর্ণ প্রোজেক্টগুলোকে তাদের lint.xml ফাইলে নির্দিষ্ট লিন্ট এররটি দমন করার মাধ্যমে এই সুবিধাটি গ্রহণ করা যেতে পারে:
<?xml version="1.0" encoding="utf-8"?>
<lint>
<issue id="UnsafeOptInUsageError">
<option name="opt-in" value="androidx.media3.common.util.UnstableApi" />
</issue>
</lint>
kotlin.OptIn নামেও একটি অ্যানোটেশন আছে যা ব্যবহার করা উচিত নয়। androidx.annotation.OptIn অ্যানোটেশনটি ব্যবহার করা জরুরি।