AVAudioPlayer not playing on some devices - ios

My code is working perfectly on simulators, on iPad-4 and on iPhone 6+, all running iOS 9.0.2.
However, and I know that's a weird claim, on my iPad Air 2 it looks like it's working, but actually nothing is heard. Also reproduced on other devices like another iPhone 6+ and another iPhone 6 running iOS 8.4. I have create a demo project (link below) so that others can try their own device.
I'm doing this:
Initializing an NSURL *url with a path under [[NSBundle mainBundle] resourcePath]:
/var/mobile/Containers/Bundle/Application/0ACADB94-886E-4C7E-A327-3FFF0E54CEF9/My App.app/sndEfcts/!snap.mp3
Assigning a new object into an ivar:
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
Test url in debugger - good! (notice that the space became %20. I also verified that the file exists):
(lldb) po audioPlayer.url
file:///var/mobile/Containers/Bundle/Application/0ACADB94-886E-4C7E-A327-3FFF0E54CEF9/My%20App.app/sndEfcts/!snap.mp3`
Play if created ok:
if (audioPlayer) {
audioPlayer.delegate = self;
[audioPlayer prepareToPlay];
__unused BOOL playOk = [audioPlayer play];
}
Delegate of finish is activated:
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
... and flag is saying YES! - but nothing is heard :(
So everything appears to be ok, and still no sound is heard (although other sounds of other apps do work ok)
Does anyone have an idea for the cause of such behavior?
EDIT
I have create a simple project to demonstrate. It is happening on various devices, even on 8.4. On simulators it is always working

I have found the solution.
On problematic devices, "mute" was on, affecting some of the sounds in the device. To prevent this, call this somewhere on beginning of your app:
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: nil];
This will cause the audio to be treated as playback and thus not be muted by the mute option.
I have learned that users typically don't know where to find the mute on/off control. On iPad Air 2: raise the lower pane from bottom and press the speaker icon.

Related

Playing sound when device is in silent mode

