How to loop audio on a specific View Controller - ios

-(void)viewDidAppear:(BOOL)animated
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"Intro",
CFSTR ("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID (soundFileURLRef, &soundID);
AudioServicesPlaySystemSound (soundID);
}
I'm a beginner with this. I'm trying to play a wav file in the background of the view controller. I originally made a 30 second wav file, it wouldn't play, I reduced the length of the audio file to 10 seconds and it plays fine on the view controller. My question is, how to loop this audio file and/or play a longer audio file. Also, will the audio stop when I leave the view controller.
I am using xCode 4.3
I am running the app on a iPhone4 & 4s (iOS 5.1)
Thanks in advance...

Apple Documentation states
http://developer.apple.com/library/ios/#documentation/AudioToolbox/Reference/SystemSoundServicesReference/Reference/reference.html
You can use System Sound Services to play short (30 seconds or shorter) sounds. The interface does not provide level, positioning, looping, or timing control, and does not support simultaneous playback: You can play only one sound at a time. You can use System Sound Services to provide audible alerts. On some iOS devices, alerts can include vibration.
So no loop is available when using system sounds.
You can check out this tutorial
http://mobileorchard.com/easy-audio-playback-with-avaudioplayer/
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#/audiofile.mp3", [[NSBundle mainBundle] resourcePath]]];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
audioPlayer.numberOfLoops = -1;
if (audioPlayer == nil)
NSLog([error description]);
else
[audioPlayer play];
}
It states that if you set the numberOfLoops property to a negative number causes the audioPlayer to loop indefinitely
And dont forget to add the AVFoundation framework to your project

Related

iOS AVAudioPlayer sound stops playing when screen is locked

