iOS : How to stop a background music with only one button? - ios4

I have a music button in the main UI of iOS and I want the button function as stop music button and at the same time can play the music again. My problem is I can only stop the music but can't play it again. Here is my iOS code in xcode4. How can I define one button for both play and stop music button? I have assigned one button for both stopMusic and playMusic but it doesn't work.
- (IBAction)stopMusic{
self.playBgMusic.enabled = YES;
[self.player stop];
}
- (IBAction)playMusic{
self.playBgMusic.enabled = YES;
[self.player play];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
NSString *path = [[NSBundle mainBundle] pathForResource:#"music" ofType:#"mp3"];
self.player=[[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL];
player.delegate = self;
[player play];
player.numberOfLoops = -1;
[super viewDidLoad];
}

Rather than have a single button try to send two different messages (stopMusic, playMusic), have it send toggleMusic every time. The toggleMusic method can then stop or play the music based on the current state of the player.
- (IBAction)toggleMusic{
if ([self.player isPlaying] == YES) {
[self.player stop];
} else {
[self.player play];
}
self.playBgMusic.enabled = YES;
}

Related

Game center issue

Im New In Development think and i'm wondering about some things like the game center button , how to connect that button is there any ready code for that, the same question about the rate button . Can any one tell me how to do that
//Rate Button
if ([node.name isEqualToString:#"rateButton"]) //Your Rate Button name
{
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"itms-apps://itunes.apple.com/app/id919770861"]];//itms-apps://itunes.apple.com/app/idYourAppID
}
//Game Center Button
- (void)showGKGameCenterViewController:
(UIViewController *)viewController
{
if (!_enableGameCenter) {
NSLog(#"Local play is not authenticated");
}
GKGameCenterViewController *gameCenterViewController =
[[GKGameCenterViewController alloc] init];
gameCenterViewController.gameCenterDelegate = self;
gameCenterViewController.viewState =
GKGameCenterViewControllerStateAchievements;
[viewController presentViewController:gameCenterViewController
animated:YES
completion:nil];
}
if ([node.name isEqualToString:#"GameCenter"]) //Your Game Center Button Name
{
[self showGKGameCenterViewController:yourViewController];
}

Text field stays under the custom keyboard in UIWebView for iOS 8

I'm creating a web App for iOS and I have a custom keyboard. When I use the default keyboard, it immediately shows the keyboard and the text field is above the keyboard. I would have the same result if I change the keyboard to my custom keyboard. But the problem is for the time that I gives the focus to the text field when my custom keyboard is enabled. It has some delay to load and when it loads, text field stays under the keyboard. Here is my code for custom keybaord:
#import "KeyboardViewController.h"
#import "CustomKeyboardView.h"
#interface KeyboardViewController () <CustomKeyboardViewDelegate>
#property (nonatomic, strong) CustomKeyboardView *customKeyboardView;
#end
#implementation KeyboardViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.customKeyboardView = [[CustomKeyboardView alloc] init];
self.inputView = (UIInputView *) self.customKeyboardView;
self.customKeyboardView.delegate = self;
}
- (void)handleCharacter:(NSString *)character sender:(CustomKeyboardView *)sender
{
[self.textDocumentProxy insertText:character];
}
-(void)handelDelete:(CustomKeyboardView *)sender
{
[self.textDocumentProxy deleteBackward];
}
-(void)handleDismissKeyboard:(CustomKeyboardView *)sender
{
[self dismissKeyboard];
}
-(void)handleChangeKeyboard:(CustomKeyboardView *)sender
{
[self advanceToNextInputMode];
}
- (void)textWillChange:(id<UITextInput>)textInput {
// The app is about to change the document's contents. Perform any preparation here.
}
- (void)textDidChange:(id<UITextInput>)textInput {
// The app has just changed the document's contents, the document context has been updated.
[[NSNotificationCenter defaultCenter] postNotificationName:UITextViewTextDidChangeNotification object:textInput];
}
#end
The implementation of CustomKeyboardView class is similar to this library. Any help would be appreciated.
Try use the background threads, you have a delay because u execute a lot of code before you build your keyboard view first.

How to play track using cocoalibspotify when app is in the background?

Is it possible to play a track when the app has exited/gone into a background state?
For example:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSURL *trackURL = [NSURL URLWithString:#"spotify:track:489K1qunRVBm2OpS4XGLNd"];
[[SPSession sharedSession] trackForURL:trackURL callback:^(SPTrack *track) {
if (track != nil) {
[SPAsyncLoading waitUntilLoaded:track timeout:kSPAsyncLoadingDefaultTimeout then:^(NSArray *tracks, NSArray *notLoadedTracks) {
[self.playbackManager playTrack:track callback:^(NSError *error) {
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Cannot Play Track"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
} else {
self.currentTrack = track;
}
}];
}];
}
}];
}
The above code was taken from the Simple Player app provided with cocoalibspotify.
Copying and pasting code like this won't get you far when backgrounding - you can't use UI elements like UIAlertView, for a start.
You need to declare your application as supporting the audio background mode as documented by Apple. Then, when you go into the background you should make a background task to start playback.

iPhone SDK AVAudioPlayer - stop and then fail to start

- (IBAction)triggerSound {
if (player == nil) {
NSError *error;
player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
} else if ([player isPlaying]) {
[player stop];
player.currentTime = 0;
}
if (![player play]) {
NSLog(#"fail");
}
}
Where player is AVAudioPlayer and this action is linked with a UIButton. The sound can be played, and can be played again after the sound finish, but when I press the button again during the playback, the message "fail" is logged and the sound cannot be played, without any exception.
I and using iPad with iOS 4.2.1.
I have noticed that the audio stream fails to play after calling stop(which according to the reference undoes what prepareToPlay and play does).
Instead of calling stop, setting currentTime to player.duration(end of the stream) worked.

MPMoviePlayerController causes flash of black at start of video

The movie plays just fine but there is a quick black flash right before it plays. Is this a quirk resulting from setting the controlstyle to MPMovieControlStyleNone?
NSString *url = [[NSBundle mainBundle] pathForResource:#"00" ofType:#"mov"];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc]
initWithContentURL:[NSURL fileURLWithPath:url]];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
//---play video in implicit size---
player.view.frame = CGRectMake(80, 64, 163, 246);
[self.view addSubview:player.view];
// Hide video controls
player.controlStyle = MPMovieControlStyleNone;
//---play movie---
[player play];
I just had this problem and fixed it by adding an observer to the default NSNotificationCenter to find out when the movie was completely ready to play, and THEN adding the view as a subview to my main view.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkMovieStatus:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
...
if(moviePlayer.loadState & (MPMovieLoadStatePlayable | MPMovieLoadStatePlaythroughOK))
{
[pageShown.view addSubview:moviePlayer.view];
[moviePlayer play];
}
In IOS 6 mpmoviewplayer added a new property :readyForDisplay
this is what I'm playing around with and so far so good:
create mpmovieplayer ,add to stage, hide it.
add notification for play state on the movieController
wait for the displayState to Change and once its ready show the video controller:
- (void)moviePlayerPlayState:(NSNotification *)noti {
if (noti.object == self.movieController) {
MPMoviePlaybackState reason = self.movieController.playbackState;
if (reason==MPMoviePlaybackStatePlaying) {
[[NSNotificationCenter defaultCenter] removeObserver:self name: MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
while (self.movieController.view.hidden)
{
NSLog(#"not ready");
if (self.movieController.readyForDisplay) {
dispatch_async(dispatch_get_main_queue(), ^(void) {
NSLog(#"show");
self.movieController.view.hidden=NO;
});
}
usleep(50);
}
});
}
}
}
When the play state changes to MPMoviePlaybackStatePlaying we start checking for the readyDisplayState to change.
Evidently there is a flash of black in the movie rect until enough movie loads so it can start playback. Here is my workaround:
Create a UIImageView and put the MPMoviePlayerController in it. That way you can set the alpha to 0.
As soon as you call [player play]; to play the video, set up a .5 second timer.
When the time is done, change the alpha to 1.
This will make the player invisible for 1/2 second (which hides the black flash).
Create video without addSubview and play instructions:
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"video" ofType:#"mp4"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
MPMoviePlayerController *moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
[moviePlayerController.view setFrame:CGRectMake(80, 64, 163, 246)];
moviePlayerController.controlStyle = MPMovieControlStyleNone;
Prepare video to play and add notification:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(checkMovieStatus:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
[moviePlayerController prepareToPlay];
Create function checkMovieStatus with addSubview and play instructions:
- (void)checkMovieStatus:(NSNotification *)notification {
if(moviePlayerController.loadState & (MPMovieLoadStatePlayable | MPMovieLoadStatePlaythroughOK)) {
[self.view addSubview:moviePlayerController.view];
[moviePlayerController play];
}
}
Or simply change the color of the view, that is what your actually seeing...
player.view.backgroundColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0];
I believe the black flash may be related to the movieSourceType property of MPMoviePlayerController.
If you don't set it, it defaults to MPMovieSourceTypeUnknown which causes the UI to be delayed until the file is loaded.
Try adding this line:
player.movieSourceType = MPMovieSourceTypeFile;
Right after initializing player.
To avoid the black flash, use a MPMoviePlayerViewController instead of a MPMoviePlayerController. I think that this class creates the background on view display, rather than on video load (like MPMoviePlayerController does).
Before adding the moviePlayerViewController.moviePlayer.view to your display view, you have to add a white subview (or a subview appropriate for your content) to the backgroundView, like this:
[moviePlayerViewController.moviePlayer.view setFrame:[displayView bounds]];
UIView *movieBackgroundView = [[UIView alloc] initWithFrame:[displayView bounds]];
movieBackgroundView.backgroundColor = [UIColor whiteColor];
[moviePlayerViewController.moviePlayer.backgroundView addSubview:movieBackgroundView];
[movieBackgroundView release];
Fond solution here http://joris.kluivers.nl/blog/2010/01/04/mpmovieplayercontroller-handle-with-care/
from iOS 6
you need to use [self.moviePlayer prepareToPlay]; and catch MPMoviePlayerReadyForDisplayDidChangeNotification to use [self.moviePlayer play];

Resources