שיתוף קלט האודיו

קלט האודיו מגיע בדרך כלל מהמיקרופון המובנה, ממיקרופון חיצוני או מממשק אודיו שמחובר למכשיר. קלט אודיו יכול להגיע גם משיחה בטלפון.

לפעמים שתי אפליקציות או יותר רוצות 'לתפוס' את אותו קלט אודיו. יכול להיות שהם מבצעים משימות שונות. לדוגמה, יכול להיות שאפליקציות מסוימות שמקבלות אודיו יבצעו הקלטה, כמו אפליקציית הקלטה פשוטה, ואפליקציות אחרות יקשיבו, כמו Google Assistant או שירות נגישות שמגיב לפקודות קוליות.

בכל מקרה, האפליקציות האלה רוצות לקבל קלט אודיו. בדף הזה, אנחנו משתמשים במונח 'צילום' בלי קשר לשאלה אם האפליקציה מקליטה או רק מאזינה.

אם שתי אפליקציות או יותר רוצות ללכוד אודיו בו-זמנית, יכולה להיות בעיה בהעברת אות האודיו מאותו מקור לכל האפליקציות. בדף הזה מוסבר איך מערכת Android משתפת קלט אודיו בין כמה אפליקציות שמקליטות אודיו.

התנהגות בגרסאות Android לפני גרסה 10

לפני Android 10, אפשר היה ללכוד את זרם האודיו של הקלט רק על ידי אפליקציה אחת בכל פעם. אם אפליקציה מסוימת כבר הקליטה או האזינה לאודיו, האפליקציה שלכם יכולה ליצור אובייקט AudioRecord, אבל תוצג שגיאה כשתתקשרו אל AudioRecord.startRecording() וההקלטה לא תתחיל.

יוצא מן הכלל היה כשלאפליקציה עם הרשאות מיוחדות (כמו Google Assistant או שירות נגישות) הייתה ההרשאה android.permission.CAPTURE_AUDIO_HOTWORD והיא השתמשה במקור אודיו מסוג HOTWORD. במקרה כזה, אפליקציה אחרת יכולה להתחיל הקלטה. במקרה כזה, האפליקציה עם ההרשאות המיוחדות מסיימת את הפעולה והאפליקציה החדשה מקבלת את הקלט.

שינוי נוסף נוסף ב-Android 9: רק אפליקציות שפועלות בחזית (או שירות בחזית) יכולות ללכוד את קלט האודיו. כשמתחילה הקלטה באפליקציה בלי שירות שפועל בחזית או רכיב ממשק משתמש שפועל בחזית, האפליקציה ממשיכה לפעול אבל מקבלת שקט, גם אם היא האפליקציה היחידה שמקליטה אודיו באותו זמן.

התנהגות ב-Android 10

ההתנהגות לפני Android 10 היא 'כל הקודם זוכה'. אחרי שאפליקציה מתחילה ללכוד אודיו, לאף אפליקציה אחרת אין גישה לקלט האודיו עד שהאפליקציה שלוכדת את האודיו מפסיקה.

ב-Android 10 מוטלת תוכנית עדיפות שיכולה להעביר את זרם האודיו של הקלט בין אפליקציות בזמן שהן פועלות. ברוב המקרים, אם אפליקציה חדשה מקבלת את קלט האודיו, האפליקציה שקלטה קודם ממשיכה לפעול, אבל מקבלת שקט. במקרים מסוימים, המערכת יכולה להמשיך להפעיל אודיו בשתי האפליקציות. בהמשך מפורטים תרחישי השיתוף השונים.

השיטה הזו דומה לדרך שבה מתבצע ניהול של הרשאת אודיו כשכמה אפליקציות מתחרות על השימוש בפלט האודיו. עם זאת, ניהול המיקוד של האודיו מתבצע באמצעות בקשות תוכנה להשגת המיקוד ולשחרורו, בעוד שסכמת המעבר בין מקורות הקלט שמתוארת כאן מבוססת על מדיניות תעדוף שמוחלת באופן אוטומטי בכל פעם שאפליקציה חדשה מתחילה ללכוד אודיו.

לצורך הקלטת אודיו, מערכת Android מבחינה בין שני סוגים של אפליקציות:

  • אפליקציות 'רגילות' מותקנות על ידי המשתמש.
  • אפליקציות עם הרשאות מיוחדות מותקנות מראש במכשיר. הם כוללים את Google Assistant ואת כל שירותי הנגישות.

