UriAudioSource.m 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #import "UriAudioSource.h"
  2. #import "IndexedAudioSource.h"
  3. #import "IndexedPlayerItem.h"
  4. #import <AVFoundation/AVFoundation.h>
  5. @implementation UriAudioSource {
  6. NSString *_uri;
  7. IndexedPlayerItem *_playerItem;
  8. /* CMTime _duration; */
  9. }
  10. - (instancetype)initWithId:(NSString *)sid uri:(NSString *)uri {
  11. self = [super initWithId:sid];
  12. NSAssert(self, @"super init cannot be nil");
  13. _uri = uri;
  14. if ([_uri hasPrefix:@"file://"]) {
  15. _playerItem = [[IndexedPlayerItem alloc] initWithURL:[NSURL fileURLWithPath:[_uri substringFromIndex:7]]];
  16. } else {
  17. _playerItem = [[IndexedPlayerItem alloc] initWithURL:[NSURL URLWithString:_uri]];
  18. }
  19. if (@available(macOS 10.13, iOS 11.0, *)) {
  20. // This does the best at reducing distortion on voice with speeds below 1.0
  21. _playerItem.audioTimePitchAlgorithm = AVAudioTimePitchAlgorithmTimeDomain;
  22. }
  23. /* NSKeyValueObservingOptions options = */
  24. /* NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew; */
  25. /* [_playerItem addObserver:self */
  26. /* forKeyPath:@"duration" */
  27. /* options:options */
  28. /* context:nil]; */
  29. return self;
  30. }
  31. - (IndexedPlayerItem *)playerItem {
  32. return _playerItem;
  33. }
  34. - (NSArray *)getShuffleOrder {
  35. return @[@(0)];
  36. }
  37. - (void)play:(AVQueuePlayer *)player {
  38. }
  39. - (void)pause:(AVQueuePlayer *)player {
  40. }
  41. - (void)stop:(AVQueuePlayer *)player {
  42. }
  43. - (void)seek:(CMTime)position completionHandler:(void (^)(BOOL))completionHandler {
  44. if (!completionHandler || (_playerItem.status == AVPlayerItemStatusReadyToPlay)) {
  45. CMTimeRange seekableRange = [_playerItem.seekableTimeRanges.lastObject CMTimeRangeValue];
  46. CMTime relativePosition = CMTimeAdd(position, seekableRange.start);
  47. [_playerItem seekToTime:relativePosition toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero completionHandler:completionHandler];
  48. }
  49. }
  50. - (CMTime)duration {
  51. NSValue *seekableRange = _playerItem.seekableTimeRanges.lastObject;
  52. if (seekableRange) {
  53. CMTimeRange seekableDuration = [seekableRange CMTimeRangeValue];;
  54. return seekableDuration.duration;
  55. }
  56. else {
  57. return _playerItem.duration;
  58. }
  59. return kCMTimeInvalid;
  60. }
  61. - (void)setDuration:(CMTime)duration {
  62. }
  63. - (CMTime)position {
  64. NSValue *seekableRange = _playerItem.seekableTimeRanges.lastObject;
  65. if (seekableRange) {
  66. CMTimeRange range = [seekableRange CMTimeRangeValue];
  67. return CMTimeSubtract(_playerItem.currentTime, range.start);
  68. } else {
  69. return _playerItem.currentTime;
  70. }
  71. }
  72. - (CMTime)bufferedPosition {
  73. NSValue *last = _playerItem.loadedTimeRanges.lastObject;
  74. if (last) {
  75. CMTimeRange timeRange = [last CMTimeRangeValue];
  76. return CMTimeAdd(timeRange.start, timeRange.duration);
  77. } else {
  78. return _playerItem.currentTime;
  79. }
  80. return kCMTimeInvalid;
  81. }
  82. @end