Advertisement
Guest User

Untitled

a guest
Oct 31st, 2014
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.82 KB | None | 0 0
  1. - (NSTimeInterval) playableDuration
  2. {
  3. //  use loadedTimeRanges to compute playableDuration.
  4. AVPlayerItem * item = player.currentItem;
  5.  
  6. if (item.status == AVPlayerItemStatusReadyToPlay) {
  7. NSArray * timeRangeArray = item.loadedTimeRanges;
  8.  
  9. CMTimeRange aTimeRange = [[timeRangeArray objectAtIndex:0] CMTimeRangeValue];
  10.  
  11. double startTime = CMTimeGetSeconds(aTimeRange.start);
  12. double loadedDuration = CMTimeGetSeconds(aTimeRange.duration);
  13.  
  14. NSLog(@"get time range, its start is %f seconds, its duration is %f seconds.", startTime/60, loadedDuration/60);
  15. return (NSTimeInterval)(startTime + loadedDuration);
  16. }
  17. else
  18. {
  19. return(CMTimeGetSeconds(kCMTimeInvalid));
  20. }
  21. }
  22. -(NSTimeInterval)currentItemPlayableDuration{
  23.  
  24. //  use loadedTimeRanges to compute playableDuration.
  25. AVPlayerItem * item = player.currentItem;
  26.  
  27. if (item.status == AVPlayerItemStatusReadyToPlay) {
  28. NSArray * timeRangeArray = item.loadedTimeRanges;
  29.  
  30. CMTime currentTime = player.currentTime;
  31.  
  32. __block CMTimeRange aTimeRange;
  33.  
  34. [timeRangeArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  35.  
  36. aTimeRange = [[timeRangeArray objectAtIndex:0] CMTimeRangeValue];
  37.  
  38. if(CMTimeRangeContainsTime(aTimeRange, currentTime))
  39. *stop = YES;
  40.  
  41. }];
  42.  
  43. CMTime maxTime = CMTimeRangeGetEnd(aTimeRange);
  44.  
  45. return CMTimeGetSeconds(maxTime);
  46. }
  47. else
  48. {
  49. return(CMTimeGetSeconds(kCMTimeInvalid));
  50. }
  51. }
  52. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  53. {
  54. if(player!= nil)
  55. {
  56. [player.currentItem removeObserver:self forKeyPath:@"status"];
  57. }
  58. [player pause];
  59. player = nil;
  60. btnPlay.hidden=true;
  61. btnPause.hidden=false;
  62. selectedSongIndex = indexPath.row;
  63. url = [[NSURL alloc] initWithString:[arrURL objectAtIndex:indexPath.row]];
  64. [self setupAVPlayerForURL:url];
  65. //[player play];
  66. AVPlayerItem *item = player.currentItem;
  67. [item addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionInitial| NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld| NSKeyValueObservingOptionPrior context:nil];
  68. [player play];
  69. //[tableView deselectRowAtIndexPath:indexPath animated:YES];
  70. } #pragma mark - Player Methods
  71. - (IBAction)btnBack_Click:(id)sender {
  72. int index = selectedSongIndex;
  73. if (index==0) {
  74. if(player!= nil)
  75. {
  76. [player.currentItem removeObserver:self forKeyPath:@"status"];
  77. }
  78. [player pause];
  79. player = nil;
  80. selectedSongIndex = [arrURL count]-1;
  81. url = [[NSURL alloc] initWithString:[arrURL objectAtIndex:selectedSongIndex]];
  82. [self setupAVPlayerForURL:url];
  83. AVPlayerItem *item = player.currentItem;
  84. [item addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionInitial| NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld| NSKeyValueObservingOptionPrior context:nil];
  85. [player play];
  86. }
  87. else if(index >= 0 && index < [arrURL count])
  88. {
  89. if(player!= nil)
  90. {
  91. [player.currentItem removeObserver:self forKeyPath:@"status"];
  92. }
  93. [player pause];
  94. player = nil;
  95. index = selectedSongIndex - 1;
  96. selectedSongIndex = index;
  97. url = [[NSURL alloc] initWithString:[arrURL objectAtIndex:index]];
  98. [self setupAVPlayerForURL:url];
  99. AVPlayerItem *item = player.currentItem;
  100. [item addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionInitial| NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld| NSKeyValueObservingOptionPrior context:nil];
  101. [player play];
  102. }
  103. }
  104. - (IBAction)btnPlay_Click:(id)sender {
  105.  
  106. btnPlay.hidden=true;
  107. btnPause.hidden=false;
  108. //url = [[NSURL alloc] initWithString:[arrURL objectAtIndex:indexPath.row]];
  109. if([strPlay isEqualToString:@"ViewWillAppear"] || [strPlay isEqualToString:@"Stop"])
  110. {
  111. [currentTimeSlider setValue:0.0];
  112. lblStart.text = @"0:00";
  113. [self setupAVPlayerForURL:url];
  114. }
  115. AVPlayerItem *item = player.currentItem;
  116. [item addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionInitial| NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld| NSKeyValueObservingOptionPrior context:nil];
  117. [player play];
  118. }
  119.  
  120. - (IBAction)btnPause_Click:(id)sender {
  121. btnPlay.hidden=false;
  122. btnPause.hidden=true;
  123. strPlay = @"Pause";
  124. [player pause];
  125. }
  126. - (IBAction)btnStop_Click:(id)sender {
  127. btnPlay.hidden=false;
  128. btnPause.hidden=true;
  129. strPlay = @"Stop";
  130. //[player removeObserver:self forKeyPath:@"status"];
  131. [player pause];
  132. player = nil;
  133.  
  134. }
  135. - (IBAction)btnNext_Click:(id)sender {
  136. int index = selectedSongIndex;
  137. if(selectedSongIndex == [arrURL count]-1)
  138. {
  139. if(player!= nil)
  140. {
  141. [player.currentItem removeObserver:self forKeyPath:@"status"];
  142. }
  143. [player pause];
  144. player = nil;
  145.  
  146. AVPlayerItem *item = player.currentItem;
  147. [item removeObserver:self forKeyPath:@"timedMetadata"];
  148.  
  149. selectedSongIndex=0;
  150. url = [[NSURL alloc] initWithString:[arrURL objectAtIndex:0]];
  151. [self setupAVPlayerForURL:url];
  152. AVPlayerItem *item1 = player.currentItem;
  153. [item1 addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionInitial| NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld| NSKeyValueObservingOptionPrior context:nil];
  154. [player play];
  155. }
  156. else if(index < [arrURL count])
  157. {
  158. if(player!= nil)
  159. {
  160. [player.currentItem removeObserver:self forKeyPath:@"status"];
  161. }
  162. [player pause];
  163. player = nil;
  164.  
  165. AVPlayerItem *item = player.currentItem;
  166. [item removeObserver:self forKeyPath:@"timedMetadata"];
  167. index = selectedSongIndex+1;
  168. selectedSongIndex = index;
  169. url = [[NSURL alloc] initWithString:[arrURL objectAtIndex:index]];
  170. [self setupAVPlayerForURL:url];
  171. AVPlayerItem *item1 = player.currentItem;
  172. [item1 addObserver:self forKeyPath:@"timedMetadata" options:NSKeyValueObservingOptionInitial| NSKeyValueObservingOptionNew| NSKeyValueObservingOptionOld| NSKeyValueObservingOptionPrior context:nil];
  173. [player play];
  174. }
  175. }
  176. -(void) setupAVPlayerForURL: (NSURL*) url1 {
  177. AVAsset *asset = [AVURLAsset URLAssetWithURL:url1 options:nil];
  178. AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];
  179. if(player!= nil)
  180. {
  181. [player.currentItem removeObserver:self forKeyPath:@"status"];
  182. }
  183. player = [AVPlayer playerWithPlayerItem:anItem];
  184. [player.currentItem addObserver:self forKeyPath:@"status" options:0 context:nil];
  185. [player play];
  186. }
  187. - (CMTime)playerItemDuration
  188. {
  189. AVPlayerItem *thePlayerItem = [player currentItem];
  190. if (thePlayerItem.status == AVPlayerItemStatusReadyToPlay)
  191. {
  192.  
  193. return([thePlayerItem duration]);
  194. }
  195.  
  196. return(kCMTimeInvalid);
  197. }
  198. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
  199. if([keyPath isEqualToString:@"timedMetadata"])
  200. {
  201. AVPlayerItem *item = (AVPlayerItem *)object;
  202. NSLog(@"Item.timedMetadata: %@",item.timedMetadata);
  203. NSLog(@"-- META DATA ---");
  204. // AVPlayerItem *pItem = (AVPlayerItem *)object;
  205. for (AVMetadataItem *metaItem in item.timedMetadata) {
  206. NSLog(@"meta data = %@",[metaItem commonKey]);
  207. NSString *key = [metaItem commonKey]; //key = publisher , key = title
  208. NSString *value = [metaItem stringValue];
  209. NSLog(@"key = %@, value = %@", key, value);
  210. if([[metaItem commonKey] isEqualToString:@"title"])
  211. {
  212. self.lblTitle.text = [metaItem stringValue];
  213. }
  214. }
  215. }
  216. if (object == player.currentItem && [keyPath isEqualToString:@"status"]) {
  217. if (player.status == AVPlayerStatusFailed) {
  218. NSLog(@"AVPlayer Failed");
  219. } else if (player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
  220. NSLog(@"AVPlayer Ready to Play");
  221.  
  222. NSTimeInterval totalSeconds = CMTimeGetSeconds(player.currentItem.asset.duration);
  223. int minutes = (int)totalSeconds / 60;
  224. int seconds = (int)totalSeconds % 60;
  225. NSString *minutes1;
  226. NSString *seconds1;
  227. if (minutes < 10) {
  228. minutes1=[NSString stringWithFormat:@"%02d",minutes];
  229. seconds1=[NSString stringWithFormat:@"%02d",seconds];
  230. }
  231. lblEnd.text = [NSString stringWithFormat:@"%@:%@",minutes1,seconds1];
  232. NSLog(@"lblEnd Duration: %@",lblEnd.text);
  233. double interval = .1f;
  234.  
  235. CMTime playerDuration = [self playerItemDuration]; // return player duration.
  236. if (CMTIME_IS_INVALID(playerDuration))
  237. {
  238. return;
  239. }
  240. double duration = CMTimeGetSeconds(playerDuration);
  241. if (isfinite(duration))
  242. {
  243. CGFloat width = CGRectGetWidth([currentTimeSlider bounds]);
  244. interval = 0.5f * duration / width;
  245. }
  246.  
  247. /* Update the scrubber during normal playback. */
  248. id timeObserver = [player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(interval, NSEC_PER_SEC)
  249. queue:NULL
  250. usingBlock:
  251. ^(CMTime time)
  252. {
  253. [self syncScrubber];
  254. NSLog(@"Available: %f",[self availableDuration]);
  255. }];
  256.  
  257. } else if (player.status == AVPlayerItemStatusUnknown) {
  258. NSLog(@"AVPlayer Unknown");
  259. }
  260. }
  261. }
  262. - (IBAction)currentTimeSliderValueChanged:(id)sender {
  263. CMTime playerDuration = [self playerItemDuration];
  264. double duration = CMTimeGetSeconds(playerDuration);
  265. float minValue = [currentTimeSlider minimumValue];
  266. float maxValue = [currentTimeSlider maximumValue];
  267. double time = CMTimeGetSeconds([player currentTime]);
  268.  
  269. int32_t timeScale = self.player.currentItem.asset.duration.timescale;
  270. [player seekToTime:CMTimeMake((maxValue - minValue) * time / duration + minValue, 1)];
  271. }
  272.  
  273. - (NSTimeInterval) availableDuration;
  274. {
  275. int result1 = 0;
  276. NSArray *loadedTimeRanges = [[self.player currentItem] loadedTimeRanges];
  277. if([loadedTimeRanges count]>0)
  278. {
  279. CMTimeRange timeRange = [[loadedTimeRanges objectAtIndex:0] CMTimeRangeValue];
  280. Float64 startSeconds = CMTimeGetSeconds(timeRange.start);
  281. Float64 durationSeconds = CMTimeGetSeconds(timeRange.duration);
  282. NSTimeInterval result = startSeconds + durationSeconds;
  283. result1 =result;
  284. }
  285. return result1;
  286. }
  287. #pragma mark -
  288. #pragma mark Music scrubber control
  289.  
  290. /* Cancels the previously registered time observer. */
  291. -(void)removePlayerTimeObserver
  292. {
  293. if (mTimeObserver)
  294. {
  295. [self.player removeTimeObserver:mTimeObserver];
  296. mTimeObserver = nil;
  297. }
  298. }
  299.  
  300. /* Requests invocation of a given block during media playback to update the movie scrubber control. */
  301. -(void)initScrubberTimer
  302. {
  303. double interval = .1f;
  304.  
  305. CMTime playerDuration = [self playerItemDuration];
  306. if (CMTIME_IS_INVALID(playerDuration))
  307. {
  308. return;
  309. }
  310. double duration = CMTimeGetSeconds(playerDuration);
  311. if (isfinite(duration))
  312. {
  313. CGFloat width = CGRectGetWidth([self.currentTimeSlider bounds]);
  314. interval = 0.5f * duration / width;
  315. }
  316.  
  317. /* Update the scrubber during normal playback. */
  318. __weak playerScreenViewController *weakSelf = self;
  319. mTimeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(interval, NSEC_PER_SEC)
  320. queue:NULL /* If you pass NULL, the main queue is used. */
  321. usingBlock:^(CMTime time)
  322. {
  323. [weakSelf syncScrubber];
  324. }];
  325. }
  326.  
  327. /* Set the scrubber based on the player current time. */
  328. - (void)syncScrubber
  329. {
  330. CMTime playerDuration = [self playerItemDuration];
  331. if (CMTIME_IS_INVALID(playerDuration))
  332. {
  333. currentTimeSlider.minimumValue = 0.0;
  334. return;
  335. }
  336.  
  337. double duration = CMTimeGetSeconds(playerDuration);
  338. if (isfinite(duration))
  339. {
  340. float minValue = [self.currentTimeSlider minimumValue];
  341. float maxValue = [self.currentTimeSlider maximumValue];
  342. double time = CMTimeGetSeconds([self.player currentTime]);
  343.  
  344. [self.currentTimeSlider setValue:(maxValue - minValue) * time / duration + minValue];
  345.  
  346. int minutes = (int)time / 60;
  347. int seconds = (int)time % 60;
  348. NSString *minutes1;
  349. NSString *seconds1;
  350. if (minutes < 10) {
  351. minutes1=[NSString stringWithFormat:@"%02d",minutes];
  352. seconds1=[NSString stringWithFormat:@"%02d",seconds];
  353. }
  354. lblStart.text = [NSString stringWithFormat:@"%@:%@",minutes1,seconds1];
  355. [currentTimeSlider setValue:(maxValue - minValue) * time / duration + minValue];
  356.  
  357. int difference = duration-time;
  358.  
  359. if (difference == 0) {
  360. [self removePlayerTimeObserver];
  361. [self btnNext_Click:nil];
  362. }
  363. }
  364. }
  365.  
  366. /* The user is dragging the movie controller thumb to scrub through the movie. */
  367. - (IBAction)beginScrubbing:(id)sender
  368. {
  369. mRestoreAfterScrubbingRate = [self.player rate];
  370. [self.player setRate:0.f];
  371.  
  372. /* Remove previous timer. */
  373. [self removePlayerTimeObserver];
  374. }
  375.  
  376. /* Set the player current time to match the scrubber position. */
  377. - (IBAction)scrub:(id)sender
  378. {
  379. if ([sender isKindOfClass:[UISlider class]] && !isSeeking)
  380. {
  381. isSeeking = YES;
  382. UISlider* slider = sender;
  383.  
  384. CMTime playerDuration = [self playerItemDuration];
  385. if (CMTIME_IS_INVALID(playerDuration)) {
  386. return;
  387. }
  388.  
  389. double duration = CMTimeGetSeconds(playerDuration);
  390. if (isfinite(duration))
  391. {
  392. float minValue = [slider minimumValue];
  393. float maxValue = [slider maximumValue];
  394. float value = [slider value];
  395.  
  396. double time = duration * (value - minValue) / (maxValue - minValue);
  397.  
  398. [self.player seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC) completionHandler:^(BOOL finished) {
  399. dispatch_async(dispatch_get_main_queue(), ^{
  400. isSeeking = NO;
  401. });
  402. }];
  403. }
  404. }
  405. }
  406.  
  407. /* The user has released the movie thumb control to stop scrubbing through the movie. */
  408. - (IBAction)endScrubbing:(id)sender
  409. {
  410. if (!mTimeObserver)
  411. {
  412. CMTime playerDuration = [self playerItemDuration];
  413. if (CMTIME_IS_INVALID(playerDuration))
  414. {
  415. return;
  416. }
  417.  
  418. double duration = CMTimeGetSeconds(playerDuration);
  419. if (isfinite(duration))
  420. {
  421. CGFloat width = CGRectGetWidth([self.currentTimeSlider bounds]);
  422. double tolerance = 0.5f * duration / width;
  423.  
  424. __weak playerScreenViewController *weakSelf = self;
  425. mTimeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(tolerance, NSEC_PER_SEC) queue:NULL usingBlock:
  426. ^(CMTime time)
  427. {
  428. [weakSelf syncScrubber];
  429. }];
  430. }
  431. }
  432.  
  433. if (mRestoreAfterScrubbingRate)
  434. {
  435. [self.player setRate:mRestoreAfterScrubbingRate];
  436. mRestoreAfterScrubbingRate = 0.f;
  437. }
  438. }
  439.  
  440. - (BOOL)isScrubbing
  441. {
  442. return mRestoreAfterScrubbingRate != 0.f;
  443. }
  444.  
  445. -(void)enableScrubber
  446. {
  447. self.currentTimeSlider.enabled = YES;
  448. }
  449.  
  450. -(void)disableScrubber
  451. {
  452. self.currentTimeSlider.enabled = NO;
  453. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement