Array of sounds with .plist file? - ios

Here is my code:
MainViewConroller.h
#import <UIKit/UIKit.h>
#import "FlipsideViewController.h"
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#interface MainViewController : UIViewController <FlipsideViewControllerDelegate> {
AVAudioPlayer *audioPlayer;
NSArray *soundsArray;
}
#property(nonatomic, retain) AVAudioPlayer *audioPlayer;
#property(nonatomic, retain) NSArray *soundsArray;
-(void)prepareSounds;
- (IBAction)playSound:(UIButton *)sender;
#end
Here is my MainViewController.m:
#import "MainViewController.h"
#interface MainViewController ()
#end
#implementation MainViewController
#synthesize audioPlayer;
#synthesize soundsArray;
-(void)prepareSounds
{
NSString *filepath= [[NSBundle mainBundle] pathForResource:#"Sound" ofType:#"plist"];
self.soundsArray = [[NSArray alloc] initWithContentsOfFile:filepath];
}
- (void)stopAudio
{
if (audioPlayer!= nil) {
[audioPlayer stop];
//do some task for changing the Image i.e setting the default image
}
}
- (IBAction)playSound:(UIButton *)sender
{
UIButton *btn = (UIButton*)sender;
NSString *soundName = [soundsArray objectAtIndex:(btn.tag - 1)];
NSString *path = [[NSBundle mainBundle] pathForResource:soundName ofType:#"mp3"];
NSURL *file = [[NSURL alloc] initFileURLWithPath:path];
AVAudioPlayer *p = [[AVAudioPlayer alloc] initWithContentsOfURL:file error:nil];
self.audioPlayer = p;
if([audioPlayer isPlaying])
{
[self stopAudio];
}
[self.audioPlayer 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.
}
#pragma mark - Flipside View
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
[self dismissViewControllerAnimated:YES completion:nil];
}
- (IBAction)showInfo:(id)sender
{
FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideViewController" bundle:nil];
controller.delegate = self;
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:controller animated:YES completion:nil];
}
#end
I have 3 buttons. In the 'Supporting Files' folder I have an array of strings with the name of the sound files I want to play, named 'Sound.plist', and in the 'Supporting Files' folder I have a folder named 'Sounds', which contains the sound files.
All of my buttons play the same sound, even when I delete the .plist file. It seems to always play the sound that is first in the 'Sounds' folder. Can someone please provide some insight, I feel like I have tried everything. Thanks!

Related

How can I keep background music playing when switching ViewControllers?

I currently have a SettingsViewController which handles starting/stopping music and adjusting the musics volume.
Is it possible to make the music stay on after unwinding the SettingsViewController? And after turning on the music and switching ViewControllers, can I re-open the SettingsViewController and turn off the music as well? Please let me know the limitations.
Here is the code for my SettingsViewController.h
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#interface SettingsViewController : UIViewController <AVAudioPlayerDelegate>
{
AVAudioPlayer *audioPlayer;
IBOutlet UISwitch *Switch;
IBOutlet UISlider *Slider;
}
-(IBAction)Switch:(UISwitch *)sender;
-(IBAction)Slider:(UISlider *)sender;
#end
And here is the code for my SettingsViewController.m
#import "SettingsViewController.h"
#interface SettingsViewController ()
#end
#implementation SettingsViewController
-(IBAction)Switch:(UISwitch *)sender{
NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
if(sender.tag == 0){
if(sender.on){
[standardDefaults setObject:#"On" forKey:#"keyName"];
//choosing and setting the music file
NSString *music = [[NSBundle mainBundle]pathForResource:#"bgmusic1" ofType:#"mp3"];
audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:music] error:NULL];
audioPlayer.delegate = self;
audioPlayer.numberOfLoops= -1; //sets the music to loop infinitely
[audioPlayer play]; //plays the music
} else if (sender.on == 0){
[standardDefaults setObject:#"Off" forKey:#"keyName"];
[audioPlayer stop]; //stops the music
}
}
[standardDefaults synchronize];
}
-(IBAction)Slider:(UISlider *)sender{
audioPlayer.volume = sender.value / 100.0; //will adjust the volume of the music according the slider value
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
Let me know what needs to be modified!
Do that in your AppDelegate.
To access it from anywhere, import it's .h file in your ViewControllers .m file and access it with
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
Make the audioplayer to a property in your AppDelegate.h to allow public access (for e.g. your other viewControllers)
#interface AppDelegate: NSAppDelegate
{
IBOutlet UISwitch *Switch;
IBOutlet UISlider *Slider;
}
#property AVAudioPlayer *audioPlayer; // <------
-(IBAction)Switch:(UISwitch *)sender;
-(IBAction)Slider:(UISlider *)sender;
#end
Then adjust each call of your audioplayer in the m file to adopt the change in your h file.
//Instead of [audioplayer doSomething] write...
[self.audioplayer doSomething];
// in modern objective-c you can use also
[_audioplayer doSomething];
To call your audioplayer from other ViewControllers then implement the first mentioned code and call your player like so
[appDelegate.audioplayer doSomething]
Because your audioPlayer will be release when its parent SettingsViewController released.
So you should add it to global and you can make it with Singleton Pattern.
Create BackgroundPlayer.h
#interface BackgroundPlayer: NSObject {
AVAudioPlayer *audioPlayer;
}
+ (id)sharedManager;
#end
and BackgroundPlayer.m
#implementation BackgroundPlayer
static BackgroundPlayer* sharedInstance = nil;
+ (BackgroundPlayer*) sharedInstance {
if (sharedInstance == nil) {
sharedInstance = [[super allocWithZone:NULL] init];
}
return sharedInstance;
}
- (id)init
{
self = [super init];
return self;
}
-(void)playAudio:(NSString *) audioPath
{
audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:audioPath] error:NULL];
audioPlayer.delegate = self;
audioPlayer.numberOfLoops= -1; //sets the music to loop infinitely
[audioPlayer play]; //plays the music
}
-(void)setVolum:(float) volum {
if (audioPlayer) {
audioPlayer.volume = sender.value / 100.0;
}
}
Then you just call
NSString *music = [[NSBundle mainBundle]pathForResource:#"bgmusic1" ofType:#"mp3"];
[[BackgroundPlayersharedInstance] playAudio:music];

How to save audio to documents in iPhone?

I tried to record an audio and save it to documents folder, but the program can only work in simulator. Once I run it in my iPhone(ios 8.3), it cannot work. Is there something wrong with my codes? Thank you.
Here is h file:
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <AVFoundation/AVAudioPlayer.h>
#import <AVFoundation/AVAudioRecorder.h>
#import <Accelerate/Accelerate.h>
#interface ViewController : UIViewController{
AVAudioPlayer *player;
AVAudioRecorder *recorder;
}
- (IBAction)REC:(id)sender;
- (IBAction)STOP_and_SAVE:(id)sender;
- (IBAction)PLAY:(id)sender;
#property (nonatomic, strong) NSString *Record_path1_string;
#end
m file:
#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)REC:(id)sender {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
self.Record_path1_string = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"bbb.wav"];
recorder = [[AVAudioRecorder alloc] initWithURL:[NSURL fileURLWithPath: self.Record_path1_string] settings:nil error:nil];
[recorder prepareToRecord];
[recorder record];
NSLog(#"recording!");
}
- (IBAction)STOP_and_SAVE:(id)sender {
[recorder stop];
}
- (IBAction)PLAY:(id)sender {
player = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath: self.Record_path1_string] error:nil];
[player play];
}
#end
I have checked the Documents folder in simulator in my Mac, the audio file has been saved, but I cannot check Documents folder in my iPhone.

