AFSoundPlayback.m 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. //
  2. // AFSoundPlayback.m
  3. // AFSoundManager-Demo
  4. //
  5. // Created by Alvaro Franco on 21/01/15.
  6. // Copyright (c) 2015 AlvaroFranco. All rights reserved.
  7. //
  8. #import "AFSoundPlayback.h"
  9. #import "AFSoundManager.h"
  10. #import "NSTimer+AFSoundManager.h"
  11. @interface AFSoundPlayback ()
  12. -(void)setUpItem:(AFSoundItem *)item;
  13. @property (nonatomic, strong) NSTimer *feedbackTimer;
  14. @end
  15. @implementation AFSoundPlayback
  16. NSString * const AFSoundPlaybackStatus = @"status";
  17. NSString * const AFSoundStatusDuration = @"duration";
  18. NSString * const AFSoundStatusTimeElapsed = @"timeElapsed";
  19. NSString * const AFSoundPlaybackFinishedNotification = @"kAFSoundPlaybackFinishedNotification";
  20. -(id)initWithItem:(AFSoundItem *)item {
  21. if (self == [super init]) {
  22. _currentItem = item;
  23. [self setUpItem:item];
  24. _status = AFSoundStatusNotStarted;
  25. }
  26. return self;
  27. }
  28. -(void)setUpItem:(AFSoundItem *)item {
  29. _player = [[AVPlayer alloc] initWithURL:item.URL];
  30. [_player play];
  31. _player.actionAtItemEnd = AVPlayerActionAtItemEndPause;
  32. _status = AFSoundStatusPlaying;
  33. _currentItem = item;
  34. _currentItem.duration = (int)CMTimeGetSeconds(_player.currentItem.asset.duration);
  35. [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
  36. [[AVAudioSession sharedInstance] setActive:YES error:nil];
  37. [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
  38. }
  39. -(void)listenFeedbackUpdatesWithBlock:(feedbackBlock)block andFinishedBlock:(finishedBlock)finishedBlock {
  40. CGFloat updateRate = 1;
  41. if (_player.rate > 0) {
  42. updateRate = 1 / _player.rate;
  43. }
  44. _feedbackTimer = [NSTimer scheduledTimerWithTimeInterval:updateRate block:^{
  45. _currentItem.timePlayed = (int)CMTimeGetSeconds(_player.currentTime);
  46. if (block) {
  47. block(_currentItem);
  48. }
  49. if (self.statusDictionary[AFSoundStatusDuration] == self.statusDictionary[AFSoundStatusTimeElapsed]) {
  50. [_feedbackTimer pauseTimer];
  51. _status = AFSoundStatusFinished;
  52. if (finishedBlock) {
  53. finishedBlock();
  54. }
  55. }
  56. } repeats:YES];
  57. }
  58. -(NSDictionary *)playingInfo {
  59. NSMutableDictionary *dict = [NSMutableDictionary dictionary];
  60. [dict setValue:[NSNumber numberWithDouble:CMTimeGetSeconds(_player.currentItem.currentTime)] forKey:MPNowPlayingInfoPropertyElapsedPlaybackTime];
  61. [dict setValue:@(_player.rate) forKey:MPNowPlayingInfoPropertyPlaybackRate];
  62. return dict;
  63. }
  64. -(void)play {
  65. [_player play];
  66. [_feedbackTimer resumeTimer];
  67. [[MPRemoteCommandCenter sharedCommandCenter] playCommand];
  68. _status = AFSoundStatusPlaying;
  69. }
  70. -(void)pause {
  71. [_player pause];
  72. [_feedbackTimer pauseTimer];
  73. [[MPRemoteCommandCenter sharedCommandCenter] pauseCommand];
  74. _status = AFSoundStatusPaused;
  75. }
  76. -(void)restart {
  77. [_player seekToTime:CMTimeMake(0, 1)];
  78. }
  79. -(void)playAtSecond:(NSInteger)second {
  80. [_player seekToTime:CMTimeMake(second, 1)];
  81. }
  82. -(void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
  83. if (receivedEvent.type == UIEventTypeRemoteControl) {
  84. switch (receivedEvent.subtype) {
  85. case UIEventSubtypeRemoteControlTogglePlayPause:
  86. [self play];
  87. break;
  88. default:
  89. break;
  90. }
  91. }
  92. }
  93. -(NSDictionary *)statusDictionary {
  94. return @{AFSoundStatusDuration: @((int)CMTimeGetSeconds(_player.currentItem.asset.duration)),
  95. AFSoundStatusTimeElapsed: @((int)CMTimeGetSeconds(_player.currentItem.currentTime)),
  96. AFSoundPlaybackStatus: @(_status)};
  97. }
  98. @end