【问题标题】:How to resume music after call通话后如何恢复音乐
【发布时间】:2017-11-26 20:54:53
【问题描述】:

我有一个在线音乐播放器。我想为其添加一个功能,如果正在播放歌曲并拨打电话(呼入或呼出),它应该暂停正在通话的音乐,并且在通话断开后,音乐应该重新开始。

这是我的代码:

// // 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

另外,插入音量视图的代码在那里,那么 UI 中也没有音量控制器。为什么会这样?

// // 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

通话后无法播放音乐。请提供可能的解决方案。

【问题讨论】:

标签: ios ios7 avplayer


【解决方案1】:

你需要在FirstViewController中添加观察者

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

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

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

别忘了移除观察者。

【讨论】:

  • 为什么不直接使用应用代理方法?
  • 在一个类的同一上下文中进行所有交易更清楚。当然,你可以在 app delegate 中编写很多不同的逻辑。但它使代码更加零碎。
【解决方案2】:

转到您的 appDelegate 文件,您会发现 UIApplicationDelegate 方法已自动为您实现。

只需在方法中添加音乐暂停和恢复代码,其他所有内容都会相应处理。只需确保您可以从应用委托访问您的音乐实例播放器。

- (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.
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    • 1970-01-01
    • 1970-01-01
    • 2020-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多