VLCMovieViewController.m 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. //
  2. // VLCMovieViewController.m
  3. // AspenProject
  4. //
  5. // Created by Felix Paul Kühne on 27.02.13.
  6. // Copyright (c) 2013 VideoLAN. All rights reserved.
  7. //
  8. #import "VLCMovieViewController.h"
  9. #import "VLCExternalDisplayController.h"
  10. @interface VLCMovieViewController () <UIGestureRecognizerDelegate>
  11. @property (nonatomic, strong) UIPopoverController *masterPopoverController;
  12. @property (nonatomic, strong) UIWindow *externalWindow;
  13. @end
  14. @implementation VLCMovieViewController
  15. - (void)dealloc
  16. {
  17. [_mediaPlayer stop];
  18. [[NSNotificationCenter defaultCenter] removeObserver:self];
  19. }
  20. #pragma mark - Managing the media item
  21. - (void)setMediaItem:(id)newMediaItem
  22. {
  23. if (_mediaItem != newMediaItem) {
  24. _mediaItem = newMediaItem;
  25. }
  26. if (self.masterPopoverController != nil)
  27. [self.masterPopoverController dismissPopoverAnimated:YES];
  28. }
  29. - (void)viewDidLoad
  30. {
  31. [super viewDidLoad];
  32. self.wantsFullScreenLayout = YES;
  33. _mediaPlayer = [[VLCMediaPlayer alloc] init];
  34. [_mediaPlayer setDelegate:self];
  35. [_mediaPlayer setDrawable:self.movieView];
  36. NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
  37. [center addObserver:self selector:@selector(handleExternalScreenDidConnect:)
  38. name:UIScreenDidConnectNotification object:nil];
  39. [center addObserver:self selector:@selector(handleExternalScreenDidDisconnect:)
  40. name:UIScreenDidDisconnectNotification object:nil];
  41. [center addObserver:self selector:@selector(appWillResign:) name:UIApplicationWillResignActiveNotification object:nil];
  42. _playingExternallyTitle.text = NSLocalizedString(@"PLAYING_EXTERNALLY_TITLE", @"");
  43. _playingExternallyDescription.text = NSLocalizedString(@"PLAYING_EXTERNALLY_DESC", @"");
  44. if ([self hasExternalDisplay]) {
  45. [self showOnExternalDisplay];
  46. }
  47. _movieView.userInteractionEnabled = NO;
  48. UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(toogleControlsVisible)];
  49. recognizer.delegate = self;
  50. [self.view addGestureRecognizer:recognizer];
  51. }
  52. - (void)viewWillAppear:(BOOL)animated
  53. {
  54. [super viewWillAppear:animated];
  55. [self.navigationController setNavigationBarHidden:YES animated:YES];
  56. if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
  57. [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackTranslucent;
  58. if (!self.mediaItem)
  59. return;
  60. self.title = [self.mediaItem title];
  61. [_mediaPlayer setMedia:[VLCMedia mediaWithURL:[NSURL URLWithString:self.mediaItem.url]]];
  62. [_mediaPlayer play];
  63. if (self.mediaItem.lastPosition && [self.mediaItem.lastPosition floatValue] < 0.99)
  64. [_mediaPlayer setPosition:[self.mediaItem.lastPosition floatValue]];
  65. }
  66. - (void)viewWillDisappear:(BOOL)animated
  67. {
  68. [self.navigationController setNavigationBarHidden:NO animated:YES];
  69. [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleBlackOpaque;
  70. [_mediaPlayer pause];
  71. [super viewWillDisappear:animated];
  72. self.mediaItem.lastPosition = [NSNumber numberWithFloat:[_mediaPlayer position]];
  73. }
  74. - (void)didReceiveMemoryWarning
  75. {
  76. [super didReceiveMemoryWarning];
  77. // Dispose of any resources that can be recreated.
  78. }
  79. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  80. {
  81. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
  82. if (self)
  83. self.title = @"Video Playback";
  84. return self;
  85. }
  86. #pragma mark - controls visibility
  87. - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
  88. {
  89. if (touch.view != self.view)
  90. return NO;
  91. return YES;
  92. }
  93. - (void)toogleControlsVisible
  94. {
  95. _controlsHidden = !_controlsHidden;
  96. CGFloat alpha = _controlsHidden? 0.0f: 1.0f;
  97. if (!_controlsHidden) {
  98. _controllerPanel.alpha = 0.0f;
  99. _controllerPanel.hidden = NO;
  100. _toolbar.alpha = 0.0f;
  101. _toolbar.hidden = NO;
  102. }
  103. void (^animationBlock)() = ^() {
  104. _controllerPanel.alpha = alpha;
  105. _toolbar.alpha = alpha;
  106. };
  107. void (^completionBlock)(BOOL finished) = ^(BOOL finished) {
  108. _controllerPanel.hidden = _controlsHidden;
  109. _toolbar.hidden = _controlsHidden;
  110. };
  111. [UIView animateWithDuration:0.3f animations:animationBlock completion:completionBlock];
  112. [[UIApplication sharedApplication] setStatusBarHidden:_controlsHidden withAnimation:UIStatusBarAnimationFade];
  113. }
  114. #pragma mark - controls
  115. - (IBAction)closePlayback:(id)sender
  116. {
  117. [self.navigationController popViewControllerAnimated:YES];
  118. }
  119. - (IBAction)positionSliderAction:(UISlider *)sender
  120. {
  121. _mediaPlayer.position = sender.value;
  122. }
  123. - (void)mediaPlayerTimeChanged:(NSNotification *)aNotification {
  124. self.positionSlider.value = [_mediaPlayer position];
  125. self.timeDisplay.title = [[_mediaPlayer remainingTime] stringValue];
  126. }
  127. - (void)mediaPlayerStateChanged:(NSNotification *)aNotification
  128. {
  129. // TODO
  130. }
  131. - (IBAction)play:(id)sender
  132. {
  133. if ([_mediaPlayer isPlaying]) {
  134. [_mediaPlayer pause];
  135. _playPauseButton.titleLabel.text = @"Pse";
  136. } else {
  137. [_mediaPlayer play];
  138. _playPauseButton.titleLabel.text = @"Play";
  139. }
  140. }
  141. - (IBAction)forward:(id)sender
  142. {
  143. [_mediaPlayer mediumJumpForward];
  144. }
  145. - (IBAction)backward:(id)sender
  146. {
  147. [_mediaPlayer mediumJumpBackward];
  148. }
  149. - (IBAction)switchAudioTrack:(id)sender
  150. {
  151. _audiotrackActionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"Choose Audio Track", @"audio track selector") delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles: nil];
  152. NSArray *audioTracks = [_mediaPlayer audioTrackNames];
  153. NSUInteger count = [audioTracks count];
  154. for (NSUInteger i = 0; i < count; i++)
  155. [_audiotrackActionSheet addButtonWithTitle:[audioTracks objectAtIndex:i]];
  156. [_audiotrackActionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", @"audio track selector")];
  157. [_audiotrackActionSheet setCancelButtonIndex:[_audiotrackActionSheet numberOfButtons] - 1];
  158. [_audiotrackActionSheet showFromRect:[self.audioSwitcherButton frame] inView:self.audioSwitcherButton animated:YES];
  159. }
  160. - (IBAction)switchSubtitleTrack:(id)sender
  161. {
  162. NSArray *spuTracks = [_mediaPlayer videoSubTitlesNames];
  163. NSUInteger count = [spuTracks count];
  164. if (count <= 1)
  165. return;
  166. _subtitleActionSheet = [[UIActionSheet alloc] initWithTitle:NSLocalizedString(@"Choose Subtitle Track", @"subtitle track selector") delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles: nil];
  167. for (NSUInteger i = 0; i < count; i++)
  168. [_subtitleActionSheet addButtonWithTitle:[spuTracks objectAtIndex:i]];
  169. [_subtitleActionSheet addButtonWithTitle:NSLocalizedString(@"Cancel", @"subtitle track selector")];
  170. [_subtitleActionSheet setCancelButtonIndex:[_subtitleActionSheet numberOfButtons] - 1];
  171. [_subtitleActionSheet showFromRect:[self.subtitleSwitcherButton frame] inView:self.subtitleSwitcherButton animated:YES];
  172. }
  173. - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
  174. NSUInteger arrayIndex = 0;
  175. NSArray *indexArray;
  176. NSArray *namesArray;
  177. if (actionSheet == _subtitleActionSheet) {
  178. namesArray = _mediaPlayer.videoSubTitlesNames;
  179. arrayIndex = [namesArray indexOfObject:[actionSheet buttonTitleAtIndex:buttonIndex]];
  180. if (arrayIndex != NSNotFound) {
  181. indexArray = _mediaPlayer.videoSubTitlesIndexes;
  182. _mediaPlayer.currentVideoSubTitleIndex = [[indexArray objectAtIndex:arrayIndex] intValue];
  183. }
  184. } else {
  185. namesArray = _mediaPlayer.audioTrackNames;
  186. arrayIndex = [namesArray indexOfObject:[actionSheet buttonTitleAtIndex:buttonIndex]];
  187. if (arrayIndex != NSNotFound) {
  188. indexArray = _mediaPlayer.audioTrackIndexes;
  189. _mediaPlayer.currentAudioTrackIndex = [[indexArray objectAtIndex:arrayIndex] intValue];
  190. }
  191. }
  192. }
  193. #pragma mark -
  194. - (void)appWillResign:(NSNotification *)aNotification
  195. {
  196. self.mediaItem.lastPosition = [NSNumber numberWithFloat:[_mediaPlayer position]];
  197. }
  198. #pragma mark - External Display
  199. - (BOOL)hasExternalDisplay
  200. {
  201. return ([[UIScreen screens] count] > 1);
  202. }
  203. - (void)showOnExternalDisplay
  204. {
  205. UIScreen *screen = [[UIScreen screens] objectAtIndex:1];
  206. screen.overscanCompensation = UIScreenOverscanCompensationInsetApplicationFrame;
  207. self.externalWindow = [[UIWindow alloc] initWithFrame:screen.bounds];
  208. UIViewController *controller = [[VLCExternalDisplayController alloc] init];
  209. self.externalWindow.rootViewController = controller;
  210. [controller.view addSubview:_movieView];
  211. controller.view.frame = screen.bounds;
  212. _movieView.frame = screen.bounds;
  213. self.playingExternallyView.hidden = NO;
  214. self.externalWindow.screen = screen;
  215. self.externalWindow.hidden = NO;
  216. }
  217. - (void)hideFromExternalDisplay
  218. {
  219. [self.view addSubview:_movieView];
  220. [self.view sendSubviewToBack:_movieView];
  221. _movieView.frame = self.view.frame;
  222. self.playingExternallyView.hidden = YES;
  223. self.externalWindow.hidden = YES;
  224. self.externalWindow = nil;
  225. }
  226. - (void)handleExternalScreenDidConnect:(NSNotification *)notification
  227. {
  228. [self showOnExternalDisplay];
  229. }
  230. - (void)handleExternalScreenDidDisconnect:(NSNotification *)notification
  231. {
  232. [self hideFromExternalDisplay];
  233. }
  234. @end