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

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

לפעמים שתי אפליקציות או יותר רוצות 'ללכוד' את אותו קלט אודיו. יכול להיות שהם מבצעים משימות שונות. לדוגמה, אפליקציות מסוימות שמקבלות אודיו עשויות להיות במצב 'הקלטה', כמו מקליט קול פשוט, ואילו אפליקציות אחרות עשויות להיות במצב 'האזנה', כמו 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()
Returns true if the audio returned to the client is currently being silenced due to the capture policy.
getAudioDevice()
מחזירה את מכשיר האודיו הפעיל.
getEffects()
מחזירה את אפקט העיבוד המקדים הפעיל. שימו לב: יכול להיות שהאפקט הפעיל לא יהיה זהה לאפקטים שמוחזרים על ידי getClientEffects() אם הלקוח הוא לא האפליקציה הפעילה עם העדיפות הכי גבוהה.
getFormat()
מחזירה את מאפייני הזרם. שימו לב שנתוני האודיו בפועל שמתקבלים על ידי הלקוח תמיד תואמים לפורמט הנדרש שמוחזר על ידי getClientFormat(). המסגרת מבצעת באופן אוטומטי את הדגימה מחדש, ההמרה של הערוץ וההמרה של הפורמט מהפורמט שבו נעשה שימוש בממשק החומרה לפורמט שצוין על ידי הלקוח.
AudioRecord.getActiveRecordingConfiguration().
מחזירה את הגדרות התיעוד הפעילות.

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