JXVideoPlayerVC.m 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  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. dispatch_async(dispatch_get_main_queue(), ^{
  257. playStatus.text = Localized(@"StreamPlayerViewController_Loading");
  258. });
  259. else
  260. dispatch_async(dispatch_get_main_queue(), ^{
  261. playStatus.text = Localized(@"StreamPlayerViewController_Paused");
  262. });
  263. }
  264. dispatch_async(dispatch_get_main_queue(), ^{
  265. self.pauseButton.selected = [self isPlaying];
  266. });
  267. }
  268. /* Called when the player item has played to its end time. */
  269. - (void) playerItemDidPlayToEnd:(NSNotification*) aNotification
  270. {
  271. [self.view removeGestureRecognizer:_singleTap];
  272. seekToZeroBeforePlay = YES;
  273. if (delegate && [delegate respondsToSelector:didPlayNext])
  274. // [delegate performSelector:didPlayNext];
  275. [delegate performSelectorOnMainThread:didPlayNext withObject:nil waitUntilDone:NO];
  276. }
  277. /* Update current ad list, set slider to match current player item seekable time ranges */
  278. - (void)updateAdList:(NSArray *)newAdList
  279. {
  280. if (!adList || ![adList isEqualToArray:newAdList])
  281. {
  282. newAdList = [newAdList copy];
  283. // [adList release];
  284. adList = newAdList;
  285. [self sliderSyncToPlayerSeekableTimeRanges];
  286. }
  287. }
  288. #pragma mark Timed metadata
  289. - (void)handleTimedMetadata:(AVMetadataItem*)timedMetadata
  290. {
  291. /* We expect the content to contain plists encoded as timed metadata. AVPlayer turns these into NSDictionaries. */
  292. if ([(NSString *)[timedMetadata key] isEqualToString:AVMetadataID3MetadataKeyGeneralEncapsulatedObject])
  293. {
  294. if ([[timedMetadata value] isKindOfClass:[NSDictionary class]])
  295. {
  296. NSDictionary *propertyList = (NSDictionary *)[timedMetadata value];
  297. /* Metadata payload could be the list of ads. */
  298. NSArray *newAdList = [propertyList objectForKey:@"ad-list"];
  299. if (newAdList != nil)
  300. {
  301. [self updateAdList:newAdList];
  302. NSLog(@"ad-list is %@", newAdList);
  303. }
  304. /* Or it might be an ad record. */
  305. NSString *adURL = [propertyList objectForKey:@"url"];
  306. if (adURL != nil)
  307. {
  308. if ([adURL isEqualToString:@""])
  309. {
  310. /* Ad is not playing, so clear text. */
  311. //self.playStatus.text = @"";
  312. movieTimeControl.enabled = YES; /* Enable seeking for main content. */
  313. NSLog(@"enabling seek at %g", CMTimeGetSeconds([_player currentTime]));
  314. }
  315. else
  316. {
  317. /* Display text indicating that an Ad is now playing. */
  318. //self.playStatus.text = @"< Ad now playing, seeking is disabled on the movie controller... >";
  319. movieTimeControl.enabled = NO; /* Disable seeking for ad content. */
  320. NSLog(@"disabling seek at %g", CMTimeGetSeconds([_player currentTime]));
  321. }
  322. }
  323. }
  324. }
  325. }
  326. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
  327. {
  328. if(_player == nil)
  329. return;
  330. /* Observe the AVPlayer "rate" property to synchronize the movie slider control 'play'
  331. and 'pause' buttons. */
  332. if (context == StreamPlayerViewControllerRateObservationContext)
  333. {
  334. [self syncPlayPauseButtons];
  335. }
  336. else if (context == StreamPlayerViewControllerCurrentItemObservationContext)
  337. {
  338. [playerLayerView.playerLayer setPlayer:_player];
  339. }
  340. /* Observe the AVPlayer "currentItem.timedMetadata" property to parse the media stream
  341. timed metadata. */
  342. else if (context == StreamPlayerViewControllerTimedMetadataObserverContext)
  343. {
  344. NSArray* array = [[_player currentItem] timedMetadata];
  345. for (AVMetadataItem *metadataItem in array)
  346. {
  347. [self handleTimedMetadata:metadataItem];
  348. }
  349. }
  350. /* Observe the player item 'status' property to determing when it is ready to play. */
  351. else if (context == StreamPlayerViewControllerPlayerItemStatusObserverContext)
  352. {
  353. [self syncPlayPauseButtons];
  354. AVPlayerItem *thePlayerItem = (AVPlayerItem *)object;
  355. if (thePlayerItem.status == AVPlayerItemStatusReadyToPlay)
  356. {
  357. if(isVideo){
  358. playerLayerView.playerLayer.hidden = NO;
  359. playerLayerView.playerLayer.backgroundColor = [[UIColor blackColor] CGColor];
  360. [playerLayerView.playerLayer setPlayer:_player];
  361. //[_player seekToTime:CMTimeMakeWithSeconds(0.5, NSEC_PER_SEC)];
  362. }
  363. movieTimeControl.enabled = YES;
  364. [self initScrubberTimer];
  365. _isIniting = NO;
  366. self.isOpened = 1;
  367. if (delegate && [delegate respondsToSelector:self.didOpen])
  368. // [delegate performSelector:self.didOpen];
  369. [delegate performSelectorOnMainThread:self.didOpen withObject:nil waitUntilDone:NO];
  370. [self play:pauseButton];
  371. }
  372. else if (thePlayerItem.status == AVPlayerItemStatusFailed)
  373. {
  374. self.isOpened = 0;
  375. if([movieURL isFileURL]){
  376. playStatus.text = Localized(@"StreamPlayerViewController_ReadFailure");
  377. [g_App.jxServer showMsg:Localized(@"StreamPlayerViewController_OpenSongFails")];
  378. }
  379. else{
  380. playStatus.text = Localized(@"StreamPlayerViewController_ReadFailure");
  381. [g_App.jxServer showMsg:Localized(@"StreamPlayerViewController_OpenServerFails")];
  382. }
  383. }
  384. else if (thePlayerItem.status == AVPlayerItemStatusUnknown)
  385. {
  386. self.isOpened = 0;
  387. if([movieURL isFileURL]){
  388. playStatus.text = Localized(@"StreamPlayerViewController_ReadFailure");
  389. [g_App.jxServer showMsg:Localized(@"StreamPlayerViewController_OpenSongFails")];
  390. }
  391. else{
  392. playStatus.text = Localized(@"StreamPlayerViewController_ReadFailure");
  393. [g_App.jxServer showMsg:Localized(@"StreamPlayerViewController_OpenServerFails")];
  394. }
  395. }
  396. }
  397. else
  398. {
  399. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  400. }
  401. }
  402. #pragma mark Button Action Methods
  403. -(id)init{
  404. self = [super init];
  405. if(self) {
  406. kTracksKey = @"tracks";
  407. kPlayableKey = @"playable";
  408. kStatusKey = @"status";
  409. kRateKey = @"rate";
  410. kCurrentItemKey = @"currentItem";
  411. kDurationKey = @"duration";
  412. kTimedMetadataKey = @"currentItem.timedMetadata";
  413. // [kTracksKey retain];
  414. // [kPlayableKey retain];
  415. // [kStatusKey retain];
  416. // [kRateKey retain];
  417. // [kCurrentItemKey retain];
  418. // [kDurationKey retain];
  419. // [kTimedMetadataKey retain];
  420. self.isFullScreen = NO;
  421. isOpened = 0;
  422. _isIniting = YES;
  423. _player = nil;
  424. isUserPause = NO;
  425. self.view.backgroundColor = [UIColor clearColor];
  426. self.view.userInteractionEnabled = YES;
  427. playerLayerView = [[MyPlayerLayerView alloc] init];
  428. playerLayerView.userInteractionEnabled = YES;
  429. playerLayerView.backgroundColor = [UIColor clearColor];
  430. [playerLayerView setVideoFillMode:AVLayerVideoGravityResizeAspect];
  431. // [playerLayerView setVideoFillMode:AVLayerVideoGravityResize];
  432. [self.view addSubview:playerLayerView];
  433. _singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onClick:)];
  434. [self.view addGestureRecognizer:_singleTap];
  435. _wait = [[JXWaitView alloc] initWithParent:playerLayerView];
  436. timerShowPeak = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(showVolPeak:) userInfo:nil repeats: YES];
  437. _curProFloat = 0;
  438. _n = 0; // 当前进度条进度, _n 减少误差
  439. //进度条
  440. // movieTimeControl = [[UISlider alloc] initWithFrame:CGRectMake(100, JX_SCREEN_HEIGHT-50, JX_SCREEN_WIDTH-160, 10)];
  441. // movieTimeControl.maximumTrackTintColor = [UIColor lightGrayColor];
  442. // movieTimeControl.minimumTrackTintColor = [UIColor whiteColor];
  443. // movieTimeControl.continuous = YES;
  444. // movieTimeControl.minimumValue = 0;
  445. // movieTimeControl.maximumValue = timeLen;
  446. //
  447. // [movieTimeControl setThumbImage:[self scaleToSize:[UIImage imageNamed:@"circular"] size:CGSizeMake(14, 14)] forState:UIControlStateNormal];
  448. // [self.view addSubview:movieTimeControl];
  449. [movieTimeControl addTarget:self action:@selector(beginScrubbing:) forControlEvents:UIControlEventTouchDown];
  450. [movieTimeControl addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpInside];
  451. [movieTimeControl addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpOutside];
  452. [movieTimeControl addTarget:self action:@selector(scrub:) forControlEvents:UIControlEventValueChanged];
  453. [movieTimeControl addTarget:self action:@selector(scrub:) forControlEvents:UIControlEventTouchDragInside];
  454. }
  455. return self;
  456. }
  457. - (UIImage *)scaleToSize:(UIImage *)img size:(CGSize)size {
  458. UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
  459. [img drawInRect:CGRectMake(0,0, size.width, size.height)];
  460. UIImage* scaledImage = UIGraphicsGetImageFromCurrentImageContext();
  461. UIGraphicsEndImageContext();
  462. return scaledImage;
  463. }
  464. - (void)dealloc
  465. {
  466. NSLog(@"JXVideoPlayerVC.dealloc");
  467. // NSLog(@"streamPlayer=%d,player=%d,mPlayerItem=%d",self.retainCount,_player.retainCount,mPlayerItem.retainCount);
  468. // [timeObserver release];
  469. // [movieURL release];
  470. // [adList release];
  471. // [playStatus release];
  472. // [pauseButton release];
  473. // [_wait release];
  474. // [_singleTap release];
  475. timeObserver = nil;
  476. movieURL = nil;
  477. adList = nil;
  478. playStatus = nil;
  479. pauseButton = nil;
  480. _wait = nil;
  481. _singleTap = nil;
  482. [self stopTimer];
  483. // if(timerShowPeak)
  484. // [timerShowPeak invalidate];
  485. // [timeEnd release];
  486. // [timeCur release];
  487. timeEnd = nil;
  488. timeCur = nil;
  489. [playerLayerView removeFromSuperview];
  490. // [playerLayerView release];
  491. playerLayerView = nil;
  492. [movieTimeControl removeTarget:self action:@selector(beginScrubbing:) forControlEvents:UIControlEventTouchDown];
  493. [movieTimeControl removeTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpInside];
  494. [movieTimeControl removeTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpOutside];
  495. [movieTimeControl removeTarget:self action:@selector(scrub:) forControlEvents:UIControlEventValueChanged];
  496. [movieTimeControl removeTarget:self action:@selector(scrub:) forControlEvents:UIControlEventTouchDragInside];
  497. // [movieTimeControl release];
  498. movieTimeControl = nil;
  499. // [super dealloc];
  500. }
  501. -(void)setSliderHidden:(BOOL)b{
  502. playStatus.hidden = b;
  503. movieTimeControl.hidden = b;
  504. if(!isVideo)
  505. playerLayerView.hidden = YES;
  506. }
  507. -(void)stop{
  508. isOpened = 0;
  509. [self pause:nil];
  510. [self stopTimer];
  511. [mPlayerItem removeObserver:self forKeyPath:kStatusKey];
  512. [self removePlayerTimeObserver];
  513. [g_notify removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:mPlayerItem];
  514. [_player removeObserver:self forKeyPath:kCurrentItemKey];
  515. [_player removeObserver:self forKeyPath:kRateKey];
  516. // [_player removeObserver:self forKeyPath:kTimedMetadataKey];
  517. // NSLog(@"streamPlayer=%d,player=%d,mPlayerItem=%d",self.retainCount,_player.retainCount,mPlayerItem.retainCount);
  518. [playerLayerView.playerLayer setPlayer:nil];
  519. [playerLayerView removeFromSuperview];
  520. playerLayerView.hidden = YES;
  521. // [_player release];
  522. _player = nil;
  523. mPlayerItem = nil;
  524. }
  525. -(void)open:(NSString*)value{
  526. if([value length]<=0)
  527. return;
  528. self.isOpened = 0;
  529. self.filepath = [value copy];
  530. NSURL* url;
  531. if([[NSFileManager defaultManager] fileExistsAtPath:value]){
  532. url=[[NSURL alloc]initFileURLWithPath:value];
  533. // NSLog(@"播放本地文件");
  534. }
  535. else
  536. url=[[NSURL alloc] initWithString:value];
  537. [self prepareToPlayItemWithURL:url];
  538. // [url release];
  539. }
  540. - (void)play:(id)sender
  541. {
  542. if(_player == nil)
  543. return;
  544. if (YES == seekToZeroBeforePlay)
  545. {
  546. seekToZeroBeforePlay = NO;
  547. [_player seekToTime:kCMTimeZero];
  548. }
  549. if (!timerShowPeak) {
  550. timerShowPeak = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(showVolPeak:) userInfo:nil repeats: YES];
  551. }
  552. [self.view addGestureRecognizer:_singleTap];
  553. [_player play];
  554. isPause = NO;
  555. }
  556. - (void)pause:(id)sender
  557. {
  558. [self stopTimer];
  559. // [self.view removeGestureRecognizer:_singleTap];
  560. [_player pause];
  561. isPause = YES;
  562. }
  563. -(void) showVolPeak:(NSTimer *) timer {
  564. if(![self isPlaying])
  565. return;
  566. NSTimeInterval n1 = _player.currentTime.value /_player.currentTime.timescale;
  567. playStatus.text = @"";
  568. timeCur.text = [NSString stringWithFormat:@"%@", [self formatTime:n1]];
  569. timeEnd.text = [NSString stringWithFormat:@"%@", [self formatTime:timeLen]];
  570. // 进度条
  571. _curProFloat += 0.1; // 防止视频进度条1s前出问题
  572. if (_curProFloat <= 0.1) {
  573. _curProFloat = 1;
  574. }
  575. if (n1 != _n || _curProFloat == 1) {
  576. movieTimeControl.value = _curProFloat <= 1 ? _curProFloat : n1;
  577. movieTimeControl.maximumValue = timeLen;
  578. }
  579. _n = n1; // 记录上个时间防止进度条多次赋值
  580. }
  581. - (NSString *) formatTime: (NSTimeInterval) num
  582. {
  583. int n = num;
  584. int secs = n % 60;
  585. int min = n / 60;
  586. if (num < 60) return [NSString stringWithFormat:@"0:%02d", n];
  587. return [NSString stringWithFormat:@"%d:%02d", min, secs];
  588. }
  589. - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
  590. {
  591. return YES;
  592. }
  593. -(void)initVolume:(float)volume playItem:(AVPlayerItem*)playItem{
  594. NSArray *audioTracks = [_asset tracksWithMediaType:AVMediaTypeAudio];
  595. NSMutableArray *allAudioParams = [NSMutableArray array];
  596. for (AVAssetTrack *track in audioTracks){
  597. AVMutableAudioMixInputParameters *_audioInputParams;
  598. _audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters];
  599. [_audioInputParams setVolume:volume atTime:kCMTimeZero];
  600. [_audioInputParams setTrackID:[track trackID]];
  601. [allAudioParams addObject:_audioInputParams];
  602. break;
  603. }
  604. AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
  605. [audioMix setInputParameters:allAudioParams];
  606. [playItem setAudioMix:audioMix];
  607. }
  608. -(void)set90{
  609. if(_isNeed90)
  610. [playerLayerView set90];
  611. }
  612. -(void)setPlayStatus:(JXLabel *)sender{
  613. if(playStatus!=sender){
  614. // [playStatus release];
  615. playStatus = sender;
  616. }
  617. sender.text = Localized(@"StreamPlayerViewController_Loading");
  618. }
  619. -(void)setMovieTimeControl:(UISlider *)sender{
  620. if(movieTimeControl!=sender){
  621. // [movieTimeControl release];
  622. movieTimeControl = sender;
  623. // movieTimeControl = sender;
  624. [movieTimeControl addTarget:self action:@selector(beginScrubbing:) forControlEvents:UIControlEventTouchDown];
  625. [movieTimeControl addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpInside];
  626. [movieTimeControl addTarget:self action:@selector(endScrubbing:) forControlEvents:UIControlEventTouchUpOutside];
  627. [movieTimeControl addTarget:self action:@selector(scrub:) forControlEvents:UIControlEventValueChanged];
  628. [movieTimeControl addTarget:self action:@selector(scrub:) forControlEvents:UIControlEventTouchDragInside];
  629. }
  630. }
  631. - (void)onClick:(id)sender {
  632. if (delegate && [delegate respondsToSelector:didClick])
  633. // [delegate performSelector:didClick withObject:self.view];
  634. [delegate performSelectorOnMainThread:didClick withObject:self.view waitUntilDone:NO];
  635. }
  636. -(void)setPauseBtn:(UIButton*)value{
  637. if([pauseButton isEqual:value])
  638. return;
  639. // [pauseButton release];
  640. pauseButton = value;
  641. }
  642. -(void)setFrame:(CGRect)frame{
  643. self.view.frame = frame;
  644. self.playerLayerView.frame = self.view.bounds;
  645. [_wait adjust];
  646. }
  647. -(void)setIsOpened:(BOOL)value{
  648. isOpened = value;
  649. if(isOpened){
  650. pauseButton.hidden = NO;
  651. [_wait stop];
  652. }else{
  653. pauseButton.hidden = YES;
  654. [_wait start];
  655. }
  656. }
  657. - (void)stopTimer {
  658. if(timerShowPeak){
  659. [timerShowPeak invalidate];
  660. timerShowPeak = nil;
  661. }
  662. }
  663. @end