Chia sẻ đầu vào âm thanh

Đầu vào âm thanh thường đến từ micrô tích hợp, micrô bên ngoài hoặc một micrô giao diện âm thanh gắn với thiết bị. Thiết bị đầu vào âm thanh cũng có thể đến từ một cuộc trò chuyện qua điện thoại.

Đôi khi, có thể hai hoặc nhiều ứng dụng cùng muốn "chụp" cùng một lúc cùng một đầu vào âm thanh. Các vị trí này có thể đang thực hiện các nhiệm vụ khác nhau. Ví dụ: một số ứng dụng nhận được âm thanh có thể là "bản ghi âm" giống như một trình ghi âm giọng nói đơn giản, trong khi các ứng dụng khác có thể "lắng nghe", như Trợ lý Google hoặc dịch vụ hỗ trợ tiếp cận phản hồi lệnh thoại.

Trong cả hai trường hợp, các ứng dụng này đều muốn nhận đầu vào âm thanh. Trên toàn bộ trang này, chúng tôi sử dụng thuật ngữ "chụp ảnh" bất kể đang ghi âm hay chỉ nghe.

Nếu hai hoặc nhiều ứng dụng muốn ghi âm cùng lúc, thì có thể đã xảy ra sự cố truyền tín hiệu âm thanh từ cùng một nguồn đến tất cả thiết bị. Trang này mô tả cách hệ thống Android chia sẻ đầu vào âm thanh giữa nhiều ứng dụng ghi âm.

Cách hoạt động trước Android 10

Trước Android 10, chỉ một ứng dụng mới có thể ghi lại luồng âm thanh đầu vào tại bất cứ lúc nào. Nếu một ứng dụng nào đó đang ghi âm hoặc nghe âm thanh, thì ứng dụng đó có thể tạo một đối tượng AudioRecord nhưng hệ thống sẽ trả về lỗi khi bạn gọi AudioRecord.startRecording() và quá trình ghi lại không bắt đầu.

Một ngoại lệ đối với quy tắc này là khi một ứng dụng có đặc quyền (như Trợ lý Google hoặc dịch vụ hỗ trợ tiếp cận) đã có quyền android.permission.CAPTURE_AUDIO_HOTWORD và đã sử dụng nguồn âm thanh thuộc loại HOTWORD. Trong trường hợp này, một ứng dụng khác có thể bắt đầu ghi. Khi việc đó xảy ra, ứng dụng có đặc quyền đã kết thúc và ứng dụng mới đã thu thập dữ liệu đầu vào.

Một thay đổi nữa đã được thêm vào Android 9: chỉ những ứng dụng chạy trên nền trước (hoặc dịch vụ trên nền trước) có thể thu được đầu vào âm thanh. Khi một ứng dụng không có dịch vụ trên nền trước hoặc thành phần giao diện người dùng trên nền trước đã bắt đầu chụp, ứng dụng tiếp tục chạy nhưng bị im lặng, ngay cả khi đó là ứng dụng duy nhất chụp âm thanh tại thời điểm đó.

Hành vi của Android 10

Hành vi trước Android 10 là "ưu tiên người đến trước". Sau khi một ứng dụng bắt đầu ghi âm, không ứng dụng nào khác có thể truy cập vào đầu vào âm thanh cho đến khi ứng dụng đang ghi âm dừng lại.

Android 10 áp dụng một lược đồ ưu tiên có thể chuyển đổi luồng âm thanh đầu vào giữa các ứng dụng trong khi chúng đang chạy. Trong hầu hết các trường hợp, nếu một ứng dụng mới có được đầu vào âm thanh, ứng dụng đã chụp trước đó sẽ tiếp tục chạy nhưng bị tắt tiếng. Trong một số trường hợp hệ thống có thể tiếp tục phân phối âm thanh đến cả hai ứng dụng. Các lựa chọn trường hợp chia sẻ được giải thích bên dưới.

Giao thức này tương tự như cách quyền phát âm thanh xử lý nhiều ứng dụng cạnh tranh về việc sử dụng đầu ra âm thanh. Tuy nhiên, quyền phát âm thanh được quản lý bằng các yêu cầu có lập trình để lấy và giải phóng tiêu điểm, trong khi việc chuyển đổi đầu vào lược đồ được mô tả ở đây dựa trên chính sách ưu tiên được áp dụng tự động bất cứ khi nào một ứng dụng mới bắt đầu thu âm.

