pause only one AVAudioPlayerNode - objective-c

I encounter some problems with AVFoundation and sound spatialisation.
I have several instances of player (AVAudioPlayerNode) attached to the audio engine.
they are connected to one environment node (AVAudioEnvironmentNode). the players node play some mini sounds. An finally, the environment node is connected to the main mixer
[engine mainMixerNode];
It works great, but when I decide to pause one particular player with
[player pause];
It pause the player but also all the other playerNodes.

Related

How do you designate audio device channels when using AVPlayer?

I am attempting to designate output channels of an audio interface for sending audio during video playback on macOS. I am using AVPlayer to play a video file:
auto player = [AVPlayer playerWithPlayerItem:playerItem]; // playerItem created from a file path
player.audioOutputDeviceUniqueID = deviceID; // deviceID determined by passing kAudioObjectPropertyName to AudioObjectGetPropertyData and inspecting device name, e.g. "Babyface Pro"
/* select hardware channels? */
[player play];
The AVPlayer defaults to playing channels 1/2 of my Babyface Pro, but I'd like to select, for instance, channels 3/4. I cannot select these channel routes globally (i.e. through TotalMix FX) since I am using more than one AVPlayer and selecting separate channels for each.
I came across a nearly identical question, however the question did not require playing video, only audio.

Home Button doesn't terminate multiplayer match on Game Center / Gamekit

First of all I have to say I am new to iOS development.
My problem is during a multiplayer game using Game Center. I don't now how to get a notification from Game Center if the other player (my game is a 2 player game) leaves the game with the home button of the device.
I need to know when one player closes the game since the game always starts from scratch when re-opened, this means, it will show the splash screen and go directly to the main menu. I've tried re-matching but Game Center seems to be creating a new connection and looking for new players, meanwhile player 2 keeps 'playing' with player 1 without any response happening, so his match will never end.
Any method, didChangeState, matchmakerViewControllerWasCancelled nor authenticationChanged, the latter being under a notification, seem to do anything when the home button is pressed.
Any help would be appreciated
Try subscribing to NSNoficationCenter to find out when your app goes to the background:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(userPressedHomeButton:)
name:UIApplicationDidEnterBackgroundNotification object:nil];
In your userPressedHomeButton: function you can decide how to notify the other player or suspend the game. BUT, you must take action quickly, because iOS will not allow your app to run more than a few seconds after it has been suspended.
As an alternate to subscribing to NSNotificationCenter, you can do your implementation in your AppDelegate:
- (void)applicationWillResignActive:(NSNotification *)notification { }

AVQueuePlayer playing items simultaneously rather than in sequence

I am trying to put together a simple app to play a pre-roll video followed by some content video.
Currently, I'm trying to use the AVQueuePlayer class to get this done. Unfortunately, it seems to want to play the videos properly in sequence.
For example, the pre-roll plays by itself for a few seconds, then (prior to the pre-roll being complete) it starts to try and play the content video. For a few seconds, the player seems to be at war with itself and switches back and forth between the two videos (neither playing very well at all). Finally, when the pre-roll is finished, the content video then plays the rest of the way normally.
I've looked through the documentation for the AVQueuePlayer and I don't see anything obvious that I'm missing.
My code is pretty basic:
AVPlayerItem *preRollItem = [AVPlayerItem playerItemWithURL: preRollUrl];
AVPlayerItem *contentItem = [AVPlayerItem playerItemWithURL: contentUrl];
self.player = [AVQueuePlayer queuePlayerWithItems:[NSArray arrayWithObjects:preRollItem, contentItem, nil]];
[self.player play];
What is the trick to getting the videos to play in sequence.
Make sure you are actually testing on the device. From my experience the iOS5 simulator has big problems with AVQueuePlayer and does bizarre things.
I found the iOS4.3 simulator is doing a much better job when it comes to testing AVFoundation.

How do you know when a user chooses to play a video through AirPlay?

