패키지, 저장소 및 앱 카테고리 검색

패키지 상세v0.2.4

audio_session

앱의 iOS 오디오 세션 카테고리와 Android 오디오 속성을 설정하고 앱의 오디오 포커스, 믹싱 및 덱킹 동작을 관리합니다.

AndroidiOSWebmacOS
30일 다운로드
184만
좋아요
367
Pub 점수
150

패키지 설치

flutter pub add audio_session

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

audio_session 패키지는 Android, iOS, Web, macOS에서 Flutter 앱을 위한 크로스플랫폼 오디오 구성 기능을 제공합니다. 오디오 세션 카테고리, 속성 및 포커스를 관리하여 믹싱, 덱킹, 중단 처리 등의 적절한 오디오 동작을 보장합니다. 개발자는 앱이 다른 오디오 소스와 어떻게 상호작용하는지 제어할 수 있으며, 음악, 팟캐스트, 음성 애플리케이션에서 사용자 경험을 향상시킬 수 있습니다. 이 패키지는 통합된 API를 통해 플랫폼별 오디오 설정을 단순화합니다.

사용 사례

  • 음악 재생 앱
  • 팟캐스트 플레이어
  • 음성 녹음 도구
  • 오디오 메시징 앱
  • 백그라운드 오디오 처리

주요 기능

  • 크로스 플랫폼 오디오 세션 관리
  • 오디오 포커스 처리
  • 덕킹 및 믹싱 지원
  • 플랫폼별 구성
  • Flutter와의 간편한 통합

적합한 대상

  • 백그라운드 오디오가 필요한 앱
  • 오디오 포커스가 필요한 미디어 플레이어
  • 다중 오디오 스트림을 가진 애플리케이션
  • iOS 및 안드로이드를 대상으로 하는 개발자
  • 다양한 플랫폼 간에 일관된 오디오 동작이 필요한 프로젝트

고려 사항

  • 플랫폼별 권한이 필요합니다
  • 제한된 웹 오디오 기능
  • 복잡한 오디오 워크플로우를 위해 추가 구성이 필요할 수 있습니다
  • 저수준 오디오 처리에 적합하지 않습니다
  • 오디오 포커스 API의 올바른 사용에 따라 달라집니다

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

audio_session

This plugin informs the operating system of the nature of your audio app (e.g. game, media player, assistant, etc.) and how your app will handle and initiate audio interruptions (e.g. phone call interruptions). It also provides access to all of the capabilities of AVAudioSession on iOS and AudioManager on Android, providing for discoverability and configuration of audio hardware.

Audio apps often have unique requirements. For example, when a navigator app speaks driving instructions, a music player should duck its audio while a podcast player should pause its audio. Depending on which one of these three apps you are building, you will need to configure your app's audio settings and callbacks to appropriately handle these interactions.

This plugin can be used both by app developers, to initialise appropriate audio settings for their app, and by plugin authors, to provide easy access to low level features of iOS's AVAudioSession and Android's AudioManager in Dart.

For app developers

Configuring the audio session

Configure your app's audio session with reasonable defaults for playing music:

final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration.music());

Configure your app's audio session with reasonable defaults for playing podcasts/audiobooks:

final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration.speech());

Or use a custom configuration:

final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration(
  avAudioSessionCategory: AVAudioSessionCategory.playAndRecord,
  avAudioSessionCategoryOptions: AVAudioSessionCategoryOptions.allowBluetooth,
  avAudioSessionMode: AVAudioSessionMode.spokenAudio,
  avAudioSessionRouteSharingPolicy: AVAudioSessionRouteSharingPolicy.defaultPolicy,
  avAudioSessionSetActiveOptions: AVAudioSessionSetActiveOptions.none,
  androidAudioAttributes: const AndroidAudioAttributes(
    contentType: AndroidAudioContentType.speech,
    flags: AndroidAudioFlags.none,
    usage: AndroidAudioUsage.voiceCommunication,
  ),
  androidAudioFocusGainType: AndroidAudioFocusGainType.gain,
  androidWillPauseWhenDucked: true,
));

Note that iOS (and hence this plugin) provides a single audio session to your app which is shared by all of the different audio plugins you use. If your app uses multiple audio plugins, e.g. any combination of audio recording, text to speech, background audio, audio playing, or speech recognition, then it is possible that those plugins may internally overwrite each other's choice of these global system audio settings, including the ones you set via this plugin. Therefore, it is recommended that you apply your own preferred configuration using audio_session after all other audio plugins have loaded. You may consider asking the developer of each audio plugin you use to provide an option to not overwrite these global settings and allow them be managed externally.

Activating the audio session

Each time you invoke an audio plugin to play audio, that plugin will activate your app's shared audio session to inform the operating system that your app is now actively playing audio. Depending on the configuration set above, this will also inform other audio apps to either stop playing audio, or possibly continue playing at a lower volume (i.e. ducking). You normally do not need to activate the audio session yourself, however if the audio plugin you use does not activate the audio session, you can activate it yourself:

