অডিও ইনপুট শেয়ার করা হচ্ছে

অডিও ইনপুট সাধারণত বিল্ট-ইন মাইক, এক্সটার্নাল মাইক বা ডিভাইসের সাথে অ্যাটাচ করা অডিও ইন্টারফেস থেকে আসে। এছাড়াও, ফোন কথোপকথন থেকে অডিও ইনপুট আসতে পারে।

কখনও কখনও দুটি বা তার বেশি অ্যাপ একই অডিও ইনপুট "ক্যাপচার" করতে চাইতে পারে। তারা হয়ত বিভিন্ন টাস্ক পারফর্ম করছে। যেমন, অডিও রিসিভ করে এমন কিছু অ্যাপ "রেকর্ডিং" করতে পারে, যেমন একটি সাধারণ ভয়েস রেকর্ডার, আবার অন্যান্য অ্যাপ "শুনতে" পারে, যেমন Google Assistant বা অ্যাক্সেসিবিলিটি পরিষেবা যা ভয়েস কমান্ডে সাড়া দেয়।

দুই ক্ষেত্রেই, এই অ্যাপগুলি অডিও ইনপুট পেতে চায়। এই পৃষ্ঠা জুড়ে, কোনও অ্যাপ রেকর্ড করছে বা শুধু শুনছে কিনা তা নির্বিশেষে আমরা "ক্যাপচার" শব্দটি ব্যবহার করি।

দুটি বা তার বেশি অ্যাপ একই সময়ে অডিও ক্যাপচার করতে চাইলে, একই সোর্স থেকে সবকটি অ্যাপে অডিও সিগন্যাল ডেলিভার করার ক্ষেত্রে সমস্যা হতে পারে। এই পৃষ্ঠায় বর্ণনা করা হয়েছে যে কীভাবে Android সিস্টেম অডিও ক্যাপচার করে এমন একাধিক অ্যাপের মধ্যে অডিও ইনপুট শেয়ার করে।

Android 10-এর আগের ভার্সনের আচরণ

Android ১০-এর আগে ইনপুট অডিও স্ট্রিম একবারে শুধুমাত্র একটি অ্যাপই ক্যাপচার করতে পারত। কোনও অ্যাপ আগে থেকেই অডিও রেকর্ড বা শুনলে, আপনার অ্যাপ AudioRecord অবজেক্ট তৈরি করতে পারে, তবে আপনি AudioRecord.startRecording() কল করলে সমস্যা দেখা দেবে এবং রেকর্ডিং শুরু হবে না।

এই নিয়মের একটি ব্যতিক্রম হল, যখন কোনও বিশেষাধিকার প্রাপ্ত অ্যাপ (যেমন Google Assistant বা অ্যাক্সেসিবিলিটি পরিষেবা) android.permission.CAPTURE_AUDIO_HOTWORD অনুমতি পায় এবং HOTWORD ধরনের অডিও সোর্স ব্যবহার করে। এই ক্ষেত্রে অন্য অ্যাপ রেকর্ডিং শুরু করতে পারে। এটি ঘটলে বিশেষ অধিকারপ্রাপ্ত অ্যাপটি বন্ধ হয়ে যায় এবং নতুন অ্যাপটি ইনপুট ক্যাপচার করে।

Android 9-এ আরও একটি পরিবর্তন করা হয়েছে: শুধুমাত্র ফোরগ্রাউন্ডে (বা ফোরগ্রাউন্ড সার্ভিসে) চালানো অ্যাপ অডিও ইনপুট ক্যাপচার করতে পারে। ফোরগ্রাউন্ড সার্ভিস বা ফোরগ্রাউন্ড UI কম্পোনেন্ট ছাড়া কোনও অ্যাপ ক্যাপচার করা শুরু করলে, অ্যাপটি চলতে থাকে কিন্তু কোনও অডিও ক্যাপচার করে না, এমনকি সেই সময় অডিও ক্যাপচার করা একমাত্র অ্যাপ হলেও।

Android 10-এর আচরণ

"Android ১০-এর আগের ভার্সনে "আগে আসলে আগে পাবেন" নীতি মেনে চলা হয়।" কোনও অ্যাপ অডিও ক্যাপচার করা শুরু করলে, অন্য কোনও অ্যাপ অডিও ইনপুট অ্যাক্সেস করতে পারবে না যতক্ষণ না অডিও ক্যাপচার করা অ্যাপটি বন্ধ হচ্ছে।

