LMMediaPlayerView.m 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. //
  2. // LMMediaPlayerView.m
  3. // iPodMusicSample
  4. //
  5. // Created by Akira Matsuda on 2014/01/10.
  6. // Copyright (c) 2014年 Akira Matsuda. All rights reserved.
  7. //
  8. #import "LMMediaPlayerView.h"
  9. #import <MediaPlayer/MediaPlayer.h>
  10. #import <objc/runtime.h>
  11. #import "LMMediaPlayerHelper.h"
  12. static CGFloat const kFullscreenTransitionDuration = 0.2;
  13. static CGFloat const kActionButtonDefaultEdgeLength = 35;
  14. static CGFloat const kActionButtonDefaultRightMergin = 8;
  15. NSString *const LMMediaPlayerViewPlayButtonImageKey = @"playButtonImageKey";
  16. NSString *const LMMediaPlayerViewPlayButtonSelectedImageKey = @"playButtonSelectedImageKey";
  17. NSString *const LMMediaPlayerViewStopButtonImageKey = @"stopButtonImageKey";
  18. NSString *const LMMediaPlayerViewStopButtonSelectedImageKey = @"stopButtonSelectedImageKey";
  19. NSString *const LMMediaPlayerViewFullscreenButtonImageKey = @"fullscreenButtonImageKey";
  20. NSString *const LMMediaPlayerViewFullscreenButtonSelectedImageKey = @"fullscreenButtonSelectedImageKey";
  21. NSString *const LMMediaPlayerViewUnfullscreenButtonImageKey = @"unfullscreenButtonImageKey";
  22. NSString *const LMMediaPlayerViewUnfullscreenButtonSelectedImageKey = @"unfullscreenButtonSelectedImageKey";
  23. NSString *const LMMediaPlayerViewShuffleButtonShuffledImageKey = @"shuffleButtonShuffledImageKey";
  24. NSString *const LMMediaPlayerViewShuffleButtonShuffledSelectedImageKey = @"shuffleButtonShuffledSelectedImageKey";
  25. NSString *const LMMediaPlayerViewShuffleButtonUnshuffledImageKey = @"shuffleButtonUnshuffledImageKey";
  26. NSString *const LMMediaPlayerViewShuffleButtonUnshuffledSelectedImageKey = @"shuffleButtonUnshuffledSelectedImageKey";
  27. NSString *const LMMediaPlayerViewRepeatButtonRepeatOneImageKey = @"repeatButtonRepeatOneImageKey";
  28. NSString *const LMMediaPlayerViewRepeatButtonRepeatOneSelectedImageKey = @"repeatButtonRepeatOneSelectedImageKey";
  29. NSString *const LMMediaPlayerViewRepeatButtonRepeatAllImageKey = @"repeatButtonRepeatAllImageKey";
  30. NSString *const LMMediaPlayerViewRepeatButtonRepeatAllSelectedImageKey = @"repeatButtonRepeatAllSelectedImageKey";
  31. NSString *const LMMediaPlayerViewRepeatButtonRepeatNoneImageKey = @"repeatButtonRepeatNoneImageKey";
  32. NSString *const LMMediaPlayerViewRepeatButtonRepeatNoneSelectedImageKey = @"repeatButtonRepeatNoneSelectedImageKey";
  33. NSString *const LMMediaPlayerViewActionButtonImageKey = @"LMMediaPlayerViewActionButtonImageKey";
  34. @interface UIViewController (LMMediaPlayerPrefersStatusBarHidden)
  35. - (void)mediaPlayerPrefersStatusBarHidden:(BOOL)hidden;
  36. @end
  37. @interface LMMediaPlayerFullscreenViewController : UIViewController
  38. @end
  39. @implementation LMMediaPlayerFullscreenViewController
  40. - (BOOL)shouldAutorotate
  41. {
  42. return YES;
  43. }
  44. - (UIInterfaceOrientationMask)supportedInterfaceOrientations
  45. {
  46. return UIInterfaceOrientationMaskAllButUpsideDown;
  47. }
  48. - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
  49. {
  50. return UIInterfaceOrientationPortrait;
  51. }
  52. @end
  53. @interface LMMediaPlayerView () {
  54. __unsafe_unretained IBOutlet UILabel *playbackTimeLabel_;
  55. __unsafe_unretained IBOutlet UILabel *remainingTimeLabel_;
  56. __unsafe_unretained IBOutlet UIView *headerView_;
  57. __unsafe_unretained IBOutlet UIView *footerView_;
  58. __unsafe_unretained IBOutlet UIImageView *artworkImageView_;
  59. __unsafe_unretained IBOutlet UIButton *playButton_;
  60. __unsafe_unretained IBOutlet UIButton *shuffleButton_;
  61. __unsafe_unretained IBOutlet UIButton *repeatButton_;
  62. //__unsafe_unretained IBOutlet UIButton *fullscreenButton_;
  63. __unsafe_unretained IBOutlet UIButton *actionButton_;
  64. __unsafe_unretained IBOutlet NSLayoutConstraint *actionButtonWidth_;
  65. __unsafe_unretained IBOutlet NSLayoutConstraint *actionButtonRightMergin;
  66. BOOL fullscreen_;
  67. BOOL seeking_;
  68. BOOL needToSetPlayer_;
  69. UIView *superView_;
  70. NSMutableDictionary *buttonImages_;
  71. AVPlayerLayer *playerLayer_;
  72. #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
  73. UIVisualEffectView *headerBlurView_;
  74. UIVisualEffectView *footerBlurView_;
  75. #endif
  76. UIWindow *mainWindow_;
  77. }
  78. @end
  79. @implementation LMMediaPlayerView
  80. @synthesize isFullscreen = fullscreen_;
  81. static LMMediaPlayerView *sharedPlayerView;
  82. + (instancetype)sharedPlayerView
  83. {
  84. static dispatch_once_t onceToken;
  85. dispatch_once(&onceToken, ^{
  86. sharedPlayerView = [[self class] create];
  87. });
  88. return sharedPlayerView;
  89. }
  90. + (instancetype)create
  91. {
  92. return [[UINib nibWithNibName:NSStringFromClass([self class]) bundle:[NSBundle mainBundle]] instantiateWithOwner:nil options:nil][0];
  93. }
  94. - (instancetype)initWithFrame:(CGRect)frame
  95. {
  96. self = [super initWithFrame:frame];
  97. if (self) {
  98. [self setup];
  99. }
  100. return self;
  101. }
  102. - (void)drawRect:(CGRect)rect
  103. {
  104. [super drawRect:rect];
  105. if (needToSetPlayer_) {
  106. [playerLayer_ setPlayer:self.mediaPlayer.corePlayer];
  107. needToSetPlayer_ = NO;
  108. }
  109. }
  110. - (void)dealloc
  111. {
  112. _mediaPlayer.delegate = nil;
  113. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillEnterForegroundNotification object:nil];
  114. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
  115. LM_RELEASE(playbackTimeLabel_);
  116. LM_RELEASE(remainingTimeLabel_);
  117. LM_RELEASE(headerView_);
  118. LM_RELEASE(footerView_);
  119. LM_RELEASE(artworkImageView_);
  120. LM_RELEASE(playButton_);
  121. LM_RELEASE(_nextButton);
  122. LM_RELEASE(_previousButton);
  123. LM_RELEASE(shuffleButton_);
  124. LM_RELEASE(repeatButton_);
  125. LM_RELEASE(fullscreenButton_);
  126. LM_RELEASE(_mediaPlayer);
  127. LM_RELEASE(buttonImages_);
  128. LM_DEALLOC(super);
  129. }
  130. - (void)awakeFromNib
  131. {
  132. [super awakeFromNib];
  133. [self setup];
  134. [self setupUserInterface];
  135. }
  136. - (void)layoutSubviews
  137. {
  138. // resize your layers based on the view's new bounds
  139. [super layoutSubviews];
  140. playerLayer_.frame = self.bounds;
  141. }
  142. - (UIButton *)actionButton
  143. {
  144. return actionButton_;
  145. }
  146. - (void)setBluredUserInterface:(BOOL)bluredUserInterface visualEffect:(UIVisualEffect *)effect
  147. {
  148. #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_8_0
  149. if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) {
  150. _bluredUserInterface = bluredUserInterface;
  151. if (_bluredUserInterface == YES) {
  152. if (headerBlurView_ == nil) {
  153. headerBlurView_ = [[UIVisualEffectView alloc] initWithEffect:effect];
  154. footerBlurView_ = [[UIVisualEffectView alloc] initWithEffect:effect];
  155. headerBlurView_.frame = headerView_.bounds;
  156. headerBlurView_.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  157. footerBlurView_.frame = footerView_.bounds;
  158. footerBlurView_.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  159. [headerView_ insertSubview:headerBlurView_ atIndex:0];
  160. [footerView_ insertSubview:footerBlurView_ atIndex:0];
  161. }
  162. headerView_.backgroundColor = [UIColor clearColor];
  163. footerView_.backgroundColor = [UIColor clearColor];
  164. }
  165. else {
  166. UIColor *backgroundColor = [UIColor colorWithWhite:0.000 alpha:0.400];
  167. headerView_.backgroundColor = backgroundColor;
  168. footerView_.backgroundColor = backgroundColor;
  169. }
  170. headerBlurView_.hidden = footerBlurView_.hidden = !_bluredUserInterface;
  171. }
  172. #endif
  173. }
  174. #pragma mark -
  175. - (void)setup
  176. {
  177. [self setTranslatesAutoresizingMaskIntoConstraints:YES];
  178. self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
  179. mainWindow_ = [[UIApplication sharedApplication] keyWindow];
  180. if (mainWindow_ == nil) {
  181. mainWindow_ = [[UIApplication sharedApplication] windows][0];
  182. }
  183. LM_RETAIN(mainWindow_);
  184. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mediaPlayerBecomeForgroundMode:) name:UIApplicationWillEnterForegroundNotification object:nil];
  185. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mediaPlayerBecomeBackgroundMode:) name:UIApplicationDidEnterBackgroundNotification object:nil];
  186. needToSetPlayer_ = NO;
  187. _userInterfaceHidden = NO;
  188. _mediaPlayer = [[LMMediaPlayer alloc] init];
  189. _mediaPlayer.delegate = self;
  190. }
  191. - (void)setupUserInterface
  192. {
  193. UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(reverseUserInterfaceHidden)];
  194. [self addGestureRecognizer:gesture];
  195. LM_RELEASE(gesture);
  196. artworkImageView_.contentMode = UIViewContentModeScaleAspectFit;
  197. [_currentTimeSlider addTarget:self action:@selector(beginSeek:) forControlEvents:UIControlEventTouchDown];
  198. [_currentTimeSlider addTarget:self action:@selector(seekPositionChanged:) forControlEvents:UIControlEventValueChanged];
  199. [_currentTimeSlider addTarget:self action:@selector(endSeek:) forControlEvents:(UIControlEventTouchUpInside | UIControlEventTouchUpOutside | UIControlEventTouchCancel)];
  200. [playButton_ addTarget:self action:@selector(changePlaybackState:) forControlEvents:UIControlEventTouchUpInside];
  201. [_nextButton addTarget:self action:@selector(fourcePlayNextMedia) forControlEvents:UIControlEventTouchUpInside];
  202. [_previousButton addTarget:self action:@selector(fourcePlayPreviousMedia) forControlEvents:UIControlEventTouchUpInside];
  203. UIColor *backgroundColor = [UIColor colorWithWhite:0.000 alpha:0.400];
  204. footerView_.backgroundColor = headerView_.backgroundColor = backgroundColor;
  205. [_mediaPlayer setShuffleEnabled:NO];
  206. [_mediaPlayer setRepeatMode:LMMediaRepeatModeDefault];
  207. buttonImages_ = [@{ LMMediaPlayerViewPlayButtonImageKey : [[self class] imageForFilename:@"play"],
  208. LMMediaPlayerViewPlayButtonSelectedImageKey : [[self class] imageForFilename:@"play"],
  209. LMMediaPlayerViewStopButtonImageKey : [[self class] imageForFilename:@"pause"],
  210. LMMediaPlayerViewStopButtonSelectedImageKey : [[self class] imageForFilename:@"pause"],
  211. LMMediaPlayerViewShuffleButtonShuffledImageKey : [[self class] imageForFilename:@"shuffle"],
  212. LMMediaPlayerViewShuffleButtonShuffledSelectedImageKey : [[self class] imageForFilename:@"shuffle"],
  213. LMMediaPlayerViewShuffleButtonUnshuffledImageKey : [[self class] imageForFilename:@"unshuffle"],
  214. LMMediaPlayerViewShuffleButtonUnshuffledSelectedImageKey : [[self class] imageForFilename:@"unshuffle"],
  215. LMMediaPlayerViewRepeatButtonRepeatNoneImageKey : [[self class] imageForFilename:@"repeat_none"],
  216. LMMediaPlayerViewRepeatButtonRepeatNoneSelectedImageKey : [[self class] imageForFilename:@"repeat_none"],
  217. LMMediaPlayerViewRepeatButtonRepeatOneImageKey : [[self class] imageForFilename:@"repeat_one"],
  218. LMMediaPlayerViewRepeatButtonRepeatOneSelectedImageKey : [[self class] imageForFilename:@"repeat_one"],
  219. LMMediaPlayerViewRepeatButtonRepeatAllImageKey : [[self class] imageForFilename:@"repeat_all"],
  220. LMMediaPlayerViewRepeatButtonRepeatAllSelectedImageKey : [[self class] imageForFilename:@"repeat_all"],
  221. LMMediaPlayerViewFullscreenButtonImageKey : [[self class] imageForFilename:@"fullscreen"],
  222. LMMediaPlayerViewFullscreenButtonSelectedImageKey : [[self class] imageForFilename:@"fullscreen"],
  223. LMMediaPlayerViewUnfullscreenButtonImageKey : [[self class] imageForFilename:@"unfullscreen"],
  224. LMMediaPlayerViewUnfullscreenButtonSelectedImageKey : [[self class] imageForFilename:@"unfullscreen"]
  225. } mutableCopy];
  226. [playButton_.imageView setContentMode:UIViewContentModeScaleAspectFit];
  227. [playButton_ setImage:buttonImages_[LMMediaPlayerViewPlayButtonImageKey] forState:UIControlStateNormal];
  228. [playButton_ setImage:buttonImages_[LMMediaPlayerViewPlayButtonSelectedImageKey] forState:UIControlStateSelected];
  229. [_fullscreenButton_.imageView setContentMode:UIViewContentModeScaleAspectFit];
  230. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewFullscreenButtonImageKey] forState:UIControlStateNormal];
  231. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewFullscreenButtonSelectedImageKey] forState:UIControlStateSelected];
  232. [repeatButton_.imageView setContentMode:UIViewContentModeScaleAspectFit];
  233. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatNoneImageKey] forState:UIControlStateNormal];
  234. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatNoneSelectedImageKey] forState:UIControlStateSelected];
  235. [shuffleButton_.imageView setContentMode:UIViewContentModeScaleAspectFit];
  236. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonUnshuffledImageKey] forState:UIControlStateNormal];
  237. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonUnshuffledSelectedImageKey] forState:UIControlStateSelected];
  238. [actionButton_.imageView setContentMode:UIViewContentModeScaleAspectFit];
  239. actionButtonWidth_.constant = 0;
  240. actionButtonRightMergin.constant = 0;
  241. }
  242. - (void)mediaPlayerBecomeForgroundMode:(NSNotification *)notification
  243. {
  244. needToSetPlayer_ = YES;
  245. [self setNeedsDisplay];
  246. }
  247. - (void)mediaPlayerBecomeBackgroundMode:(NSNotification *)notification
  248. {
  249. double delayInSeconds = 0.01;
  250. dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
  251. dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
  252. [playerLayer_ setPlayer:nil];
  253. if (self.mediaPlayer.playbackState == LMMediaPlaybackStatePlaying) {
  254. [self.mediaPlayer play];
  255. }
  256. });
  257. }
  258. #pragma mark LMMediaPlayerDelegate
  259. - (void)mediaPlayerWillChangeState:(LMMediaPlaybackState)state
  260. {
  261. if ([self.delegate respondsToSelector:@selector(mediaPlayerViewWillChangeState:state:)]) {
  262. [self.delegate mediaPlayerViewWillChangeState:self state:state];
  263. }
  264. if (state == LMMediaPlaybackStateStopped || state == LMMediaPlaybackStatePaused) {
  265. [playButton_ setImage:buttonImages_[LMMediaPlayerViewPlayButtonImageKey] ?: nil forState:UIControlStateNormal];
  266. [playButton_ setImage:buttonImages_[LMMediaPlayerViewPlayButtonSelectedImageKey] ?: nil forState:UIControlStateSelected];
  267. }
  268. else {
  269. [playButton_ setImage:buttonImages_[LMMediaPlayerViewStopButtonImageKey] ?: nil forState:UIControlStateNormal];
  270. [playButton_ setImage:buttonImages_[LMMediaPlayerViewStopButtonSelectedImageKey] ?: nil forState:UIControlStateSelected];
  271. }
  272. }
  273. - (BOOL)mediaPlayerWillStartPlaying:(LMMediaPlayer *)player media:(LMMediaItem *)media
  274. {
  275. BOOL result = NO;
  276. if ([self.delegate respondsToSelector:@selector(mediaPlayerViewWillStartPlaying:media:)] == YES) {
  277. result = [self.delegate mediaPlayerViewWillStartPlaying:self media:media];
  278. }
  279. else {
  280. result = YES;
  281. }
  282. self.titleLabel.text = media.title;
  283. return result;
  284. }
  285. - (void)mediaPlayerDidStartPlaying:(LMMediaPlayer *)player media:(LMMediaItem *)media
  286. {
  287. if (media.isVideo) {
  288. artworkImageView_.hidden = YES;
  289. self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
  290. if (playerLayer_ == nil) {
  291. playerLayer_ = [AVPlayerLayer playerLayerWithPlayer:player.corePlayer];
  292. playerLayer_.frame = self.frame;
  293. [self.layer insertSublayer:playerLayer_ atIndex:0];
  294. }
  295. needToSetPlayer_ = YES;
  296. playerLayer_.hidden = NO;
  297. }
  298. else {
  299. playerLayer_.hidden = YES;
  300. artworkImageView_.hidden = NO;
  301. artworkImageView_.image = [media artworkImageWithSize:self.frame.size];
  302. }
  303. if ([self.delegate respondsToSelector:@selector(mediaPlayerViewDidStartPlaying:media:)]) {
  304. [self.delegate mediaPlayerViewDidStartPlaying:self media:media];
  305. }
  306. }
  307. - (void)mediaPlayerDidFinishPlaying:(LMMediaPlayer *)player media:(LMMediaItem *)media
  308. {
  309. _currentTimeSlider.value = 1.0;
  310. if ([self.delegate respondsToSelector:@selector(mediaPlayerViewDidFinishPlaying:media:)]) {
  311. [self.delegate mediaPlayerViewDidFinishPlaying:self media:media];
  312. }
  313. }
  314. - (void)mediaPlayerDidChangeCurrentTime:(LMMediaPlayer *)player
  315. {
  316. if (seeking_ == NO) {
  317. _currentTimeSlider.value = player.currentPlaybackTime / player.currentPlaybackDuration;
  318. NSMutableString *durationString = [NSMutableString new];
  319. NSInteger duration = (NSInteger)player.currentPlaybackTime;
  320. if (duration / (60 * 60) > 0) {
  321. [durationString appendFormat:@"%02ld:",
  322. (long int)duration / (60 * 60)];
  323. duration /= 60 * 60;
  324. }
  325. [durationString appendFormat:@"%02ld:", (long int)duration / 60];
  326. duration %= 60;
  327. [durationString appendFormat:@"%02ld", (long int)duration];
  328. playbackTimeLabel_.text = durationString;
  329. LM_RELEASE(durationString);
  330. durationString = [[NSMutableString alloc] initWithString:@"-"];
  331. duration = (NSInteger)fabs(player.currentPlaybackTime - player.currentPlaybackDuration);
  332. if (duration / (60 * 60) > 0) {
  333. [durationString appendFormat:@"%02ld:",
  334. (long int)duration / (60 * 60)];
  335. duration /= 60 * 60;
  336. }
  337. [durationString appendFormat:@"%02ld:", (long int)duration / 60];
  338. duration %= 60;
  339. [durationString appendFormat:@"%02ld", (long int)duration];
  340. remainingTimeLabel_.text = durationString;
  341. LM_RELEASE(durationString);
  342. }
  343. if ([self.delegate respondsToSelector:@selector(mediaPlayerViewDidChangeCurrentTime:)]) {
  344. [self.delegate mediaPlayerViewDidChangeCurrentTime:self];
  345. }
  346. }
  347. - (void)mediaPlayerDidChangeRepeatMode:(LMMediaRepeatMode)mode player:(LMMediaPlayer *)player
  348. {
  349. [self setRepeatButtonImageWithRepeatMode:mode];
  350. if ([self.delegate respondsToSelector:@selector(mediaPlayerViewDidChangeRepeatMode:playerView:)]) {
  351. [self.delegate mediaPlayerViewDidChangeRepeatMode:mode playerView:self];
  352. }
  353. }
  354. - (void)mediaPlayerDidChangeShuffleMode:(BOOL)enabled player:(LMMediaPlayer *)player
  355. {
  356. [self setShuffleButtonImageWithShuffleMode:enabled];
  357. if ([self.delegate respondsToSelector:@selector(mediaPlayerViewDidChangeShuffleMode:playerView:)]) {
  358. [self.delegate mediaPlayerViewDidChangeShuffleMode:enabled playerView:self];
  359. }
  360. }
  361. #pragma mark -
  362. - (void)beginSeek:(id)sender
  363. {
  364. seeking_ = YES;
  365. }
  366. - (void)seekPositionChanged:(id)sender
  367. {
  368. NSMutableString *durationString = [NSMutableString new];
  369. NSInteger currentTime = (NSInteger)_mediaPlayer.currentPlaybackDuration * _currentTimeSlider.value;
  370. NSInteger duration = currentTime;
  371. if (duration / (60 * 60) > 0) {
  372. [durationString appendFormat:@"%02ld:",
  373. (long int)duration / (60 * 60)];
  374. duration /= 60 * 60;
  375. }
  376. [durationString appendFormat:@"%02ld:", (long int)duration / 60];
  377. duration %= 60;
  378. [durationString appendFormat:@"%02ld", (long int)duration];
  379. playbackTimeLabel_.text = durationString;
  380. LM_RELEASE(durationString);
  381. durationString = [[NSMutableString alloc] initWithString:@"-"];
  382. duration = (NSInteger)_mediaPlayer.currentPlaybackDuration - currentTime;
  383. if (duration / (60 * 60) > 0) {
  384. [durationString appendFormat:@"%02ld:",
  385. (long int)duration / (60 * 60)];
  386. duration /= 60 * 60;
  387. }
  388. [durationString appendFormat:@"%02ld:", (long int)duration / 60];
  389. duration %= 60;
  390. [durationString appendFormat:@"%02ld", (long int)duration];
  391. remainingTimeLabel_.text = durationString;
  392. LM_RELEASE(durationString);
  393. }
  394. - (void)endSeek:(id)sender
  395. {
  396. UISlider *slider = (UISlider *)sender;
  397. [_mediaPlayer seekTo:_mediaPlayer.currentPlaybackDuration * slider.value];
  398. seeking_ = NO;
  399. }
  400. - (void)changePlaybackState:(id)sender
  401. {
  402. if ([_mediaPlayer playbackState] == LMMediaPlaybackStatePlaying) {
  403. [_mediaPlayer pause];
  404. }
  405. else if ([_mediaPlayer playbackState] == LMMediaPlaybackStatePaused || [_mediaPlayer playbackState] == LMMediaPlaybackStateStopped) {
  406. [_mediaPlayer play];
  407. }
  408. }
  409. - (void)reverseUserInterfaceHidden
  410. {
  411. if (seeking_ == NO) {
  412. [self setUserInterfaceHidden:!_userInterfaceHidden];
  413. }
  414. }
  415. - (void)fourcePlayNextMedia
  416. {
  417. LMMediaRepeatMode repeatMode = _mediaPlayer.repeatMode;
  418. if (repeatMode == LMMediaRepeatModeOne) {
  419. _mediaPlayer.repeatMode = LMMediaRepeatModeDefault;
  420. }
  421. [_mediaPlayer playNextMedia];
  422. _mediaPlayer.repeatMode = repeatMode;
  423. }
  424. - (void)fourcePlayPreviousMedia
  425. {
  426. LMMediaRepeatMode repeatMode = _mediaPlayer.repeatMode;
  427. if (repeatMode == LMMediaRepeatModeOne) {
  428. _mediaPlayer.repeatMode = LMMediaRepeatModeDefault;
  429. }
  430. [_mediaPlayer playPreviousMedia];
  431. _mediaPlayer.repeatMode = repeatMode;
  432. }
  433. - (IBAction)shuffleButtonPressed:(id)sender
  434. {
  435. [_mediaPlayer setShuffleEnabled:!_mediaPlayer.shuffleMode];
  436. if (_mediaPlayer.shuffleMode) {
  437. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonShuffledImageKey] forState:UIControlStateNormal];
  438. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonShuffledSelectedImageKey] forState:UIControlStateSelected];
  439. }
  440. else {
  441. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonUnshuffledImageKey] forState:UIControlStateNormal];
  442. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonUnshuffledSelectedImageKey] forState:UIControlStateSelected];
  443. }
  444. [self setRepeatButtonImageWithRepeatMode:_mediaPlayer.repeatMode];
  445. }
  446. - (IBAction)repeatButtonPressed:(id)sender
  447. {
  448. switch (_mediaPlayer.repeatMode) {
  449. case LMMediaRepeatModeAll: {
  450. _mediaPlayer.repeatMode = LMMediaRepeatModeOne;
  451. } break;
  452. case LMMediaRepeatModeOne: {
  453. _mediaPlayer.repeatMode = LMMediaRepeatModeDefault;
  454. } break;
  455. case LMMediaRepeatModeDefault: {
  456. _mediaPlayer.repeatMode = LMMediaRepeatModeAll;
  457. } break;
  458. default:
  459. break;
  460. }
  461. [self setRepeatButtonImageWithRepeatMode:_mediaPlayer.repeatMode];
  462. }
  463. - (void)setShuffleButtonImageWithShuffleMode:(BOOL)mode
  464. {
  465. if (mode) {
  466. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonShuffledImageKey] forState:UIControlStateNormal];
  467. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonShuffledSelectedImageKey] forState:UIControlStateSelected];
  468. }
  469. else {
  470. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonUnshuffledImageKey] forState:UIControlStateNormal];
  471. [shuffleButton_ setImage:buttonImages_[LMMediaPlayerViewShuffleButtonUnshuffledSelectedImageKey] forState:UIControlStateSelected];
  472. }
  473. }
  474. - (void)setRepeatButtonImageWithRepeatMode:(LMMediaRepeatMode)mode
  475. {
  476. switch (_mediaPlayer.repeatMode) {
  477. case LMMediaRepeatModeAll: {
  478. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatAllImageKey] forState:UIControlStateNormal];
  479. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatAllSelectedImageKey] forState:UIControlStateSelected];
  480. } break;
  481. case LMMediaRepeatModeOne: {
  482. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatOneImageKey] forState:UIControlStateNormal];
  483. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatOneSelectedImageKey] forState:UIControlStateSelected];
  484. } break;
  485. case LMMediaRepeatModeDefault: {
  486. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatNoneImageKey] forState:UIControlStateNormal];
  487. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatNoneSelectedImageKey] forState:UIControlStateSelected];
  488. } break;
  489. default: {
  490. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatNoneImageKey] forState:UIControlStateNormal];
  491. [repeatButton_ setImage:buttonImages_[LMMediaPlayerViewRepeatButtonRepeatNoneSelectedImageKey] forState:UIControlStateSelected];
  492. } break;
  493. }
  494. }
  495. - (IBAction)fullscreenButtonPressed:(id)sender
  496. {
  497. [self setFullscreen:!fullscreen_];
  498. }
  499. #pragma mark -
  500. - (void)setHeaderViewHidden:(BOOL)hidden
  501. {
  502. headerView_.hidden = hidden;
  503. }
  504. - (void)setFooterViewHidden:(BOOL)hidden
  505. {
  506. footerView_.hidden = hidden;
  507. }
  508. - (void)setUserInterfaceHidden:(BOOL)hidden
  509. {
  510. _userInterfaceHidden = hidden;
  511. if (hidden) {
  512. [UIView animateWithDuration:0.3 animations:^{
  513. headerView_.alpha = 0;
  514. footerView_.alpha = 0;
  515. _currentTimeSlider.alpha = 0;
  516. _nextButton.superview.alpha = 0;
  517. _previousButton.superview.alpha = 0;
  518. } completion:^(BOOL finished){
  519. }];
  520. }
  521. else {
  522. [UIView animateWithDuration:0.3 animations:^{
  523. headerView_.alpha = 1;
  524. footerView_.alpha = 1;
  525. _currentTimeSlider.alpha = 1;
  526. _nextButton.superview.alpha = 1;
  527. _previousButton.superview.alpha = 1;
  528. } completion:^(BOOL finished){
  529. }];
  530. }
  531. }
  532. - (void)setFullscreen:(BOOL)fullscreen animated:(BOOL)animated
  533. {
  534. if (fullscreen_ == fullscreen) {
  535. return;
  536. }
  537. if ([self.delegate respondsToSelector:@selector(mediaPlayerViewWillChangeFullscreenMode:)]) {
  538. [self.delegate mediaPlayerViewWillChangeFullscreenMode:fullscreen];
  539. }
  540. LMMediaPlayerFullscreenViewController *viewController = [[LMMediaPlayerFullscreenViewController alloc] init];
  541. LM_AUTORELEASE(viewController);
  542. viewController.view.frame = [UIScreen mainScreen].bounds;
  543. if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_7_0) {
  544. viewController.extendedLayoutIncludesOpaqueBars = YES;
  545. }
  546. else {
  547. //viewController.wantsFullScreenLayout = YES;
  548. }
  549. CGRect newRect;
  550. if (fullscreen == NO) {
  551. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewFullscreenButtonImageKey] forState:UIControlStateNormal];
  552. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewFullscreenButtonSelectedImageKey] forState:UIControlStateSelected];
  553. newRect = superView_.bounds;
  554. newRect.size.height = newRect.size.height - 20; //TWS
  555. self.frame = newRect;
  556. [superView_ addSubview:self];
  557. LM_RELEASE(superView_);
  558. [mainWindow_ makeKeyAndVisible];
  559. [[[UIApplication sharedApplication] delegate] setWindow:mainWindow_];
  560. [[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
  561. [[UIApplication sharedApplication] setStatusBarOrientation:[[UIApplication sharedApplication] statusBarOrientation]];
  562. [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationFade];
  563. }
  564. else {
  565. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewUnfullscreenButtonImageKey] forState:UIControlStateNormal];
  566. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewUnfullscreenButtonSelectedImageKey] forState:UIControlStateSelected];
  567. superView_ = self.superview;
  568. LM_RETAIN(superView_);
  569. newRect = mainWindow_.frame;
  570. //UIViewController *rootViewController = [mainWindow_ rootViewController];
  571. UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; //rootViewController.interfaceOrientation;
  572. if (orientation == UIInterfaceOrientationLandscapeRight || orientation == UIInterfaceOrientationLandscapeLeft) {
  573. if (floor(NSFoundationVersionNumber) >= NSFoundationVersionNumber_iOS_7_0) {
  574. newRect = CGRectMake(0, 0, CGRectGetWidth(mainWindow_.frame), CGRectGetHeight(mainWindow_.frame));
  575. }
  576. else {
  577. newRect = CGRectMake(0, 0, CGRectGetHeight(mainWindow_.frame), CGRectGetWidth(mainWindow_.frame));
  578. }
  579. }
  580. [self removeFromSuperview];
  581. [viewController.view addSubview:self];
  582. UIWindow *newWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
  583. newWindow.windowLevel = UIWindowLevelAlert;
  584. newWindow.rootViewController = viewController;
  585. [newWindow addSubview:viewController.view];
  586. [newWindow makeKeyAndVisible];
  587. [[[UIApplication sharedApplication] delegate] setWindow:newWindow];
  588. LM_RELEASE(newWindow);
  589. }
  590. self.frame = newRect;
  591. if (animated) {
  592. self.alpha = 0;
  593. [UIView animateWithDuration:kFullscreenTransitionDuration animations:^{
  594. self.alpha = 1;
  595. }];
  596. }
  597. fullscreen_ = fullscreen;
  598. if ([self.delegate respondsToSelector:@selector(mediaPlayerViewDidChangeFullscreenMode:)]) {
  599. [self.delegate mediaPlayerViewDidChangeFullscreenMode:fullscreen];
  600. }
  601. [[UIApplication sharedApplication] setStatusBarHidden:fullscreen];
  602. [[NSNotificationCenter defaultCenter] postNotificationName:UIDeviceOrientationDidChangeNotification object:[UIDevice currentDevice]];
  603. }
  604. - (void)setFullscreen:(BOOL)fullscreen
  605. {
  606. [self setFullscreen:fullscreen animated:YES];
  607. }
  608. - (void)setButtonImages:(NSDictionary *)info
  609. {
  610. for (NSString *key in info) {
  611. buttonImages_[key] = info[key];
  612. }
  613. if ([buttonImages_[LMMediaPlayerViewActionButtonImageKey] isKindOfClass:[UIImage class]]) {
  614. actionButtonWidth_.constant = kActionButtonDefaultEdgeLength;
  615. actionButtonRightMergin.constant = kActionButtonDefaultRightMergin;
  616. [actionButton_ setImage:info[LMMediaPlayerViewActionButtonImageKey] forState:UIControlStateNormal];
  617. }
  618. else {
  619. actionButtonWidth_.constant = 0;
  620. actionButtonRightMergin.constant = 0;
  621. }
  622. [self updateButtonImages];
  623. }
  624. - (void)updateButtonImages
  625. {
  626. if (self.mediaPlayer.playbackState == LMMediaPlaybackStatePlaying) {
  627. [playButton_ setImage:buttonImages_[LMMediaPlayerViewStopButtonImageKey] forState:UIControlStateNormal];
  628. [playButton_ setImage:buttonImages_[LMMediaPlayerViewStopButtonSelectedImageKey] forState:UIControlStateSelected];
  629. }
  630. else {
  631. [playButton_ setImage:buttonImages_[LMMediaPlayerViewPlayButtonImageKey] forState:UIControlStateNormal];
  632. [playButton_ setImage:buttonImages_[LMMediaPlayerViewPlayButtonSelectedImageKey] forState:UIControlStateSelected];
  633. }
  634. if (self.isFullscreen) {
  635. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewUnfullscreenButtonImageKey] forState:UIControlStateNormal];
  636. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewUnfullscreenButtonSelectedImageKey] forState:UIControlStateSelected];
  637. }
  638. else {
  639. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewFullscreenButtonImageKey] forState:UIControlStateNormal];
  640. [_fullscreenButton_ setImage:buttonImages_[LMMediaPlayerViewFullscreenButtonSelectedImageKey] forState:UIControlStateSelected];
  641. }
  642. [self setRepeatButtonImageWithRepeatMode:self.mediaPlayer.repeatMode];
  643. [self setShuffleButtonImageWithShuffleMode:self.mediaPlayer.shuffleMode];
  644. }
  645. + (UIImage *)imageForFilename:(NSString *)filename
  646. {
  647. NSString *version = @"7";
  648. if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
  649. version = @"6";
  650. }
  651. UIImage *image = [UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@/%@.png", [[NSBundle mainBundle] pathForResource:@"LMMediaPlayerView" ofType:@"bundle"], version, filename]];
  652. return image;
  653. }
  654. @end