For my APP, one of the important function is to mute the iPhone, but I can't find any available iOS API that I can use to mute the phone(or change the ringer volume level to minimum). Is their a specific API for developer to mute (or change the ringer volume of) the phone, if their is not, is there a indirect way to do this?
I believe you can only mute other application sounds. You need to configure the AVAudioSession category :
AVAudioSession Class Reference : http://goo.gl/rh7CX7 .
Look for which fit the most for your application. You only need to set it once in your code (make sure it's called).
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategorySoloAmbient, error: nil) // AVAudioSessionCategorySoloAmbient is default AVAudioSession.sharedInstance().setActive(true, error: nil)
No.
Applications developed using the official SDK cannot change (and in most cases cannot even access) system-wide settings.
It is possible, but only using private API's. I only went as far as muting the ringer, but you should be able to control the master level as well.
See How to disable iOS System Sounds
Related
I am developing an Xcode/Swift/SwiftUI app for real-time music visualization. I allow the user to push a button to toggle between microphone-input and file-play input (but never both at the same time). My app runs fine on my Mac and on my iPad, but on my iPhone, the speaker audio is only at half-volume (and appears to be only coming from the back speakers) - even when I am in file-play mode. I have traced the problem to one offending line in my code - namely the declaration
let mic = engine.inputNode // where engine = AVAudioEngine()
When I comment-out this line, the iPhone speaker level (for file-play mode) is fine. But when I un-comment it, the iPhone speaker level is barely audible. Even when I wrap this line inside a conditional if(micEnabled){} construct, the sound level is fine at first; but as soon as I select the microphone and then toggle back to file-play, the volume again decreases.
I suspect that iOS detects when a microphone is declared and automatically reduces the speaker volume to avoid audio feedback. This would make sense because nobody wants music playing when they are speaking on a telephone call. But it would also make sense to provide developers a way to override this feature if they want to handle it themselves. In my case, for the microphone-input case, I purposely assign the audio stream a zero-volume after it is tapped and before going to the speaker.
My source code is available here. All of the audio code is inside the MuVis / Shared / AudioManager.swift class.
Can anyone help me to get the file-play mode to work with full volume on my iPhone - while also allowing the user the option to select microphone-input mode?
Many thanks to Rob Napier for pointing me in the right direction for solving my problem.
As a macOS-only developer, I had ignored AVAudioSession (since it caused compiler errors on macOS). When I converted my MuVis app from macOS-only to multiplatform, I simply started a new Xcode project with the appropriate multiplatform settings, and then pasted my existing code into the shared folder. After cleaning up a few errors (mostly calls to NSObject), it magically worked on all Apple platforms - except for the iPhone audio problem described in my question. After a little research and a lot of trial-and-error, I found that my audio-volume problem is solved by inserting the following code into my setupAudio() function:
#if os(iOS)
// For iOS devices, set the audioSession category, mode, and options:
let session = AVAudioSession.sharedInstance() // Get the singleton instance of an AVAudioSession.
do {
if(filePlayEnabled) {
// This is required by iOS to prevent output audio from going only to the iPhone's rear speaker.
try session.setCategory(AVAudioSession.Category.playAndRecord, mode: AVAudioSession.Mode.default, options: [.defaultToSpeaker])
}
else {
try session.setCategory(AVAudioSession.Category.playAndRecord, mode: AVAudioSession.Mode.default, options: [])
}
} catch { print("Failed to set audioSession category.") }
#endif
Again, thank you Rob.
Issue: When the iOS device is on silent, the sound being played from the app is muted.
Upon some digging into the iOS code, I found that out of the 7 "audio session categories" the right one to use for a music app is playback.
Question: How do I set the category in the audio_service package?
Package version: 0.18.0-beta.1
audio_service only manages remote control of your app via notifications, lock screens, etc. The audio session is typically managed by the audio player plugin that you use.
If you use just_audio, it will by default set the required category, but if not, you can manually override the category via the audio_session package. e.g. The code below will configure reasonable defaults for a podcast app, including setting the category to playback:
(await AudioSession.instance).configure(const AudioSessionConfiguration.speech());
This library helped me to solve this problem: https://pub.dev/packages/audio_session
import 'package:audio_session/audio_session.dart';
...
final session = await AudioSession.instance;
await session.configure(AudioSessionConfiguration.music());
...
I'm trying to combine media playback with VoIP feature (via Twilio) for iOS 9 and 8.While an audio stream plays in the background, I connect or disconnect a Voice Conference session which results in a volume jump from value X to value Y. This jump can be heard, as well as observed by a [AVAudioSession sharedInstance].outputVolume value change.I would like to prevent this jump and keep the volume at a constant level, unless the user manually decides to change it.Further investigation showed that while AVAudioSession's category is set to AVAudioSessionCategoryPlayAndRecord, switching between modes[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeDefault error:&error]and[[AVAudioSession sharedInstance] setMode:AVAudioSessionModeVoiceChat error:&error]causes the app to operate in two completely separate volume scales, respectively.i.e there a volume for Mode "Default" and a completely unrelated volume for Mode "Voice Chat".AVAudioSession's documentation seems to omit any mention of volume in relation to mode/category switches and I can't find anything relevant on the interwebs...
Appreciate any help.
When setting your play and record category, pass AVAudioSessionCategoryOptionDefaultToSpeaker as an option:
[[AVAudioSession sharedInstance] AVAudioSessionCategoryPlayAndRecord withOptions: AVAudioSessionCategoryOptionDefaultToSpeaker error:&error];
This overrides the default play-and-record behaviour of switching from the speaker to the much quieter receiver. The reason for this being that play-and-record was designed for telephony, where you'd be holding the phone to year ear & presumably wouldn't want to have your hearing damaged by loud sounds.
Megan from Twilio here.
I'm not most familiar with the iOS SDK but you should be able to control connection audio from TCDevice parameters incomingSoundEnabled, outgoingSoundEnabled, and disconnectSoundEnabled as documented here.
Otherwise, I would suggest looking at the sharedInstance properties of AVAudioSession that the Twilio SDK calls upon as demonstrated in this post:
setCategory:error:
setActive:error:
overrideOutputAudioPort:error:
Please let me know if this helps.
This is for a jailbreak tweak, so it doesn't matter that I need to use private frameworks.
How can you change the volume of the device and how can you turn off silent mode?
If there is an easier way to play a sound at a specific volume and will always play regardless of silent mode is on or off, this will actually be better.
You can change the volume using the VolumeControl class:
static void setVolume(float volume) {
VolumeControl *volumeControl = [VolumeControl sharedVolumeControl];
[volumeControl setMediaVolume:volume];
}
I don't know how to toggle the silent switch yet.
I haven't tried this out, so no guarantees regarding it functioning properly ...
but just by looking at the dumped header, I would try this for turning silent mode on or off:
VolumeControl *volumeControl = [VolumeControl sharedVolumeControl];
[volumeControl toggleMute];
let me know if it works for you ...
I'm using AudioSessionSetActive(true) and AudioSessionSetActive(false) for setting the AudioSession to true or false in my iOS app.
At any point, I want to find out whether the session is active or not. Is there a way to do that?
Just ran into the same thing! There is no AudioSessionProperty key for querying whether or not the session is active. I believe this is another one of those set it and forget it deals where Apple believes apps should behave a certain way. Eg. most apps shouldn't need to know the state they should just set it as they need audio and kill it unconditionally as they are done playing audio. Of course this only works for the 90%. Apologies as this is not the best answer, I'm only reporting my suspicions. Maybe others have a better idea?
You can check if any audio is playing as it was launched by another app by inspecting the otherAudioPlaying property when you launch the app.
For internal tracking perhaps you could use a boolean when you do the AudioSessionSetActive(BOOL setActive) call. Though use of BOOL does not sound as a wonderful approach. Given my current knowledge I couldnt find any other way of determining if the AudioSession is active or not.
You can use this api to find out if audio session is active in iOS.
BOOL isPlaying = [[AVAudioSession sharedInstance] isOtherAudioPlaying];