【问题标题】:avplayer doesn't pause when clicked on pause button if screen is locked如果屏幕锁定,单击暂停按钮时,avplayer 不会暂停
【发布时间】:2017-05-16 06:18:30
【问题描述】:

如果应用正在播放音频并且手机屏幕被锁定,则控制屏幕如下所示。我无法对 avplayer 采取任何行动

在我的 appdelegate 中我实现了:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];
[[rcc skipForwardCommand] setEnabled:NO];
[[rcc skipBackwardCommand] setEnabled:NO];
[[rcc nextTrackCommand] setEnabled:NO];
[[rcc previousTrackCommand] setEnabled:NO];
[[rcc skipForwardCommand] setEnabled:NO];
[[rcc skipBackwardCommand] setEnabled:NO];
rcc.playCommand.enabled = YES;
rcc.pauseCommand.enabled = YES;
[[MPRemoteCommandCenter sharedCommandCenter].playCommand addTarget:self action:@selector(play)];
[[MPRemoteCommandCenter sharedCommandCenter].pauseCommand addTarget:self action:@selector(pause)];
}

- (void) play {
[[MyVideoController instance] play];
}

- (void) pause {
[[MyVideoController instance] pause];
}

MyVideoController 类包括:

- (void) pause {
    [self.avPlayer pause];
}

- (void) play {
    [self.avPlayer play];
}

即使触发了这些方法(添加了断点进行检查),也不会对 avplayer 执行任何操作。无论如何,avplayer 不会暂停。

有什么办法可以暂停avplayer吗?

编辑 1: 添加完整代码

在我的 AppDelegate 中:

- (void) remoteControlReceivedWithEvent: (UIEvent *) event {
[[ZVideoPlayerController instance] eventReceived:event];
if (event.type == UIEventTypeRemoteControl) {
    switch (event.subtype) {
        case UIEventSubtypeRemoteControlTogglePlayPause: {

            break;
        }
        case UIEventSubtypeRemoteControlPlay: {
            [[ZVideoPlayerController instance] play];
            break;
        }
        case UIEventSubtypeRemoteControlPause: {
            [[ZVideoPlayerController instance] pause];
            break;
        }
        default:
            break;
    }
}

}

- (void)applicationDidEnterBackground:(UIApplication *)application {
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
}

我正在接收事件,但在 AVPLAYER 上调用暂停方法后音频没有暂停。

编辑 2: PlayerController 类中的实例声明

+ (instancetype)instance {
static id instance = nil;
if (instance == nil)
{
    static dispatch_once_t onceToken = 0;
    dispatch_once(&onceToken, ^(void) {
        NSAssert(instance == nil, @"Singleton instance is already allocated.");
        instance = [[super allocWithZone:NULL] init];
    });
}
return instance;
}

初始化 AVPlayer

    AVURLAsset *avAsset = [AVURLAsset URLAssetWithURL:url options:nil];
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:avAsset];
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
NSError *activationError = nil;
BOOL success = [[AVAudioSession sharedInstance] setActive: YES error: &activationError];

NSMutableDictionary *songInfo = [[NSMutableDictionary alloc] init];

MPMediaItemArtwork *albumArt = [[MPMediaItemArtwork alloc] initWithImage: [UIImage imageNamed:@"Audio_Thumbnail_Play"]];
[songInfo setObject:title forKey:MPMediaItemPropertyTitle];
[songInfo setObject:@"100" forKey:MPMediaItemPropertyPlaybackDuration];
[songInfo setObject:albumArt forKey:MPMediaItemPropertyArtwork];
[[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:songInfo];
self.avPlayer = [AVPlayer playerWithPlayerItem:playerItem];
self.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.avPlayer];

【问题讨论】:

  • 而不是暂停方法,将速率设置为0.0并再次检查。
  • 我试过 self.avPlayer.rate = 0.0;也一样,但没有运气。

标签: ios objective-c background-audio screen-lock


【解决方案1】:

我找到了解决问题的方法。当我得到 avPlayer 的 nil 值时,我使用我的 PageViewController 类来获取 PlayerController 的实例。然后我使用这个 playerController 的实例来播放和暂停我的 avplayer,因为这个实例持有对 avPlayer 的引用。

