AFSoundQueue.m 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. //
  2. // AFSoundQueue.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 "AFSoundQueue.h"
  9. #import "AFSoundManager.h"
  10. #import "NSTimer+AFSoundManager.h"
  11. #import <objc/runtime.h>
  12. @interface AFSoundQueue ()
  13. @property (nonatomic, strong) AFSoundPlayback *queuePlayer;
  14. @property (nonatomic, strong) NSMutableArray *items;
  15. @property (nonatomic, strong) NSTimer *feedbackTimer;
  16. @end
  17. @implementation AFSoundQueue
  18. -(id)initWithItems:(NSArray *)items {
  19. if (self == [super init]) {
  20. if (items) {
  21. _items = [NSMutableArray arrayWithArray:items];
  22. _queuePlayer = [[AFSoundPlayback alloc] initWithItem:items.firstObject];
  23. [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
  24. }
  25. }
  26. return self;
  27. }
  28. -(void)listenFeedbackUpdatesWithBlock:(feedbackBlock)block andFinishedBlock:(itemFinishedBlock)finishedBlock {
  29. CGFloat updateRate = 1;
  30. if (_queuePlayer.player.rate > 0) {
  31. updateRate = 1 / _queuePlayer.player.rate;
  32. }
  33. _feedbackTimer = [NSTimer scheduledTimerWithTimeInterval:updateRate block:^{
  34. if (block) {
  35. _queuePlayer.currentItem.timePlayed = (int)CMTimeGetSeconds(_queuePlayer.player.currentTime);
  36. block(_queuePlayer.currentItem);
  37. }
  38. if (_queuePlayer.currentItem.timePlayed == _queuePlayer.currentItem.duration) {
  39. if (finishedBlock) {
  40. if ([self indexOfCurrentItem] + 1 < _items.count) {
  41. finishedBlock(_items[[self indexOfCurrentItem] + 1]);
  42. } else {
  43. finishedBlock(nil);
  44. }
  45. }
  46. [_feedbackTimer pauseTimer];
  47. [self playNextItem];
  48. }
  49. } repeats:YES];
  50. }
  51. -(void)addItem:(AFSoundItem *)item {
  52. [self addItem:item atIndex:_items.count];
  53. }
  54. -(void)addItem:(AFSoundItem *)item atIndex:(NSInteger)index {
  55. [_items insertObject:item atIndex:(_items.count >= index) ? _items.count : index];
  56. }
  57. -(void)removeItem:(AFSoundItem *)item {
  58. if ([_items containsObject:item]) {
  59. [self removeItemAtIndex:[_items indexOfObject:item]];
  60. }
  61. }
  62. -(void)removeItemAtIndex:(NSInteger)index {
  63. if (_items.count >= index) {
  64. AFSoundItem *item = _items[index];
  65. [_items removeObject:item];
  66. if (_queuePlayer.currentItem == item) {
  67. [self playNextItem];
  68. [_feedbackTimer resumeTimer];
  69. }
  70. }
  71. }
  72. -(void)clearQueue {
  73. [_queuePlayer pause];
  74. [_items removeAllObjects];
  75. [_feedbackTimer pauseTimer];
  76. }
  77. -(void)playCurrentItem {
  78. [_queuePlayer play];
  79. [[MPRemoteCommandCenter sharedCommandCenter] playCommand];
  80. [_feedbackTimer resumeTimer];
  81. }
  82. -(void)pause {
  83. [_queuePlayer pause];
  84. [[MPRemoteCommandCenter sharedCommandCenter] pauseCommand];
  85. [_feedbackTimer pauseTimer];
  86. }
  87. -(void)playNextItem {
  88. if ([_items containsObject:_queuePlayer.currentItem]) {
  89. [self playItemAtIndex:([_items indexOfObject:_queuePlayer.currentItem] + 1)];
  90. [[MPRemoteCommandCenter sharedCommandCenter] nextTrackCommand];
  91. [_feedbackTimer resumeTimer];
  92. }
  93. }
  94. -(void)playPreviousItem {
  95. if ([_items containsObject:_queuePlayer.currentItem] && [_items indexOfObject:_queuePlayer.currentItem] > 0) {
  96. [self playItemAtIndex:([_items indexOfObject:_queuePlayer.currentItem] - 1)];
  97. [[MPRemoteCommandCenter sharedCommandCenter] previousTrackCommand];
  98. }
  99. }
  100. -(void)playItemAtIndex:(NSInteger)index {
  101. if (_items.count > index) {
  102. [self playItem:_items[index]];
  103. }
  104. }
  105. -(void)playItem:(AFSoundItem *)item {
  106. if ([_items containsObject:item]) {
  107. if (_queuePlayer.status == AFSoundStatusNotStarted || _queuePlayer.status == AFSoundStatusPaused || _queuePlayer.status == AFSoundStatusFinished) {
  108. // [_feedbackTimer resumeTimer];
  109. }
  110. _queuePlayer = [[AFSoundPlayback alloc] initWithItem:item];
  111. [_queuePlayer play];
  112. [[MPRemoteCommandCenter sharedCommandCenter] playCommand];
  113. }
  114. }
  115. -(AFSoundItem *)getCurrentItem {
  116. return _queuePlayer.currentItem;
  117. }
  118. -(NSInteger)indexOfCurrentItem {
  119. AFSoundItem *currentItem = [self getCurrentItem];
  120. if ([_items containsObject:currentItem]) {
  121. return [_items indexOfObject:currentItem];
  122. }
  123. return NAN;
  124. }
  125. -(void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
  126. if (receivedEvent.type == UIEventTypeRemoteControl) {
  127. switch (receivedEvent.subtype) {
  128. case UIEventSubtypeRemoteControlPreviousTrack:
  129. [self playPreviousItem];
  130. break;
  131. case UIEventSubtypeRemoteControlNextTrack:
  132. [self playNextItem];
  133. break;
  134. default:
  135. break;
  136. }
  137. }
  138. }
  139. @end