VLCPlayerControlWebSocket.m 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. /*****************************************************************************
  2. * VLCPlayerControlWebSocket.m
  3. * VLC for iOS
  4. *****************************************************************************
  5. * Copyright (c) 2015 VideoLAN. All rights reserved.
  6. * $Id$
  7. *
  8. * Authors: Felix Paul Kühne <fkuehne # videolan.org>
  9. *
  10. * Refer to the COPYING file of the official project for license.
  11. *****************************************************************************/
  12. #import "VLCPlayerControlWebSocket.h"
  13. @implementation VLCPlayerControlWebSocket
  14. - (void)dealloc
  15. {
  16. [[NSNotificationCenter defaultCenter] removeObserver:self];
  17. }
  18. - (void)didOpen
  19. {
  20. NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
  21. [notificationCenter addObserver:self
  22. selector:@selector(playbackStarted)
  23. name:VLCPlaybackControllerPlaybackDidStart
  24. object:nil];
  25. [notificationCenter addObserver:self
  26. selector:@selector(playbackStarted)
  27. name:VLCPlaybackControllerPlaybackDidResume
  28. object:nil];
  29. [notificationCenter addObserver:self
  30. selector:@selector(_respondToPlaying)
  31. name:VLCPlaybackControllerPlaybackMetadataDidChange
  32. object:nil];
  33. [notificationCenter addObserver:self
  34. selector:@selector(playbackPaused)
  35. name:VLCPlaybackControllerPlaybackDidPause
  36. object:nil];
  37. [notificationCenter addObserver:self
  38. selector:@selector(playbackEnded)
  39. name:VLCPlaybackControllerPlaybackDidStop
  40. object:nil];
  41. [notificationCenter addObserver:self
  42. selector:@selector(playbackEnded)
  43. name:VLCPlaybackControllerPlaybackDidFail
  44. object:nil];
  45. [notificationCenter addObserver:self
  46. selector:@selector(playbackSeekTo)
  47. name:VLCPlaybackControllerPlaybackPositionUpdated
  48. object:nil];
  49. APLog(@"web socket did open");
  50. [super didOpen];
  51. }
  52. - (void)didReceiveMessage:(NSString *)msg
  53. {
  54. NSError *error;
  55. NSDictionary *receivedDict = [NSJSONSerialization JSONObjectWithData:[msg dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingAllowFragments error:&error];
  56. if (error != nil) {
  57. APLog(@"JSON deserialization failed for %@", msg);
  58. return;
  59. }
  60. NSString *type = receivedDict[@"type"];
  61. if (!type) {
  62. APLog(@"No type in received JSON dict %@", receivedDict);
  63. }
  64. if ([type isEqualToString:@"playing"]) {
  65. [self _respondToPlaying];
  66. } else if ([type isEqualToString:@"play"]) {
  67. [self _respondToPlay];
  68. } else if ([type isEqualToString:@"pause"]) {
  69. [self _respondToPause];
  70. } else if ([type isEqualToString:@"ended"]) {
  71. [self _respondToEnded];
  72. } else if ([type isEqualToString:@"seekTo"]) {
  73. [self _respondToSeek:receivedDict];
  74. } else if ([type isEqualToString:@"openURL"]) {
  75. [self _respondToOpenURL:receivedDict];
  76. } else if ([type isEqualToString:@"volume"]) {
  77. [self sendMessage:@"VOLUME CONTROL NOT SUPPORTED ON THIS DEVICE"];
  78. } else
  79. [self sendMessage:@"INVALID REQUEST!"];
  80. }
  81. #ifndef NDEBUG
  82. - (void)didClose
  83. {
  84. APLog(@"web socket did close");
  85. [super didClose];
  86. }
  87. #endif
  88. - (void)_respondToPlaying
  89. {
  90. /* JSON response
  91. {
  92. "type": "playing",
  93. "currentTime": 42,
  94. "media": {
  95. "id": "some id",
  96. "title": "some title",
  97. "duration": 120000
  98. }
  99. }
  100. */
  101. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  102. NSDictionary *returnDict;
  103. if (vpc.activePlaybackSession) {
  104. VLCMediaPlayer *player = vpc.mediaPlayer;
  105. if (player) {
  106. VLCMedia *media = player.media;
  107. if (media) {
  108. NSURL *url = media.url;
  109. NSString *mediaTitle = vpc.mediaTitle;
  110. if (!mediaTitle)
  111. mediaTitle = url.lastPathComponent;
  112. NSDictionary *mediaDict = @{ @"id" : url.absoluteString,
  113. @"title" : mediaTitle,
  114. @"duration" : @(media.length.intValue)};
  115. returnDict = @{ @"currentTime" : @(player.time.intValue),
  116. @"type" : @"playing",
  117. @"media" : mediaDict };
  118. }
  119. }
  120. }
  121. if (!returnDict) {
  122. returnDict = [NSDictionary dictionary];
  123. }
  124. NSError *error;
  125. NSData *returnData = [NSJSONSerialization dataWithJSONObject:returnDict options:0 error:&error];
  126. if (error != nil) {
  127. APLog(@"%s: JSON serialization failed %@", __PRETTY_FUNCTION__, error);
  128. }
  129. [self sendData:returnData];
  130. }
  131. #pragma mark - play
  132. - (void)_respondToPlay
  133. {
  134. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  135. VLCMediaListPlayer *listPlayer = vpc.listPlayer;
  136. if (listPlayer) {
  137. [listPlayer play];
  138. }
  139. }
  140. - (void)playbackStarted
  141. {
  142. /*
  143. {
  144. "type": "play",
  145. "currentTime": 42
  146. }
  147. */
  148. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  149. VLCMediaPlayer *player = vpc.mediaPlayer;
  150. if (player) {
  151. VLCMedia *media = player.media;
  152. if (media) {
  153. NSDictionary *returnDict = @{ @"currentTime" : @(player.time.intValue),
  154. @"type" : @"play" };
  155. NSError *error;
  156. NSData *returnData = [NSJSONSerialization dataWithJSONObject:returnDict options:0 error:&error];
  157. if (error != nil) {
  158. APLog(@"%s: JSON serialization failed %@", __PRETTY_FUNCTION__, error);
  159. }
  160. [self sendData:returnData];
  161. }
  162. }
  163. }
  164. #pragma mark - pause
  165. - (void)_respondToPause
  166. {
  167. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  168. VLCMediaListPlayer *listPlayer = vpc.listPlayer;
  169. if (listPlayer) {
  170. [listPlayer pause];
  171. }
  172. }
  173. - (void)playbackPaused
  174. {
  175. /*
  176. {
  177. "type": "pause",
  178. "currentTime": 42,
  179. }
  180. */
  181. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  182. VLCMediaPlayer *player = vpc.mediaPlayer;
  183. if (player) {
  184. VLCMedia *media = player.media;
  185. if (media) {
  186. NSDictionary *returnDict = @{ @"currentTime" : @(player.time.intValue),
  187. @"type" : @"pause" };
  188. NSError *error;
  189. NSData *returnData = [NSJSONSerialization dataWithJSONObject:returnDict options:0 error:&error];
  190. if (error != nil) {
  191. APLog(@"%s: JSON serialization failed %@", __PRETTY_FUNCTION__, error);
  192. }
  193. [self sendData:returnData];
  194. }
  195. }
  196. }
  197. #pragma mark - ended
  198. - (void)_respondToEnded
  199. {
  200. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  201. [vpc stopPlayback];
  202. }
  203. - (void)playbackEnded
  204. {
  205. /*
  206. {
  207. "type": "ended"
  208. }
  209. */
  210. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  211. VLCMediaPlayer *player = vpc.mediaPlayer;
  212. if (player) {
  213. VLCMedia *media = player.media;
  214. if (media) {
  215. NSDictionary *returnDict = @{ @"type" : @"ended" };
  216. NSError *error;
  217. NSData *returnData = [NSJSONSerialization dataWithJSONObject:returnDict options:0 error:&error];
  218. if (error != nil) {
  219. APLog(@"%s: JSON serialization failed %@", __PRETTY_FUNCTION__, error);
  220. }
  221. [self sendData:returnData];
  222. }
  223. }
  224. }
  225. #pragma mark - seek
  226. - (void)_respondToSeek:(NSDictionary *)dictionary
  227. {
  228. /*
  229. {
  230. "currentTime" = 12514;
  231. "type" = seekTo;
  232. }
  233. */
  234. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  235. VLCMediaPlayer *player = vpc.mediaPlayer;
  236. if (!player)
  237. return;
  238. VLCMedia *media = player.media;
  239. if (!media)
  240. return;
  241. player.position = [dictionary[@"currentTime"] floatValue] / (CGFloat)media.length.intValue;
  242. }
  243. - (void)playbackSeekTo
  244. {
  245. /*
  246. {
  247. "type": "seekTo",
  248. "currentTime": 42,
  249. "media": {
  250. "id": 42
  251. }
  252. }
  253. */
  254. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  255. VLCMediaPlayer *player = vpc.mediaPlayer;
  256. if (player) {
  257. VLCMedia *media = player.media;
  258. if (media) {
  259. NSDictionary *mediaDict = @{ @"id" : media.url.absoluteString};
  260. NSDictionary *returnDict = @{ @"currentTime" : @(player.time.intValue),
  261. @"type" : @"seekTo",
  262. @"media" : mediaDict };
  263. NSError *error;
  264. NSData *returnData = [NSJSONSerialization dataWithJSONObject:returnDict options:0 error:&error];
  265. if (error != nil) {
  266. APLog(@"%s: JSON serialization failed %@", __PRETTY_FUNCTION__, error);
  267. }
  268. [self sendData:returnData];
  269. }
  270. }
  271. }
  272. #pragma mark - openURL
  273. - (void)_respondToOpenURL:(NSDictionary *)dictionary
  274. {
  275. /*
  276.  {
  277. "type": "OpenURL",
  278. "url": "https://vimeo.com/74370512"
  279. }
  280. */
  281. BOOL needsMediaList;
  282. VLCPlaybackController *vpc = [VLCPlaybackController sharedInstance];
  283. VLCMediaList *mediaList = vpc.mediaList;
  284. if (!mediaList) {
  285. needsMediaList = YES;
  286. mediaList = [[VLCMediaList alloc] init];
  287. }
  288. [mediaList addMedia:[VLCMedia mediaWithURL:[NSURL URLWithString:dictionary[@"url"]]]];
  289. if (needsMediaList) {
  290. [vpc playMediaList:mediaList firstIndex:0];
  291. }
  292. }
  293. @end