I'm using the systemMusicPlayer to play songs inside an app.
If a user pushes noiseButton on the Now Playing view, it will pause the systemMusicPlayer song audio file for 10 seconds to play the noiseButton audio file, and then pick back up on the systemMusicPlayer song audio file.
I'm able to get the systemMusicPlayer song audio file to pause and then pick back up after 10 seconds, but I am not able to get the noiseButton to play its sound in the 10 seconds.
I know the noiseButton audio file works
I'm NSLogging before and after the method that plays the noiseButton file
I'm not sure what I'm missing?
Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
musicPlayer = [MPMusicPlayerController systemMusicPlayer];
[self registerMediaPlayerNotifications];
// Construct URL to sound file
NSString *path = [NSString stringWithFormat:#"%#/background-music-aac.caf", [[NSBundle mainBundle] resourcePath]];
NSURL *soundUrl = [NSURL fileURLWithPath:path];
// Create audio player object and initialize with URL to sound
_audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
}
- (void)willPlayClip {
[NSTimer scheduledTimerWithTimeInterval:10.0
target:self
selector:#selector(willPlayMusicInTenSeconds:)
userInfo:nil
repeats:NO];
}
- (void)willPlayMusicInTenSeconds:(NSTimer *)timer {
NSLog(#"Get ready to Play noise sound");
[_audioPlayer play];
NSLog(#"Play noise sound");
[musicPlayer play];
NSLog(#"Start playing again");
}
And the code inside the noiseButton for when it gets pressed:
if ([musicPlayer playbackState] == MPMusicPlaybackStatePlaying) {
[musicPlayer pause];
NSLog(#"Paused!");
[self willPlayClip];
} else {
NSLog(#"Already paused");
}
What AudioSession category are you setting? If you're not, refer to this documentation:
Audio Session Categories
I believe that you should get the desired behaviour if you set your session to AVAudioSessionCategoryAmbient:
The category for an app in which sound playback is nonprimary—that is, your app can be used successfully with the sound turned off.
This category is also appropriate for “play along” style apps, such as a virtual piano that a user plays while the Music app is playing. When you use this category, audio from other apps mixes with your audio. Your audio is silenced by screen locking and by the Silent switch (called the Ring/Silent switch on iPhone).
Give that a try if you're not already.
Related
I have an app that plays various musical sounds using AVAudioPlayer. It lets people select a song from their library and plays it with MPMusicPlayerController. It used to work that they could jam with it, but now when MPMusicPlayerController is playing it doesn't play the sound using AVAudioPlayer. It even doesn't play the sound once MPMusicPlayerController has stopped. I've tested it on 13.4.1 and 13.6. What changed to make it stop working and what can I do to fix it?
It plays the sound like this:
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&err];
[player prepareToPlay];
[player setVolume: 1.0];
[player play];
For the music, it gets a MPMediaItemCollection using MPMediaPickerController, then plays it like this:
- (void) playMusic: (MPMediaItemCollection *) collection {
[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryAmbient error: nil];
if (musicPlayer == nil) {
musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
[musicPlayer setShuffleMode: MPMusicShuffleModeOff];
[musicPlayer setRepeatMode: MPMusicRepeatModeNone];
}
[musicPlayer setQueueWithItemCollection:collection];
[musicPlayer play];
}
Feeling stupid. The phones were set to silent mode. For some reason, it can play the sounds or the music on silent, but it can't play them both together.
I am using AVAudioPlayer to play audio of .caf file store in the sandbox of the simulator. When I run the program and play the audio of the file that I created just now, it works, but I can't play the audio of the files created when the application ran last time.
My code for playing the audio:
if (self.audioURL != nil) {
_player = [[AVAudioPlayer alloc] initWithContentsOfURL:self.audioURL error:nil];
if (!_player) {
} else {
[_player setNumberOfLoops:0];
[_player setDelegate:self];
[_player play];
}
}
My .caf files are stored in the sandbox:
/Users/kiki/Library/Developer/CoreSimulator/Devices/2AF173A9-8C49-4F2E-9547-079AEDC0B020/data/Containers/Data/Application/EF2931D8-B498-4239-84AD-00525CA62F48/Documents
And the player didn't respond any error message, in other words, the methods of "audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error" and "audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag" not called.
How can I solve this?
Whenever I present my scene, I want to start playing a music file and stop the music playing from the last time my scene was presented. I'm trying to do it like this.
[self removeActionForKey:#"Music"];
[self runAction:[SKAction repeatActionForever:[SKAction playSoundFileNamed:#"Music.wav" waitForCompletion:YES]] withKey:#"Music"];
Should I use AVAudioPlayer or [SKAction playSoundFileNamed:]?
Also I would like to know if there is a way to play music file forever in all scenes without starting from the beginning.
To play background music in all scenes I will recommend AVAudioPlayer. You can write the code somewhere in your AppDelegate to access from all the scenes. Here is a sample code to achieve this using AVAudioPlayer
// AVAudioPlayer *bgMusicLoop;
- (void)playBackroundMusic:(NSString *)fileName withExtenstion:(NSString *)fileExtension
{
NSString *filePath = [[NSBundle mainBundle] pathForResource:fileName ofType:fileExtension];
NSError *error;
if(bgMusicLoop)
[bgMusicLoop stop];
bgMusicLoop = nil;
bgMusicLoop = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:&error];
if (error) {
NSLog(#"Error in audioPlayer: %#", [error localizedDescription]);
} else {
bgMusicLoop.numberOfLoops = -1;
[bgMusicLoop prepareToPlay];
[bgMusicLoop play];
}
}
- (void)stopBackgroundMusic
{
if(bgMusicLoop)
[bgMusicLoop stop];
bgMusicLoop = nil;
}
- (void)pauseBackgroundMusic
{
if(bgMusicLoop && bgMusicLoop.isPlaying)
[bgMusicLoop pause];
}
- (void)resumeBackgroundMusic
{
if(bgMusicLoop && !bgMusicLoop.isPlaying)
[bgMusicLoop play];
}
For music you should use AVAudioPlayer as using SKAction to play music will block any other actions you might want to run on the scene and its a bit more cumbersome to handle especially if you want to play more sounds along with the music.
Use SKAction to play short sound files (like player jump/fire etc...)
With AVAudioPlayer you can easily set your file to play repeatedly until stopped
I have a working AudioServicesPlaySystemSound code to run a 10s background music.
Is there a way for me to loop this audio every 10s ? I want it to run forever until an action is triggered to stop the audio (e.g: a button is pressed to stop the loop)
I read an article about dispatch_after and thought that it might be an appropriate way to create the loop.
Switch to AVAudioPlayer instead. Not only can you specify a number of times to play the sound, but you have more control over the sound, including volume level.
It isn't that much harder. For example, here is how you would play a sound, looped indefinitely:
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
AVAudioPlayer *player = [{AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: nil];
player.numberofLoops = -1;
[player play];
and this is how you would stop it:
[player stop];
In a view controller I have a video playing and also some background music. If the background music is playing, the video freezes when it goes to loop. If the background music is not playing the video loops normally as it should.
Here's how I'm setting up the video player:
self.moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:[self getBundleClip:#"MyVideo"]];
self.moviePlayer.controlStyle = MPMovieControlStyleNone;
self.moviePlayer.shouldAutoplay = YES;
self.moviePlayer.repeatMode = MPMovieRepeatModeOne;
The audio is playing via this Sound Manager. Any idea why the video would be freezing?
Try to use play music in background AVAudioPlayer and play same time MPMoviePlayerController like below code for play the AVAudioplayer in repeat mode:
first initialize the AVAudioplayer object in your header file (.h) like below:
#interface Yourviewcontroller : UIViewController
{
//your some codes after
AVAudioPlayer *audioPlayer;
}
#property (strong, nonatomic) AVAudioPlayer *audioPlayer;
after implement play audio file in background like below code:
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath: [[NSBundle mainBundle] pathForResource:#"audio" ofType:#"mp3"]] error:NULL];
audioPlayer.numberOfLoops =-1;//it's play audio repeatedly
audioPlayer.currentTime=0.0f;
[audioPlayer prepareToPlay];
after play audio any part of project like below code:
[audioPlayer play];
you want stop the audio player like below code:
[audioPlayer stop];