diff --git a/README.md b/README.md index 9d2bca0..f9ba2a1 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,24 @@ If you wish to connect to non-HTTPS URLS, add the following to your `Info.plist` ``` +By default, iOS will mute your app's audio when your phone is switched to +silent mode. Depending on the requirements of your app, you can change the +default audio session category using `AudioPlayer.setIosCategory`. For example, +if you are writing a media app, Apple recommends that you set the category to +`AVAudioSessionCategoryPlayback`, which you can achieve by adding the following +code to your app's initialisation: + +```dart +AudioPlayer.setIosCategory(IosCategory.playback); +``` + +Note: If your app uses a number of different audio plugins in combination, e.g. +for audio recording, or text to speech, or background audio, it is possible +that those plugins may internally override the setting you choose here. You may +consider asking the developer of each other plugin you use to provide a similar +method so that you can configure the same audio session category universally +across all plugins you use. + ### MacOS To allow your MacOS application to access audio files on the Internet, add the following to your `DebugProfile.entitlements` and `Release.entitlements` files: diff --git a/lib/just_audio.dart b/lib/just_audio.dart index 5c81b6b..d43baab 100644 --- a/lib/just_audio.dart +++ b/lib/just_audio.dart @@ -50,18 +50,22 @@ class AudioPlayer { return MethodChannel('com.ryanheise.just_audio.methods.$id'); } - /// Configure the audio session category on iOS. Has no effect on Android. + /// Configure the audio session category on iOS. This method should be called + /// before playing any audio. It has no effect on Android or Flutter for Web. /// /// Note that the default category on iOS is [IosCategory.soloAmbient], but - /// for a typical media app, you will probably want to change this to - /// [IosCategory.playback]. If you wish to override the default, call this - /// method before playing any audio. + /// for a typical media app, Apple recommends setting this to + /// [IosCategory.playback]. If you don't call this method, `just_audio` will + /// respect any prior category that was already set on your app's audio + /// session and will leave it alone. If it hasn't been previously set, this + /// will be [IosCategory.soloAmbient]. But if another audio plugin in your + /// app has configured a particular category, that will also be left alone. /// /// Note: If you use other audio plugins in conjunction with this one, it is - /// possible that the other audio plugin may override the setting you choose - /// here. (You may consider asking the developer of each other plugin you use - /// to provide a similar method so that you can configure the same category - /// universally.) + /// possible that each of those audio plugins may override the setting you + /// choose here. (You may consider asking the developers of the other plugins + /// to provide similar configurability so that you have complete control over + /// setting the overall category that you want for your app.) static Future setIosCategory(IosCategory category) async { await _mainChannel.invokeMethod('setIosCategory', category.index); } @@ -147,16 +151,25 @@ class AudioPlayer { url: data[5][1][4], isPublic: data[5][1][5])), )); - _eventChannelStreamSubscription = - _eventChannelStream.listen(_playbackEventSubject.add, onError: _playbackEventSubject.addError); - _playbackStateSubject - .addStream(playbackEventStream.map((state) => state.state).distinct().handleError((err,stack){ /* noop */ })); - _bufferingSubject.addStream( - playbackEventStream.map((state) => state.buffering).distinct().handleError((err,stack){ /* noop */ })); - _bufferedPositionSubject.addStream( - playbackEventStream.map((state) => state.bufferedPosition).distinct().handleError((err,stack){ /* noop */ })); - _icyMetadataSubject.addStream( - playbackEventStream.map((state) => state.icyMetadata).distinct().handleError((err,stack){ /* noop */ })); + _eventChannelStreamSubscription = _eventChannelStream.listen( + _playbackEventSubject.add, + onError: _playbackEventSubject.addError); + _playbackStateSubject.addStream(playbackEventStream + .map((state) => state.state) + .distinct() + .handleError((err, stack) {/* noop */})); + _bufferingSubject.addStream(playbackEventStream + .map((state) => state.buffering) + .distinct() + .handleError((err, stack) {/* noop */})); + _bufferedPositionSubject.addStream(playbackEventStream + .map((state) => state.bufferedPosition) + .distinct() + .handleError((err, stack) {/* noop */})); + _icyMetadataSubject.addStream(playbackEventStream + .map((state) => state.icyMetadata) + .distinct() + .handleError((err, stack) {/* noop */})); _fullPlaybackStateSubject.addStream(Rx.combineLatest3( playbackStateStream, diff --git a/lib/just_audio_web.dart b/lib/just_audio_web.dart index 0fca151..5a4df36 100644 --- a/lib/just_audio_web.dart +++ b/lib/just_audio_web.dart @@ -27,6 +27,8 @@ class JustAudioPlugin { final String id = call.arguments[0]; new Html5AudioPlayer(id: id, registrar: registrar); return null; + case 'setIosCategory': + return null; default: throw PlatformException(code: 'Unimplemented'); }