VLCRemoteControlService.m 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. return @[cc.pauseCommand,
  19. cc.playCommand,
  20. cc.stopCommand,
  21. cc.togglePlayPauseCommand,
  22. cc.nextTrackCommand,
  23. cc.previousTrackCommand,
  24. cc.skipForwardCommand,
  25. cc.skipBackwardCommand,
  26. cc.changePlaybackRateCommand,
  27. ];
  28. }
  29. - (void)subscribeToRemoteCommands
  30. {
  31. MPRemoteCommandCenter *commandCenter = [MPRemoteCommandCenter sharedCommandCenter];
  32. /* Since the control center and lockscreen shows only either skipForward/Backward
  33. * or next/previousTrack buttons but prefers skip buttons,
  34. * we only enable skip buttons if we have no medialist
  35. */
  36. BOOL enableSkip = NO;
  37. if (_remoteControlServiceDelegate) {
  38. enableSkip = [_remoteControlServiceDelegate remoteControlServiceNumberOfMediaItemsinList:self] <= 1;
  39. }
  40. commandCenter.skipForwardCommand.enabled = enableSkip;
  41. commandCenter.skipBackwardCommand.enabled = enableSkip;
  42. //Enable when you want to support these
  43. commandCenter.ratingCommand.enabled = NO;
  44. commandCenter.likeCommand.enabled = NO;
  45. commandCenter.dislikeCommand.enabled = NO;
  46. commandCenter.bookmarkCommand.enabled = NO;
  47. commandCenter.enableLanguageOptionCommand.enabled = NO;
  48. commandCenter.disableLanguageOptionCommand.enabled = NO;
  49. commandCenter.changeRepeatModeCommand.enabled = NO;
  50. commandCenter.changeShuffleModeCommand.enabled = NO;
  51. commandCenter.seekForwardCommand.enabled = NO;
  52. commandCenter.seekBackwardCommand.enabled = NO;
  53. commandCenter.changePlaybackPositionCommand.enabled = NO;
  54. NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
  55. NSNumber *forwardSkip = [defaults valueForKey:kVLCSettingPlaybackForwardSkipLength];
  56. commandCenter.skipForwardCommand.preferredIntervals = @[forwardSkip];
  57. NSNumber *backwardSkip = [defaults valueForKey:kVLCSettingPlaybackBackwardSkipLength];
  58. commandCenter.skipBackwardCommand.preferredIntervals = @[backwardSkip];
  59. commandCenter.changePlaybackRateCommand.supportedPlaybackRates = @[@(0.5),@(0.75),@(1.0),@(1.25),@(1.5),@(1.75),@(2.0)];
  60. for (MPRemoteCommand *command in RemoteCommandCenterCommandsToHandle()) {
  61. [command addTarget:self action:@selector(remoteCommandEvent:)];
  62. }
  63. }
  64. - (void)unsubscribeFromRemoteCommands
  65. {
  66. [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = nil;
  67. for (MPRemoteCommand *command in RemoteCommandCenterCommandsToHandle()) {
  68. [command removeTarget:self];
  69. }
  70. }
  71. - (MPRemoteCommandHandlerStatus )remoteCommandEvent:(MPRemoteCommandEvent *)event
  72. {
  73. if (!_remoteControlServiceDelegate) return MPRemoteCommandHandlerStatusCommandFailed;
  74. MPRemoteCommandCenter *cc = [MPRemoteCommandCenter sharedCommandCenter];
  75. if (event.command == cc.pauseCommand) {
  76. [_remoteControlServiceDelegate remoteControlServiceHitPause:self];
  77. return MPRemoteCommandHandlerStatusSuccess;
  78. }
  79. if (event.command == cc.playCommand) {
  80. [_remoteControlServiceDelegate remoteControlServiceHitPlay:self];
  81. return MPRemoteCommandHandlerStatusSuccess;
  82. }
  83. if (event.command == cc.stopCommand) {
  84. [_remoteControlServiceDelegate remoteControlServiceHitStop:self];
  85. return MPRemoteCommandHandlerStatusSuccess;
  86. }
  87. if (event.command == cc.togglePlayPauseCommand) {
  88. [_remoteControlServiceDelegate remoteControlServiceTogglePlayPause:self];
  89. return MPRemoteCommandHandlerStatusSuccess;
  90. }
  91. if (event.command == cc.nextTrackCommand) {
  92. BOOL success = [_remoteControlServiceDelegate remoteControlServiceHitPlayNextIfPossible:self];
  93. return success ? MPRemoteCommandHandlerStatusSuccess : MPRemoteCommandHandlerStatusNoSuchContent;
  94. }
  95. if (event.command == cc.previousTrackCommand) {
  96. BOOL success = [_remoteControlServiceDelegate remoteControlServiceHitPlayPreviousIfPossible:self];
  97. return success ? MPRemoteCommandHandlerStatusSuccess : MPRemoteCommandHandlerStatusNoSuchContent;
  98. }
  99. if (event.command == cc.skipForwardCommand) {
  100. MPSkipIntervalCommandEvent *skipEvent = (MPSkipIntervalCommandEvent *)event;
  101. [_remoteControlServiceDelegate remoteControlService:self jumpForwardInSeconds:skipEvent.interval];
  102. return MPRemoteCommandHandlerStatusSuccess;
  103. }
  104. if (event.command == cc.skipBackwardCommand) {
  105. MPSkipIntervalCommandEvent *skipEvent = (MPSkipIntervalCommandEvent *)event;
  106. [_remoteControlServiceDelegate remoteControlService:self jumpBackwardInSeconds:skipEvent.interval];
  107. return MPRemoteCommandHandlerStatusSuccess;
  108. }
  109. if (event.command == cc.changePlaybackRateCommand) {
  110. MPChangePlaybackRateCommandEvent *rateEvent = (MPChangePlaybackRateCommandEvent *)event;
  111. [_remoteControlServiceDelegate remoteControlService:self setPlaybackRate:rateEvent.playbackRate];
  112. return MPRemoteCommandHandlerStatusSuccess;
  113. }
  114. NSAssert(NO, @"remote control event not handled");
  115. APLog(@"%s Wasn't able to handle remote control event: %@",__PRETTY_FUNCTION__,event);
  116. return MPRemoteCommandHandlerStatusCommandFailed;
  117. }
  118. @end