audioPlayer sound played on IPhone different than IPAD (Iphone is low volume and has to be held to ear) - objective-c

I am playing a sound file in an APP and on the iPhone plays with volume like it is a phone call (you have to hold the phone to your ear).
When played on the iPad it plays like you would expect, sounds like a music file being played.
Does anyone know how to make the iPhone play a sound like it is music playing?
Here is what I use to play the sound:
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/30perMinute2.caf", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
if (audioPlayer == nil)
NSLog(#"selection didn't work");
else {
// [audioPlayer stop];
[audioPlayer play];
}
I have set the volume in audioPlayer.

Here is whatr ended up fixing the problem:
In AppDelegate.h
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
In AppDelegate.m
In application didFinishLaunchingWithOptions add
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute, sizeof(audioRouteOverride), &audioRouteOverride);

Related

Play sound when app is in background or screen is locked

I have a timer that plays a sound when time reaches 0, but now I can't understand how to fire the event in order to play the sound if the app is in background mode or the screen is locked, What I found searching on the web was to set "UIBackgroundModes" in my .plist file, and add "audio" as array member.
UIBackgroundModes Array
Item0 String audio
Then add in the app delegate the following code:
NSError *setCategoryErr = nil;
NSError *activationErr = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:&setCategoryErr];
[[AVAudioSession sharedInstance] setActive:YES error:&activationErr];
But the sound doesn't get played.. So I was wondering if it's possible to do something like this or I should change method
EDIT:
I imported:
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
And this is the code I use to create the sound:
AVAudioPlayer *player;
NSString *soundFilePath = [NSString stringWithFormat:#"%#/clock.mp3",
[[NSBundle mainBundle] resourcePath]];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL
error:nil];
player.numberOfLoops = -1;
dispatch_async(dispatch_get_main_queue(), ^{
[player prepareToPlay];
});
Then to play it:
[player play];
I have just a snippet of Swift code but it should be easy to convert it to Obj-C
Try to use AVPlayerItem init with URL and then set AVPlayer init with PlayerItem
let assetUrl = self.nowPlayingItem!.associatedItem!.valueForProperty(MPMediaItemPropertyAssetURL) as! NSURL
let playerItem = AVPlayerItem(URL: assetUrl)
if let player = self.player {
player.replaceCurrentItemWithPlayerItem(playerItem)
} else {
self.player = AVPlayer(playerItem: playerItem)
}
self.player!.play()
and for this line of code:
NSString *soundFilePath = [NSString stringWithFormat:#"%#/clock.mp3",
[[NSBundle mainBundle] resourcePath]];
Have you tried:
[[NSBundle mainBundle] URLForResource:#"song" withExtension:#"mp3"];
// Create a new player item
NSURL *assetUrl = [nowPlayingItem valueForProperty:MPMediaItemPropertyAssetURL];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:assetUrl];
// Either create a player or replace it
if (self.player) {
[self.player replaceCurrentItemWithPlayerItem:playerItem];
} else {
self.player = [AVPlayer playerWithPlayerItem:playerItem];
}
nowPlayingItem is here a MPMediaItem but just replace NSURL *assetUrl = [nowPlayingItem valueForProperty:MPMediaItemPropertyAssetURL]; by NSURL *assetUrl =[[NSBundle mainBundle] URLForResource:#"song" withExtension:#"mp3"];

AVAudioPlayer on OS X not playing any sound

I'm trying to play a sound using AVAudioPlayer on os x (not iOS!). I'm using the following code:
AVAudioPlayer *player;
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:name ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
player = [[AVAudioPlayer alloc] initWithContentsOfURL:
soundFileURL error:&err];
if( err ){
NSLog(#"Failed with reason: %#", [err localizedDescription]);
}
else{
player.delegate = self;
player.numberOfLoops = -1;
player.currentTime = 0;
player.volume = 1.0;
[player play];
}
All is ok, and the player calls play function without the errors. However I can't hear any sound after that. I'm sure that my audio file is ok, because I was able to play it using NSSound class. The reason I want to use AVAudioPlayer is that when I'm using NSSound class and I play it in a loop there is short pause in between and that's why I wanted to try AVAudioPlayer.
Define the *player as a property so it gets not evaporated after your method finishes.

Play Audio iOS Objective-C

I'm trying to get an audio file playing in my iOS app. This is my current code
NSString *soundFilePath = [NSString stringWithFormat:#"%#/test.m4a", [[NSBundle mainBundle] resourcePath]];
NSLog(#"%#",soundFilePath);
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[audioPlayer setVolume:1.0];
audioPlayer.delegate = self;
[audioPlayer stop];
[audioPlayer setCurrentTime:0];
[audioPlayer play];
I've being checking a bunch of other posts but they all generally do the same thing. I'm not getting an error, but I don't hear any audio playing on the simulator or device.
This is the path I get for the audio file on the simulator
/Users/username/Library/Application Support/iPhone Simulator/5.1/Applications/long-numbered-thing/BookAdventure.app/test.m4a
Any help is appreciated!
Maybe you should try using the NSBundle method pathForResource:ofType: method to create the path to the file.
The following code should successfully play an audio file. I have only used it with an mp3, but I imagine it should also work with m4a. If this code does not work, you could try changing the format of the audio file. For this code, the audio file is located in the main project directory.
/* Use this code to play an audio file */
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"m4a"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
player.numberOfLoops = -1; //Infinite
[player play];
EDIT
Ok, so try this:
NSString *soundFilePath = [NSString stringWithFormat:#"%#/test.m4a",[[NSBundle mainBundle] resourcePath]];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
player.numberOfLoops = -1; //Infinite
[player play];
Also, make sure you do the proper imports:
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
You need to store a strong reference to 'AVAudioPlayer'
#property (strong) AVAudioPlayer *audioPlayer;
And if you are sure that your audio file is in following Bundle Resources, it should play.
Project>Build Phases>Copy
To play file with extension .caf, .m4a, .mp4, .mp3,.wav, .aif
Download following two files from GitHub
SoundManager.h
SoundManager.m
Add these files to your project
Also add audio files to resource folder (sample files)
mysound.mp3, song.mp3
Import header file in desired file
#import "SoundManager.h"
And add following two lines in -(void)viewDidLoad
[SoundManager sharedManager].allowsBackgroundMusic = YES;
[[SoundManager sharedManager] prepareToPlay];
Use following line to play sound (mysound.mp3)
[[SoundManager sharedManager] playSound:#"mysound" looping:NO];
Use following line to stop the sound (mysound.mp3)
[[SoundManager sharedManager] stopSound:#"mysound"];
Also you can play music (song.mp3) as
[[SoundManager sharedManager] playMusic:#"song" looping:YES];
And can be stop music as
[[SoundManager sharedManager] stopMusic];
Complete Documentation is on GitHub
First import this framework to your file
#import <AVFoundation/AVFoundation.h>
Then declare an instance of AVAudioPlayer.
AVAudioPlayer *audioPlayer;
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"Name of your audio file"
ofType:#"type of your audio file example: mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
audioPlayer.numberOfLoops = -1;
[audioPlayer play];
To play your bundle audio file using below code if you generate the system sound ID
for(int i = 0 ;i< 5;i++)
{
SystemSoundID soundFileObject;
NSString *audioFileName = [NSString stringWithFormat:#"Alarm%d",i+1];
NSURL *tapSound = [[NSBundle mainBundle] URLForResource: audioFileName
withExtension: #"caf"];
// Store the URL as a CFURLRef instance
CFURLRef soundFileURLRef = (__bridge CFURLRef) tapSound;
// Create a system sound object representing the sound file.
AudioServicesCreateSystemSoundID (
soundFileURLRef,
&soundFileObject
);
[alarmToneIdList addObject:[NSNumber numberWithUnsignedLong:soundFileObject]];
}
You can play the sound by using below code
AudioServicesPlaySystemSound([[alarmToneIdList objectAtIndex:row]unsignedLongValue]);
To achieve this below framework need to add in your Xcode
AudioToolbox
Finally below header files are needs to be import in controller
#import AudioToolbox/AudioToolbox.h
#import AudioToolbox/AudioServices.h
Updated for Swift 4
Playing from main bundle
- iOS 11 only
import AVFoundation
var player: AVAudioPlayer?
The following code loads the sound file and plays it, returning an error if necessary.
guard let url = Bundle.main.url(forResource: "test", withExtension: "m4a") else { return }
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
try AVAudioSession.sharedInstance().setActive(true)
guard let player = player else { return }
player.play()
} catch let error {
// Prints a readable error
print(error.localizedDescription)
}
Swift 4.2
var soundFilePath = "\(Bundle.main.resourcePath ?? "")/test.m4a"
var soundFileURL = URL(fileURLWithPath: soundFilePath)
var player = try? AVAudioPlayer(contentsOf: soundFileURL)
player?.numberOfLoops = -1 //Infinite
player?.play()

No sound/volume in Iphone Simulator 4.3 . But plays ok in Iphone simulator 5.1

I am developing a IPhone app to play sound files. My deployment target is 4.0. While trying to play in IPhone Simulator 4.3 it plays with no sound/volume. But it playing ok in Simulator 5.1.
My code:
NSString *fileName=[NSString stringWithFormat:#"book%i_chapter_%i",book_number,chapter_number];
NSString *path=[[NSBundle mainBundle] pathForResource:fileName ofType:#"mp3" inDirectory:nil];
NSURL *url = [NSURL fileURLWithPath:path];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if(error)
{
NSLog(#"Error in audio Player: %#",[error localizedDescription]);
}
else
{
[audioPlayer prepareToPlay];
//audioPlayer.delegate=self;
[audioPlayer setVolume:20.0];
[audioSlider setValue:0.0];
[audioSlider setMaximumValue:[audioPlayer duration]];
[audioPlayer play];
}
Please help me to fix this. Thanks

Play music in the background using AVAudioplayer

I want to play music even if the app goes in background. I checked all stackoverflow links but none of them worked. Please help need to do it today.
I had used following code:-
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"Day At The Beach" ofType: #"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
NSError *error;
playerTemp = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:&error];
playerTemp.numberOfLoops = 0;
AudioSessionSetActive(true);
[playerTemp play];
I had solved this question by referring iOS Application Background tasks
and make some changes in .plist file of our application..
Update
write this code in your controller's view did load method like this
- (void)viewDidLoad
{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"in-the-storm" ofType:#"mp3"]];
AVAudioPlayer *audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[audioPlayer play];
[super viewDidLoad];
}
I just wanted to add a note to Mehul's answer. This line:
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
is actually very important. I used other tutorials to get my AVAudioPlayer up and running. Everything worked fine except my audio would not START if the app was in the background. To clarify, my audio was fine if it was already playing when the app went into the background...but it would not start if the app was already in the background.
Adding the above line of code made it so my audio would start even if the app was in the background.
You need to set 'audio' as one of your UIBackgroundModes in Info.plist. Apple has documentation on the issue.
Write this line in to plist for background run...
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
Write this code Where you want to use
AVAudioPlayer* audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:self.urlForConevW error:&error];
audioPlayer.delegate = self;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
audioPlayer.numberOfLoops = 1;
[audioPlayer play];
Step1
Make the following changes in info.plist
Application does not run in background : NO
Required background modes
item0 :App plays audio or streams audio/video using AirPlay
Step 2
Don't forget to add the following things in MainViewController.h file
#import <'AVFoundation/AVAudioPlayer.h>
#interface MainViewController:<'AVAudioPlayerDelegate>
AVAudioPlayer *H_audio_player;
Step 3
Add the following code inside the play action of your MainViewController class.
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:#"%d-%d",C_CID, C_SID] ofType:#"mp3"];
NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath];
H_audio_player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil];
H_audio_player.delegate = self;
H_audio_player.numberOfLoops = -1;
Also important here if you are using MPMusicPlayerController:
You must use:
[MPMusicPlayerController iPodMusicPlayer]
And Not
[MPMusicPlayerController applicationMusicPlayer]
Also if you don't want your app to stop music which was playing when your app is started, look here:
AVAudioPlayer turns off iPod - how to work around?
You can use MPMoviePlayerController even to play solo-audio movies. If you like it, read this detailed Apple Library Technical Q&A:
iOS Developer Library Technical Q&A QA1668
I use the below code. It work for me, and call on the button click of audio player instance method.
NSError *error; NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"music" ofType:#"mp3"]];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&error];
[[AVAudioSession sharedInstance] setActive:YES error: &error];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self.player prepareToPlay];
From all answers is missing this code to control the player when user is waking the device:
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay:
[_audioPlayer play];
break;
case UIEventSubtypeRemoteControlPause:
[_audioPlayer pause];
break;
default:
break;
}
}
And you have all these options:
UIEventSubtypeRemoteControlPlay = 100,
UIEventSubtypeRemoteControlPause = 101,
UIEventSubtypeRemoteControlStop = 102,
UIEventSubtypeRemoteControlTogglePlayPause = 103,
UIEventSubtypeRemoteControlNextTrack = 104,
UIEventSubtypeRemoteControlPreviousTrack = 105,
UIEventSubtypeRemoteControlBeginSeekingBackward = 106,
UIEventSubtypeRemoteControlEndSeekingBackward = 107,
UIEventSubtypeRemoteControlBeginSeekingForward = 108,
UIEventSubtypeRemoteControlEndSeekingForward = 109,
If even after setting audio as one of your UIBackgroundModes in the plist the audio stops when going to background, try setting your application's audio session to media playback.
Here's the related reference:
https://developer.apple.com/library/ios/documentation/Audio/Conceptual/AudioSessionProgrammingGuide/Introduction/Introduction.html
Here's about what the code's gonna look like:
NSError *activationError = nil;
[[AVAudioSession sharedInstance] setActive: YES error: &activationError];
NSError*setCategoryError = nil;
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error: &setCategoryError];
To play your audio in background
Step 1 :Just add in your info.plistmake an array
step2 :
- (void)applicationDidEnterBackground:(UIApplication *)application
{
__block UIBackgroundTaskIdentifier task = 0;
task=[application beginBackgroundTaskWithExpirationHandler:^{
NSLog(#"Expiration handler called %f",[application backgroundTimeRemaining]);
[application endBackgroundTask:task];
task=UIBackgroundTaskInvalid;
}];
}
step3 :
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"iNamokar" ofType:#"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath];
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[player prepareToPlay];
[self.player play];
From Apple's sample code: Audio Mixer (MixerHost)
// If using a nonmixable audio session category, as this app does, you must activate reception of
// remote-control events to allow reactivation of the audio session when running in the background.
// Also, to receive remote-control events, the app must be eligible to become the first responder.
- (void) viewDidAppear: (BOOL) animated {
[super viewDidAppear: animated];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
I think remote control events are not needed for the following case:
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryMixWithOthers,
sizeof(value), &value);