Android 10-এ একটি প্রায়োরিটি স্কিম আছে যা অ্যাপ চলাকালীন ইনপুট অডিও স্ট্রিম অ্যাপের মধ্যে পরিবর্তন করতে পারে। বেশিরভাগ ক্ষেত্রে, কোনও নতুন অ্যাপ অডিও ইনপুট পেলে, আগে ক্যাপচার করা অ্যাপ চলতে থাকে, কিন্তু কোনও শব্দ পায় না। কিছু ক্ষেত্রে সিস্টেম দুটি অ্যাপেই অডিও ডেলিভার করা চালিয়ে যেতে পারে। বিভিন্ন শেয়ারিংয়ের পরিস্থিতি নিচে ব্যাখ্যা করা হয়েছে।

এই স্কিমটি অডিও ফোকাস যেভাবে একাধিক অ্যাপের অডিও আউটপুট ব্যবহার করার জন্য প্রতিদ্বন্দ্বিতা করে, তার সাথে মিল আছে। তবে, অডিও ফোকাস প্রোগ্রাম্যাটিক অনুরোধের মাধ্যমে ম্যানেজ করা হয় যাতে ফোকাস পাওয়া ও রিলিজ করা যায়, যেখানে এখানে বর্ণিত ইনপুট সুইচিং স্কিম অগ্রাধিকার নীতির উপর ভিত্তি করে তৈরি করা হয়েছে যা নতুন অ্যাপ অডিও ক্যাপচার করা শুরু করলেই অটোমেটিক প্রয়োগ করা হয়।

অডিও ক্যাপচার করার জন্য, Android দুই ধরনের অ্যাপকে আলাদা করে:

  • "সাধারণ" অ্যাপ ব্যবহারকারী ইনস্টল করেন।
  • "প্রিভিলেজড" অ্যাপ ডিভাইসে আগে থেকেই ইনস্টল করা থাকে। এর মধ্যে Google Assistant এবং সব অ্যাক্সেসিবিলিটি পরিষেবা অন্তর্ভুক্ত।

এছাড়াও, কোনও অ্যাপ "গোপনীয়তা-সংবেদনশীল" অডিও সোর্স ব্যবহার করলে, সেটিকে আলাদাভাবে বিবেচনা করা হয়: CAMCORDER অথবা VOICE_COMMUNICATION।

অডিও ইনপুট ব্যবহার ও শেয়ার করার জন্য অগ্রাধিকার সংক্রান্ত নিয়মগুলি নিচে দেওয়া হল:

  • সাধারণ অ্যাপের তুলনায় বিশেষ সুবিধা পাওয়া অ্যাপের অগ্রাধিকার বেশি।
  • ব্যাকগ্রাউন্ড অ্যাপের চেয়ে দৃশ্যমান ফোরগ্রাউন্ড UI সহ অ্যাপের অগ্রাধিকার বেশি।
  • যেসব অ্যাপ গোপনীয়তা-সংবেদনশীল সোর্স থেকে অডিও ক্যাপচার করে, সেগুলির অগ্রাধিকার অন্যান্য অ্যাপের থেকে বেশি।
  • দুটি সাধারণ অ্যাপ কখনই একই সময়ে অডিও ক্যাপচার করতে পারে না।
  • কিছু ক্ষেত্রে, বিশেষ অধিকারপ্রাপ্ত অ্যাপ অন্য অ্যাপের সাথে অডিও ইনপুট শেয়ার করতে পারে।
  • একই অগ্রাধিকারের দুটি ব্যাকগ্রাউন্ড অ্যাপ অডিও ক্যাপচার করলে, যেটি পরে শুরু হয়েছে সেটির অগ্রাধিকার বেশি।

পরিস্থিতি শেয়ার করা

দুটি অ্যাপ অডিও ক্যাপচার করার চেষ্টা করলে, দুটি অ্যাপই ইনপুট সিগন্যাল পেতে পারে অথবা একটি অ্যাপ সাইলেন্স পেতে পারে।

চারটি প্রধান পরিস্থিতি রয়েছে:

  • Assistant + সাধারণ অ্যাপ
  • অ্যাক্সেসিবিলিটি পরিষেবা + সাধারণ অ্যাপ
  • দুটি সাধারণ অ্যাপ
  • ভয়েস কল + সাধারণ অ্যাপ

Assistant + সাধারণ অ্যাপ

Assistant হল একটি বিশেষ সুবিধা প্রাপ্ত অ্যাপ কারণ এটি আগে থেকে ইনস্টল করা থাকে এবং এটি RoleManager.ROLE_ASSISTANT ভূমিকা পালন করে। এই ভূমিকা সহ আগে থেকে ইনস্টল করা অন্য যেকোনও অ্যাপকে একইভাবে বিবেচনা করা হয়।

