I have an iPhone app that plays tracks through an AVPlayer, and separately want button click sounds. I first used AVAudioPlayer for the clicks and this works fine except I don't want the 'Play' icon in the status bar to appear every time the user clicks a button and the click sample is played.
I turned my attention to System Sounds, which I read has limitations in that you cannot directly set the volume. However, I am seeing strange volume behaviour which makes me wonder if I can:
NSURL *clickURL = [[NSBundle mainBundle] URLForResource:#"click" withExtension:#"wav"];
SystemSoundID clickSoundID;
AudioServicesCreateSystemSoundID((CFURLRef)clickURL, &clickSoundID);
AudioServicesPlaySystemSound(clickSoundID);
If I click a button before playing a track the volume is set to the phone ringer volume. However, after playing a track using AVPlayer the volume is set to the player volume (as I would like it to be).
Any ideas how I can make the System Sound sample take on the app volume level regardless of if AVPlayer has been in action first? Alternatively is there a way to disable play icon notifications in the status bar?
You need to set the correct AVAudioSession. There is one called solo ambient which will not do the play button I think. Can't be more detailed at the moment, because I'm on my phone. (will fix later with a more fuller description)
Related
I can't seem to make iOS show the correct play / pause button in the remote audio controls. I do receive the remote control events and set all values of the nowPlayingInfo dictionary.
Everything works fine and I even see a cover photo on the lock screen. Except the pause/play button. It always looks like pause even if my AVAudioPlayer is playing. It sends a pause event regardless of playback state.
How can I notify iOS that AVAudioPlayer is paused and that it should now show a play button in the remote control buttons bar?
Make sure that you're setting the MPNowPlayingInfoPropertyPlaybackRate property. 0.0f to indicate paused, 1.0f to indicate playing. You'll also need to set the MPNowPlayingInfoPropertyElapsedPlaybackTime when you change these values.
Here is example code where updateMetadata is a function that applies those changes to the MPNowPlayingInfoCenter.nowPlayingInfo dictionary. This would indicate to the center that the player is paused.
[self updateMetadata:[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithDouble:audioFile.player.currentTime],
MPNowPlayingInfoPropertyElapsedPlaybackTime,
[NSNumber numberWithFloat:0.0f],
MPNowPlayingInfoPropertyPlaybackRate,
nil]];
I had this problem today: I found that the fact that I was recording audio as well as playing it caused the button to show the pause symbol.
When I stopped the AVAudioRecorder from recording the pause button became a play button.
Quite often, the problem is simply the iPhone Simulator. As soon as you are using the play() function of your AVAudioPlayer instance, the remote control bar is supposed to toggle pause/play automatically. If you run into problems where this doesn't happen, try to run your program on a device.
To toggle the button, you do not need to set any playingInfo of the MPNowPlayingInfoCenter, neither do you need to hold an active AVAudioSession.
Here is example code where updateMetadata is a function that applies those changes to the MPNowPlayingInfoCenter.nowPlayingInfo dictionary. This would indicate to the center that the player is paused.In swift
self.updateMetadata(NSDictionary.dictionaryWithValuesForKeys(NSNumber(Double(audioFile.player.currentTime))),MPNowPlayingInfoPropertyElapsedPlaybackTime,NSNumber(numberWithFloat:0.0f),MPNowPlayingInfoPropertyPlaybackRate,nil)
I am playing the sound in my App and sound still continue play even when App enter into background i want to control the Volume of that audio when it enter into background . Like in this APP example.I want audio volume remain maximum even user try to turn off the volume. I am unable to splve it can any one out there help me out.
if you are using AVAudioPlayer the just use AVAudioPlayer instance say player like this:
player.volume=1; //for maximum volume
This is AVAudioPlayer's volume, and in reply to your question that even if user minimizes volume of Iphone it should remain in full, then you should know that according to apple policies, there are things which have control for user only, this is what they call user privilege, your app can not control iphone volume,
and for controlling player volume (you don't need any effort if you talk about iphone volume) , i am little doubtful how you want to do this, i mean you must have some button or horizontal slider to achieve this, anyhow proceed with your logic with the delegate method
- (void)applicationDidEnterBackground:(UIApplication *)application
in your appdelegate class
I am writing an iPad app that uses the "Flite" text-to-speech engine to announce specific events. The Flite engine uses an AVAudioPlayer instance to play the speech audio once it renders. For fun, I decided to add some simple controls to my app to allow the user to control iPod playback (next, prev, play/pause and volume - the basics) while my app is running using MPMusicPlayerController (of course).
The problem I am having is that when I adjust the iPod volume using MPMusicPlayerController, all of my audio is affected, including other sound effects and the speech audio. I set the volume for these other audio players (AVAudioPlayer instances) to 1.0 before playing the sound but it seems that the volume is always capped at whatever the iPod player volume is set to...
Is this normal? And what can I do to get around it? I want my app's audio to play at system full volume regardless of the volume level of the iPod player. (Example: The user had set the system volume to 80% of the device's max. I want my app to play audio at 100% of that 80% while allowing the user to adjust the iPod audio playback to 0-100% of that 80%.) Note: I am not interested in "ducking" but setting the iPod volume lower at all times while my app is running (background music).
I also have the problem, that -sometimes- when you first launch the app and press play on the iPod player (which sends the [player play] call), the iPod does not respond. If I press the home button, go into the iPod app and start playback then, once returning to my app, it works fine. What the deal with that?
Thanks in advance for any help!!
It could be something to do with the audio session category you've specified. Check out the Audio Session Programming Guide to see if you've chosen the right category.
The volume buttons on the side control the system volume and by extension the volume of your app's sounds.
I guess it's considered to be the Master volume control.
you can set the volume for specific samples or sounds using the AVItem's setVolume
[item setVolume]
You can create an AVItem to reference an existing sound file in your application or on the iphone. The code is pretty simple and looks like this -->
AVItem *item [[AVItem alloc]
initWithPath:#"the file"];
[item setVolume];
btw, this will not affect the rest of the audio channel (instantiated by some kinda AVController object) and the volume that you've set in your code will not be displayed on you screen so im not sure if you can change it at run time.
Is it possible to use the external speaker volume controls of iphone as a control for an App you have developed?
For example as a control of a timer app for which the enable button for the timer to start counting is the top external volume button and disable timer is the lower external button.
If so, which classes of iOS 4 sdk can override those external buttons for an application or those external buttons are locked only for volume controls and nothing else?
I have seen a video of the Camera+ app that supposedly uses the volume key to snap a picture (instead of touching the button on the screen). http://taptaptap.com/blog/volumesnap/
I, myself, was pretty confused when I saw that and thought it must have been a mock up or something. But I asked around and apparently, if you're running an audio player, you get notifications when the volume keys are pressed.
The idea was put forward that if you can run a silent audio on a loop and hook into the volume key notifications to do what you want.
However, I've looked at both the AVAudioPlayer and the MPMoviePlayerController class documentation and can't see any such notifications. I suspect they're private, which isn't very useful.
We have a game that is very close to being released, but we have one extremely annoying problem. One on of our Beta testers phones, he can't hear any of the in game sound effects. He can, however, hear the background music and the title screen music just fine.
The background and title music are both being played via AVAudioPlayer (they are longer, we need looping and volume control, etc). The sound effects are simply being played with AudioServicesPlaySystemSound (they are very short, we don't need precise control or to know when they end, etc). This works on most iPhones, but not on this one. All of this is being played with an audio session of AVAudioSessionCategorySoloAmbient.
So I have two questions:
- First, is this an acceptable implementation? i.e. is there something I missed that says you can't mix these two frameworks, or a reason why its a bad idea to mix them?
- Second, has anyone seen something like this before? If so, did you find a way around it?
Additional background note: I can pretty conclusively say that on his phone, it is the mixing of the two frameworks. He was able to hear sounds until roughly the same build where we added the title screen music. Also, if I change one of the sounds to work through an AVAudioPlayer, he's able to hear it. Unfortunately, I can't simply move the sounds into AVAudioPlayers because it just doesn't perform well at all, and I need better synchronization.
EDIT 2:
I've determined the cause of the error. The two different audio frameworks play on two different volume settings. There is the main volume (that's what shows up once you are in the app, and has no title on it) and the ringer volume (that's what shows up when you're on the home screen without any app loaded). The AVAudioPlayer calls play with the main volume setting. As I have set the category to AVAudioSessionCategorySoloAmbient (see code below), this is the volume control that will be adjusted if you use the volume rocker inside the app. The SystemSounds, however, are played at the Ringer Volume. This will NOT come up inside the app, and as such does not allow the user to adjust their settings during the game.
It's easy to see the possible confusion for the user: Let's say they have their ringer set to low, or even off. They start playing the game. They hear the title screen music (AVAudioPlayer) and are able to turn the volume up or down and it responds normally. Then they start the game and the sound effects play (SystemSounds), and they hear nothing because the ringer volume is low/off. In an effort to hear the sound effects, they bump up the volume and the background music responds accordingly. So from this point of view, it definitely looks like the sound effects just aren't playing.
If you have this similar situation, have your user make sure that their ringer volume is up before playing the game and their mute switch is on (i.e. not muted). You can also verify all of this by doing the test yourself - drop your ringer volume and bump your in-app volume up. Your SystemSounds should drop out of the mix.
Original answer:
In re-digging through all of the docs, I found the answer. I wasn't properly activating the audio session. Previously I only had this code to set the category:
NSError *setCategoryError = nil;
BOOL categoryWasSet = [[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategorySoloAmbient
error: &setCategoryError];
But I needed to also add the following code to explicitly activate the audio session:
NSError *activationError = nil;
BOOL activationSuccess = [[AVAudioSession sharedInstance]
setActive: YES
error: &activationError];
I've re-tested with this user, and it has completely fixed the issue. Hope that helps anyone who might have a similar problem.
EDIT: This doesn't seem to have resolved the issue after all. I got a false positive from my tester, and when examined more in detail it seems that he didn't actually hear the SystemSound generated sounds.
I have two apps on the app store that mix those two frameworks. AVAudioPlayer for sounds that require start and stop and volume control and AudioServices toolbox for short little beeps and clicks. The only think I can think of, off the top of my head, is that the volume of AVAudioPlayer seems to be controlled separately from the AudioServices sounds. So check to make sure that the tester doesn't have sounds turned off (with the vibrate mode switch) or the volume turned way down.
If this doesn't help, tell me more about your sounds/code and I can add some code to my app to see if I can get the same behavior. Of course, sounds like most your testers don't have this problem, and I probably won't see it either.