בנוסף, היחס לאפליקציה שונה אם היא משתמשת במקור אודיו ש "רגיש לפרטיות": CAMCORDER או VOICE_COMMUNICATION.

אלה כללי העדיפות לשימוש בקלט אודיו ולשיתוף שלו:

  • לאפליקציות עם הרשאות יש עדיפות גבוהה יותר מאפליקציות רגילות.
  • לאפליקציות עם ממשקי משתמש גלויים בחזית יש עדיפות גבוהה יותר מאפליקציות ברקע.
  • לאפליקציות שמקליטות אודיו ממקורות שרגישים לפרטיות יש עדיפות גבוהה יותר מאפליקציות שלא מקליטות אודיו.
  • שתי אפליקציות רגילות לא יכולות להקליט אודיו בו-זמנית.
  • במקרים מסוימים, אפליקציה עם הרשאות יכולה לשתף קלט אודיו עם אפליקציה אחרת.
  • אם שתי אפליקציות ברקע עם אותה עדיפות מצלמות אודיו, העדיפות של האפליקציה שהופעלה אחרונה תהיה גבוהה יותר.

תרחישי שיתוף

כששתי אפליקציות מנסות לצלם אודיו, יכול להיות ששתיהן יקבלו את אות הקלט, או שאחת מהן תקבל שקט.

יש ארבעה תרחישים עיקריים:

  • ‫Assistant + אפליקציה רגילה
  • שירות נגישות + אפליקציה רגילה
  • שתי אפליקציות רגילות
  • שיחת טלפון + אפליקציה רגילה

‫Assistant + אפליקציה רגילה

‫Assistant היא אפליקציה עם הרשאות מיוחדות כי היא מותקנת מראש ויש לה את התפקיד RoleManager.ROLE_ASSISTANT. כל אפליקציה אחרת שמותקנת מראש עם התפקיד הזה מקבלת יחס דומה.

מערכת Android משתפת את האודיו שמתקבל מהמיקרופון בהתאם לכללים הבאים:

  • ‫Assistant יכולה לקבל אודיו (לא משנה אם היא בחזית או ברקע), אלא אם אפליקציה אחרת שמשתמשת במקור אודיו שרגיש לפרטיות כבר מבצעת הקלטה.

  • האפליקציה מקבלת אודיו, אלא אם יש לרכיב בממשק המשתמש של Assistant רכיב גלוי בחלק העליון של המסך.

חשוב לדעת: שתי האפליקציות מקבלות אודיו רק כש-Assistant פועלת ברקע, והאפליקציה השנייה לא מקבלת אודיו ממקור אודיו שרגיש לפרטיות.

שירות נגישות + אפליקציה רגילה

AccessibilityService מחייב הצהרה מדויקת.

מערכת Android משתפת את האודיו שמתקבל מהמיקרופון בהתאם לכללים הבאים:

  • אם ממשק המשתמש של השירות מוצג בחלק העליון, גם השירות וגם האפליקציה מקבלים קלט אודיו. ההתנהגות הזו מאפשרת לבצע פעולות כמו שליטה בשיחת טלפון או בצילום וידאו באמצעות פקודות קוליות.

  • אם השירות לא נמצא בחלק העליון, המקרה הזה מטופל כמו המקרה הרגיל של שתי אפליקציות שמתואר בהמשך.

שתי אפליקציות רגילות

כששתי אפליקציות מצלמות בו-זמנית, רק אפליקציה אחת מקבלת אודיו והשנייה מקבלת שקט.

מערכת Android משתפת את האודיו שמתקבל מהמיקרופון בהתאם לכללים הבאים:

  • אם אף אחת מהאפליקציות לא רגישה לפרטיות, האודיו יועבר לאפליקציה עם ממשק המשתמש העליון. אם לאף אחת מהאפליקציות אין ממשק משתמש, האודיו מועבר לאפליקציה שהתחילה את הלכידה לאחרונה.
  • אם אחת מהאפליקציות רגישה לפרטיות, היא מקבלת אודיו והאפליקציה השנייה מקבלת שקט, גם אם יש לה ממשק משתמש בחלק העליון או שהיא התחילה לצלם לאחרונה.
  • אם שתי האפליקציות רגישות לפרטיות, האפליקציה שהתחילה את ההקלטה לאחרונה מקבלת אודיו, והאפליקציה השנייה מקבלת שקט.

