TBPlayer.m 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649
  1. //
  2. // TBPlayer.m
  3. // TBPlayer
  4. //
  5. // Created by qianjianeng on 16/1/31.
  6. // Copyright © 2016年 SF. All rights reserved.
  7. //
  8. //// github地址:https://github.com/suifengqjn/TBPlayer
  9. #import "TBPlayer.h"
  10. #import "TBloaderURLConnection.h"
  11. #import "TBVideoRequestTask.h"
  12. #import "XCHudHelper.h"
  13. #define kScreenHeight ([UIScreen mainScreen].bounds.size.height)
  14. #define kScreenWidth ([UIScreen mainScreen].bounds.size.width)
  15. #define IOS_VERSION ([[[UIDevice currentDevice] systemVersion] floatValue])
  16. NSString *const kTBPlayerStateChangedNotification = @"TBPlayerStateChangedNotification";
  17. NSString *const kTBPlayerProgressChangedNotification = @"TBPlayerProgressChangedNotification";
  18. NSString *const kTBPlayerLoadProgressChangedNotification = @"TBPlayerLoadProgressChangedNotification";
  19. @interface TBPlayer ()<TBloaderURLConnectionDelegate>
  20. @property (nonatomic ) TBPlayerState state;
  21. @property (nonatomic ) CGFloat loadedProgress;//缓冲进度
  22. @property (nonatomic ) CGFloat duration;//视频总时间
  23. @property (nonatomic ) CGFloat current;//当前播放时间
  24. @property (nonatomic, strong) AVURLAsset *videoURLAsset;
  25. @property (nonatomic, strong) AVAsset *videoAsset;
  26. @property (nonatomic, strong) TBloaderURLConnection *resouerLoader;
  27. @property (nonatomic, strong) AVPlayer *player;
  28. @property (nonatomic, strong) AVPlayerItem *currentPlayerItem;
  29. @property (nonatomic, strong) AVPlayerLayer *currentPlayerLayer;
  30. @property (nonatomic, strong) NSObject *playbackTimeObserver;
  31. @property (nonatomic ) BOOL isPauseByUser; //是否被用户暂停
  32. @property (nonatomic, ) BOOL isLocalVideo; //是否播放本地文件
  33. @property (nonatomic, ) BOOL isFinishLoad; //是否下载完毕
  34. @property (nonatomic, weak) UIView *showView;
  35. @property (nonatomic, strong) UIView *navBar;
  36. @property (nonatomic, strong) UILabel *currentTimeLabel;
  37. @property (nonatomic, strong) UILabel *totolTimeLabel;
  38. @property (nonatomic, strong) UIProgressView *videoProgressView; //缓冲进度条
  39. @property (nonatomic, strong) UISlider *playSlider; //滑竿
  40. @property (nonatomic, strong) UIButton *stopButton;//播放暂停按钮
  41. @property (nonatomic, strong) UIButton *screenBUtton;//全屏按钮
  42. @property (nonatomic, assign) BOOL isFullScreen;
  43. @end
  44. @implementation TBPlayer
  45. + (instancetype)sharedInstance {
  46. static dispatch_once_t onceToken;
  47. static id _sInstance;
  48. dispatch_once(&onceToken, ^{
  49. _sInstance = [[self alloc] init];
  50. });
  51. return _sInstance;
  52. }
  53. - (instancetype)init
  54. {
  55. self = [super init];
  56. if (self) {
  57. _isPauseByUser = YES;
  58. _loadedProgress = 0;
  59. _duration = 0;
  60. _current = 0;
  61. _state = TBPlayerStateStopped;
  62. _stopWhenAppDidEnterBackground = YES;
  63. }
  64. return self;
  65. }
  66. //清空播放器监听属性
  67. - (void)releasePlayer
  68. {
  69. if (!self.currentPlayerItem) {
  70. return;
  71. }
  72. [[NSNotificationCenter defaultCenter] removeObserver:self];
  73. [self.currentPlayerItem removeObserver:self forKeyPath:@"status"];
  74. [self.currentPlayerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
  75. [self.currentPlayerItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
  76. [self.currentPlayerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
  77. [self.player removeTimeObserver:self.playbackTimeObserver];
  78. self.playbackTimeObserver = nil;
  79. self.currentPlayerItem = nil;
  80. }
  81. - (void)playWithUrl:(NSURL *)url showView:(UIView *)showView
  82. {
  83. [self.player pause];
  84. [self releasePlayer];
  85. self.isPauseByUser = NO;
  86. self.loadedProgress = 0;
  87. self.duration = 0;
  88. self.current = 0;
  89. _showView = showView;
  90. NSString *str = [url absoluteString];
  91. //如果是ios < 7 或者是本地资源,直接播放
  92. if (IOS_VERSION < 7.0 || ![str hasPrefix:@"http"]) {
  93. self.videoAsset = [AVURLAsset URLAssetWithURL:url options:nil];
  94. self.currentPlayerItem = [AVPlayerItem playerItemWithAsset:_videoAsset];
  95. if (!self.player) {
  96. self.player = [AVPlayer playerWithPlayerItem:self.currentPlayerItem];
  97. } else {
  98. [self.player replaceCurrentItemWithPlayerItem:self.currentPlayerItem];
  99. }
  100. self.currentPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
  101. self.currentPlayerLayer.frame = CGRectMake(0, 44, showView.bounds.size.width, showView.bounds.size.height-44);
  102. _isLocalVideo = YES;
  103. } else { //ios7以上采用resourceLoader给播放器补充数据
  104. self.resouerLoader = [[TBloaderURLConnection alloc] init];
  105. self.resouerLoader.delegate = self;
  106. NSURL *playUrl = [_resouerLoader getSchemeVideoURL:url];
  107. self.videoURLAsset = [AVURLAsset URLAssetWithURL:playUrl options:nil];
  108. [_videoURLAsset.resourceLoader setDelegate:_resouerLoader queue:dispatch_get_main_queue()];
  109. self.currentPlayerItem = [AVPlayerItem playerItemWithAsset:_videoURLAsset];
  110. if (!self.player) {
  111. self.player = [AVPlayer playerWithPlayerItem:self.currentPlayerItem];
  112. } else {
  113. [self.player replaceCurrentItemWithPlayerItem:self.currentPlayerItem];
  114. }
  115. self.currentPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
  116. self.currentPlayerLayer.frame = CGRectMake(0, 44, showView.bounds.size.width, showView.bounds.size.height-44);
  117. _isLocalVideo = NO;
  118. }
  119. [showView.layer addSublayer:self.currentPlayerLayer];
  120. [self.currentPlayerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
  121. [self.currentPlayerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
  122. [self.currentPlayerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
  123. [self.currentPlayerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
  124. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterBackground) name:UIApplicationWillResignActiveNotification object:nil];
  125. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidEnterPlayGround) name:UIApplicationDidBecomeActiveNotification object:nil];
  126. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidPlayToEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.currentPlayerItem];
  127. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemPlaybackStalled:) name:AVPlayerItemPlaybackStalledNotification object:self.currentPlayerItem];
  128. // 本地文件不设置TBPlayerStateBuffering状态
  129. if ([url.scheme isEqualToString:@"file"]) {
  130. // 如果已经在TBPlayerStatePlaying,则直接发通知,否则设置状态
  131. if (self.state == TBPlayerStatePlaying) {
  132. [[NSNotificationCenter defaultCenter] postNotificationName:kTBPlayerStateChangedNotification object:nil];
  133. } else {
  134. self.state = TBPlayerStatePlaying;
  135. }
  136. } else {
  137. // 如果已经在TBPlayerStateBuffering,则直接发通知,否则设置状态
  138. if (self.state == TBPlayerStateBuffering) {
  139. [[NSNotificationCenter defaultCenter] postNotificationName:kTBPlayerStateChangedNotification object:nil];
  140. } else {
  141. self.state = TBPlayerStateBuffering;
  142. }
  143. }
  144. if (!_navBar) {
  145. _navBar = [[UIView alloc] init];
  146. [showView addSubview:_navBar];
  147. }
  148. [self buildVideoNavBar];
  149. [[XCHudHelper sharedInstance] showHudOnView:_showView caption:nil image:nil acitivity:YES autoHideTime:0];
  150. [[NSNotificationCenter defaultCenter] postNotificationName:kTBPlayerProgressChangedNotification object:nil];
  151. UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(halfScreen)];
  152. [showView addGestureRecognizer:tap];
  153. }
  154. - (void)fullScreen
  155. {
  156. _navBar.hidden = YES;
  157. self.currentPlayerLayer.transform = CATransform3DMakeRotation(M_PI/2, 0, 0, 1);
  158. self.currentPlayerLayer.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
  159. }
  160. - (void)halfScreen
  161. {
  162. _navBar.hidden = NO;
  163. self.currentPlayerLayer.transform = CATransform3DIdentity;
  164. self.currentPlayerLayer.frame = CGRectMake(0, 0, kScreenWidth, kScreenHeight);
  165. }
  166. - (void)seekToTime:(CGFloat)seconds
  167. {
  168. if (self.state == TBPlayerStateStopped) {
  169. return;
  170. }
  171. seconds = MAX(0, seconds);
  172. seconds = MIN(seconds, self.duration);
  173. [self.player pause];
  174. [self.player seekToTime:CMTimeMakeWithSeconds(seconds, NSEC_PER_SEC) completionHandler:^(BOOL finished) {
  175. self.isPauseByUser = NO;
  176. [self.player play];
  177. if (!self.currentPlayerItem.isPlaybackLikelyToKeepUp) {
  178. self.state = TBPlayerStateBuffering;
  179. [[XCHudHelper sharedInstance] showHudOnView:_showView caption:nil image:nil acitivity:YES autoHideTime:0];
  180. }
  181. }];
  182. }
  183. - (void)resumeOrPause
  184. {
  185. if (!self.currentPlayerItem) {
  186. return;
  187. }
  188. if (self.state == TBPlayerStatePlaying) {
  189. [_stopButton setImage:[self imageNamed:@"icon_play"] forState:UIControlStateNormal];
  190. [_stopButton setImage:[self imageNamed:@"icon_play_hl"] forState:UIControlStateHighlighted];
  191. [self.player pause];
  192. self.state = TBPlayerStatePause;
  193. } else if (self.state == TBPlayerStatePause) {
  194. [_stopButton setImage:[self imageNamed:@"icon_pause"] forState:UIControlStateNormal];
  195. [_stopButton setImage:[self imageNamed:@"icon_pause_hl"] forState:UIControlStateHighlighted];
  196. [self.player play];
  197. self.state = TBPlayerStatePlaying;
  198. }
  199. self.isPauseByUser = YES;
  200. }
  201. - (void)resume
  202. {
  203. if (!self.currentPlayerItem) {
  204. return;
  205. }
  206. [_stopButton setImage:[self imageNamed:@"icon_pause"] forState:UIControlStateNormal];
  207. [_stopButton setImage:[self imageNamed:@"icon_pause_hl"] forState:UIControlStateHighlighted];
  208. self.isPauseByUser = NO;
  209. [self.player play];
  210. }
  211. - (void)pause
  212. {
  213. if (!self.currentPlayerItem) {
  214. return;
  215. }
  216. [_stopButton setImage:[self imageNamed:@"icon_play"] forState:UIControlStateNormal];
  217. [_stopButton setImage:[self imageNamed:@"icon_play_hl"] forState:UIControlStateHighlighted];
  218. self.isPauseByUser = YES;
  219. self.state = TBPlayerStatePause;
  220. [self.player pause];
  221. }
  222. - (void)stop
  223. {
  224. self.isPauseByUser = YES;
  225. self.loadedProgress = 0;
  226. self.duration = 0;
  227. self.current = 0;
  228. self.state = TBPlayerStateStopped;
  229. [self.player pause];
  230. [self releasePlayer];
  231. [[NSNotificationCenter defaultCenter] postNotificationName:kTBPlayerProgressChangedNotification object:nil];
  232. }
  233. - (CGFloat)progress
  234. {
  235. if (self.duration > 0) {
  236. return self.current / self.duration;
  237. }
  238. return 0;
  239. }
  240. #pragma mark - observer
  241. - (void)appDidEnterBackground
  242. {
  243. if (self.stopWhenAppDidEnterBackground) {
  244. [self pause];
  245. self.state = TBPlayerStatePause;
  246. self.isPauseByUser = NO;
  247. }
  248. }
  249. - (void)appDidEnterPlayGround
  250. {
  251. if (!self.isPauseByUser) {
  252. [self resume];
  253. self.state = TBPlayerStatePlaying;
  254. }
  255. }
  256. - (void)playerItemDidPlayToEnd:(NSNotification *)notification
  257. {
  258. [self stop];
  259. }
  260. //在监听播放器状态中处理比较准确
  261. - (void)playerItemPlaybackStalled:(NSNotification *)notification
  262. {
  263. // 这里网络不好的时候,就会进入,不做处理,会在playbackBufferEmpty里面缓存之后重新播放
  264. NSLog(@"buffing-----buffing");
  265. }
  266. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
  267. {
  268. AVPlayerItem *playerItem = (AVPlayerItem *)object;
  269. if ([keyPath isEqualToString:@"status"]) {
  270. if ([playerItem status] == AVPlayerStatusReadyToPlay) {
  271. [self monitoringPlayback:playerItem];// 给播放器添加计时器
  272. } else if ([playerItem status] == AVPlayerStatusFailed || [playerItem status] == AVPlayerStatusUnknown) {
  273. [self stop];
  274. }
  275. } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) { //监听播放器的下载进度
  276. [self calculateDownloadProgress:playerItem];
  277. } else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) { //监听播放器在缓冲数据的状态
  278. [[XCHudHelper sharedInstance] showHudOnView:_showView caption:nil image:nil acitivity:YES autoHideTime:0];
  279. if (playerItem.isPlaybackBufferEmpty) {
  280. self.state = TBPlayerStateBuffering;
  281. [self bufferingSomeSecond];
  282. }
  283. }
  284. }
  285. - (void)monitoringPlayback:(AVPlayerItem *)playerItem
  286. {
  287. self.duration = playerItem.duration.value / playerItem.duration.timescale; //视频总时间
  288. [self.player play];
  289. [self updateTotolTime:self.duration];
  290. [self setPlaySliderValue:self.duration];
  291. __weak __typeof(self)weakSelf = self;
  292. self.playbackTimeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time) {
  293. __strong __typeof(weakSelf)strongSelf = weakSelf;
  294. CGFloat current = playerItem.currentTime.value/playerItem.currentTime.timescale;
  295. [strongSelf updateCurrentTime:current];
  296. [strongSelf updateVideoSlider:current];
  297. if (strongSelf.isPauseByUser == NO) {
  298. strongSelf.state = TBPlayerStatePlaying;
  299. }
  300. // 不相等的时候才更新,并发通知,否则seek时会继续跳动
  301. if (strongSelf.current != current) {
  302. strongSelf.current = current;
  303. if (strongSelf.current > strongSelf.duration) {
  304. strongSelf.duration = strongSelf.current;
  305. }
  306. [[NSNotificationCenter defaultCenter] postNotificationName:kTBPlayerProgressChangedNotification object:nil];
  307. }
  308. }];
  309. }
  310. - (void)calculateDownloadProgress:(AVPlayerItem *)playerItem
  311. {
  312. NSArray *loadedTimeRanges = [playerItem loadedTimeRanges];
  313. CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域
  314. float startSeconds = CMTimeGetSeconds(timeRange.start);
  315. float durationSeconds = CMTimeGetSeconds(timeRange.duration);
  316. NSTimeInterval timeInterval = startSeconds + durationSeconds;// 计算缓冲总进度
  317. CMTime duration = playerItem.duration;
  318. CGFloat totalDuration = CMTimeGetSeconds(duration);
  319. self.loadedProgress = timeInterval / totalDuration;
  320. [self.videoProgressView setProgress:timeInterval / totalDuration animated:YES];
  321. }
  322. - (void)bufferingSomeSecond
  323. {
  324. // playbackBufferEmpty会反复进入,因此在bufferingOneSecond延时播放执行完之前再调用bufferingSomeSecond都忽略
  325. static BOOL isBuffering = NO;
  326. if (isBuffering) {
  327. return;
  328. }
  329. isBuffering = YES;
  330. // 需要先暂停一小会之后再播放,否则网络状况不好的时候时间在走,声音播放不出来
  331. [self.player pause];
  332. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  333. // 如果此时用户已经暂停了,则不再需要开启播放了
  334. if (self.isPauseByUser) {
  335. isBuffering = NO;
  336. return;
  337. }
  338. [self.player play];
  339. // 如果执行了play还是没有播放则说明还没有缓存好,则再次缓存一段时间
  340. isBuffering = NO;
  341. if (!self.currentPlayerItem.isPlaybackLikelyToKeepUp) {
  342. [self bufferingSomeSecond];
  343. }
  344. });
  345. }
  346. - (void)setLoadedProgress:(CGFloat)loadedProgress
  347. {
  348. if (_loadedProgress == loadedProgress) {
  349. return;
  350. }
  351. _loadedProgress = loadedProgress;
  352. [[NSNotificationCenter defaultCenter] postNotificationName:kTBPlayerLoadProgressChangedNotification object:nil];
  353. }
  354. - (void)setState:(TBPlayerState)state
  355. {
  356. if (state != TBPlayerStateBuffering) {
  357. [[XCHudHelper sharedInstance] hideHud];
  358. }
  359. if (_state == state) {
  360. return;
  361. }
  362. _state = state;
  363. [[NSNotificationCenter defaultCenter] postNotificationName:kTBPlayerStateChangedNotification object:nil];
  364. }
  365. #pragma mark - UI界面
  366. - (void)buildVideoNavBar
  367. {
  368. _navBar.backgroundColor = [self colorWithHex:0x000000 alpha:0.5];
  369. _navBar.frame = CGRectMake(0, 0, kScreenWidth, 44);
  370. //当前时间
  371. if (!self.currentTimeLabel) {
  372. self.currentTimeLabel = [[UILabel alloc] init];
  373. _currentTimeLabel.textColor = [self colorWithHex:0xffffff alpha:1.0];
  374. _currentTimeLabel.font = [UIFont systemFontOfSize:10.0];
  375. _currentTimeLabel.frame = CGRectMake(30, 0, 52, 44);
  376. _currentTimeLabel.textAlignment = NSTextAlignmentRight;
  377. [_navBar addSubview:_currentTimeLabel];
  378. }
  379. //总时间
  380. if (!self.totolTimeLabel) {
  381. self.totolTimeLabel = [[UILabel alloc] init];
  382. _totolTimeLabel.textColor = [self colorWithHex:0xffffff alpha:1.0];
  383. _totolTimeLabel.font = [UIFont systemFontOfSize:10.0];
  384. _totolTimeLabel.frame = CGRectMake(kScreenWidth-52-15, 0, 52, 44);
  385. _totolTimeLabel.textAlignment = NSTextAlignmentLeft;
  386. [_navBar addSubview:_totolTimeLabel];
  387. }
  388. //进度条
  389. if (!self.videoProgressView) {
  390. self.videoProgressView = [[UIProgressView alloc] init];
  391. _videoProgressView.progressTintColor = [self colorWithHex:0xffffff alpha:1.0]; //填充部分颜色
  392. _videoProgressView.trackTintColor = [self colorWithHex:0xffffff alpha:0.18]; // 未填充部分颜色
  393. _videoProgressView.frame = CGRectMake(62+30, 21, kScreenWidth-124-44, 20);
  394. _videoProgressView.layer.cornerRadius = 1.5;
  395. _videoProgressView.layer.masksToBounds = YES;
  396. CGAffineTransform transform = CGAffineTransformMakeScale(1.0, 1.5);
  397. _videoProgressView.transform = transform;
  398. [_navBar addSubview:_videoProgressView];
  399. }
  400. //滑竿
  401. if (!self.playSlider) {
  402. self.playSlider = [[UISlider alloc] init];
  403. _playSlider.frame = CGRectMake(62+30, 0, kScreenWidth-124-44, 44);
  404. [_playSlider setThumbImage:[self imageNamed:@"icon_progress"] forState:UIControlStateNormal];
  405. _playSlider.minimumTrackTintColor = [UIColor clearColor];
  406. _playSlider.maximumTrackTintColor = [UIColor clearColor];
  407. [_playSlider addTarget:self action:@selector(playSliderChange:) forControlEvents:UIControlEventValueChanged]; //拖动滑竿更新时间
  408. [_playSlider addTarget:self action:@selector(playSliderChangeEnd:) forControlEvents:UIControlEventTouchUpInside]; //松手,滑块拖动停止
  409. [_playSlider addTarget:self action:@selector(playSliderChangeEnd:) forControlEvents:UIControlEventTouchUpOutside];
  410. [_playSlider addTarget:self action:@selector(playSliderChangeEnd:) forControlEvents:UIControlEventTouchCancel];
  411. [_navBar addSubview:_playSlider];
  412. }
  413. //暂停按钮
  414. if (!self.stopButton) {
  415. self.stopButton = [UIButton buttonWithType:UIButtonTypeCustom];
  416. _stopButton.frame = CGRectMake(0, 0, 44, 44);
  417. [_stopButton addTarget:self action:@selector(resumeOrPause) forControlEvents:UIControlEventTouchUpInside];
  418. [_stopButton setImage:[self imageNamed:@"icon_pause"] forState:UIControlStateNormal];
  419. [_stopButton setImage:[self imageNamed:@"icon_pause_hl"] forState:UIControlStateHighlighted];
  420. [_navBar addSubview:_stopButton];
  421. }
  422. //全屏按钮
  423. if (!self.screenBUtton) {
  424. self.screenBUtton = [[UIButton alloc] init];
  425. _screenBUtton.frame = CGRectMake(kScreenWidth - 40, 0, 44, 44);
  426. [_screenBUtton addTarget:self action:@selector(fullScreen) forControlEvents:UIControlEventTouchUpInside];
  427. [_screenBUtton setImage:[self imageNamed:@"quanping"] forState:UIControlStateNormal];
  428. [_screenBUtton setImage:[self imageNamed:@"quanping"] forState:UIControlStateHighlighted];
  429. [_navBar addSubview:_screenBUtton];
  430. }
  431. }
  432. //手指结束拖动,播放器从当前点开始播放,开启滑竿的时间走动
  433. - (void)playSliderChangeEnd:(UISlider *)slider
  434. {
  435. [self seekToTime:slider.value];
  436. [self updateCurrentTime:slider.value];
  437. [_stopButton setImage:[self imageNamed:@"icon_pause"] forState:UIControlStateNormal];
  438. [_stopButton setImage:[self imageNamed:@"icon_pause_hl"] forState:UIControlStateHighlighted];
  439. }
  440. //手指正在拖动,播放器继续播放,但是停止滑竿的时间走动
  441. - (void)playSliderChange:(UISlider *)slider
  442. {
  443. [self updateCurrentTime:slider.value];
  444. }
  445. #pragma mark - 控件拖动
  446. - (void)setPlaySliderValue:(CGFloat)time
  447. {
  448. _playSlider.minimumValue = 0.0;
  449. _playSlider.maximumValue = (NSInteger)time;
  450. }
  451. - (void)updateCurrentTime:(CGFloat)time
  452. {
  453. long videocurrent = ceil(time);
  454. NSString *str = nil;
  455. if (videocurrent < 3600) {
  456. str = [NSString stringWithFormat:@"%02li:%02li",lround(floor(videocurrent/60.f)),lround(floor(videocurrent/1.f))%60];
  457. } else {
  458. str = [NSString stringWithFormat:@"%02li:%02li:%02li",lround(floor(videocurrent/3600.f)),lround(floor(videocurrent%3600)/60.f),lround(floor(videocurrent/1.f))%60];
  459. }
  460. _currentTimeLabel.text = str;
  461. }
  462. - (void)updateTotolTime:(CGFloat)time
  463. {
  464. long videoLenth = ceil(time);
  465. NSString *strtotol = nil;
  466. if (videoLenth < 3600) {
  467. strtotol = [NSString stringWithFormat:@"%02li:%02li",lround(floor(videoLenth/60.f)),lround(floor(videoLenth/1.f))%60];
  468. } else {
  469. strtotol = [NSString stringWithFormat:@"%02li:%02li:%02li",lround(floor(videoLenth/3600.f)),lround(floor(videoLenth%3600)/60.f),lround(floor(videoLenth/1.f))%60];
  470. }
  471. _totolTimeLabel.text = strtotol;
  472. }
  473. - (void)updateVideoSlider:(CGFloat)currentSecond {
  474. [self.playSlider setValue:currentSecond animated:YES];
  475. }
  476. #pragma mark - TBloaderURLConnectionDelegate
  477. - (void)didFinishLoadingWithTask:(TBVideoRequestTask *)task
  478. {
  479. _isFinishLoad = task.isFinishLoad;
  480. }
  481. //网络中断:-1005
  482. //无网络连接:-1009
  483. //请求超时:-1001
  484. //服务器内部错误:-1004
  485. //找不到服务器:-1003
  486. - (void)didFailLoadingWithTask:(TBVideoRequestTask *)task WithError:(NSInteger)errorCode
  487. {
  488. NSString *str = nil;
  489. switch (errorCode) {
  490. case -1001:
  491. str = @"请求超时";
  492. break;
  493. case -1003:
  494. case -1004:
  495. str = @"服务器错误";
  496. break;
  497. case -1005:
  498. str = @"网络中断";
  499. break;
  500. case -1009:
  501. str = @"无网络连接";
  502. break;
  503. default:
  504. str = [NSString stringWithFormat:@"%@", @"(_errorCode)"];
  505. break;
  506. }
  507. [XCHudHelper showMessage:str];
  508. }
  509. #pragma mark - color
  510. - (UIColor*)colorWithHex:(NSInteger)hexValue alpha:(CGFloat)alphaValue
  511. {
  512. return [UIColor colorWithRed:((float)((hexValue & 0xFF0000) >> 16))/255.0
  513. green:((float)((hexValue & 0xFF00) >> 8))/255.0
  514. blue:((float)(hexValue & 0xFF))/255.0
  515. alpha:alphaValue];
  516. }
  517. - (void)dealloc
  518. {
  519. [self releasePlayer];
  520. }
  521. #pragma mark - image addtion
  522. - (UIImage *)imageNamed:(NSString *)imageName {
  523. NSString *path = [[NSBundle mainBundle] pathForResource:@"TBPlayer" ofType:@"bundle"];
  524. NSString *imagePath= [path stringByAppendingPathComponent:@"images"];
  525. return [UIImage imageWithContentsOfFile:[imagePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.png", imageName]]];
  526. }
  527. @end