- (PlayerController *)getVideoController {
NSArray *controllers = [UtiliyClass getNavigationController].viewControllers;
PageViewController *pageController = nil;
for (UIViewController *cont in controllers) {
    if ([cont isKindOfClass:[PageViewController class]]) {
        pageController = (PageViewController *)cont;
        break;
    }
}
if (pageController == nil) {
    return nil;
}
NSArray *objectsController =pageController.pageController.viewControllers;
PlayerController *videoPlayerController = nil;
for (UIViewController *item in objectsController) {
    if ([item isKindOfClass:[PlayerController class]]) {
        videoPlayerController = (PlayerController *)item;
        break;
    }
}
return videoPlayerController;
}

- (void) pause {
PlayerController *controller = [self getVideoController];
[controller.avPlayer pause];
}

- (void) play {
PlayerController *controller = [self getVideoController];
[controller.avPlayer play];
}

【讨论】:

    【解决方案2】:

    当应用程序被锁定时,您需要注册远程通知以更新播放器状态。如下:

    在你的 AppDelegate 中添加这个,最好是在 applicationDidEnterBackground:

    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
    

    这在 applicationDidBecomeActive:

    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    

    通过在 AppDelagate 中添加它来接收远程通知。这将在手机锁定时侦听所有操作。

    - (void)remoteControlReceivedWithEvent:(UIEvent *)event {
        if (event.type == UIEventTypeRemoteControl){
            // Call method of your player where you want to make change (Pause , Paly),
            // I am calling a shared view for example, Its up to your logic how you want to deal it
          [[AudioPlayerView sharedPlayerView] remoteControlReceivedWithEvent:event];
    
    
        }
     }
    

    然后得到你想要的事件并相应地更新状态

     - (void)remoteControlReceivedWithEvent:(UIEvent *)event {
    
           if (event.type == UIEventTypeRemoteControl){
               switch (event.subtype){
                   case UIEventSubtypeRemoteControlPlay:
                        [[MyVideoController instance] play];
                         break;
                   case UIEventSubtypeRemoteControlPause:
                        [[MyVideoController instance] pause];
                        break;
    
                   case UIEventSubtypeRemoteControlTogglePlayPause:
                       // Check if state is playing , call pause else call play
                        break;
                    }
            default:
                break;
            }
         }
     }
    

    【讨论】:

    • 正如我在问题中已经提到的,我正在接收播放/暂停事件。只是我无法在调用暂停功能时暂停音频。让我编辑问题
    • 你在处理 AVPlayer 类中的事件吗?还是在 AppDelgate 中?
    • AppDelegate。我编辑了这个问题。感谢您对此进行调查。
    • 当你检查断点时,是否有有效的 AVPlayer 参考?
    • 当前您正在尝试在应用委托中播放/暂停。尝试在此方法中暂停/播放 [[ZVideoPlayerController instance] eventReceived:event]; ZVideoPlayerController.m 内
    【解决方案3】:

    在 iOS 7.1 及更高版本中,使用共享的 MPRemoteCommandCenter 对象来注册远程控制事件。使用共享命令中心对象时无需调用此方法。 此方法使用响应者链启动远程控制事件的传递。远程控制事件源自耳机和外部附件发出的命令,旨在控制应用程序呈现的多媒体。要停止接收远程控制事件,您必须调用 endReceivingRemoteControlEvents()。

    在 didfinishlunching 中为 init audio season 添加以下代码并获取远程控制事件:

            // Initialize the AVAudioSession here.
            if (![[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:&myErr]) {
                // Handle the error here.
                NSLog(@"Audio Session error %@, %@", myErr, [myErr userInfo]);
            }
            else{
                // Since there were no errors initializing the session, we'll allow begin receiving remote control events
                [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
            }
    

    要接收命令,请使用此代码:

    - (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
    
        if (receivedEvent.type == UIEventTypeRemoteControl) {
    
            switch (receivedEvent.subtype) {
    
                case UIEventSubtypeRemoteControlPreviousTrack:
    
                    break;
    
                case UIEventSubtypeRemoteControlNextTrack:
    
                    break;
    
                case UIEventSubtypeRemoteControlPlay:
                    [[MyVideoController instance] play];
                    break;
    
                case UIEventSubtypeRemoteControlPause:
                    [[MyVideoController instance] pause];
                    break;
    
                default:
                    break;
            }
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 1970-01-01
      • 2017-01-25
      相关资源
      最近更新 更多