Question

I have an online music player. I want to add a feature to it that if the song is being played and a call (incoming or outgoing) is made, it should pause the music which call is going on and after the call is disconnected, the music should start again.

here is the code I have:

// // FirstViewController.m

#import "FirstViewController.h"
CM_EXPORT const CMTime kCMTimeZero;
@interface FirstViewController ()

@end


@implementation FirstViewController
@synthesize  metadatas;
@synthesize toggleButton;
@synthesize slider;
@synthesize mpVolumeView = _mpVolumeView;
@synthesize viewVolume;

- (void)viewDidLoad
{
    //[super viewDidLoad];
    //slider.transform = CGAffineTransformRotate(slider.transform,270.0/180*M_PI);
    //[slider setMaximumValue:2];
    //[slider setMinimumValue:0];
    //[slider setSelected:YES];


    //[[self mpVolumeView] setBackgroundColor:[UIColor clearColor]];

    //MPVolumeView *myVolumeView = [[MPVolumeView alloc] initWithFrame: [[self mpVolumeView] bounds]];
    //[[self mpVolumeView] addSubview:myVolumeView];
    //toggleIsOn =TRUE;
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    toggleIsOn=TRUE;
    MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:self.viewVolume.bounds] ;

    [self.viewVolume addSubview:volumeView];

    [volumeView sizeToFit];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

-(IBAction)playButtonPressed:(id)sender
{



    if(toggleIsOn){

        toggleIsOn=!toggleIsOn;

        player = nil;
        NSString *stringurl = @"";
        stringurl = @"http://majestic.wavestreamer.com:6221/listen.pls";
        NSURL *url = [NSURL URLWithString:stringurl];
        asset = [AVURLAsset URLAssetWithURL:url options:nil];
        playerItem = [AVPlayerItem playerItemWithAsset:asset];
        player = [AVPlayer playerWithPlayerItem:playerItem];
        player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
        [playerItem addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionNew context:nil];
        [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
        [player play];

        [self.toggleButton setImage:[UIImage imageNamed:@"reload.png"] forState:UIControlStateNormal];
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
        [[AVAudioSession sharedInstance] setActive: YES error: nil];
        [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    }
    else {

        [self.toggleButton setImage:[UIImage imageNamed:@"playMusic.png"] forState:UIControlStateNormal];
        self->player.rate=0.0;
        toggleIsOn=!toggleIsOn;



    }


}
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}


- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                        change:(NSDictionary *)change context:(void *)context {

    [playerItem removeObserver:self forKeyPath:keyPath];


    if ([keyPath isEqualToString:@"status"]) {
        AVPlayerItem *pItem = (AVPlayerItem *)object;
        if (pItem.status == AVPlayerItemStatusReadyToPlay)
        {
            metadatas.text = @"";
        }
    }
    if ([keyPath isEqualToString:@"timedMetadata"]) {
        for (AVAssetTrack *track in playerItem.tracks) {
            for (AVPlayerItemTrack *item in player.currentItem.tracks) {
                if ([item.assetTrack.mediaType isEqual:AVMediaTypeAudio]) {
                    NSArray *meta = [playerItem timedMetadata];
                    for (AVMetadataItem *metaItem in meta) {

                        NSString *source = metaItem.stringValue;
                        metadatas.text = source;
                    }
                }
            }
        }
    }

    [self.toggleButton setImage:[UIImage imageNamed:toggleIsOn ? @"playMusic.png" :@"stop.png"] forState:UIControlStateNormal];

}


-(IBAction)fbButtonPressed:(id)sender
{

    NSURL *url = [NSURL URLWithString:@"http://www.facebook.com"];

    if (![[UIApplication sharedApplication] openURL:url])
        NSLog(@"%@%@",@"Failed to open url:",[url description]);
}


-(IBAction)inButtonPressed:(id)sender
{

    NSURL *url = [NSURL URLWithString:@"http://www.linkedin.com"];

    if (![[UIApplication sharedApplication] openURL:url])
        NSLog(@"%@%@",@"Failed to open url:",[url description]);
}

-(IBAction)tweetButtonPressed:(id)sender
{

    NSURL *url = [NSURL URLWithString:@"http://www.twitter.com"];

    if (![[UIApplication sharedApplication] openURL:url])
        NSLog(@"%@%@",@"Failed to open url:",[url description]);
}
-(IBAction) sliderChanged:(id)sender
{


}

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

@end

Also, the code for inserting volume view is there, then also there is no volume controller in the UI. Why so.?

// // FirstViewController.m

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>
#import <MediaPlayer/MediaPlayer.h>

@class AVPlayer;
@class AVPlayerItem;

@interface FirstViewController : UIViewController
{

    UIView *viewVolume;
    AVAsset *asset;
    AVPlayerItem *playerItem;
    AVPlayer *player;
    NSURL *mURL;
    MPVolumeView *_mpVolumeView;
    IBOutlet UILabel *metadatas;
    IBOutlet UIButton *toggleButton;
    BOOL toggleIsOn;
    IBOutlet UISlider *slider;


}

-(IBAction)playButtonPressed:(id)sender;
-(IBAction)fbButtonPressed:(id)sender;
-(IBAction)inButtonPressed:(id)sender;
-(IBAction)tweetButtonPressed:(id)sender;
-(IBAction) sliderChanged:(id)sender;
@property (strong, nonatomic) IBOutlet UISlider *slider;
@property (nonatomic, retain) IBOutlet MPVolumeView *mpVolumeView;
@property (nonatomic, retain) IBOutlet UILabel *metadatas;
@property (nonatomic, retain) IBOutlet UIButton *toggleButton;
@property (nonatomic, strong) IBOutlet UIView *viewVolume;

@end

am unable to start the music after call. Please help with possible solutions.

Was it helpful?

Solution 2

Go to your appDelegate file and there you will find the UIApplicationDelegate methods automatically having been implemented for you.

Simply add your music pause and resume code in the methods and everything else will be handled accordingly. Just make sure that you can access your music instance player from the app delegate.

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

OTHER TIPS

You need to add observer in FirstViewController

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resumePlayMusic)     name:UIApplicationDidBecomeActiveNotification object:nil];
}

- (void) resumePlayMusic
{
   .......
}

And don't forget to remove observer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top