I’ve read many articles/posts on this topic, but I’m still unable to play a sound while the screen is locked.
In viewDidLoad, I initialize the audio session and set the audio property to kAudioSessionCategory_MediaPlayback:
AudioSessionInitialize(NULL, NULL, interruptionListenerCallback, self);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(sessionCategory), &sessionCategory);
AudioSessionSetActive(true);
I then initialize my AVAudioPlayer variable (audioPlayer):
NSString *soundFilePath = [[NSBundle mainBundle] pathForResource: #"click" ofType: #"wav"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
NSError *error;
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: &error];
[fileURL release];
I added “App plays audio” to a “Required background modes” section of my info.plist.
I added AVAudioPlayerDelegate and AVAudioSessionDelegate to my view controller’s *.h file (although I don’t know if that was necessary).
I play the (very short) sound periodically (~1x per second):
[audioPlayer play]
The sound plays fine when the screen is unlocked, but stops playing when I lock it. When I then unlock the screen, the (queued) sounds are played.
Ideas? Thanks!
Thanks holex:
I got "App plays audio" from http://mobile.tutsplus.com/tutorials/iphone/ios-sdk_background-audio/.
If you add a row with UIBackgroundModes to the plist, it's automatically populated and includes this and six other background modes. If you Google "App plays audio" and UIBackgroundModes you'll see plenty of hits.
[I would have replied via a Comment rather than an Answer, but alas, I don't have the reputation.]
It seems the problem is that I'm starting to play the sound after the screen has been locked. That's mostly answered in How to play sounds in locked mode on iPhone.

Creating AVAudioPlayer object much before playing the dynamic audio

Whenever i play an audio file like below, it is taking few seconds to start playing the audio. I have seen from some forums and understand that, AVAudioPlayer will take few seconds to start playing if we allocate the object there itself. I am thinking to allocate this object much earlier (may be Appdelegate itself), before when i want to play, so that when i want to play it, it will play immediately.
NSURL *audioPathURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:audioName ofType:#"wav"]];
audioP = [[AVAudioPlayer alloc]initWithContentsOfURL:audioPathURL error:NULL];
[appDelegate.audioP play];
but, i am passing audio url dynamically at run time, so i would like to know how can i allocate the object earlier and then be able to pass dynamic audio url path later?
Please note, my question is different from this question Slow start for AVAudioPlayer the first time a sound is played
In the existing question, they are telling about one audio file and play it when required. But, i am having many different audio file and url path is generated randomly and at run time to play, so i do not know what the actual url path to set and play. So, the answer mentioned here->Slow start for AVAudioPlayer the first time a sound is played
won't help for my question.
I can't use prepareToPlay, because audio path url is set at run time and not just one audio is being used for all the times to play, there will more than 20 audio file randomly chosen and set to play one at a time. So, i need the right answer for it, it is not a duplicate question.
Thank you!
For a single file here the solution:
in your file.h
#import <AVFoundation/AVFoundation.h>
#interface AudioPlayer : UIViewController <AVAudioPlayerDelegate> {
}
To use with button add - (IBAction)Sound:(id)sender; in your file.h
Now in your file.m
//this is a action but you can use inside a void to start auto
#implementation AudioPlayer {
SystemSoundID soundID;
}
- (IBAction)Sound:(id)sender {
AudioServicesDisposeSystemSoundID(soundID);
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
//you can use here extension .mp3 / .wav / .aif / .ogg / .caf / and more
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"sound" ,CFSTR ("mp3") , NULL);
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
}
If you want use your code to play audio from URL you can use this:
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>
#interface AudioPlayer : UIViewController <AVAudioPlayerDelegate> {
AVPlayer *mySound;
}
#property (strong, nonatomic) AVPlayer *mySound;
#end
And file.m
- (IBAction)playPause:(id)sender {
if (mySound.rate == 0){
NSURL *url = [NSURL URLWithString:#"http://link.mp3"];
mySound = [[AVPlayer alloc] initWithURL:url];
[mySound setAllowsExternalPlayback:YES];
[mySound setUsesExternalPlaybackWhileExternalScreenIsActive: YES];
[mySound play];
} else {
[mySound pause];
}
}
Hope this can help you!
One thing you can do to reduce the latency of the first load+play is to "spin up" the underlying audio system before you need it by loading and playing a dummy file. For example, in application:didFinishLaunchingWithOptions: add some code like this:
// this won't effect the problem you're seeing, but it's good practice to explicitly
// set your app's audio session category
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
NSURL *audioURL = [[NSBundle mainBundle] URLForResource:#"dummy.wav" withExtension:nil];
AVAudioPlayer *dplayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:nil];
// we don't want to hear it (alternatively, the audiofile you use for this purpose can be silence.)
dplayer.volume = 0.f;
[dplayer prepareToPlay];
[dplayer play];
[dplayer stop];
Once this code completes, subsequent instantiations and playback of AVAudioPlayer instances should have pretty low latency (certainly well under 1 second)

AVfoundation AudioPlayer not working

I am trying to play a sound on button click using the AVFoundation framework. Previously, i used audio toolbox however when i use the audioplayer nothing comes out. What is weird is that when i test it on my phone and i press the button, the volume controls aren't the normal ringer volume controls. This suggests that it should be playing but i can't hear anything, on my phone or the simulator. I have used different files, created new project changed the code, nothing has helped.
Here's the code in .h:
#interface MainViewController : UIViewController <AVAudioPlayerDelegate>
- (IBAction)test;
Here's the code in .m:
- (IBAction)test {
NSString *path = [[NSBundle mainBundle] pathForResource:#"sound" ofType:#"mp3"];
AVAudioPlayer* theAudio = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
theAudio.delegate = self;
[theAudio play];
}
can you do this before you play the sound i think you might have the wrong category:
AudioSessionInitialize (NULL,NULL,NULL,NULL);
UInt32 sessionCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty (kAudioSessionProperty_AudioCategory,sizeof (sessionCategory),&sessionCategory);
AudioSessionSetActive(true);

iOS sound plays while muted

I am making a learn-the-alphabet app for toddlers and I have encountered a problem with the sound output. Every sound the app plays when testing on my ipad has the same volume whether the device's sound is set at maximum or mute. In other words, the same sound level comes out regardless of the device's volume setting.
The code I use to play sounds is (using the A-sound as an example):
- (IBAction)aSpill:(id)sender {
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef soundFileURLRef;
soundFileURLRef = CFBundleCopyResourceURL(mainBundle, (CFStringRef) #"aLyd", CFSTR("wav"), NULL);
UInt32 soundID;
AudioServicesCreateSystemSoundID(soundFileURLRef, &soundID);
AudioServicesPlaySystemSound(soundID);
Any help is much appreciated! :)
Please see the answer here AudioServicesPlaySystemSound Volume?
It explains that system sounds don't always use the system volume.
I suggest using AVAudioPlayer to play your sound instead.
So from here : http://developer.apple.com/library/ios/#documentation/AudioVideo/Conceptual/MultimediaPG/UsingAudio/UsingAudio.html
Try following the code using the below kind of code.
NSString *soundFilePath =
[[NSBundle mainBundle] pathForResource: #"sound"
ofType: #"wav"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
AVAudioPlayer *newPlayer =
[[AVAudioPlayer alloc] initWithContentsOfURL: fileURL
error: nil];
[fileURL release];
self.player = newPlayer;
[newPlayer release];
[player prepareToPlay];
It is about halfway down the page.

playing audio when apps running

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

Resources