I'm trying to get a short audio file (mp3) to play in my app. Here is the code i'm using:
AVAudioPlayer *AudioPlayer;
NSError *error;
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"filename"
ofType:#"mp3"]];
AudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
AudioPlayer.delegate = self;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
if (error)
{
NSLog(#"Error: %#",
[error localizedDescription]);
}
else
{
[AudioPlayer play];
}
I don't really know what i'm missing, the examples i've followed seem to match what i'm doing.
edit: I should also mention that the code runs without error, there is a try catch around this.
I had a similar problem due to ARC. Instead of defining the AVAudioPlayer in the same method you are using it, you should should have an instance variable somewhere else, such as the UIViewController. This way ARC doesn't auto release this object and audio can play.
I've made some additions and got it work:
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface FirstViewController : UIViewController <AVAudioPlayerDelegate> {
AVAudioPlayer *data;
UIButton *playButton_;
}
#property(nonatomic, retain) IBOutlet UIButton *playButton;
-(IBAction)musicPlayButtonClicked:(id)sender;
#end
#import "ViewController.h"
#implementation FirstViewController
#synthesize playButton=playButton_;
- (IBAction)musicPlayButtonClicked:(id)sender {
NSString *name = [[NSString alloc] initWithFormat:#"09 No Money"];
NSString *source = [[NSBundle mainBundle] pathForResource:name ofType:#"mp3"];
if (data) {
[data stop];
data = nil;
}
data=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath: source] error:NULL];
data.delegate = self;
[data play];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
In Interface Builder I've added a button and connected it with IBOutlet and musicPlayButtonClicked IBAction.
And don't forget to add AVFoundation framework to your project.
ps
I'm really sorry for my english, please, be indulgent.
I had this problem myself, until I found out that the sound was not coming through the speakers (instead - it was redirected to the calls speaker). Try adding this to redirect the sound through the speakers:
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
sizeof (doChangeDefaultRoute),
&doChangeDefaultRoute);
Related
I am making an alarm app for iPhones and want to continuously loop the audio until the button is pressed again. As of now all it does is play the audio once when pressed. Here's the code:
-(IBAction)PlayAudioButton:(id)sender {
AudioServicesPlaySystemSound(PlaySoundID);
}
- (void)viewDidLoad {
NSURL *SoundURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"Sound" ofType:#"wav"]];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)SoundURL, &PlaySoundID);
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
Any suggestions?
Use AVAudioPlayer to play the sound. You must add AVFoundation.framework to your project for this to work. Start by declaring an AVAudioPlayer object. It must be declared either as a property with a strong attribute, e.g.
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
or as an instance variable with a __strong attribute
#interface Class : SuperClass //or #implementation Class
{
AVAudioPlayer __strong *audioPlayer;
}
Then, to load and play the file,
- (void)viewDidLoad
{
NSString *audioFilePath = [[NSBundle mainBundle] pathForResource:#"Sound" ofType:#"wav"];
NSURL *audioFileURL = [NSURL fileURLWithString:audioFilePath];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioFileURL error:nil];
audioPlayer.numberOfLoops = -1; //plays indefinitely
[audioPlayer prepareToPlay];
}
- (IBAction)PlayAudioButton:(id)sender
{
if ([audioPlayer isPlaying])
[audioPlayer pause]; //or "[audioPlayer stop];", depending on what you want
else
[audioPlayer play];
}
and, when you want to stop playing the sound, call
[audioPlayer stop];
i am an amateur ios developer with version 4.6 of xcode and OSX 10.8.4. I am trying to make an app which plays sound but when i try to run the app i get this message:
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '* - [NSURL initFileURLWithPath:]: nil string parameter'
My app also wont launch.
Here is the code for my view controller.h:
ViewController.h:
#import <UIKit/UIKit.h>
#import <RevMobAds/RevMobAds.h>
#import <AVFoundation/AVFoundation.h>
#interface ViewController : UIViewController
- (IBAction)playButton:(id)sender;
- (IBAction)stopButton:(id)sender;
#end
And here is my view controller.m:
Viewcontroller.m:
#import "ViewController.h"
#import <RevMobAds/RevMobAds.h>
#interface ViewController ()
{
AVAudioPlayer *avPlayer;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSString *stringPath = [[NSBundle mainBundle]pathForResource:#"98648__dobroide__20100606-mosquito" ofType:#"mp3"];
NSURL *url = [NSURL fileURLWithPath:stringPath];
NSError *error;
avPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
[avPlayer setNumberOfLoops:-1];
}
- (void)didReceiveMemoryWarning{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)playButton:(id)sender {
[avPlayer play];
}
- (IBAction)stopButton:(id)sender {
[avPlayer pause];
}
#end
The problem is pathForResource is returning nil. Have you added that exact file name to your bundle?
Also, you should be testing for stringPath and error before continuing to load the player. For example:
NSString *stringPath = [[NSBundle mainBundle]pathForResource:#"98648__dobroide__20100606-mosquito" ofType:#"mp3"];
if (stringPath) {
NSURL *url = [NSURL fileURLWithPath:stringPath];
NSError *error;
avPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
if (!error) {
[avPlayer setNumberOfLoops:-1];
} else {
NSLog(#"Error occurred: %#", [error localizedDescription]);
}
} else {
NSLog(#"Resource not found");
}
This question already has answers here:
How do I programmatically play an MP3 on an iPhone?
(4 answers)
Closed 4 years ago.
I can't figure out how to play a music file in an iPhone game.
Im creating a Game and I am trying to figure out how to play music whenever the app is launched.
I tried this:
- (void)awakeFromNib {
NSString *path = [[NSBundle mainBundle] pathForResource:#"musicamenu" ofType:#"mp3"];
AVAudioPlayer *theAudio = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
[theAudio play];
}
This is how you do it. In your v1AppDelegate.h file add
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#interface v1AppDelegate : UIResponder <UIApplicationDelegate>
{
AVAudioPlayer *myAudioPlayer;
}
#property (nonatomic, retain) AVAudioPlayer *myAudioPlayer;
#property (strong, nonatomic) UIWindow *window;
#end
Now in your v1AppDelegate.m file add this
#import "v1AppDelegate.h"
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>
#implementation v1AppDelegate
#synthesize window = _window;
#synthesize myAudioPlayer;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//start a background sound
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:#"Soothing_Music2_Long" ofType: #"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:soundFilePath ];
myAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
myAudioPlayer.numberOfLoops = -1; //infinite loop
[myAudioPlayer play];
// Override point for customization after application launch.
return YES;
}
If you wish to stop or start this music from anywhere else in your code then simply add this
#import "v1AppDelegate.h"
- (IBAction)stopMusic
{
v1AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.myAudioPlayer stop];
}
- (IBAction)startMusic
{
v1AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate.myAudioPlayer play];
}
I recommend to add the play music method in applicationDidBecomeActive: method. Because you want the music played every time the app is launched. Note you should hold a reference to the player. Else the music will not be played.
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Play music on another queue so that the main queue is not blocked.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self playMusic];
});
}
- (void)playMusic
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"done" ofType:#"mp3"];
NSError *error = nil;
NSURL *url = [NSURL fileURLWithPath:path];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
[self.player play];
}
For Swift 3.1 :
Use this two imports :
import AVFoundation
import AudioToolbox
Create a reference for your AVAudioPlayer :
private var mAudioPlayer : AVAudioPlayer?
Use this function for play a sound you are storing in your app :
func onTapSound(){
let soundFile = Bundle.main.path(forResource: "slap_placeholder.wav", ofType: nil)
let url = URL(fileURLWithPath: soundFile!)
self.mAudioPlayer = try! AVAudioPlayer(contentsOf: url as URL)
self.mAudioPlayer?.play()
}
This is a newbie question.
I have a very simple app that is supposed to only play an audio file when a button on the main view is tapped.
I am using XCode version 4.6.
I added an audio file 'audioclip.wav' to my project. I have added the AVFoundation.framework.
My project only has ViewController.h and ViewController.m.
I double clicked and dragged from the button in the storyboard to the .h file using the assistant editor to create my IBAction connection.
My ViewController.h:
#import <UIKit/UIKit.h>
#import<AVFoundation/AVAudioPlayer.h>
#interface ViewController : UIViewController <AVAudioPlayerDelegate> {
}
- (IBAction)playAudio:(id)sender;
#end
My ViewController.m:
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)playAudio:(id)sender {
AVAudioPlayer *audioPlayer;
NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"audioclip" ofType:#"wav" ];
NSURL *audioURL = [NSURL fileURLWithPath:audioPath];
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:nil];
[audioPlayer play];
}
#end
For whatever reason (probably something silly I left out) The audioclip.wav file does not play when I click the button. I have tested on the iPhone 6.1 simulator and on my device.
I think there is some problem with wav files. Some people seem to get it to work, but I've tried several different files and none of them play. The mp3 and m4a files that are commented out in the code below worked fine. There's no need to do anything with a delegate, it's optional.
#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#interface ViewController ()
#property (strong,nonatomic) AVAudioPlayer *audioPlayer;
#end
#implementation ViewController
- (IBAction)playAudio:(id)sender {
//NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"11 Prayer" ofType:#"mp3" ];
//NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"Sunshine" ofType:#"m4a" ];
NSString *audioPath = [[NSBundle mainBundle] pathForResource:#"space" ofType:#"wav" ];
NSURL *audioURL = [NSURL fileURLWithPath:audioPath];
NSError *error;
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
[self.audioPlayer play];
}
If I log the error, with the wav file I get:
Error Domain=NSOSStatusErrorDomain Code=1685348671 "The operation couldn’t be completed. (OSStatus error 1685348671.)"
Please try to use this one..
- (IBAction)playAudio:(id)sender
{
NSURL *url=[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:#"audioclip" ofType:#"wav"]];
NSData *data =[NSData dataWithContentsOfURL:url];
audioPlayer = [[AVAudioPlayer alloc] initWithData:data error:nil];
audioPlayer.delegate = self;
[audioPlayer setNumberOfLoops:0];
[audioPlayer play];
}
i hope this will help u
try like this ,
NSString *audio=[[NSBundle mainBundle]pathForResource:#"audioclip" ofType:#"wav"];
NSURL *url=[[NSURL alloc]initFileURLWithPath:audio];
avPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
avPlayer.delegate = self;
[avPlayer prepareToPlay];
[avPlayer play];
and once check IBOutlet connected or not and check the button action method with breakpoints.
As i can see you have made the code quite simple, so the way it's made does require that it is not a big wav file.
And by that you need to cut down the audio file to something like 10 seconds and under.
I was using the .m4a when I encountered this problem. For me, not implementing AVAudioSession was the issue
var session = AVAudioSession.sharedInstance()
do {
session.setCategory(AVAudioSessionCategoryPlayAndRecord)
try session.setActive(true)
} catch {
gf.displayAlert("problem encountered", userMessageTitle: "")
self.navigationController?.popViewControllerAnimated(true)
}
i am using the AVAudioPlayer and setting its delegate but its delegate is not getting called
+ (void) playflip
{
NSString *path;
path = [[NSBundle mainBundle] pathForResource:#"flip" ofType:#"mp3"];
AVAudioPlayer *flip;
flip = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:Nil];
flip.delegate = self;
[flip play];
}
My class where i am implementing is the sound class
#interface SoundClass : NSObject <AVAudioPlayerDelegate>
I am calling this delegate
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
NSLog(#"delegate called");
[player release];
player = nil;
}
It looks like maybe your flip object is going out of scope, because the rest of your code looks fine. Here's what I do:
// controller.h
#interface SoundClass : NSObject <AVAudioPlayerDelegate> {}
// #property(nonatomic,retain) NSMutableDictionary *sounds;
// I have lots of sounds, pre-loaded in a dictionary so that I can reference by name
// With one player, you can just use:
#property(nonatomic,retain) AVAudioPlayer *player;
Then allocate and load the sound in your .m
player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:Nil];
[player prepareToPlay];
player.delegate = self;
[player play];
Now you should get your DidFinishPlaying notification.