Để ghi âm, Android phân biệt hai loại ứng dụng:

  • "Thông thường" ứng dụng do người dùng cài đặt.
  • "Đặc quyền" được cài đặt sẵn trên thiết bị. Các dịch vụ này bao gồm Trợ lý Google và tất cả các dịch vụ hỗ trợ tiếp cận.

Ngoài ra, ứng dụng được xử lý theo cách khác nếu trang web sử dụng cụm từ "nhạy cảm về quyền riêng tư" nguồn âm thanh: CAMCORDER hoặc VOICE_COMMUNICATION.

Sau đây là quy tắc ưu tiên để sử dụng và chia sẻ âm thanh đầu vào:

  • Những ứng dụng ưu tiên có mức độ ưu tiên cao hơn những ứng dụng thông thường.
  • Ứng dụng có giao diện người dùng hiển thị trên nền trước có mức độ ưu tiên cao hơn ứng dụng nền.
  • Các ứng dụng ghi âm từ một nguồn nhạy cảm về quyền riêng tư có mức độ ưu tiên cao hơn so với các ứng dụng khác không làm như vậy.
  • Hai ứng dụng thông thường không bao giờ thu được âm thanh cùng một lúc.
  • Trong một số trường hợp, một ứng dụng đặc quyền có thể chia sẻ đầu vào âm thanh với một ứng dụng khác.
  • Nếu 2 ứng dụng trong nền có cùng mức độ ưu tiên đang ghi âm, thì ứng dụng cuối cùng bắt đầu có mức độ ưu tiên cao hơn.

Tình huống chia sẻ

Khi hai ứng dụng đang cố gắng ghi âm, cả hai thiết bị đều có thể nhận được tín hiệu đầu vào hoặc một trong hai thiết bị có thể nhận được tắt tiếng.

Có bốn tình huống chính:

  • Trợ lý + ứng dụng thông thường
  • Dịch vụ hỗ trợ tiếp cận + ứng dụng thông thường
  • Hai ứng dụng thông thường
  • Cuộc gọi thoại + ứng dụng thông thường

Trợ lý + ứng dụng thông thường

Trợ lý là một ứng dụng đặc quyền vì được cài đặt sẵn và chứa vai trò RoleManager.ROLE_ASSISTANT. Mọi ứng dụng cài đặt sẵn khác có vai trò này đều được xử lý tương tự.

Android chia sẻ âm thanh đầu vào theo các quy tắc sau:

  • Trợ lý có thể nhận âm thanh (bất kể ở chế độ nền trước hay nền) trừ phi một ứng dụng khác dùng nguồn âm thanh nhạy cảm về quyền riêng tư đang ghi âm.

  • Ứng dụng sẽ nhận được âm thanh trừ phi Trợ lý có giao diện người dùng hiển thị rõ ràng thành phần ở đầu màn hình.

Xin lưu ý rằng cả hai ứng dụng đều chỉ nhận được âm thanh khi Trợ lý ở chế độ nền còn ứng dụng còn lại không thu âm từ một nguồn âm thanh có giới hạn về quyền riêng tư.

Dịch vụ hỗ trợ tiếp cận + ứng dụng thông thường

AccessibilityService bạn phải có một nội dung khai báo nghiêm ngặt.

Android chia sẻ âm thanh đầu vào theo các quy tắc sau:

  • Nếu giao diện người dùng của dịch vụ nằm ở trên cùng, thì cả dịch vụ và ứng dụng đều nhận được đầu vào âm thanh. Hành vi này cung cấp chức năng như điều khiển cuộc gọi thoại hoặc video chụp bằng lệnh thoại.

  • Nếu dịch vụ không ở trên cùng, trường hợp này được xử lý giống như trường hợp hai ứng dụng thông thường bên dưới.

Hai ứng dụng thông thường

Khi 2 ứng dụng chụp đồng thời, chỉ một ứng dụng nhận được âm thanh còn ứng dụng còn lại chuyển sang chế độ im lặng.

Android chia sẻ âm thanh đầu vào theo các quy tắc sau:

  • Nếu không có ứng dụng nào nhạy cảm về quyền riêng tư, ứng dụng có giao diện người dùng ở trên cùng sẽ nhận được âm thanh. Nếu cả hai ứng dụng đều không có giao diện người dùng, thì ứng dụng bắt đầu ghi âm gần đây nhất sẽ nhận được âm thanh.
  • Nếu một trong các ứng dụng nhạy cảm về quyền riêng tư, ứng dụng đó sẽ nhận được âm thanh và ứng dụng khác bị tắt tiếng ngay cả khi có giao diện người dùng ở trên cùng hoặc đã bắt đầu chụp gần đây hơn.
  • Nếu cả hai ứng dụng đều nhạy cảm về quyền riêng tư, thì là ứng dụng bắt đầu chụp ảnh nhiều nhất gần đây nhận được âm thanh và quảng cáo khác chuyển sang chế độ im lặng.

