My application plays audio using AudioQueue and AudioSession. I can't stop playing according to application workflow. Currently, my customer ask me to perform iPhone vibration according to some conditions. I've tried to perform it with AudioServices playing vibration as system sound or alert sound. There is not positive result. Could somebody help me and tell how to implement it? I'm making legal application for non jailbreaked iPhones and can't use custom freamworks because Apple can reject application.
Thank you.
Solved using this solution :)
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayback error:&err];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
This is how I get the vibration:
#import <AudioToolbox/AudioToolbox.h>
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayback error:&err];
AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);
Hope it helps
For reference, I'm not using AudioQueue but an AVAudioEngine to record something, and for my case I pinpointed it down to having to pause the input in order to play the vibration properly with AudioServicesPlaySystemSound during a record session.
So in my case, I did something like this
audioEngine?.pause()
AudioServicesPlaySystemSound(1519)
do {
try audioEngine.start()
} catch let error {
print("An error occurred starting audio engine. \(error.localizedDescription)")
}
Related
Hi guys I'm doing an enterprise app to detect when an iOS device as a failing microphone or speaker.
I need to use the secondary microphone (the one used when recording video) and the only way I found it was using AVAudioSessionModeVideoRecording but I also need to use lower speaker and I am using AVAudioSessionPortOverrideNone, but the problem is that when I use AVAudioSessionModeVideoRecording the audio always goes thru the speaker and not the default earpiece.
here is my code
AVAudioSession* session = [AVAudioSession sharedInstance];
BOOL success;
NSError* error;
success = [session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
if (!success) NSLog(#"AVAudioSession error setting category:%#",error);
success = [session overrideOutputAudioPort:AVAudioSessionPortOverrideNone error:&error];
if (!success) NSLog(#"AVAudioSession error on output audio port: %#",error);
success = [session setMode:AVAudioSessionModeVideoRecording error:&error];
if (!success) NSLog(#"AVAudioSession error setting mode: %#",error);
thanks guys
The issue is that AVAudioPlayer in itself behaves as it should. It plays background music when the device is not in silent mode (silent/ringer switch is on). When the silent switch is on, it also respects this state and does not play the background music.
However, one peculiar scenario that the AVAudioPlayer plays in silent mode is when I play a video in MPMoviePlayer.
In my app, the BG sound is played first before playing the movie.
Can anyone help? This only occurs when I play the movie.
For other details:
BG Loop used - m4a type
Movie type used - m4v
I also found out that this scenario repeatedly surfaces in iOS 5 but it sometimes happen even in the latest versions.
I've researched everywhere in Google, Apple's documents, and in SO but I couldn't find anything regarding this particular scenario.
I even tried explicitly setting the AVAudioSession's category to AVAudioSessionCategoryAmbient and then calling setActive. (Also tried the setCategory:withOptions:error method but the app crashes for some reason -- tested on device)
I even tried setting the delegate and implementing methods when I tried to use the AVAudioPlayerDelegate.
Help anyone? :(
NSURL *url = [NSURL URLWithString:self.videoURL];
MPMoviePlayerViewController *mpvc = [[MPMoviePlayerViewController alloc] initWithContentURL:url];
NSError *_error = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &_error];
[self presentMoviePlayerViewControllerAnimated:mpvc];
Add this framework
#import <AVFoundation/AVFoundation.h>
try like this...
try to set the audio session in this way
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *err = nil;
[audioSession setCategory :AVAudioSessionCategoryPlayAndRecord error:&err];
if(err){
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
[audioSession setActive:YES error:&err];
err = nil;
if(err){
NSLog(#"audioSession: %# %d %#", [err domain], [err code], [[err userInfo] description]);
return;
}
This question already has answers here:
iPhone - Is it possible to override silent mode or have a recursive alert sound with push notification? [closed]
(3 answers)
Closed 4 years ago.
I want to make an application which creates sound, music, or system sound when an iPhone is in silent mode. Is it possible to play any type of sound whether music or system tones when it is silent mode?
It's not advisable, but who am I to say you can't do it. You may have a good reason to be playing sound.
If you are using Audio Sessions, then include <AVFoundation/AVFoundation.h> at the start of your file and
[[AVAudioSession sharedInstance]
setCategory: AVAudioSessionCategoryPlayback
error: nil];
should do the trick. Note if you play music or sounds, then iPod playback will be paused.
Once this has been done, probably somewhere in the initialization of one of your classes that plays the sounds, you can instantiate sounds like this:
// probably an instance variable: AVAudioPlayer *player;
NSString *path = [[NSBundle mainBundle] pathForResource...];
NSURL *url = [NSURL fileURLWithPath:path];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url];
When that's done, you can play with it any time you want with:
[player play]; // Play the sound
[player pause]; // Pause the sound halfway through playing
player.currentTime += 10 // skip forward 10 seconds
player.duration // Get the duration
And other nice stuff. Look up the AVAudioPlayer Class reference.
And for Swift 2, 3, 4.2
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
Yes you can play sound when the phone is set to vibrate.
Simply use the AVAudioPlayer class.
By default, playing an Audio Session
sound will ~not~ respect the setting
of the mute switch on the iPhone. In
other words, if you make a call to
play a sound and the silent (hardware)
switch on the iPhone is set to silent,
you’ll still hear the sound.
This is what you want. So now you know that playing an Audio Session when your phone is in silent mode will still play the sound you just need to know how to create an audio session to play the sound, like so:
taken from this website: http://iosdevelopertips.com/audio/playing-short-sounds-audio-session-services.html
SystemSoundID soundID;
NSString *path = [[NSBundle mainBundle]
pathForResource:#"RapidFire" ofType:#"wav"];
AudioServicesCreateSystemSoundID((CFURLRef)[NSURL fileURLWithPath:path],&soundID);
AudioServicesPlaySystemSound (soundID);
For this to work, you will need to import header file, and also add the AudioToolbox.framework to your project.
And that's it.
So from this answer you now know that you can play sound while the phone is on vibrate.
You don't need extra or special code to allow you to do this functionality as it already does that by default.
Pk
Works on iOS 6 and above
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
Just put this in your viewDidLoad:
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,
sizeof(sessionCategory), &sessionCategory);
For playing a sound in silent mode and even when it goes to background, try this:
Put this code in application:didFinishLaunchingWithOpitons:
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive:YES error:nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
and this code in applicationDidEnterBackground:
[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
Also setup a background mode of Playing Audio/Air Play and include AVFoundation header.
for Objective C, you could play system sound with following code:
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
*The system path could be modified.*
NSString *path = #"/System/Library/Audio/UISounds/begin_record.caf";
NSURL *url = [NSURL fileURLWithPath:path];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[player play];
Swift - Call this function before playing your audio/video to force playback when the phone is on silent. This also silences other audio that is currently playing.
You can change .duckOthers to .mixWithOthers if you don't want to silence other audio.
func setupAudio() {
let audioSession = AVAudioSession.sharedInstance()
_ = try? audioSession.setCategory(AVAudioSessionCategoryPlayback, with: .duckOthers)
_ = try? audioSession.setActive(true)
}
I am trying to make the audio record and play back at the same time. Here is the code. It will only record and play back later. I want it to play back simultaneously over the speakers. Any help. I am not even sure I am using the right classes.
AVAudioSession * audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
[audioSession setActive:YES error:nil];
temporaryRecFile = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithString:#"VoiceFile"]]];
recorder = [[AVAudioRecorder alloc] initWithURL:temporaryRecFile settings:nil error:nil];
[recorder setDelegate:self];
[recorder prepareToRecord];
[recorder record];
AVAudioPlayer * player = [[AVAudioPlayer alloc] initWithContentsOfURL:temporaryRecFile error:nil];
player.volume = 1;
[player play];
Are you recording from the iPhone microphone? Chances are you'll get feedback if you try to play the recording back while recording it. The microphone will hear what the speakers are playing and rerecord it at a slight delay. This would snowball until your recording sounds like a train wreck.
You are using correct classes but I think you must add AutioUnits also.
Apple has a sample code aurioTouch2 and I think it contains what you need.
I have an iphone design question regarding downloading and playing an audio file. Thanks to Matt Gallagher's AudioStreamer sample I can stream audio and play it back, bu that does not save it locally on the phone for later. Using an NSURLConnection I can download and save the audio files, but I have to wait until I have downloaded them to init my AVAudioPlayer given the data property is read only. I can not add to the buffer.
My question is how can I start the download, but then start playing the file after "enough" of it is downloaded, but before it is finished? Is there another audio player other then AVAudioPlayer that I can feed data into as it is being downloaded.
The only way I can see to do it now would be to do both in different threads, but then of course I would be pulling down the data twice.
Thoughts?
I thought you could do it with AVAudioPlayer but I havent tested it. I believe I have played audio without it loading fully with AVPlayer like so:
self.player = [AVPlayer playerWithURL:assetUrl];
[player play];
I would use an AVAudioSession along with a MPMoviePlayerViewController.
/**
* Play audio session
*
* #version $Revision: 0.1
*/
- (void)playAudioWithURL:(NSString *)audioURL {
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
NSError *setCategoryError = nil;
[audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
if (setCategoryError) {
}
NSError *activationError = nil;
[audioSession setActive:YES error:&activationError];
if (activationError) {
}
MPMoviePlayerViewController *tempPlayer = [[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL URLWithString:[audioURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
// Make sure we have airplay
if([tempPlayer.moviePlayer respondsToSelector:#selector(setAllowsAirPlay:)]) {
tempPlayer.moviePlayer.allowsAirPlay = YES;
}
tempPlayer.moviePlayer.shouldAutoplay = YES;
tempPlayer.moviePlayer.useApplicationAudioSession = NO;
[self presentMoviePlayerViewControllerAnimated:tempPlayer];
[tempPlayer.moviePlayer play];
[tempPlayer release];
}//end