I am making an app that needs to play sounds even if the iPhone is in silent mode, but with the code I have now (look at bottom of this post) it wont't play sounds if the iPhone is in silent mode.
I am using the following code:
Viewcontroller.h:
#interface SoundViewController : UIViewController <UICollectionViewDataSource, UIApplicationDelegate, AVAudioPlayerDelegate, ADBannerViewDelegate, UIActionSheetDelegate> {
SystemSoundID SoundID;
NSString *listPath;
}
ViewController.m:
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (__bridge CFStringRef) [mainArray objectAtIndex:indexPath.row], CFSTR("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
The way you are triggering sounds using AudioServicesPlaySystemSound will ALWAYS obey the ringer/silent switch.
To play sound when the device is set to silent you need to use another way such as AVAudioPlayer class.
Related
I have this code to play sounds:
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"audio2", CFSTR ("mp3"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
It works fine for an audio file that I have that is about 1 second long. It does not, however, work for one of my files that is about 4 minutes long. How can I fix this? They're both mp3 files and placed in the same directory.
According to the apple's doc, AudioServicesPlaySystemSound has a limits as below:
Sound files that you play using this function must be:
- No longer than 30 seconds in duration
You can use AVAudioPlayer instead.
I'm making a soundboard app, everything goes fine but I have one issue, the sounds doesn't play if the ringer is off.
I have tried this:
[super viewDidLoad];
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil];
I'm using the AVFoundation Framework
The code to play the button is this:
- (IBAction)queChin:(id)sender {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"chin", CFSTR ("m4a"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
I have searched this topic but I couldn't find any answer that works. Maybe I'm missing something?
As alternative I can put an alert to the user saying "hey, turn your ringer on" but I don't know how to detect if the phone is silenced.
Any hints?
Thank you.
Well, I found out, you can't play System sounds with AudioServicesPlaySystemSound even if you initialize an Audio Session using this:
[[AVAudioSession sharedInstance] setDelegate: self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error: nil];
System sounds are meant to remain silent if the user mutes the device.
I ended up using AVAudioPlayer and that solved the problem.
Old code using System Sound:
- (IBAction)queChin:(id)sender {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"chin", CFSTR ("m4a"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
CFRelease(soundFileURLRef);//prevents memory leak
AudioServicesPlaySystemSound(soundID);
}
New code using AVAudioPlayer:
- (IBAction)queChin:(id)sender {
NSURL *url = [[NSBundle mainBundle] URLForResource:#"chin" withExtension:#"wav"];
_chingosound = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:NULL];
_chingosound.delegate = self;
[_chingosound prepareToPlay];
[_chingosound play];
}
You MUST initialize the audio session to play sounds with the ringer off.
I uploaded a file audio.wav into my supporting files folder.
This is my PlayAudio.h
#import <UIKit/UIKit.h>
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#interface PlayAudio : UIViewController {
}
-(IBAction) PlayIt;
#end
This is my PlayAudio.m after the implementation command
- (IBAction) PlayIt; {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"audio", CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
I then ctrl-clicked from the play button to the First Responder in my view controller and selected PlayIt. I see it's associated with Touch Up Inside.
For some reason I can click the button, but nothing plays. I'm doing this in Storyboard.
You can use NSURL to get the path of your wav file and cast it to CFURLRef, check the following code:
SystemSoundID soundID;
NSURL *soundPath = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"audio" ofType:#"wav"]];
if (AudioServicesCreateSystemSoundID ((CFURLRef)soundPath, &soundID) != kAudioServicesNoError) {
AudioServicesPlayAlertSound(soundID);
}
Note, that if mute button on iphone is enable AudioServicesCreateSystemSoundID function will fail(Vibration can be used in this case:soundID = kSystemSoundID_Vibrate;). If you want to play sound disregarding the mute switch, use AVAudioPlayer api.
I have an app that currently plays a 5 sec sound when a button is pressed within a view controller. I am trying to change this set up to where if I have a tableview, a specific cell is touched and the sound plays. I do not want an action where you select the cell and it pushes to another window to play the sound. I simply want the sound to play on touch of the cell.
Currently for my button set up I had the following to play the sound in my view controller:
In the SoundLibViewController.h
// Identifying UIButton associated with sound file
-(IBAction)CarHorn:(id)sender;
#end
In the SoundLibViewController.m
-(IBAction)CarHorn:(id)sender {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"CarHorn", CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
Unfortunately I can not find any help online to point me in the direction to change my code into incorporate a tableviewcell.
To give an example of what I'm looking to do: You go into your iPhone/iPad and under settings you select "Sounds". Then you choose "Ringtone", which takes you to a list of sounds. If you press the cell related to the sound it plays. THAT is what I want to do.
You need something like this in your UITableViewDelegate
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString * soundName = [self.soundNames objectAtIndex: indexPath.row]; // Assuming you have an array of sound names
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef)soundName, CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
I've been trying lately to get my app to play a sound from when it open to when its closed and I'm have difficulty. I have some code on playing a sound when I press a button and it's fine I'm just wondering if there is any tweaks I could do to make it play on its own and from the start or is there a way I could say press play and make the sound loop why I'm playing the game.
.h
#import <AudioToolbox/AudioToolbox.h>
- (IBAction)t1:(id)sender;
.m
- (IBAction)t1:(id)sender {
CFBundleRef mainbundle = CFBundleGetMainBundle();
CFURLRef soundFileUrlRef;
soundFileUrlRef = CFBundleCopyResourceURL(mainbundle, (CFStringRef) #"t1", CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileUrlRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
how about trying AVAudioPlayer and turning on the continuous playback by setting number of loops to -1:
myPlayer.numberOfLoops = -1
[myPlayer prepareToPlay];
[myPlayer play];
//when application did enter background or something
[myPlayer stop];
http://developer.apple.com/library/ios/#DOCUMENTATION/AVFoundation/Reference/AVAudioPlayerClassReference/Reference/Reference.html
Also make sure your Audio Sessions are set properly for background playback:
http://developer.apple.com/library/ios/#DOCUMENTATION/Audio/Conceptual/AudioSessionProgrammingGuide/Basics/Basics.html#//apple_ref/doc/uid/TP40007875-CH2-SW2