I am new to coding applications, and I have created a simple app that plays a sound. I have tested it and it works just fine. However, I want to play the sound on silent mode.
Here is the code:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(IBAction)Button1Sound:(id)sender{
AudioServicesPlaySystemSound(Button1);
}
- (void)viewDidLoad {
NSURL *Button1Sound = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"nobody" ofType:#"m4a"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)Button1Sound, & Button1);
[super viewDidLoad];
}
#end
I have looked at other questions online, and they said to add this line of code:
[[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryPlayback
error: nil];
I am not sure where to put it or if I am using the right syntax. I am using an audiotoolbox framework as well.
When in silent mode, unless the user explicitly initiates sound playback, such as media playback, it is in violation of the Human Interface Guidelines (HIG) and is grounds for the app being rejected.
Per the HIG:
Silence. People switch their device to silent to avoid being interrupted by unexpected sounds, such as ringtones and incoming message sounds. They also want nonessential sounds disabled, including keyboard sounds, sound effects, game soundtracks, and other audible feedback. When the device is set to silent, only explicitly initiated sounds should occur, such as audio during media playback, alarms, and audio/video messaging.
If you feel your need is not in violation, see this post for a solution.

Xcode: Play an audio file with music on the background

I've build an iOS application with Cordova 3.6.3 that uses interface sounds. When you click on buttons the application plays a short "click"-sound. This works great. But when I use my application while music is playing on the background from another app this happens:
1. The background music fades out.
2. The interface sound is played.
3. The background music fades in.
This is not how it should happen. I would like to play interface-sounds while the background music is still on. What do I need to change to Cordova / Phonegap to change this behavior? Something with AVAudioSession?
Thank you for helping.
I've found the solution in CDVSound.m.
Old version
NSString* sessionCategory = bPlayAudioWhenScreenIsLocked ? AVAudioSessionCategoryPlayback : AVAudioSessionCategorySoloAmbient;
[self.avSession setCategory:sessionCategory error:&err];
New version
NSString* sessionCategory = bPlayAudioWhenScreenIsLocked ? AVAudioSessionCategoryAmbient : AVAudioSessionCategoryAmbient;
[self.avSession setCategory:sessionCategory error:&err];
Check https://developer.apple.com/Library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/AudioSessionBasics/AudioSessionBasics.html for more info.

How to let a video, that is streamed via AirPlay not pause, when the screen is locked?

I use both, a MPMoviePlayerViewController and a MPMoviePlayerController to play back videos in my app. I also allow the use of AirPlay to stream these videos on to an Apple TV.
This all works fine. The only problem is, that the streamed video pauses, when the screen gets locked.
I noticed, that a lot of apps support this, but I don't know how to achive this feature.
I tried to set:
moviePlayerViewController.moviePlayer.useApplicationAudioSession = NO;
But that didn't work on either iOS 5 or iOS 6 so I tried using :
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
But that didn't even compile.
Both ways are discussed here: http://stackoverflow.com/questions/12814574/how-to-support-airplay-in-the-background-in-ios6
What can I do? Or what do I do wrong?
Thanks a lot!
Andreas
This answer and this one as well should help you, I've had the same problem in one of my apps and these helped. Let me know if it doesn't work.

How do I stop AirPlay audio with AVPlayer?

I'm working on an iOS app that, for reasons we won't get into here, wants to sometimes disable AirPlay playback on a remote device, and only play video locally on the iOS device, regardless of the user's settings.
I'm using AVPlayer to play the video, and that's currently non-negotiable.
I'm setting the iOS 5.0+ AVPlayer property allowsAirPlayVideo to NO, which prevents the video from playing remotely. But if the user has turned on AirPlay on the iOS device, the audio is still streamed through the remote device.
I don't see a comparable allowsAirPlayAudio flag in Apple's documentation, nor have I found mention of this issue anywhere else.
For example, this Stack Overflow question:
Audio Output Routes for AirPlay
talks about "audio output destinations in a USB audio accessory", which doesn't sound like what I need.
I don't want to just turn off audio, I want the audio to keep being played through my iOS device.
Am I missing something? Thanks!
Possible a duplicate of How to detect if a bluetooth headset plugged or not IOS 8?
I know it's an old question, but hey, it may help some one
This is what I do to disconnect the audio, mConnectDisconnect is boolean parameter.
allowsExternalPlayback will remove the image from airplay and play it on your device screen.
AVAudioSessionCategoryOptionDefaultToSpeaker this option will let you change audio to the device
AVAudioSession* session = [AVAudioSession sharedInstance];
self.player.allowsExternalPlayback = mConnectDisconnect;
if(allowsExternalPlayback){
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionAllowAirPlay error:nil];
}else{
[session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];
}
[session setActive:true error:nil];
}

AudioServicesPlaySystemSound Volume on iPad

in my application I use AudioServicesPlaySystemSound to play little caf files.
When run my app on the iPhone and I change volume by lateral buttons, the app's sound changes
too, but on iPad the sound's volume in my app is always the same.
Maybe because on the iPhone is the ring volume, instead on the iPad is device volume.
How can I obtain same iPhone behavior on iPad?
Excuse me for my bad English....
I had the same problem but if you change the system sounds volume with buttons all the system sounds will be modified along with your app's. I found this really annoying.
The solution is to use AVAudioPlayer in place of AudioServices: as easy, but way more versatile. And there you can finely tune the volume for each sound, programmatically.
NSURL *soundurl = [[NSBundle mainBundle] URLForResource: #"mysound" withExtension: #"caf"];
AVAudioPlayer *mySoundPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:soundurl error:&error];
mySoundPlayer .volume=0.4f; //between 0 and 1
[mySoundPlayer prepareToPlay];
mySoundPlayer.numberOfLoops=0; //or more if needed
[mySoundPlayer play];

Resources