VLCRemoteControlService.m 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*****************************************************************************
  2. * VLCRemoteControlService.m
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2017 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Authors: Carola Nitz <nitz.carola # gmail.com>
  9. *
  10. * Refer to the COPYING file of the official project for license.
  11. *****************************************************************************/
  12. #import "VLCRemoteControlService.h"
  13. #import <MediaPlayer/MediaPlayer.h>
  14. @implementation VLCRemoteControlService
  15. static inline NSArray * RemoteCommandCenterCommandsToHandle()
  16. {
  17. MPRemoteCommandCenter *cc = [MPRemoteCommandCenter sharedCommandCenter];
  18. NSMutableArray *commands = [NSMutableArray arrayWithObjects:
  19. cc.pauseCommand,
  20. cc.playCommand,
  21. cc.stopCommand,
  22. cc.togglePlayPauseCommand,
  23. cc.nextTrackCommand,
  24. cc.previousTrackCommand,
  25. cc.skipForwardCommand,
  26. cc.skipBackwardCommand,
  27. cc.changePlaybackRateCommand,
  28. nil];
  29. if (@available(iOS 9.1, *)) {
  30. [commands addObject:cc.changePlaybackPositionCommand];
  31. }
  32. return [commands copy];
  33. }
  34. - (void)subscribeToRemoteCommands
  35. {
  36. MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
  37. /* Since the control center and lockscreen shows only either skipForward/Backward
  38. * or next/previousTrack buttons but prefers skip buttons,
  39. * we only enable skip buttons if we have no medialist
  40. */
  41. BOOL enableSkip = NO;
  42. if (_remoteControlServiceDelegate) {
  43. enableSkip = [_remoteControlServiceDelegate remoteControlServiceNumberOfMediaItemsinList:self] <= 1;
  44. }
  45. commandCenter.skipForwardCommand.enabled = enableSkip;
  46. commandCenter.skipBackwardCommand.enabled = enableSkip;
  47. //Enable when you want to support these
  48. commandCenter.ratingCommand.enabled = NO;
  49. commandCenter.likeCommand.enabled = NO;
  50. commandCenter.dislikeCommand.enabled = NO;
  51. commandCenter.bookmarkCommand.enabled = NO;
  52. commandCenter.enableLanguageOptionCommand.enabled = NO;
  53. commandCenter.disableLanguageOptionCommand.enabled = NO;
  54. commandCenter.changeRepeatModeCommand.enabled = NO;
  55. commandCenter.changeShuffleModeCommand.enabled = NO;
  56. commandCenter.seekForwardCommand.enabled = NO;
  57. commandCenter.seekBackwardCommand.enabled = NO;
  58. NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  59. NSNumber *forwardSkip = [defaults valueForKey:kVLCSettingPlaybackForwardSkipLength];
  60. commandCenter.skipForwardCommand.preferredIntervals = @[forwardSkip];
  61. NSNumber *backwardSkip = [defaults valueForKey:kVLCSettingPlaybackBackwardSkipLength];
  62. commandCenter.skipBackwardCommand.preferredIntervals = @[backwardSkip];
  63. commandCenter.changePlaybackRateCommand.supportedPlaybackRates = @[@(0.5),@(0.75),@(1.0),@(1.25),@(1.5),@(1.75),@(2.0)];
  64. for (MPRemoteCommand *command in RemoteCommandCenterCommandsToHandle()) {
  65. [command addTarget:self action:@selector(remoteCommandEvent:)];
  66. }
  67. }
  68. - (void)unsubscribeFromRemoteCommands
  69. {
  70. [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nil;
  71. for (MPRemoteCommand *command in RemoteCommandCenterCommandsToHandle()) {
  72. [command removeTarget:self];
  73. }
  74. }
  75. - (MPRemoteCommandHandlerStatus )remoteCommandEvent:(MPRemoteCommandEvent *)event
  76. {
  77. if (!_remoteControlServiceDelegate) return MPRemoteCommandHandlerStatusCommandFailed;
  78. MPRemoteCommandCenter *cc = [MPRemoteCommandCenter sharedCommandCenter];
  79. if (event.command == cc.pauseCommand) {
  80. [_remoteControlServiceDelegate remoteControlServiceHitPause:self];
  81. return MPRemoteCommandHandlerStatusSuccess;
  82. }
  83. if (event.command == cc.playCommand) {
  84. [_remoteControlServiceDelegate remoteControlServiceHitPlay:self];
  85. return MPRemoteCommandHandlerStatusSuccess;
  86. }
  87. if (event.command == cc.stopCommand) {
  88. [_remoteControlServiceDelegate remoteControlServiceHitStop:self];
  89. return MPRemoteCommandHandlerStatusSuccess;
  90. }
  91. if (event.command == cc.togglePlayPauseCommand) {
  92. [_remoteControlServiceDelegate remoteControlServiceTogglePlayPause:self];
  93. return MPRemoteCommandHandlerStatusSuccess;
  94. }
  95. if (event.command == cc.nextTrackCommand) {
  96. BOOL success = [_remoteControlServiceDelegate remoteControlServiceHitPlayNextIfPossible:self];
  97. return success ? MPRemoteCommandHandlerStatusSuccess : MPRemoteCommandHandlerStatusNoSuchContent;
  98. }
  99. if (event.command == cc.previousTrackCommand) {
  100. BOOL success = [_remoteControlServiceDelegate remoteControlServiceHitPlayPreviousIfPossible:self];
  101. return success ? MPRemoteCommandHandlerStatusSuccess : MPRemoteCommandHandlerStatusNoSuchContent;
  102. }
  103. if (event.command == cc.skipForwardCommand) {
  104. MPSkipIntervalCommandEvent *skipEvent = (MPSkipIntervalCommandEvent *)event;
  105. [_remoteControlServiceDelegate remoteControlService:self jumpForwardInSeconds:skipEvent.interval];
  106. return MPRemoteCommandHandlerStatusSuccess;
  107. }
  108. if (event.command == cc.skipBackwardCommand) {
  109. MPSkipIntervalCommandEvent *skipEvent = (MPSkipIntervalCommandEvent *)event;
  110. [_remoteControlServiceDelegate remoteControlService:self jumpBackwardInSeconds:skipEvent.interval];
  111. return MPRemoteCommandHandlerStatusSuccess;
  112. }
  113. if (event.command == cc.changePlaybackRateCommand) {
  114. MPChangePlaybackRateCommandEvent *rateEvent = (MPChangePlaybackRateCommandEvent *)event;
  115. [_remoteControlServiceDelegate remoteControlService:self setPlaybackRate:rateEvent.playbackRate];
  116. return MPRemoteCommandHandlerStatusSuccess;
  117. }
  118. if (@available(iOS 9.1, *)) {
  119. if (event.command == cc.changePlaybackPositionCommand) {
  120. MPChangePlaybackPositionCommandEvent *positionEvent = (MPChangePlaybackPositionCommandEvent *)event;
  121. [_remoteControlServiceDelegate remoteControlService:self setCurrentPlaybackTime:positionEvent.positionTime];
  122. return MPRemoteCommandHandlerStatusSuccess;
  123. }
  124. }
  125. NSAssert(NO, @"remote control event not handled");
  126. APLog(@"%s Wasn't able to handle remote control event: %@",__PRETTY_FUNCTION__,event);
  127. return MPRemoteCommandHandlerStatusCommandFailed;
  128. }
  129. @end