VLCWatchCommunication.m 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*****************************************************************************
  2. * VLCWatchCommunication.m
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2015 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Author: Tobias Conradi <videolan # tobias-conradi.de>
  9. *
  10. * Refer to the COPYING file of the official project for license.
  11. *****************************************************************************/
  12. #import "VLCWatchCommunication.h"
  13. #import "VLCWatchMessage.h"
  14. #import "VLCPlaybackController+MediaLibrary.h"
  15. #import <MediaPlayer/MediaPlayer.h>
  16. @implementation VLCWatchCommunication
  17. - (instancetype)init
  18. {
  19. self = [super init];
  20. if (self) {
  21. if ([WCSession isSupported]) {
  22. WCSession *session = [WCSession defaultSession];
  23. session.delegate = self;
  24. [session activateSession];
  25. }
  26. }
  27. return self;
  28. }
  29. static VLCWatchCommunication *_singeltonInstance = nil;
  30. + (VLCWatchCommunication *)sharedInstance
  31. {
  32. @synchronized(self) {
  33. static dispatch_once_t pred;
  34. dispatch_once(&pred, ^{
  35. _singeltonInstance = [[self alloc] init];
  36. });
  37. }
  38. return _singeltonInstance;
  39. }
  40. - (void)playFileFromWatch:(VLCWatchMessage *)message
  41. {
  42. NSManagedObject *managedObject = nil;
  43. NSString *uriString = (id)message.payload;
  44. if ([uriString isKindOfClass:[NSString class]]) {
  45. NSURL *uriRepresentation = [NSURL URLWithString:uriString];
  46. managedObject = [[MLMediaLibrary sharedMediaLibrary] objectForURIRepresentation:uriRepresentation];
  47. }
  48. if (managedObject == nil) {
  49. APLog(@"%s file not found: %@",__PRETTY_FUNCTION__,message);
  50. return;
  51. }
  52. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  53. [vpc playMediaLibraryObject:managedObject];
  54. }
  55. - (void)session:(nonnull WCSession *)session didReceiveMessage:(nonnull NSDictionary<NSString *,id> *)userInfo replyHandler:(nonnull void (^)(NSDictionary<NSString *,id> * _Nonnull))replyHandler {
  56. UIApplication *application = [UIApplication sharedApplication];
  57. /* dispatch background task */
  58. __block UIBackgroundTaskIdentifier taskIdentifier = [application beginBackgroundTaskWithName:nil
  59. expirationHandler:^{
  60. [application endBackgroundTask:taskIdentifier];
  61. taskIdentifier = UIBackgroundTaskInvalid;
  62. }];
  63. VLCWatchMessage *message = [[VLCWatchMessage alloc] initWithDictionary:userInfo];
  64. NSString *name = message.name;
  65. NSDictionary *responseDict = nil;
  66. if ([name isEqualToString:VLCWatchMessageNameGetNowPlayingInfo]) {
  67. responseDict = [self nowPlayingResponseDict];
  68. } else if ([name isEqualToString:VLCWatchMessageNamePlayPause]) {
  69. [[VLCPlaybackController sharedInstance] playPause];
  70. responseDict = @{@"playing": @([VLCPlaybackController sharedInstance].isPlaying)};
  71. } else if ([name isEqualToString:VLCWatchMessageNameSkipForward]) {
  72. [[VLCPlaybackController sharedInstance] forward];
  73. } else if ([name isEqualToString:VLCWatchMessageNameSkipBackward]) {
  74. [[VLCPlaybackController sharedInstance] backward];
  75. } else if ([name isEqualToString:VLCWatchMessageNamePlayFile]) {
  76. [self playFileFromWatch:message];
  77. } else if ([name isEqualToString:VLCWatchMessageNameSetVolume]) {
  78. [self setVolumeFromWatch:message];
  79. } else {
  80. APLog(@"Did not handle request from WatchKit Extension: %@",userInfo);
  81. }
  82. replyHandler(responseDict);
  83. }
  84. - (void)setVolumeFromWatch:(VLCWatchMessage *)message
  85. {
  86. NSNumber *volume = (id)message.payload;
  87. if ([volume isKindOfClass:[NSNumber class]]) {
  88. /*
  89. * Since WatchKit doesn't provide something like MPVolumeView we use deprecated API.
  90. * rdar://20783803 Feature Request: WatchKit equivalent for MPVolumeView
  91. */
  92. [MPMusicPlayerController applicationMusicPlayer].volume = volume.floatValue;
  93. }
  94. }
  95. - (NSDictionary *)nowPlayingResponseDict {
  96. NSMutableDictionary *response = [NSMutableDictionary new];
  97. NSMutableDictionary *nowPlayingInfo = [[MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo mutableCopy];
  98. NSNumber *playbackTime = [VLCPlaybackController sharedInstance].mediaPlayer.time.numberValue;
  99. if (playbackTime) {
  100. nowPlayingInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = @(playbackTime.floatValue/1000);
  101. }
  102. if (nowPlayingInfo) {
  103. response[@"nowPlayingInfo"] = nowPlayingInfo;
  104. }
  105. MLFile *currentFile = [VLCPlaybackController sharedInstance].currentlyPlayingMediaFile;
  106. NSString *URIString = currentFile.objectID.URIRepresentation.absoluteString;
  107. if (URIString) {
  108. response[@"URIRepresentation"] = URIString;
  109. }
  110. response[@"volume"] = @([MPMusicPlayerController applicationMusicPlayer].volume);
  111. return response;
  112. }
  113. @end