Cuộc gọi thoại + ứng dụng thông thường

Cuộc gọi thoại sẽ hoạt động nếu chế độ âm thanh được AudioManager.getMode()MODE_IN_CALL hoặc MODE_IN_COMMUNICATION.

Android chia sẻ âm thanh đầu vào theo các quy tắc sau:

Hành vi của Android 11

Android 11 (API cấp 30) tuân thủ lược đồ ưu tiên của Android 10 được mô tả ở trên. API này cũng cung cấp các phương thức mới trong AudioRecord, MediaRecorderAAudioStream bật và tắt tính năng ghi âm đồng thời, bất kể trường hợp sử dụng đã chọn là gì.

Các phương thức mới là:

Khi setPrivacySensitive()true, trường hợp sử dụng chụp ảnh sẽ ở chế độ riêng tư và một Trợ lý có đặc quyền không thể chụp đồng thời. Cài đặt này ghi đè hành vi mặc định phụ thuộc vào nguồn âm thanh. Ví dụ: VOICE_COMMUNICATION là riêng tư theo mặc định nhưng UNPROCESSED thì không.

Các thay đổi về cấu hình

Khi có nhiều ứng dụng ghi âm cùng lúc, chỉ 1 hoặc 2 ứng dụng đó được tải "đang hoạt động" (nhận âm thanh); những người khác bị tắt tiếng (nhận được sự im lặng). Khi các ứng dụng đang hoạt động thay đổi, khung âm thanh có thể định cấu hình lại đường dẫn âm thanh theo các quy tắc sau:

  • Thiết bị đầu vào âm thanh cho mỗi ứng dụng đang hoạt động có thể thay đổi (ví dụ: từ micrô tích hợp với tai nghe Bluetooth đi kèm).
  • Quy trình xử lý trước liên kết với ứng dụng đang hoạt động có mức độ ưu tiên cao nhất sẽ được bật. Tất cả bỏ qua bước xử lý trước khác.

Do một ứng dụng đang hoạt động có thể bị tắt tiếng khi một ứng dụng có mức độ ưu tiên cao hơn được kích hoạt, bạn có thể đăng ký AudioManager.AudioRecordCallback vào AudioRecord hoặc MediaRecorder được thông báo khi cấu hình thay đổi. Những thay đổi có thể xảy ra là:

  • Chụp ở chế độ im lặng hoặc không tắt tiếng
  • Đã thay đổi thiết bị
  • Đã thay đổi quá trình xử lý trước
  • Thuộc tính luồng đã thay đổi (tốc độ lấy mẫu, mặt nạ kênh, định dạng mẫu)

Bạn phải gọi AudioRecord.registerAudioRecordingCallback() trước khi bắt đầu chụp. Lệnh gọi lại chỉ được thực thi khi ứng dụng đang nhận âm thanh và có thay đổi xảy ra.

Phương thức onRecordingConfigChanged() sẽ trả về một AudioRecordingConfiguration chứa trạng thái ghi âm hiện tại. Sử dụng để tìm hiểu về thay đổi:

isClientSilenced()
Trả về giá trị true nếu âm thanh trả về máy khách hiện đang bị tắt tiếng do chính sách ghi lại.
getAudioDevice()
Trả về thiết bị âm thanh đang hoạt động.
getEffects()
Trả về hiệu ứng tiền xử lý đang hoạt động. Lưu ý: hiệu ứng đang hoạt động có thể không giống với hiệu ứng do getClientEffects() trả về nếu ứng dụng không phải là ứng dụng đang hoạt động có mức độ ưu tiên cao nhất.
getFormat()
Trả về thuộc tính luồng. Lưu ý rằng dữ liệu âm thanh thực tế mà ứng dụng nhận được luôn tuân theo định dạng bắt buộc do getClientFormat() trả về. Khung này sẽ tự động thực hiện việc lấy mẫu lại, chuyển đổi kênh và định dạng cần thiết từ định dạng dùng ở giao diện phần cứng sang định dạng do máy khách chỉ định.
AudioRecord.getActiveRecordingConfiguration().
Trả về cấu hình bản ghi đang hoạt động.

Bạn có thể xem chung tất cả các bản ghi âm đang hoạt động trên thiết bị bằng cách gọi điện AudioManager.getActiveRecordingConfigurations().