Bad Access code 1 with simple NSObject

I am creating a custom object, it is currently very simple. Below you will find my .h for the object.
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>
#interface LAZMessagePlayer : NSObject <AVAudioPlayerDelegate>
- (void)play:(UIView*)viewThatWasPressed;
- (void)pause;
- (BOOL)isPlaying;
#end
and the corresponding .m for the object
#import "LAZMessagePlayer.h"
#implementation LAZMessagePlayer {
AVAudioPlayer* myPlayer;
UIView* currentViewPlaying;
}
-(id)init{
NSLog(#"init audio");
NSURL* src = [NSURL fileURLWithPath:[NSString stringWithFormat:#"/Users/Developer/Downloads/317.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError* error;
myPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:src error:&error];
}
-(void)play:(UIView*)viewThatWasPressed {
NSLog(#"play");
currentViewPlaying = viewThatWasPressed;
currentViewPlaying.hidden = YES;
[myPlayer play];
}
-(void)pause {
NSLog(#"pause");
currentViewPlaying.hidden = NO;
[myPlayer pause];
}
-(void)audioPlayerDidFinishPlaying:
(AVAudioPlayer *)player successfully:(BOOL)flag
{
NSLog(#"done");
currentViewPlaying.hidden = NO;
}
-(BOOL)isPlaying {
return myPlayer.playing;
}
#end
Inside of my ViewController i have declared a private variable at the top of my Controller.m like so,
#import "LAZMessagesViewController.h"
#interface LAZMessagesViewController () {
LAZMessagePlayer* myPlayer;
}
Inside my viewDidLoad I alloc/init myPlayer.
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationBarExtensionViewDelegate = self;
// Do any additional setup after loading the view.
myPlayer = [[LAZMessagePlayer alloc] init];
}
Later inside my Tap handler I receive a BAD ACCESS code = 1 the first time I try to reference myPlayer, here is the first line that breaks
if([myPlayer isPlaying])...
I am familiar with c++ memory management, but new to Objective-C entirely. Can somebody please point out my glaringly obvious miss.
Thank you.
Solved it myself. Inside of Object.h I needed:
self = [super init];
.
.
.
return self;

SoundBoard error no visible #interface for 'NSBundle' declares the selector 'pathForRescource:ofType:'

i am trying to make a simple audio board application, i am following the Apple documentation on the AVFoundationPlayer, but i keep getting this error (no visible #interface for 'NSBundle' declares the selector 'pathForRescource:ofType:' ) and i have searched for an hour, with no result.
my .h file
#import <UIKit/UIKit.h>
#import <AVFoundation/AVAudioPlayer.h>
#interface ViewController : UIViewController <AVAudioPlayerDelegate> {
}
//actions
-(IBAction)playSound1;
-(IBAction)playSound2;
-(IBAction)playSound3;
-(IBAction)playSound4;
#property (nonatomic, strong) AVAudioPlayer *player;
#end
my .m file
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize player;
- (void)viewDidLoad
{
NSString *soundFilePath1 =
[[NSBundle mainBundle] pathForRescource: #"trumpet"
ofType: #"mp3"];
NSURL *fileURL1 = [[NSURL alloc] initFileURLWithPath: soundFilePath1];
AVAudioPlayer *newPlayer =
[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL1 error:nil];
[fileURL1 release];
self.player= newPlayer;
[newPlayer release];
[player prepareToPlay];
[player setDelegate: self];
[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
If i can provide any other details i would be happy to help and thank you for reading.
It's a typo. You have written pathForRescource: and it is pathForResource:ofType:.
- (NSString *)pathForResource:(NSString *)name ofType:(NSString *)extension

AVAudioPlayer mp3 file not playing

I am an amateur developer making an ios app which includes a sound file (mp3) being played when a button impressed. However, the sound is not playing (tested on a mobile device, not ios simulator). I already have the sound file in bundle resources and have added AVFoundation to link binary with libraries. I have xcode 4.6 and have mac osx 10.8.4. Here is my code for 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;
#property (nonatomic, strong) AVAudioPlayer *avPlayer;
- (void)revmob;
#end
Viewcontroller.m:
#import "ViewController.h"
#import <RevMobAds/RevMobAds.h>
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[[RevMobAds session] showBanner];
// Do any additional setup after loading the view, typically from a nib.
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");
}
[self performSelector:#selector(revmob) withObject:nil afterDelay:10.0];
}
- (void)revmob
{
[[RevMobAds session] showFullscreen];
}
- (IBAction)playButton:(id)sender
{
[_avPlayer play];
NSLog(#"Sound playing");
}
- (IBAction)stopButton:(id)sender
{
[_avPlayer pause];
NSLog(#"Sound Stopped");
}
#end
In ViewController.h import the AVFoundation header file:
#import
Go the ViewController.m and add the following outlet properties and IBAction method definitions in the interface section:
#interface ViewController ()
#property (nonatomic, strong) IBOutlet UILabel *trackTitle;
#property (nonatomic, strong) IBOutlet UILabel *playedTime;
- (IBAction)stopSound:(id)sender;
- (IBAction)playOrPauseSound:(id)sender;
#end
Go back to ViewController.xib and make the following connections:
top label -> trackTitle outlet
middle label -> playedTime outlet
left button -> IBAction playOrPauseSound
right button -> IBAction stopSound
Now the connections are made we can finish our code in ViewController.m. In the interface section add the following properties
#property (nonatomic, strong) AVAudioPlayer *audioPlayer;
#property (nonatomic) BOOL isPlaying;
#property (nonatomic, strong) NSTimer *timer;
Go the ViewController.m and add the following outlet properties and IBAction method definitions in the interface section.
#interface ViewController ()
#property (nonatomic, strong) IBOutlet UILabel *trackTitle;
#property (nonatomic, strong) IBOutlet UILabel *playedTime;
- (IBAction)stopSound:(id)sender;
- (IBAction)playOrPauseSound:(id)sender;
#end
Change the viewDidLoad method in :
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.isPlaying = NO;
self.trackTitle.text = #"The Stone Foxes - EveryBody Knows";
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *filePath = [mainBundle pathForResource:#"thestonefoxes-everybodyknows" ofType:#"mp3"];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
NSError *error = nil;
self.audioPlayer = [[AVAudioPlayer alloc] initWithData:fileData error:&error]
[self.audioPlayer prepareToPlay];
}
- (IBAction)playOrPauseSound:(id)sender;
{
if (self.isPlaying)
{
// Music is currently playing
[self.audioPlayer pause];
self.isPlaying = NO;
}
else
{
// Music is currenty paused/stopped
[self.audioPlayer play];
self.isPlaying = YES;
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateTime) userInfo:nil repeats:YES];
}
}
- (void)updateTime
{
NSTimeInterval currentTime = self.audioPlayer.currentTime;
NSInteger minutes = floor(currentTime/60);
NSInteger seconds = trunc(currentTime - minutes * 60);
// update your UI with currentTime;
self.playedTime.text = [NSString stringWithFormat:#"%d:%02d", minutes, seconds];
}
- (IBAction)stopSound:(id)sender
{
[self.audioPlayer stop];
self.audioPlayer.currentTime = 0;
self.isPlaying = NO;
}
I've tested your code on my Mac and it seems to work just fine. It could be that the cause for your problem is that while your mp3 is visible in Xcode, it's not being added to the bundle during compilation. Like in this question.
To fix it, click the mp3 in Xcode, look at the File Inspector and check the Target Membership box next to your target (in the screenshot mine is SOTest).

Resources