I have a custom video player set up with custom controls, and I utilize MPVolumeView to provide an airplay button. When a user chooses to use AirPlay, they interact with that Apple UI and there is no event (that I can find) that says "hey, the video is now playing over AirPlay".
The problem is that, if I close the player and reopen it, it loads the movie (load state changes to MPMovieLoadStatePlayable), I play it, and I immediately get a playback did finish notification with reason being MPMovieFinishReasonPlaybackEnded, and the video continues to try to play through AirPlay. I'm certain the movie stops and is deallocated whenever I close the player.
If anyone has any advice on how to handle this, knows some events to listen for, or has any ideas about this whatsoever, please let me know. Thanks!
The answer here turns out to be that, at least up to 4.3, there is no way to get an answer to this through code.
The problem in this case is how you dispose of the MPMoviePlayerController when you're finished with it. Even if the video plays through, before you finally release it, you have to call pause and then stop. Like this:
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] init];
// use the player. then when done with it:
[mp pause];
[mp stop];
[mp release];
If you don't do this then the next time you create a MPMoviePlayerController, certain properties are somehow ghosted in the framework. Playing a video progressively caused audio from the previous mp to play while the new mp did its initial buffering. Also, if the previous video was playing over airplay, the next video would get a notification that the video finished right after it starts and some other weirdness.
Long story short, dispose of your video players with the above sequence to avoid issues with later movie players.

Definitive answer to what playersToInvite is for

The Game Center documentation indicates that the
playersToInvite parameter is non-nil
when your application is launched
directly from the Game Center
application to host a match.
A few people have asked how this works exactly, i.e. there doesn't appear to be a way to select a friend from the Game Center application and invite them to play from Game Center; it only works when you invite in-game. Is this documentation dated or is there a secret way to start a game-specific match from Game Center? I'd like to test my inviteHandler but I've been unable to determine how this parameter is passed to the application.
[GKMatchmaker sharedMatchmaker].inviteHandler = ^(GKInvite *acceptedInvite, NSArray *playersToInvite)
{
// clean up games in progress here
if (acceptedInvite)
{
NSLog(#"acceptedInvite %#", acceptedInvite);
// The acceptedInvite parameter is non-nil when the application receives an
// invitation directly from another player.
GKMatchmakerViewController *mmvc = [[[GKMatchmakerViewController alloc] initWithInvite:acceptedInvite] autorelease];
mmvc.matchmakerDelegate = self;
[self disableHomeUI];
[self presentModalViewController:mmvc animated:YES];
}
else if (playersToInvite)
{
NSLog(#"playersToInvite %#", playersToInvite);
// playersToInvite parameter is non-nil when your application is launched
// directly from the Game Center application to host a match
[self disableHomeUI];
[self doPresentMatchMakerUIWithPlayersToInvite:playersToInvite];
}
};
I think the docs do not reflect the current state of affairs. As far as I can tell, the Game Center App does not even offer an interface for inviting friends to play, currently.
Also, check the developer forums (apparently you have ;) ). Someone from Cupertino seems to think it is not possible. So...
After launching my application Cee-lo into production, the playersToInvite code became active. This seems to be because the Sandbox version of the Game Center app itself does not allow you to start a game with a player from there, but the production version does. Not a very good test environment if you ask me!
There is now a way to use the Game Center app to invite a Game Center friend. It ONLY works if your game calls registerListener: on the localPlayer GKPlayer:
Game Center App
-> games tab
-> your game
-> Players section
-> select a player
-> "Play a Game"
This will send a push notification invite to the other player. Game does not have to be running on either device. As of iOS7.
This flow also works:
Game Center App
-> friends tab
-> tap a friend
-> tap a game in common (your game)
-> tap the "..." in the top right corner
-> tap "Play"
I could be wrong, but i think it is just the "simulator" that can not invite particular friends to play.
I have been able to use 2 or more iPhones running in the sandbox to invite particular friends to play, and it has worked wonderfully for debugging the invite handler piece of code.
As another poster mentioned, there does not appear to be at this time a way of inviting particular friends to play a particular game from Game Center.
Happy gaming!