অডিও ইনপুট সাধারণত ডিভাইসের বিল্ট-ইন মাইক, এক্সটার্নাল মাইক বা এর সাথে সংযুক্ত কোনো অডিও ইন্টারফেস থেকে আসে। ফোন আলাপের মাধ্যমেও অডিও ইনপুট আসতে পারে।
কখনও কখনও দুই বা ততোধিক অ্যাপ একই অডিও ইনপুট "ক্যাপচার" করতে চাইতে পারে। তারা হয়তো ভিন্ন ভিন্ন কাজ করছে। উদাহরণস্বরূপ, অডিও গ্রহণকারী কিছু অ্যাপ হয়তো "রেকর্ডিং" করছে, যেমন একটি সাধারণ ভয়েস রেকর্ডার, অন্যদিকে অন্য অ্যাপগুলো হয়তো "শুনছে", যেমন গুগল অ্যাসিস্ট্যান্ট বা ভয়েস কমান্ডে সাড়া দেয় এমন কোনো অ্যাক্সেসিবিলিটি সার্ভিস।
উভয় ক্ষেত্রেই, এই অ্যাপগুলো অডিও ইনপুট গ্রহণ করতে চায়। এই পৃষ্ঠা জুড়ে, কোনো অ্যাপ রেকর্ডিং করছে বা শুধু শুনছে, তা নির্বিশেষে আমরা "ক্যাপচার" শব্দটি ব্যবহার করেছি।
যদি দুই বা ততোধিক অ্যাপ একই সময়ে অডিও ক্যাপচার করতে চায়, তাহলে একই উৎস থেকে তাদের সকলের কাছে অডিও সিগন্যাল পৌঁছে দিতে সমস্যা হতে পারে। এই পৃষ্ঠায় বর্ণনা করা হয়েছে যে, অ্যান্ড্রয়েড সিস্টেম কীভাবে অডিও ক্যাপচারকারী একাধিক অ্যাপের মধ্যে অডিও ইনপুট ভাগ করে নেয়।
অ্যান্ড্রয়েড ১০-এর পূর্ববর্তী আচরণ
অ্যান্ড্রয়েড ১০-এর আগে, ইনপুট অডিও স্ট্রিম একবারে শুধুমাত্র একটি অ্যাপই ক্যাপচার করতে পারত। যদি কোনো অ্যাপ আগে থেকেই অডিও রেকর্ড করত বা শুনত, তবে আপনার অ্যাপ একটি AudioRecord অবজেক্ট তৈরি করতে পারত, কিন্তু AudioRecord.startRecording() কল করলে একটি এরর আসত এবং রেকর্ডিং শুরু হতো না।
এই নিয়মের একটি ব্যতিক্রম ছিল যখন কোনো বিশেষাধিকারপ্রাপ্ত অ্যাপ (যেমন গুগল অ্যাসিস্ট্যান্ট বা কোনো অ্যাক্সেসিবিলিটি সার্ভিস) android.permission.CAPTURE_AUDIO_HOTWORD পারমিশনটি ব্যবহার করত এবং HOTWORD টাইপের কোনো অডিও সোর্স ব্যবহার করত। এক্ষেত্রে অন্য কোনো অ্যাপ রেকর্ডিং শুরু করতে পারত। যখন এমনটা ঘটত, তখন বিশেষাধিকারপ্রাপ্ত অ্যাপটি বন্ধ হয়ে যেত এবং নতুন অ্যাপটি ইনপুটটি ক্যাপচার করে নিত।
অ্যান্ড্রয়েড ৯-এ আরও একটি পরিবর্তন আনা হয়েছিল: শুধুমাত্র ফোরগ্রাউন্ডে চলমান অ্যাপগুলো (অথবা কোনো ফোরগ্রাউন্ড সার্ভিস) অডিও ইনপুট ক্যাপচার করতে পারত। যখন কোনো ফোরগ্রাউন্ড সার্ভিস বা ফোরগ্রাউন্ড UI কম্পোনেন্ট ছাড়া কোনো অ্যাপ ক্যাপচার করা শুরু করত, তখন অ্যাপটি চলতে থাকলেও নীরব অডিও পেত, এমনকি সেই মুহূর্তে শুধুমাত্র সেটিই অডিও ক্যাপচার করলেও।
অ্যান্ড্রয়েড ১০ এর আচরণ
অ্যান্ড্রয়েড ১০-এর আগের নিয়মটি ছিল "আগে এলে আগে পাবে"। একবার কোনো অ্যাপ অডিও ক্যাপচার করা শুরু করলে, সেই অ্যাপটি বন্ধ না করা পর্যন্ত অন্য কোনো অ্যাপ সেই অডিও ইনপুট অ্যাক্সেস করতে পারত না।
অ্যান্ড্রয়েড ১০ একটি অগ্রাধিকার ব্যবস্থা প্রয়োগ করে, যা চলমান অ্যাপগুলোর মধ্যে ইনপুট অডিও স্ট্রিম অদলবদল করতে পারে। বেশিরভাগ ক্ষেত্রে, যদি কোনো নতুন অ্যাপ অডিও ইনপুট গ্রহণ করে, তবে আগে থেকে গ্রহণকারী অ্যাপটি চলতে থাকে, কিন্তু সেটি নীরবতা গ্রহণ করে। কিছু ক্ষেত্রে সিস্টেমটি উভয় অ্যাপেই অডিও সরবরাহ করা চালিয়ে যেতে পারে। এই বিভিন্ন শেয়ারিং পরিস্থিতি নিচে ব্যাখ্যা করা হলো।
এই পদ্ধতিটি অনেকটা সেই পদ্ধতির মতোই, যেভাবে অডিও আউটপুট ব্যবহারের জন্য প্রতিদ্বন্দ্বিতাকারী একাধিক অ্যাপকে অডিও ফোকাস দ্বারা নিয়ন্ত্রণ করা হয়। তবে, অডিও ফোকাস প্রোগ্রাম্যাটিক অনুরোধের মাধ্যমে ফোকাস গ্রহণ ও ত্যাগ করার দ্বারা পরিচালিত হয়, অপরদিকে এখানে বর্ণিত ইনপুট স্যুইচিং পদ্ধতিটি একটি অগ্রাধিকার নীতির উপর ভিত্তি করে কাজ করে, যা কোনো নতুন অ্যাপ অডিও ক্যাপচার করা শুরু করলেই স্বয়ংক্রিয়ভাবে প্রয়োগ করা হয়।
অডিও ধারণ করার উদ্দেশ্যে, অ্যান্ড্রয়েড দুই ধরনের অ্যাপকে আলাদা করে দেখে:
- সাধারণ অ্যাপগুলো ব্যবহারকারী দ্বারা ইনস্টল করা হয়।
- ডিভাইসটিতে বিশেষ সুবিধাপ্রাপ্ত অ্যাপগুলো আগে থেকেই ইনস্টল করা থাকে। এর মধ্যে রয়েছে গুগল অ্যাসিস্ট্যান্ট এবং সমস্ত অ্যাক্সেসিবিলিটি পরিষেবা।
এছাড়াও, কোনো অ্যাপ যদি 'গোপনীয়তা-সংবেদনশীল' অডিও উৎস— CAMCORDER বা VOICE_COMMUNICATION —ব্যবহার করে, তবে সেটিকে ভিন্নভাবে বিবেচনা করা হয়।
অডিও ইনপুট ব্যবহার ও শেয়ার করার অগ্রাধিকারের নিয়মাবলী নিম্নরূপ:
- বিশেষাধিকারপ্রাপ্ত অ্যাপগুলো সাধারণ অ্যাপের চেয়ে উচ্চতর অগ্রাধিকার পায়।
- যেসব অ্যাপের ফোরগ্রাউন্ড ইউআই দৃশ্যমান, সেগুলোর অগ্রাধিকার ব্যাকগ্রাউন্ড অ্যাপের চেয়ে বেশি।
- গোপনীয়তা-সংবেদনশীল উৎস থেকে অডিও ধারণকারী অ্যাপগুলো, গোপনীয়তা-সংবেদনশীল নয় এমন অ্যাপের চেয়ে উচ্চতর অগ্রাধিকার পায়।
- দুটি সাধারণ অ্যাপ কখনোই একই সময়ে অডিও ধারণ করতে পারে না।
- কিছু ক্ষেত্রে, একটি বিশেষাধিকারপ্রাপ্ত অ্যাপ অন্য অ্যাপের সাথে অডিও ইনপুট শেয়ার করতে পারে।
- যদি একই অগ্রাধিকারের দুটি ব্যাকগ্রাউন্ড অ্যাপ অডিও ধারণ করে, তবে যেটি শেষে চালু হয়েছে সেটির অগ্রাধিকার বেশি।
পরিস্থিতি ভাগ করে নেওয়া
যখন দুটি অ্যাপ অডিও ক্যাপচার করার চেষ্টা করে, তখন উভয়ই ইনপুট সিগন্যাল গ্রহণ করতে পারে, অথবা তাদের মধ্যে একটি নীরবতা পেতে পারে।
চারটি প্রধান পরিস্থিতি রয়েছে:
- সহকারী + সাধারণ অ্যাপ
- অ্যাক্সেসিবিলিটি পরিষেবা + সাধারণ অ্যাপ
- দুটি সাধারণ অ্যাপ
- ভয়েস কল + সাধারণ অ্যাপ
সহকারী + সাধারণ অ্যাপ
অ্যাসিস্ট্যান্ট একটি বিশেষাধিকারপ্রাপ্ত অ্যাপ, কারণ এটি আগে থেকেই ইনস্টল করা থাকে এবং এটি RoleManager.ROLE_ASSISTANT রোলটি ধারণ করে। এই রোলযুক্ত আগে থেকে ইনস্টল করা অন্য যেকোনো অ্যাপকেও একইভাবে বিবেচনা করা হয়।
অ্যান্ড্রয়েড এই নিয়মগুলো অনুসারে ইনপুট অডিও শেয়ার করে:
অ্যাসিস্ট্যান্ট অডিও গ্রহণ করতে পারে (সেটি ফোরগ্রাউন্ডে বা ব্যাকগ্রাউন্ডে যেখানেই থাকুক না কেন), যদি না অন্য কোনো অ্যাপ আগে থেকেই গোপনীয়তা-সংবেদনশীল কোনো অডিও উৎস ব্যবহার করে তা ক্যাপচার করে থাকে।
স্ক্রিনের উপরে অ্যাসিস্ট্যান্টের কোনো দৃশ্যমান UI কম্পোনেন্ট না থাকলে অ্যাপটি অডিও গ্রহণ করে।
মনে রাখবেন যে, উভয় অ্যাপই কেবল তখনই অডিও গ্রহণ করে যখন অ্যাসিস্ট্যান্ট ব্যাকগ্রাউন্ডে থাকে এবং অন্য অ্যাপটি কোনো গোপনীয়তা-সংবেদনশীল অডিও উৎস থেকে ক্যাপচার করে না।
অ্যাক্সেসিবিলিটি পরিষেবা + সাধারণ অ্যাপ
একটি AccessibilityService জন্য একটি কঠোর ঘোষণা প্রয়োজন।
অ্যান্ড্রয়েড এই নিয়মগুলো অনুসারে ইনপুট অডিও শেয়ার করে:
যদি পরিষেবাটির ইউজার ইন্টারফেস (UI) উপরে থাকে, তাহলে পরিষেবা এবং অ্যাপ উভয়ই অডিও ইনপুট গ্রহণ করে। এই বৈশিষ্ট্যটি ভয়েস কমান্ডের মাধ্যমে ভয়েস কল নিয়ন্ত্রণ বা ভিডিও ধারণের মতো কার্যকারিতা প্রদান করে।
যদি পরিষেবাটি শীর্ষে না থাকে, তাহলে এই ক্ষেত্রটিকে নীচের সাধারণ দুটি অ্যাপের ক্ষেত্রের মতোই বিবেচনা করা হয়।
দুটি সাধারণ অ্যাপ
যখন দুটি অ্যাপ একই সাথে ক্যাপচার করে, তখন কেবল একটি অ্যাপ অডিও পায় এবং অন্যটি নীরবতা পায়।
অ্যান্ড্রয়েড এই নিয়মগুলো অনুসারে ইনপুট অডিও শেয়ার করে:
- যদি কোনো অ্যাপই গোপনীয়তা-সংবেদনশীল না হয়, তবে যে অ্যাপটির ইউজার ইন্টারফেস (UI) উপরে থাকে, সেটি অডিও গ্রহণ করে। যদি কোনো অ্যাপেরই ইউজার ইন্টারফেস না থাকে, তবে যে অ্যাপটি সবচেয়ে সম্প্রতি ক্যাপচার শুরু করেছে, সেটি অডিও গ্রহণ করে।
- অ্যাপগুলোর মধ্যে কোনো একটি যদি গোপনীয়তা-সংবেদনশীল হয়, তবে সেটি অডিও গ্রহণ করে এবং অন্য অ্যাপটি নীরবতা পায়, এমনকি যদি সেটির উপরে কোনো UI থাকে বা সেটি সম্প্রতি রেকর্ডিং শুরু করে থাকে।
- যদি উভয় অ্যাপই গোপনীয়তা-সংবেদনশীল হয়, তবে যে অ্যাপটি সবচেয়ে সম্প্রতি ক্যাপচার করা শুরু করেছে সেটি অডিও পায় এবং অন্যটি নীরবতা পায়।
ভয়েস কল + সাধারণ অ্যাপ
AudioManager.getMode() দ্বারা ফেরত আসা অডিও মোডটি যদি MODE_IN_CALL বা MODE_IN_COMMUNICATION হয়, তাহলে একটি ভয়েস কল সক্রিয় থাকে।
অ্যান্ড্রয়েড এই নিয়মগুলো অনুসারে ইনপুট অডিও শেয়ার করে:
- কলটিতে সবসময় অডিও পাওয়া যায়।
- অ্যাপটি অডিও ধারণ করতে পারে, যদি এটি একটি অ্যাক্সেসিবিলিটি পরিষেবা হয়।
অ্যাপটি ভয়েস কলটি ক্যাপচার করতে পারে, যদি এটি
CAPTURE_AUDIO_OUTPUTপারমিশনসহ একটি প্রিভিলেজড (পূর্ব-ইনস্টল করা) অ্যাপ হয়।ভয়েস কলের আপলিঙ্ক (TX), ডাউনলিঙ্ক (RX), অথবা উভয়ই ক্যাপচার করার জন্য, অ্যাপটিকে অবশ্যই
MediaRecorder.AudioSource.VOICE_UPLINKবাMediaRecorder.AudioSource.VOICE_DOWNLINKঅডিও সোর্স এবং/অথবাAudioDeviceInfo.TYPE_TELEPHONYডিভাইস নির্দিষ্ট করতে হবে।
অ্যান্ড্রয়েড ১১ এর আচরণ
অ্যান্ড্রয়েড ১১ (এপিআই লেভেল ৩০) উপরে বর্ণিত অ্যান্ড্রয়েড ১০-এর অগ্রাধিকার স্কিমটি অনুসরণ করে। এছাড়াও এটি AudioRecord , MediaRecorder , এবং AAudioStream এ নতুন কিছু মেথড প্রদান করে, যা নির্বাচিত ব্যবহারের ক্ষেত্র নির্বিশেষে একই সাথে অডিও ক্যাপচার করার ক্ষমতাকে চালু বা বন্ধ করতে পারে।
নতুন পদ্ধতিগুলো হলো:
-
AudioRecord.Builder.setPrivacySensitive() -
AudioRecord.isPrivacySensitive() -
MediaRecorder.setPrivacySensitive() -
MediaRecorder.isPrivacySensitive() -
AAudioStreamBuilder_setPrivacySensitive() -
AAudioStream_isPrivacySensitive()
যখন setPrivacySensitive() true হয়, তখন ক্যাপচার ব্যবহারের ক্ষেত্রটি ব্যক্তিগত (প্রাইভেট) হয়ে যায় এবং এমনকি একজন বিশেষাধিকারপ্রাপ্ত অ্যাসিস্ট্যান্টও একই সাথে ক্যাপচার করতে পারে না। এই সেটিংটি ডিফল্ট আচরণকে ওভাররাইড করে, যা অডিও সোর্সের উপর নির্ভর করে। উদাহরণস্বরূপ, VOICE_COMMUNICATION ডিফল্টরূপে ব্যক্তিগত হলেও UNPROCESSED নয়।
কনফিগারেশন পরিবর্তন
যখন একাধিক অ্যাপ একই সাথে অডিও ক্যাপচার করে, তখন সেগুলোর মধ্যে কেবল এক বা দুটি "সক্রিয়" (অডিও গ্রহণ করে) থাকে; বাকিগুলো মিউট (নীরবতা) থাকে। যখন সক্রিয় অ্যাপগুলো পরিবর্তিত হয়, তখন অডিও ফ্রেমওয়ার্ক এই নিয়মগুলো অনুসারে অডিও পাথগুলো পুনরায় কনফিগার করতে পারে:
- প্রতিটি সক্রিয় অ্যাপের জন্য অডিও ইনপুট ডিভাইস পরিবর্তিত হতে পারে (উদাহরণস্বরূপ, বিল্ট-ইন মাইক্রোফোন থেকে সংযুক্ত ব্লুটুথ হেডসেটে)।
- সর্বোচ্চ অগ্রাধিকারপ্রাপ্ত সক্রিয় অ্যাপটির সাথে সম্পর্কিত প্রিপ্রসেসিং সক্রিয় করা হয়েছে। অন্য সব প্রিপ্রসেসিং উপেক্ষা করা হয়েছে।
যেহেতু একটি উচ্চ-অগ্রাধিকারের অ্যাপ সক্রিয় হলে একটি সক্রিয় অ্যাপ নীরব হয়ে যেতে পারে, তাই কনফিগারেশন পরিবর্তনের সময় বিজ্ঞপ্তি পাওয়ার জন্য আপনি AudioRecord বা MediaRecorder অবজেক্টে একটি AudioManager.AudioRecordingCallback রেজিস্টার করতে পারেন। সম্ভাব্য পরিবর্তনগুলো হতে পারে:
- নীরব বা অ-নীরব ক্যাপচার
- ডিভাইস পরিবর্তন করা হয়েছে
- প্রিপ্রসেসিং পরিবর্তিত হয়েছে
- স্ট্রিমের বৈশিষ্ট্য পরিবর্তন করা হয়েছে (স্যাম্পলিং রেট, চ্যানেল মাস্ক, স্যাম্পল ফরম্যাট)
ক্যাপচার শুরু করার আগে আপনাকে অবশ্যই AudioRecord.registerAudioRecordingCallback() কল করতে হবে। এই কলব্যাকটি কেবল তখনই কার্যকর হয়, যখন অ্যাপটি অডিও গ্রহণ করার সময় কোনো পরিবর্তন ঘটে।
onRecordingConfigChanged() মেথডটি একটি AudioRecordingConfiguration রিটার্ন করে, যাতে বর্তমান অডিও ক্যাপচার অবস্থা থাকে। পরিবর্তন সম্পর্কে জানতে নিম্নলিখিত মেথডগুলো ব্যবহার করুন:
-
isClientSilenced() - ক্যাপচার পলিসির কারণে ক্লায়েন্টে ফেরত পাঠানো অডিও বর্তমানে নীরব করা থাকলে, এটি 'ট্রু' রিটার্ন করে।
-
getAudioDevice() - সক্রিয় অডিও ডিভাইসটি ফেরত দেয়।
-
getEffects() - সক্রিয় প্রিপ্রসেসিং এফেক্টটি ফেরত দেয়। উল্লেখ্য যে, ক্লায়েন্টটি সর্বোচ্চ-অগ্রাধিকারের সক্রিয় অ্যাপ না হলে, সক্রিয় এফেক্টটি
getClientEffects()দ্বারা ফেরত দেওয়া এফেক্টগুলোর মতো নাও হতে পারে। -
getFormat() - স্ট্রিম প্রোপার্টিগুলো ফেরত দেয়। উল্লেখ্য যে, ক্লায়েন্ট কর্তৃক প্রাপ্ত প্রকৃত অডিও ডেটা সর্বদা
getClientFormat()দ্বারা ফেরত দেওয়া প্রয়োজনীয় ফরম্যাটটি মেনে চলে। ফ্রেমওয়ার্কটি হার্ডওয়্যার ইন্টারফেসে ব্যবহৃত ফরম্যাট থেকে ক্লায়েন্ট কর্তৃক নির্দিষ্ট ফরম্যাটে স্বয়ংক্রিয়ভাবে প্রয়োজনীয় রিস্যাম্পলিং, চ্যানেল এবং ফরম্যাট রূপান্তর সম্পাদন করে। -
AudioRecord.getActiveRecordingConfiguration(). - সক্রিয় রেকর্ডিং কনফিগারেশনটি ফেরত দেয়।
AudioManager.getActiveRecordingConfigurations() কল করে আপনি ডিভাইসে থাকা সমস্ত সক্রিয় রেকর্ডিংয়ের একটি সাধারণ চিত্র পেতে পারেন।