שיחת טלפון + אפליקציה רגילה

שיחת טלפון פעילה אם מצב האודיו שמוחזר על ידי AudioManager.getMode() הוא MODE_IN_CALL או MODE_IN_COMMUNICATION.

מערכת Android משתפת את האודיו שמתקבל מהמיקרופון בהתאם לכללים הבאים:

התנהגות ב-Android 11

ב-Android 11 (רמת API 30) נעשה שימוש בסכימת העדיפות של Android 10 שמתוארת למעלה. בנוסף, יש בו שיטות חדשות ב-AudioRecord,‏ MediaRecorder ו-AAudioStream שמאפשרות להפעיל ולהשבית את האפשרות ללכידת אודיו בו-זמנית, ללא קשר לתרחיש השימוש שנבחר.

השיטות החדשות הן:

כש-setPrivacySensitive() הוא true, תרחיש השימוש של הצילום הוא פרטי ואפילו Assistant עם הרשאות לא יכולה לצלם במקביל. ההגדרה הזו מבטלת את התנהגות ברירת המחדל שתלויה במקור האודיו. לדוגמה, VOICE_COMMUNICATION פרטי כברירת מחדל, אבל UNPROCESSED לא.

שינויים בהגדרות

כשכמה אפליקציות מקליטות אודיו בו-זמנית, רק אחת או שתיים מהן 'פעילות' (מקבלות אודיו), והאחרות מושתקות (מקבלות שקט). כשהאפליקציות הפעילות משתנות, יכול להיות שמסגרת האודיו תגדיר מחדש את נתיבי האודיו בהתאם לכללים הבאים:

  • יכול להיות שמכשיר קלט האודיו של כל אפליקציה פעילה ישתנה (לדוגמה, ממיקרופון מובנה לאוזניות Bluetooth מחוברות).
  • העיבוד המקדים שמשויך לאפליקציה הפעילה עם העדיפות הכי גבוהה מופעל. המערכת מתעלמת מכל שאר שלבי העיבוד המקדים.

יכול להיות שאפליקציה פעילה תושבת אם אפליקציה עם עדיפות גבוהה יותר תהפוך לפעילה. לכן, אפשר לרשום AudioManager.AudioRecordingCallback באובייקט AudioRecord או MediaRecorder כדי לקבל התראה כשההגדרה משתנה. השינויים האפשריים הם:

  • הקלטה בהשתקה או ללא השתקה
  • המכשיר השתנה
  • העיבוד המקדים השתנה
  • המאפיינים של הזרם השתנו (תדירות הדגימה, מסכת הערוץ, פורמט הדגימה)

צריך להתקשר אל AudioRecord.registerAudioRecordingCallback() לפני שמתחילים את הלכידה. הקריאה החוזרת מופעלת רק כשהאפליקציה מקבלת אודיו ומתרחש שינוי.

השיטה onRecordingConfigChanged() מחזירה AudioRecordingConfiguration שמכיל את מצב לכידת האודיו הנוכחי. כדי לקבל מידע על השינוי, אפשר להשתמש בשיטות הבאות:

isClientSilenced()
הפונקציה מחזירה את הערך true אם האודיו שמוחזר ללקוח מושתק כרגע בגלל מדיניות הלכידה.
getAudioDevice()
הפונקציה מחזירה את מכשיר האודיו הפעיל.
getEffects()
מחזירה את אפקט העיבוד המקדים הפעיל. שימו לב שהאפקט הפעיל לא בהכרח זהה לאפקטים שמוחזרים על ידי getClientEffects() אם הלקוח הוא לא האפליקציה הפעילה עם העדיפות הכי גבוהה.
getFormat()
מחזירה את מאפייני הזרם. שימו לב: נתוני האודיו בפועל שמתקבלים על ידי הלקוח תמיד תואמים לפורמט הנדרש שמוחזר על ידי getClientFormat(). המסגרת מבצעת באופן אוטומטי את הדגימה מחדש, ההמרה של הערוץ וההמרה של הפורמט מהפורמט שבו נעשה שימוש בממשק החומרה לפורמט שצוין על ידי הלקוח.
AudioRecord.getActiveRecordingConfiguration()
מחזירה את הגדרות התיעוד הפעילות.

אפשר לקבל תצוגה כללית של כל ההקלטות הפעילות במכשיר על ידי קריאה ל-AudioManager.getActiveRecordingConfigurations().