JXVideoPlayerVC.m 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756
  1. #import "JXVideoPlayerVC.h"
  2. //#import "StreamPlayerViewController.h"
  3. #import "MyPlayerLayerView.h"
  4. #import "AppDelegate.h"
  5. #import <AVFoundation/AVFoundation.h>
  6. #import "JXImageView.h"
  7. #import "JXServer.h"
  8. #import "JXLabel.h"
  9. static void *StreamPlayerViewControllerTimedMetadataObserverContext = &StreamPlayerViewControllerTimedMetadataObserverContext;
  10. static void *StreamPlayerViewControllerRateObservationContext = &StreamPlayerViewControllerRateObservationContext;
  11. static void *StreamPlayerViewControllerCurrentItemObservationContext = &StreamPlayerViewControllerCurrentItemObservationContext;
  12. static void *StreamPlayerViewControllerPlayerItemStatusObserverContext = &StreamPlayerViewControllerPlayerItemStatusObserverContext;
  13. @interface JXVideoPlayerVC ()
  14. @end
  15. @implementation JXVideoPlayerVC
  16. @synthesize movieTimeControl;
  17. @synthesize playerLayerView;
  18. @synthesize playStatus;
  19. @synthesize didClick;
  20. @synthesize pauseButton,isVideo,delegate,timeLen,isPause,isUserPause,timeCur,timeEnd,isOpened,parent;
  21. @synthesize isFullScreen;
  22. @synthesize didPlayNext;
  23. @synthesize filepath;
  24. @synthesize movieURL;
  25. - (CMTime)playerItemDuration
  26. {
  27. AVPlayerItem *playerItem = [_player currentItem];
  28. if (playerItem.status == AVPlayerItemStatusReadyToPlay)
  29. {
  30. CMTime itemDuration = kCMTimeInvalid;
  31. if ([AVPlayerItem instancesRespondToSelector:
  32. @selector (duration)])
  33. {
  34. itemDuration = [playerItem duration];
  35. }
  36. else
  37. {
  38. itemDuration = [[playerItem asset] duration];
  39. }
  40. return(itemDuration);
  41. }
  42. else if (playerItem.status == AVPlayerItemStatusUnknown)
  43. {
  44. NSLog(@"playerItem.status == AVPlayerItemStatusUnknown");
  45. }
  46. else if (playerItem.status == AVPlayerItemStatusFailed)
  47. {
  48. NSLog(@"playerItem.status == AVPlayerItemStatusFailed");
  49. }
  50. return(kCMTimeInvalid);
  51. }
  52. - (void)prepareToPlayItemWithURL:(NSURL *)newMovieURL
  53. {
  54. [[NSURLCache sharedURLCache] removeAllCachedResponses];
  55. /* Check first if this is a new url. */
  56. if (!movieURL || ![movieURL isEqual:newMovieURL])
  57. {
  58. self.movieURL = newMovieURL;
  59. _asset = [[AVURLAsset alloc] initWithURL:newMovieURL options:nil];
  60. _isNeed90 = [newMovieURL.absoluteString rangeOfString:@"-isPortrait"].location != NSNotFound;
  61. [self set90];
  62. NSArray *tracksKeys = [NSArray arrayWithObjects:kTracksKey, kDurationKey, kPlayableKey, nil];
  63. [_asset loadValuesAsynchronouslyForKeys:tracksKeys completionHandler:
  64. ^{
  65. NSError *error = nil;
  66. AVKeyValueStatus status = [_asset statusOfValueForKey:[tracksKeys objectAtIndex:0] error:&error];
  67. if (status == AVKeyValueStatusLoaded)
  68. {
  69. mPlayerItem = [AVPlayerItem playerItemWithAsset:_asset];
  70. [mPlayerItem addObserver:self forKeyPath:kStatusKey
  71. options:0
  72. context:StreamPlayerViewControllerPlayerItemStatusObserverContext];
  73. [g_notify addObserver:self
  74. selector:@selector(playerItemDidPlayToEnd:)
  75. name:AVPlayerItemDidPlayToEndTimeNotification
  76. object:mPlayerItem];
  77. if(!isVideo)
  78. playerLayerView.playerLayer.hidden = YES;
  79. seekToZeroBeforePlay = NO;
  80. isSeeking = NO;
  81. if (!_player)
  82. {
  83. // _player = [[AVPlayer alloc] initWithPlayerItem:mPlayerItem];
  84. _player = [AVPlayer playerWithPlayerItem:mPlayerItem];
  85. [_player addObserver:self forKeyPath:kRateKey
  86. options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
  87. context:StreamPlayerViewControllerRateObservationContext];
  88. [_player addObserver:self
  89. forKeyPath:kCurrentItemKey
  90. options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
  91. context:StreamPlayerViewControllerCurrentItemObservationContext];
  92. }
  93. if (_player.currentItem != mPlayerItem)
  94. {
  95. [_player replaceCurrentItemWithPlayerItem:mPlayerItem];
  96. }
  97. }
  98. else if (status == AVKeyValueStatusFailed)
  99. {
  100. NSLog(@"The asset's tracks were not loaded due to an error: \n%@", [error localizedDescription]);
  101. }
  102. timeLen = _asset.duration.value / _asset.duration.timescale;
  103. // [_asset release];
  104. }];
  105. }
  106. }
  107. - (void)syncScrubber
  108. {
  109. CMTime playerDuration = [self playerItemDuration];
  110. if (CMTIME_IS_INVALID(playerDuration))
  111. {
  112. movieTimeControl.minimumValue = 0.0;
  113. return;
  114. }
  115. double duration = CMTimeGetSeconds(playerDuration);
  116. if (isfinite(duration))
  117. {
  118. float minValue = [movieTimeControl minimumValue];
  119. float maxValue = [movieTimeControl maximumValue];
  120. double time = CMTimeGetSeconds([_player currentTime]);
  121. [movieTimeControl setValue:(maxValue - minValue) * time / duration + minValue];
  122. }
  123. }
  124. -(void)initScrubberTimer
  125. {
  126. if(movieTimeControl==nil)
  127. return;
  128. double interval = .1f;
  129. CMTime playerDuration = [self playerItemDuration];
  130. if (CMTIME_IS_INVALID(playerDuration))
  131. {
  132. return;
  133. }
  134. double duration = CMTimeGetSeconds(playerDuration);
  135. if (isfinite(duration))
  136. {
  137. CGFloat width = CGRectGetWidth([movieTimeControl bounds]);
  138. interval = 0.5f * duration / width;
  139. }
  140. /* Update the scrubber during normal playback. */
  141. __weak JXVideoPlayerVC *weakSelf = self;
  142. timeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(interval, NSEC_PER_SEC)
  143. queue:NULL
  144. usingBlock:
  145. ^(CMTime time)
  146. {
  147. [weakSelf syncScrubber];
  148. }] ;
  149. }
  150. -(void)removePlayerTimeObserver
  151. {
  152. if (timeObserver)
  153. {
  154. [_player removeTimeObserver:timeObserver];
  155. // [timeObserver release];
  156. timeObserver = nil;
  157. }
  158. }
  159. /* The user is dragging the movie controller thumb to scrub through the movie. */
  160. - (IBAction)beginScrubbing:(id)sender
  161. {
  162. restoreAfterScrubbingRate = [_player rate];
  163. [_player setRate:0.f];
  164. /* Remove previous timer. */
  165. [self removePlayerTimeObserver];
  166. }
  167. /* Set the player current time to match the scrubber position. */
  168. - (IBAction)scrub:(id)sender
  169. {
  170. if ([sender isKindOfClass:[UISlider class]])
  171. {
  172. [self stopTimer];
  173. UISlider* slider = sender;
  174. CMTime playerDuration = [self playerItemDuration];
  175. if (CMTIME_IS_INVALID(playerDuration)) {
  176. return;
  177. }
  178. double duration = CMTimeGetSeconds(playerDuration);
  179. if (isfinite(duration))
  180. {
  181. float minValue = [slider minimumValue];
  182. float maxValue = [slider maximumValue];
  183. float value = [slider value];
  184. double time = duration * (value - minValue) / (maxValue - minValue);
  185. [_player seekToTime:CMTimeMakeWithSeconds(time, NSEC_PER_SEC)];
  186. // for(int i=-10;i<3;i++)
  187. // [delegate playLyric:time+i];
  188. [self play:pauseButton];
  189. }
  190. }
  191. }
  192. /* The user has released the movie thumb control to stop scrubbing through the movie. */
  193. - (IBAction)endScrubbing:(id)sender
  194. {
  195. if (!timeObserver)
  196. {
  197. CMTime playerDuration = [self playerItemDuration];
  198. if (CMTIME_IS_INVALID(playerDuration))
  199. {
  200. return;
  201. }
  202. double duration = CMTimeGetSeconds(playerDuration);
  203. if (isfinite(duration))
  204. {
  205. CGFloat width = CGRectGetWidth([movieTimeControl bounds]);
  206. double tolerance = 0.5f * duration / width;
  207. __weak JXVideoPlayerVC *weakSelf = self;
  208. timeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(tolerance, NSEC_PER_SEC) queue:dispatch_get_main_queue() usingBlock:
  209. ^(CMTime time)
  210. {
  211. [weakSelf syncScrubber];
  212. }];
  213. }
  214. }
  215. if (restoreAfterScrubbingRate)
  216. {
  217. [_player setRate:restoreAfterScrubbingRate];
  218. restoreAfterScrubbingRate = 0.f;
  219. }
  220. }
  221. - (BOOL)isScrubbing
  222. {
  223. return restoreAfterScrubbingRate != 0.f;
  224. }
  225. /* Prevent the slider from seeking during Ad playback. */
  226. - (void)sliderSyncToPlayerSeekableTimeRanges
  227. {
  228. NSArray *seekableTimeRanges = [[_player currentItem] seekableTimeRanges];
  229. if ([seekableTimeRanges count] > 0)
  230. {
  231. NSValue *range = [seekableTimeRanges objectAtIndex:0];
  232. CMTimeRange timeRange = [range CMTimeRangeValue];
  233. float startSeconds = CMTimeGetSeconds(timeRange.start);
  234. float durationSeconds = CMTimeGetSeconds(timeRange.duration);
  235. /* Set the minimum and maximum values of the time slider to match the seekable time range. */
  236. movieTimeControl.minimumValue = startSeconds;
  237. movieTimeControl.maximumValue = startSeconds + durationSeconds;
  238. }
  239. }
  240. - (BOOL)isPlaying
  241. {
  242. // return _player.timeControlStatus != AVPlayerTimeControlStatusPaused;
  243. return restoreAfterScrubbingRate != 0.f || [_player rate] != 0.f;
  244. }
  245. /* If the media is playing, show the stop button; otherwise, show the play button. */
  246. - (void)syncPlayPauseButtons
  247. {
  248. if ([self isPlaying])
  249. {
  250. NSLog(@"JXVideoPlayerVC.播放");
  251. }
  252. else
  253. {
  254. NSLog(@"JXVideoPlayerVC.暂停");
  255. if((_isIniting || !isUserPause) && !seekToZeroBeforePlay)
  256. playStatus.text = Localized(@"StreamPlayerViewController_Loading");
  257. else
  258. playStatus.text = Localized(@"StreamPlayerViewController_Paused");
  259. }
  260. self.pauseButton.selected = [self isPlaying];
  261. }
  262. /* Called when the player item has played to its end time. */
  263. - (void) playerItemDidPlayToEnd:(NSNotification*) aNotification
  264. {
  265. [self.view removeGestureRecognizer:_singleTap];
  266. seekToZeroBeforePlay = YES;
  267. if (delegate && [delegate respondsToSelector:didPlayNext])
  268. // [delegate performSelector:didPlayNext];
  269. [delegate performSelectorOnMainThread:didPlayNext withObject:nil waitUntilDone:NO];
  270. }
  271. /* Update current ad list, set slider to match current player item seekable time ranges */
  272. - (void)updateAdList:(NSArray *)newAdList
  273. {
  274. if (!adList || ![adList isEqualToArray:newAdList])
  275. {
  276. newAdList = [newAdList copy];
  277. // [adList release];
  278. adList = newAdList;
  279. [self sliderSyncToPlayerSeekableTimeRanges];
  280. }
  281. }
  282. #pragma mark Timed metadata
  283. - (void)handleTimedMetadata:(AVMetadataItem*)timedMetadata
  284. {
  285. /* We expect the content to contain plists encoded as timed metadata. AVPlayer turns these into NSDictionaries. */
  286. if ([(NSString *)[timedMetadata key] isEqualToString:AVMetadataID3MetadataKeyGeneralEncapsulatedObject])
  287. {
  288. if ([[timedMetadata value] isKindOfClass:[NSDictionary class]])
  289. {
  290. NSDictionary *propertyList = (NSDictionary *)[timedMetadata value];
  291. /* Metadata payload could be the list of ads. */
  292. NSArray *newAdList = [propertyList objectForKey:@"ad-list"];
  293. if (newAdList != nil)
  294. {
  295. [self updateAdList:newAdList];
  296. NSLog(@"ad-list is %@", newAdList);
  297. }
  298. /* Or it might be an ad record. */
  299. NSString *adURL = [propertyList objectForKey:@"url"];
  300. if (adURL != nil)
  301. {
  302. if ([adURL isEqualToString:@""])
  303. {
  304. /* Ad is not playing, so clear text. */
  305. //self.playStatus.text = @"";
  306. movieTimeControl.enabled = YES; /* Enable seeking for main content. */
  307. NSLog(@"enabling seek at %g", CMTimeGetSeconds([_player currentTime]));
  308. }
  309. else
  310. {
  311. /* Display text indicating that an Ad is now playing. */
  312. //self.playStatus.text = @"< Ad now playing, seeking is disabled on the movie controller... >";
  313. movieTimeControl.enabled = NO; /* Disable seeking for ad content. */
  314. NSLog(@"disabling seek at %g", CMTimeGetSeconds([_player currentTime]));
  315. }
  316. }
  317. }
  318. }
  319. }
  320. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
  321. {
  322. if(_player == nil)
  323. return;
  324. /* Observe the AVPlayer "rate" property to synchronize the movie slider control 'play'
  325. and 'pause' buttons. */
  326. if (context == StreamPlayerViewControllerRateObservationContext)
  327. {
  328. [self syncPlayPauseButtons];
  329. }
  330. else if (context == StreamPlayerViewControllerCurrentItemObservationContext)
  331. {
  332. [playerLayerView.playerLayer setPlayer:_player];
  333. }
  334. /* Observe the AVPlayer "currentItem.timedMetadata" property to parse the media stream
  335. timed metadata. */
  336. else if (context == StreamPlayerViewControllerTimedMetadataObserverContext)
  337. {
  338. NSArray* array = [[_player currentItem] timedMetadata];
  339. for (AVMetadataItem *metadataItem in array)
  340. {
  341. [self handleTimedMetadata:metadataItem];
  342. }
  343. }
  344. /* Observe the player item 'status' property to determing when it is ready to play. */
  345. else if (context == StreamPlayerViewControllerPlayerItemStatusObserverContext)
  346. {
  347. [self syncPlayPauseButtons];
  348. AVPlayerItem *thePlayerItem = (AVPlayerItem *)object;
  349. if (thePlayerItem.status == AVPlayerItemStatusReadyToPlay)
  350. {
  351. if(isVideo){
  352. playerLayerView.playerLayer.hidden = NO;
  353. playerLayerView.playerLayer.backgroundColor = [[UIColor blackColor] CGColor];
  354. [playerLayerView.playerLayer setPlayer:_player];
  355. //[_player seekToTime:CMTimeMakeWithSeconds(0.5, NSEC_PER_SEC)];
  356. }
  357. movieTimeControl.enabled = YES;
  358. [self initScrubberTimer];
  359. _isIniting = NO;
  360. self.isOpened = 1;
  361. if (delegate && [delegate respondsToSelector:self.didOpen])
  362. // [delegate performSelector:self.didOpen];
  363. [delegate performSelectorOnMainThread:self.didOpen withObject:nil waitUntilDone:NO];
  364. [self play:pauseButton];
  365. }
  366. else if (thePlayerItem.status == AVPlayerItemStatusFailed)
  367. {
  368. self.isOpened = 0;
  369. if([movieURL isFileURL]){
  370. playStatus.text = Localized(@"StreamPlayerViewController_ReadFailure");
  371. [g_App.jxServer showMsg:Localized(@"StreamPlayerViewController_OpenSongFails")];
  372. }
  373. else{
  374. playStatus.text = Localized(@"StreamPlayerViewController_ReadFailure");
  375. [g_App.jxServer showMsg:Localized(@"StreamPlayerViewController_OpenServerFails")];
  376. }
  377. }
  378. else if (thePlayerItem.status == AVPlayerItemStatusUnknown)
  379. {
  380. self.isOpened = 0;
  381. if([movieURL isFileURL]){
  382. playStatus.text = Localized(@"StreamPlayerViewController_ReadFailure");
  383. [g_App.jxServer showMsg:Localized(@"StreamPlayerViewController_OpenSongFails")];
  384. }
  385. else{
  386. playStatus.text = Localized(@"StreamPlayerViewController_ReadFailure");
  387. [g_App.jxServer showMsg:Localized(@"StreamPlayerViewController_OpenServerFails")];
  388. }
  389. }
  390. }
  391. else
  392. {
  393. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  394. }
  395. }
  396. #pragma mark Button Action Methods
  397. -(id)init{
  398. self = [super init];
  399. if(self) {
  400. kTracksKey = @"tracks";
  401. kPlayableKey = @"playable";
  402. kStatusKey = @"status";
  403. kRateKey = @"rate";
  404. kCurrentItemKey = @"currentItem";
  405. kDurationKey = @"duration";
  406. kTimedMetadataKey = @"currentItem.timedMetadata";
  407. // [kTracksKey retain];
  408. // [kPlayableKey retain];
  409. // [kStatusKey retain];
  410. // [kRateKey retain];
  411. // [kCurrentItemKey retain];
  412. // [kDurationKey retain];
  413. // [kTimedMetadataKey retain];
  414. self.isFullScreen = NO;
  415. isOpened = 0;
  416. _isIniting = YES;
  417. _player = nil;
  418. isUserPause = NO;
  419. self.view.backgroundColor = [UIColor clearColor];
  420. self.view.userInteractionEnabled = YES;
  421. playerLayerView = [[MyPlayerLayerView alloc] init];
  422. playerLayerView.userInteractionEnabled = YES;
  423. playerLayerView.backgroundColor = [UIColor clearColor];
  424. [playerLayerView setVideoFillMode:AVLayerVideoGravityResizeAspect];
  425. // [playerLayerView setVideoFillMode:AVLayerVideoGravityResize];
  426. [self.view addSubview:playerLayerView];
  427. _singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onClick:)];
  428. [self.view addGestureRecognizer:_singleTap];
  429. _wait = [[JXWaitView alloc] initWithParent:playerLayerView];
  430. timerShowPeak = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(showVolPeak:) userInfo:nil repeats: YES];
  431. _curProFloat = 0;
  432. _n = 0; // 当前进度条进度, _n 减少误差
  433. //进度条
  434. // movieTimeControl = [[UISlider alloc] initWithFrame:CGRectMake(100, JX_SCREEN_HEIGHT-50, JX_SCREEN_WIDTH-160, 10)];
  435. // movieTimeControl.maximumTrackTintColor = [UIColor lightGrayColor];
  436. // movieTimeControl.minimumTrackTintColor = [UIColor whiteColor];
  437. // movieTimeControl.continuous = YES;
  438. // movieTimeControl.minimumValue = 0;
  439. // movieTimeControl.maximumValue = timeLen;
  440. //
  441. // [movieTimeControl setThumbImage:[self scaleToSize:[UIImage imageNamed:@"circular"] size:CGSizeMake(14, 14)] forState:UIControlStateNormal];
  442. // [self.view addSubview:movieTimeControl];
  443. [movieTimeControl addTarget:self action:@selector(beginScrubbing:) forControlEvents:UIControlEventTouchDown];
  444. [movieTimeControl addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpInside];
  445. [movieTimeControl addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpOutside];
  446. [movieTimeControl addTarget:self action:@selector(scrub:) forControlEvents:UIControlEventValueChanged];
  447. [movieTimeControl addTarget:self action:@selector(scrub:) forControlEvents:UIControlEventTouchDragInside];
  448. }
  449. return self;
  450. }
  451. - (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size {
  452. UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
  453. [img drawInRect:CGRectMake(0,0, size.width, size.height)];
  454. UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
  455. UIGraphicsEndImageContext();
  456. return scaledImage;
  457. }
  458. - (void)dealloc
  459. {
  460. NSLog(@"JXVideoPlayerVC.dealloc");
  461. // NSLog(@"streamPlayer=%d,player=%d,mPlayerItem=%d",self.retainCount,_player.retainCount,mPlayerItem.retainCount);
  462. // [timeObserver release];
  463. // [movieURL release];
  464. // [adList release];
  465. // [playStatus release];
  466. // [pauseButton release];
  467. // [_wait release];
  468. // [_singleTap release];
  469. timeObserver = nil;
  470. movieURL = nil;
  471. adList = nil;
  472. playStatus = nil;
  473. pauseButton = nil;
  474. _wait = nil;
  475. _singleTap = nil;
  476. [self stopTimer];
  477. // if(timerShowPeak)
  478. // [timerShowPeak invalidate];
  479. // [timeEnd release];
  480. // [timeCur release];
  481. timeEnd = nil;
  482. timeCur = nil;
  483. [playerLayerView removeFromSuperview];
  484. // [playerLayerView release];
  485. playerLayerView = nil;
  486. [movieTimeControl removeTarget:self action:@selector(beginScrubbing:) forControlEvents:UIControlEventTouchDown];
  487. [movieTimeControl removeTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpInside];
  488. [movieTimeControl removeTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpOutside];
  489. [movieTimeControl removeTarget:self action:@selector(scrub:) forControlEvents:UIControlEventValueChanged];
  490. [movieTimeControl removeTarget:self action:@selector(scrub:) forControlEvents:UIControlEventTouchDragInside];
  491. // [movieTimeControl release];
  492. movieTimeControl = nil;
  493. // [super dealloc];
  494. }
  495. -(void)setSliderHidden:(BOOL)b{
  496. playStatus.hidden = b;
  497. movieTimeControl.hidden = b;
  498. if(!isVideo)
  499. playerLayerView.hidden = YES;
  500. }
  501. -(void)stop{
  502. isOpened = 0;
  503. [self pause:nil];
  504. [self stopTimer];
  505. [mPlayerItem removeObserver:self forKeyPath:kStatusKey];
  506. [self removePlayerTimeObserver];
  507. [g_notify removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:mPlayerItem];
  508. [_player removeObserver:self forKeyPath:kCurrentItemKey];
  509. [_player removeObserver:self forKeyPath:kRateKey];
  510. // [_player removeObserver:self forKeyPath:kTimedMetadataKey];
  511. // NSLog(@"streamPlayer=%d,player=%d,mPlayerItem=%d",self.retainCount,_player.retainCount,mPlayerItem.retainCount);
  512. [playerLayerView.playerLayer setPlayer:nil];
  513. [playerLayerView removeFromSuperview];
  514. playerLayerView.hidden = YES;
  515. // [_player release];
  516. _player = nil;
  517. mPlayerItem = nil;
  518. }
  519. -(void)open:(NSString*)value{
  520. if([value length]<=0)
  521. return;
  522. self.isOpened = 0;
  523. self.filepath = [value copy];
  524. NSURL* url;
  525. if([[NSFileManager defaultManager] fileExistsAtPath:value]){
  526. url=[[NSURL alloc]initFileURLWithPath:value];
  527. // NSLog(@"播放本地文件");
  528. }
  529. else
  530. url=[[NSURL alloc] initWithString:value];
  531. [self prepareToPlayItemWithURL:url];
  532. // [url release];
  533. }
  534. - (void)play:(id)sender
  535. {
  536. if(_player == nil)
  537. return;
  538. if (YES == seekToZeroBeforePlay)
  539. {
  540. seekToZeroBeforePlay = NO;
  541. [_player seekToTime:kCMTimeZero];
  542. }
  543. if (!timerShowPeak) {
  544. timerShowPeak = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(showVolPeak:) userInfo:nil repeats: YES];
  545. }
  546. [self.view addGestureRecognizer:_singleTap];
  547. [_player play];
  548. isPause = NO;
  549. }
  550. - (void)pause:(id)sender
  551. {
  552. [self stopTimer];
  553. // [self.view removeGestureRecognizer:_singleTap];
  554. [_player pause];
  555. isPause = YES;
  556. }
  557. -(void) showVolPeak:(NSTimer *) timer {
  558. if(![self isPlaying])
  559. return;
  560. NSTimeInterval n1 = _player.currentTime.value /_player.currentTime.timescale;
  561. playStatus.text = @"";
  562. timeCur.text = [NSString stringWithFormat:@"%@", [self formatTime:n1]];
  563. timeEnd.text = [NSString stringWithFormat:@"%@", [self formatTime:timeLen]];
  564. // 进度条
  565. _curProFloat += 0.1; // 防止视频进度条1s前出问题
  566. if (_curProFloat <= 0.1) {
  567. _curProFloat = 1;
  568. }
  569. if (n1 != _n || _curProFloat == 1) {
  570. movieTimeControl.value = _curProFloat <= 1 ? _curProFloat : n1;
  571. movieTimeControl.maximumValue = timeLen;
  572. }
  573. _n = n1; // 记录上个时间防止进度条多次赋值
  574. }
  575. - (NSString *) formatTime: (NSTimeInterval) num
  576. {
  577. int n = num;
  578. int secs = n % 60;
  579. int min = n / 60;
  580. if (num < 60) return [NSString stringWithFormat:@"0:%02d", n];
  581. return [NSString stringWithFormat:@"%d:%02d", min, secs];
  582. }
  583. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  584. {
  585. return YES;
  586. }
  587. -(void)initVolume:(float)volume playItem:(AVPlayerItem*)playItem{
  588. NSArray *audioTracks = [_asset tracksWithMediaType:AVMediaTypeAudio];
  589. NSMutableArray *allAudioParams = [NSMutableArray array];
  590. for (AVAssetTrack *track in audioTracks){
  591. AVMutableAudioMixInputParameters *_audioInputParams;
  592. _audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters];
  593. [_audioInputParams setVolume:volume atTime:kCMTimeZero];
  594. [_audioInputParams setTrackID:[track trackID]];
  595. [allAudioParams addObject:_audioInputParams];
  596. break;
  597. }
  598. AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
  599. [audioMix setInputParameters:allAudioParams];
  600. [playItem setAudioMix:audioMix];
  601. }
  602. -(void)set90{
  603. if(_isNeed90)
  604. [playerLayerView set90];
  605. }
  606. -(void)setPlayStatus:(JXLabel *)sender{
  607. if(playStatus!=sender){
  608. // [playStatus release];
  609. playStatus = sender;
  610. }
  611. sender.text = Localized(@"StreamPlayerViewController_Loading");
  612. }
  613. -(void)setMovieTimeControl:(UISlider *)sender{
  614. if(movieTimeControl!=sender){
  615. // [movieTimeControl release];
  616. movieTimeControl = sender;
  617. // movieTimeControl = sender;
  618. [movieTimeControl addTarget:self action:@selector(beginScrubbing:) forControlEvents:UIControlEventTouchDown];
  619. [movieTimeControl addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpInside];
  620. [movieTimeControl addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpOutside];
  621. [movieTimeControl addTarget:self action:@selector(scrub:) forControlEvents:UIControlEventValueChanged];
  622. [movieTimeControl addTarget:self action:@selector(scrub:) forControlEvents:UIControlEventTouchDragInside];
  623. }
  624. }
  625. - (void)onClick:(id)sender {
  626. if (delegate && [delegate respondsToSelector:didClick])
  627. // [delegate performSelector:didClick withObject:self.view];
  628. [delegate performSelectorOnMainThread:didClick withObject:self.view waitUntilDone:NO];
  629. }
  630. -(void)setPauseBtn:(UIButton*)value{
  631. if([pauseButton isEqual:value])
  632. return;
  633. // [pauseButton release];
  634. pauseButton = value;
  635. }
  636. -(void)setFrame:(CGRect)frame{
  637. self.view.frame = frame;
  638. self.playerLayerView.frame = self.view.bounds;
  639. [_wait adjust];
  640. }
  641. -(void)setIsOpened:(BOOL)value{
  642. isOpened = value;
  643. if(isOpened){
  644. pauseButton.hidden = NO;
  645. [_wait stop];
  646. }else{
  647. pauseButton.hidden = YES;
  648. [_wait start];
  649. }
  650. }
  651. - (void)stopTimer {
  652. if(timerShowPeak){
  653. [timerShowPeak invalidate];
  654. timerShowPeak = nil;
  655. }
  656. }
  657. @end