Android এইসব নিয়ম অনুযায়ী ইনপুট অডিও শেয়ার করে:

  • Assistant অডিও রিসিভ করতে পারে (এটি ফোরগ্রাউন্ড বা ব্যাকগ্রাউন্ডে আছে কিনা তা বিবেচ্য নয়), যদি না গোপনীয়তা-সংবেদনশীল অডিও সোর্স ব্যবহার করে অন্য কোনও অ্যাপ ইতিমধ্যেই ক্যাপচার করছে।

  • Assistant-এর স্ক্রিনের উপরে দৃশ্যমান UI কম্পোনেন্ট না থাকলে, অ্যাপটি অডিও রিসিভ করে।

মনে রাখবেন যে Assistant ব্যাকগ্রাউন্ডে থাকলে এবং অন্য অ্যাপ গোপনীয়তা-সংবেদনশীল অডিও সোর্স থেকে ক্যাপচার না করলে, তবেই দুটি অ্যাপ অডিও রিসিভ করে।

অ্যাক্সেসিবিলিটি পরিষেবা + সাধারণ অ্যাপ

AccessibilityService-এর জন্য কঠোর ঘোষণা প্রয়োজন।

Android এইসব নিয়ম অনুযায়ী ইনপুট অডিও শেয়ার করে:

  • পরিষেবার UI উপরে থাকলে, পরিষেবা ও অ্যাপ দুটিই অডিও ইনপুট পায়। এই আচরণ ভয়েস কমান্ডের মাধ্যমে ভয়েস কল বা ভিডিও ক্যাপচার কন্ট্রোল করার মতো ফাংশনালিটি অফার করে।

  • পরিষেবাটি উপরে না থাকলে, এই কেসটি নিচে উল্লেখ করা সাধারণ দুটি-অ্যাপের কেসের মতো করে বিবেচনা করা হয়।

দুটি সাধারণ অ্যাপ

দুটি অ্যাপ একসাথে ক্যাপচার করলে, শুধুমাত্র একটি অ্যাপ অডিও পায় এবং অন্যটি নীরব থাকে।

Android এইসব নিয়ম অনুযায়ী ইনপুট অডিও শেয়ার করে:

  • কোনও অ্যাপই গোপনীয়তা-সংবেদনশীল না হলে, যে অ্যাপের UI উপরে থাকে সেটি অডিও পায়। কোনও অ্যাপেরই UI না থাকলে, যেটি সবচেয়ে সম্প্রতি ক্যাপচার করা শুরু করেছে সেটি অডিও রিসিভ করে।
  • অ্যাপগুলির মধ্যে একটি যদি গোপনীয়তা-সংবেদনশীল হয়, তাহলে সেটি অডিও রিসিভ করে এবং অন্য অ্যাপটি সাইলেন্স পায়, এমনকি এটির UI উপরে থাকলেও বা আরও সম্প্রতি ক্যাপচার করা শুরু করলেও।
  • দুটি অ্যাপই গোপনীয়তা-সংবেদনশীল হলে, যে অ্যাপটি সবচেয়ে সম্প্রতি ক্যাপচার করা শুরু করেছে সেটি অডিও পায় এবং অন্যটি নীরব থাকে।

ভয়েস কল + সাধারণ অ্যাপ

AudioManager.getMode()-এর মাধ্যমে রিটার্ন করা অডিও মোড MODE_IN_CALL বা MODE_IN_COMMUNICATION হলে, ভয়েস কল অ্যাক্টিভ থাকে।

Android এইসব নিয়ম অনুযায়ী ইনপুট অডিও শেয়ার করে:

Android ১১-এর আচরণ

Android 11 (API লেভেল 30) উপরে বর্ণিত Android 10-এর অগ্রাধিকার স্কিম অনুসরণ করে। এছাড়াও, এটি AudioRecord, MediaRecorder, এবং AAudioStream-এ নতুন পদ্ধতি প্রদান করে যা বেছে নেওয়া ব্যবহারের ক্ষেত্রে নির্বিশেষে, একই সাথে অডিও ক্যাপচার করার ক্ষমতা চালু এবং বন্ধ করে।

নতুন পদ্ধতিগুলি হল:

setPrivacySensitive() true হলে, ক্যাপচার ব্যবহারের কেস ব্যক্তিগত এবং এমনকি একটি বিশেষাধিকারপ্রাপ্ত Assistant একই সাথে ক্যাপচার করতে পারে না। এই সেটিং ডিফল্ট অ্যাকশনকে ওভাররাইড করে যা অডিও সোর্সের উপর নির্ভর করে। যেমন, VOICE_COMMUNICATION ডিফল্ট হিসেবে ব্যক্তিগত কিন্তু UNPROCESSED নয়।

কনফিগারেশনে পরিবর্তন