// Activate the audio session before playing audio.
if (await session.setActive(true)) {
  // Now play audio.
} else {
  // The request was denied and the app should not play audio
}
Reacting to audio interruptions

When another app (e.g. navigator, phone app, music player) activates its audio session, it similarly may ask your app to pause or duck its audio. Once again, the particular audio plugin you use may automatically pause or duck audio when requested. However, if it does not (or if you have switched off this behaviour), then you can respond to these events yourself by listening to session.interruptionEventStream. Similarly, if the audio plugin doesn't handle unplugged headphone events, you can respond to these yourself by listening to session.becomingNoisyEventStream.

Observe interruptions to the audio session:

session.interruptionEventStream.listen((event) {
  if (event.begin) {
    switch (event.type) {
      case AudioInterruptionType.duck:
        // Another app started playing audio and we should duck.
        break;
      case AudioInterruptionType.pause:
      case AudioInterruptionType.unknown:
        // Another app started playing audio and we should pause.
        break;
    }
  } else {
    switch (event.type) {
      case AudioInterruptionType.duck:
        // The interruption ended and we should unduck.
        break;
      case AudioInterruptionType.pause:
        // The interruption ended and we should resume.
      case AudioInterruptionType.unknown:
        // The interruption ended but we should not resume.
        break;
    }
  }
});

Observe unplugged headphones:

session.becomingNoisyEventStream.listen((_) {
  // The user unplugged the headphones, so we should pause or lower the volume.
});

Observe when devices are added or removed:

session.devicesChangedEventStream.listen((event) {
  print('Devices added:   ${event.devicesAdded}');
  print('Devices removed: ${event.devicesRemoved}');
});

For plugin authors

This plugin provides easy access to the iOS AVAudioSession and Android AudioManager APIs from Dart, and provides a unified API to activate the audio session for both platforms:

// Activate the audio session before playing or recording audio.
if (await session.setActive(true)) {
  // Now play or record audio.
} else {
  // The request was denied and the app should not play audio
  // e.g. a phonecall is in progress.
}

On iOS this calls AVAudioSession.setActive and on Android this calls AudioManager.requestAudioFocus. In addition to calling the lower level APIs, it also registers callbacks and forwards events to Dart via the streams AudioSession.interruptionEventStream and AudioSession.becomingNoisyEventStream. This allows both plugins and apps to interface with a shared instance of the audio focus request and audio session without conflict.

If a plugin can handle audio interruptions (i.e. by listening to the interruptionEventStream and automatically pausing audio), it is preferable to provide an option to turn this feature on or off, since some apps may have specialised requirements. e.g.:

player = AudioPlayer(handleInterruptions: false);

Note that iOS and Android have fundamentally different ways to set the audio attributes and categories: for iOS it is app-wide, while for Android it is per player or audio track. As such, audioSession.configure() can and does set the app-wide configuration on iOS immediately, while on Android these app-wide settings are stored within audio_session and can be obtained by individual audio plugins via a Stream. The following code shows how a player plugin can listen for changes to the Android AudioAttributes and apply them:

audioSession.configurationStream
    .map((conf) => conf?.androidAudioAttributes)
    .distinct()
    .listen((attributes) {
  // apply the attributes to this Android audio track
  _channel.invokeMethod("setAudioAttributes", attributes.toJson());
});

All numeric values encoded in AndroidAudioAttributes.toJson() correspond exactly to the Android platform constants.

configurationStream will always emit the latest configuration as the first event upon subscribing, and so the above code will handle both the initial configuration choice and subsequent changes to it throughout the life of the app.

iOS setup

If you wish to use any of the APIs that access the microphone (getRecordPermission, requestRecordPermission), add this key to your Info.plist:

<key>NSMicrophoneUsageDescription</key>
<string>... explain why the app uses the microphone here ...</string>

Next, pass a build option to this plugin to enable the microphone code in your build. This can be done with either CocoaPods or SwiftPM builds.

CocoaPods

Edit your ios/Podfile as follows:

post_install do |installer|
  installer.pods_project.targets.each do |target|
    flutter_additional_ios_build_settings(target)
    
    # ADD THE NEXT SECTION
    target.build_configurations.each do |config|
      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
        '$(inherited)',
        'AUDIO_SESSION_MICROPHONE=1'
      ]
    end
    
  end
end
SwiftPM

Run flutter clean to force SwiftPM to pick up your new settings:

flutter clean

Export the environment variable AUDIO_SESSION_MICROPHONE=1 before running your build command. E.g. Using the bash command line:

AUDIO_SESSION_MICROPHONE=1 flutter run

Note: flutter clean is needed whenever the value of AUDIO_SESSION_MICROPHONE changes, or whenever you switch between different projects that use audio_session with different AUDIO_SESSION_MICROPHONE values.

카테고리

의존성

의존성 목록 2 개

소스 저장소

이 패키지를 사용하는 프로젝트