একাধিক অ্যাপ একসাথে অডিও ক্যাপচার করলে, সেগুলির মধ্যে মাত্র একটি বা দুটি "অ্যাক্টিভ" (অডিও রিসিভ করছে) থাকে; বাকিগুলি মিউট করা থাকে (নীরবতা রিসিভ করছে)। অ্যাক্টিভ অ্যাপ পরিবর্তন হলে, অডিও ফ্রেমওয়ার্ক এইসব নিয়ম অনুযায়ী অডিও পাথ আবার কনফিগার করতে পারে:

  • প্রতিটি অ্যাক্টিভ অ্যাপের জন্য অডিও ইনপুট ডিভাইস পরিবর্তন হতে পারে (যেমন, বিল্ট-ইন মাইক্রোফোন থেকে অ্যাটাচ করা ব্লুটুথ হেডসেট)।
  • সবচেয়ে বেশি অগ্রাধিকার পাওয়া অ্যাক্টিভ অ্যাপের সাথে যুক্ত প্রিপ্রসেসিং চালু করা হয়েছে। অন্য সব প্রিপ্রসেসিং উপেক্ষা করা হয়।

যেহেতু আরও বেশি অগ্রাধিকারপ্রাপ্ত অ্যাপ অ্যাক্টিভ হয়ে গেলে অ্যাক্টিভ অ্যাপ সাইলেন্স হয়ে যেতে পারে, তাই কনফিগারেশন পরিবর্তন হলে বিজ্ঞপ্তি পাওয়ার জন্য আপনি AudioRecord বা MediaRecorder অবজেক্টে AudioManager.AudioRecordingCallback রেজিস্টার করতে পারেন। সম্ভাব্য পরিবর্তনগুলি হতে পারে:

  • ক্যাপচার সাইলেন্সড বা আনসাইলেন্সড
  • ডিভাইস পরিবর্তন করা হয়েছে
  • প্রিপ্রসেসিং পরিবর্তন করা হয়েছে
  • স্ট্রিমের প্রপার্টি পরিবর্তন করা হয়েছে (স্যাম্পলিং রেট, চ্যানেল মাস্ক, স্যাম্পেল ফর্ম্যাট)

ক্যাপচার শুরু করার আগে আপনাকে অবশ্যই AudioRecord.registerAudioRecordingCallback()-এ কল করতে হবে। অ্যাপ অডিও রিসিভ করলে এবং কোনও পরিবর্তন হলে তবেই কলব্যাক এক্সিকিউট করা হয়।

onRecordingConfigChanged() পদ্ধতিটি একটি AudioRecordingConfiguration রিটার্ন করে যার মধ্যে বর্তমান অডিও ক্যাপচার স্টেট থাকে। পরিবর্তন সম্পর্কে জানতে নিম্নলিখিত পদ্ধতিগুলি ব্যবহার করুন:

isClientSilenced()
ক্যাপচার নীতির কারণে ক্লায়েন্টকে ফেরত পাঠানো অডিও বর্তমানে সাইলেন্স করা থাকলে সত্য রিটার্ন করে।
getAudioDevice()
অ্যাক্টিভ অডিও ডিভাইস ফিরিয়ে আনে।
getEffects()
অ্যাক্টিভ প্রিপ্রসেসিং এফেক্ট ফিরিয়ে আনে। মনে রাখবেন যে ক্লায়েন্ট যদি সর্বোচ্চ-অগ্রাধিকারের অ্যাক্টিভ অ্যাপ না হয়, তাহলে অ্যাক্টিভ এফেক্ট getClientEffects()-এর মাধ্যমে ফেরত পাঠানো এফেক্টের মতো নাও হতে পারে।
getFormat()
স্ট্রিমের প্রপার্টি দেখায়। মনে রাখবেন, ক্লায়েন্ট যে আসল অডিও ডেটা পায়, তা সবসময় getClientFormat()-এর পাঠানো প্রয়োজনীয় ফর্ম্যাট অনুযায়ী হয়। ফ্রেমওয়ার্ক অটোমেটিক প্রয়োজনীয় রিস্যাম্পলিং, চ্যানেল ও ফর্ম্যাট কনভার্সন করে। হার্ডওয়্যার ইন্টারফেসে ব্যবহৃত ফর্ম্যাট থেকে ক্লায়েন্টের নির্দিষ্ট করা ফর্ম্যাটে কনভার্ট করা হয়।
AudioRecord.getActiveRecordingConfiguration()
অ্যাক্টিভ রেকর্ডিং কনফিগারেশন দেখায়।

আপনি AudioManager.getActiveRecordingConfigurations() কল করে ডিভাইসে সব অ্যাক্টিভ রেকর্ডিংয়ের সাধারণ ভিউ পেতে পারেন।