123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- #import "AGPlayerView.h"
- #import "NSString+time.h"
- #import "RotationScreen.h"
- #import "Masonry.h"
- #define RGBColor(r, g, b) [UIColor colorWithRed:r / 255.0 green:g / 255.0 blue:b / 255.0 alpha:1.0]
- static const NSTimeInterval kVideoPlayerAnimationTimeinterval = 0.3f;
- @interface AGPlayerView ()
- {
- BOOL _isIntoBackground; // 是否在后台
- BOOL _isShowToolbar; // 是否显示工具条
- BOOL _isSliding; // 是否正在滑动
- AVPlayerItem *_playerItem;
- AVPlayerLayer *_playerLayer;
- NSTimer *_timer;
- id _playTimeObserver; // 观察者
-
- CGRect _originFrame;
- }
- @property (weak, nonatomic) IBOutlet UIView *mainView;
- @property (weak, nonatomic) IBOutlet UIView *playerView;
- @property (weak, nonatomic) IBOutlet UIView *topView;
- @property (weak, nonatomic) IBOutlet UIButton *moreButton;
- @property (weak, nonatomic) IBOutlet UIView *downView;
- @property (weak, nonatomic) IBOutlet UIButton *playButton;
- @property (weak, nonatomic) IBOutlet UILabel *beginLabel;
- @property (weak, nonatomic) IBOutlet UILabel *endLabel;
- @property (weak, nonatomic) IBOutlet UISlider *playProgress;
- @property (weak, nonatomic) IBOutlet UIProgressView *loadedProgress; // 缓冲进度条
- @property (weak, nonatomic) IBOutlet UIButton *rotationButton;
- @property (weak, nonatomic) IBOutlet UIButton *playerButton;
- @property (weak, nonatomic) IBOutlet UIButton *playerFullScreenButton;
- @property (weak, nonatomic) IBOutlet UIView *inspectorView; // 继续播放/暂停播放
- @property (weak, nonatomic) IBOutlet UILabel *inspectorLabel; //
- // 约束动画
- @property (weak, nonatomic) IBOutlet NSLayoutConstraint *topViewTop;
- @property (weak, nonatomic) IBOutlet NSLayoutConstraint *downViewBottom;
- @property (weak, nonatomic) IBOutlet NSLayoutConstraint *inspectorViewHeight;
- @property (weak, nonatomic) IBOutlet NSLayoutConstraint *playProgressWidth;
- @property (weak, nonatomic) IBOutlet NSLayoutConstraint *playerViewLeading;
- @property (weak, nonatomic) IBOutlet NSLayoutConstraint *playerViewTrailing;
- @property (weak, nonatomic) IBOutlet NSLayoutConstraint *playerViewAspect;
- @property (weak, nonatomic) IBOutlet NSLayoutConstraint *backLeading;
- @property (weak, nonatomic) IBOutlet NSLayoutConstraint *playLeading;
- @end
- @implementation AGPlayerView
- - (void)removeObserveAndNOtification {
- [_player replaceCurrentItemWithPlayerItem:nil];
- [_playerItem removeObserver:self forKeyPath:@"status"];
- [_playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
- [_player removeTimeObserver:_playTimeObserver];
- _playTimeObserver = nil;
- [[NSNotificationCenter defaultCenter] removeObserver:self];
- }
- - (instancetype)initWithFrame:(CGRect)frame{
- self = [super initWithFrame:frame];
- if (self) {
- //o 这里AGPlayerView。xib 实际是self。mainView。而不是self。改的别人代码有点乱(以后找时间重写吧,xib上面好多多余的元素,而且横屏机制不一样)
- // set
- self.mainView = [[[NSBundle mainBundle] loadNibNamed:@"AGPlayerView" owner:self options:nil] lastObject];
- self.mainView.frame = self.bounds;
- [self addSubview:self.mainView];
-
- self.playProgressWidth.constant = kSize.width - 200;
- // self.topViewTop.constant = _isLandscape ? 0 : (kStatusHeight-20);
-
- // setAVPlayer
- self.player = [[AVPlayer alloc] init];
- _playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
- [self.playerView.layer addSublayer:_playerLayer];
-
- // bringFront
- [self.playerView bringSubviewToFront:_topView];
- [self.playerView bringSubviewToFront:_downView];
- [self.playerView bringSubviewToFront:_playerButton];
- [self.playerView bringSubviewToFront:_playProgress];
-
- //
- [self.playerView sendSubviewToBack:_inspectorView];
- // setPortraintLayout
- [self setPortarintLayout];
-
- // slider
- self.playProgress.value = 0.0;
- [self.playProgress setThumbImage:[UIImage imageNamed:@"icmpv_thumb_light"] forState:(UIControlStateNormal)];
- // 设置progress
- self.loadedProgress.progress = 0.0;
- // inspectorBackgroundColor
- self.inspectorView.backgroundColor = [RGBColor(203, 201, 204) colorWithAlphaComponent:0.5]; // 不影响子视图的透明度
- }
- return self;
- }
- #pragma mark-
- #pragma mark 横竖屏约束
- - (void)setPortarintLayout {
- _isLandscape = NO;
-
- // 不隐藏工具条
- [self portraitShow];
- // hideInspector
- self.inspectorViewHeight.constant = 0.0f;
- [self layoutIfNeeded];
- }
- // 显示工具条
- - (void)portraitShow {
- _isShowToolbar = YES; // 显示工具条置为 yes
-
- // 约束动画
- // self.topViewTop.constant = _isLandscape ? 0 : (kStatusHeight-20);
- self.downViewBottom.constant = 0;
- [UIView animateWithDuration:0.1 animations:^{
- [self layoutIfNeeded];
- self.topView.alpha = self.downView.alpha = 1;
- self.playerButton.alpha = self.playerFullScreenButton.alpha = 1;
- } completion:^(BOOL finished) {
- }];
- // 显示状态条 (暂时找不到替代方法,然后运行在ios11上又没有问题。所以先这样吧。。)
- [[UIApplication sharedApplication] setStatusBarHidden:NO animated:YES];
- [[UIApplication sharedApplication] setStatusBarStyle:(UIStatusBarStyleLightContent)];
- }
- - (void)portraitHide {
- _isShowToolbar = NO; // 显示工具条置为 no
-
- // 约束动画
- // self.topViewTop.constant = -(_isLandscape ? 0 : (kStatusHeight-20)+self.topView.frame.size.height);
- self.downViewBottom.constant = -(self.downView.frame.size.height);
- [UIView animateWithDuration:0.1 animations:^{
- [self layoutIfNeeded];
- self.topView.alpha = self.downView.alpha = 0;
- self.playerButton.alpha = self.playerFullScreenButton.alpha = 0;
- } completion:^(BOOL finished) {
- }];
-
- // 显示状态条
- [[UIApplication sharedApplication] setStatusBarHidden:YES animated:YES];
- [[UIApplication sharedApplication] setStatusBarStyle:(UIStatusBarStyleLightContent)];
- }
- #pragma mark-
- #pragma mark inspectorView 动画
- - (void)inspectorViewShow {
- //
- [self.inspectorView.layer removeAllAnimations];
- // 更改文字
- if (_isPlaying) {
- self.inspectorLabel.text = @"继续播放";
- } else {
- self.inspectorLabel.text = @"暂停播放";
- }
- // 约束动画
- self.inspectorViewHeight.constant = 20.0f;
- [UIView animateWithDuration:0.3 animations:^{
- [self layoutIfNeeded];
- } completion:^(BOOL finished) {
- [self performSelector:@selector(inspectorViewHide) withObject:nil afterDelay:1]; // 0.2秒后隐藏
- }];
- }
- - (void)inspectorViewHide {
- self.inspectorViewHeight.constant = 0.0f;
- [UIView animateWithDuration:0.3 animations:^{
- [self layoutIfNeeded];
- } completion:^(BOOL finished) {
-
- }];
- }
- - (void)layoutSubviews {
- [super layoutSubviews];
- _playerLayer.frame = self.bounds;
- }
- #pragma mark- sizeClass 横竖屏约束
- // sizeClass 横竖屏切换时,执行
- - (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
- [super traitCollectionDidChange:previousTraitCollection];
- // 横竖屏切换时重新添加约束
- CGRect bounds = self.bounds;
- [_mainView mas_remakeConstraints:^(MASConstraintMaker *make) {
- make.top.left.equalTo(@(0));
- make.width.equalTo(@(bounds.size.width));
- make.height.equalTo(@(bounds.size.height));
- }];
- // 横竖屏判断
- if (self.traitCollection.verticalSizeClass != UIUserInterfaceSizeClassCompact) { // 竖屏
- self.downView.backgroundColor = self.topView.backgroundColor = [UIColor clearColor];
- [self.rotationButton setImage:[UIImage imageNamed:@"player_fullScreen_iphone"] forState:(UIControlStateNormal)];
- } else { // 横屏
- self.downView.backgroundColor = self.topView.backgroundColor = RGBColor(89, 87, 90);
- [self.rotationButton setImage:[UIImage imageNamed:@"player_window_iphone"] forState:(UIControlStateNormal)];
- }
-
- // iPhone 6s 6 6sP 6p
- // 竖屏情况下 compact * regular compact * regular
- // 横屏情况下 compact * compact regular * compact
- // 以 verticalClass 来判断横竖屏
- // NSLog(@"horizontal %ld", (long)self.traitCollection.horizontalSizeClass);
- // NSLog(@"vertical %ld", (long)self.traitCollection.verticalSizeClass); //
- }
- #pragma mark-
- #pragma mark 横竖屏切换
- - (IBAction)rotationAction:(id)sender {
-
- if (_isLandscape) { // 如果是横屏,
- [RotationScreen forceOrientation:(UIInterfaceOrientationPortrait)]; // 切换为竖屏
- } else {
- [RotationScreen forceOrientation:(UIInterfaceOrientationLandscapeRight)]; // 否则,切换为横屏
- }
- //1点击-调屏幕转变调私有接口setOrientation,实际上因为没有配置general landscapeLeft/right 所以我们看见的屏幕不会变化。
- //2但是监听屏幕转变的方法又检测到屏幕方向变化。所以最后是在orientationHandler里面改变的我们看见的屏幕方向
- //3orientationHandler -> setIsLandscape
- //以上2,3当手机手动横置的时候也会触发 不过我没有细分左/右,只让他home在左了
- }
- /**
- * 屏幕旋转处理
- */
- - (void)orientationHandler {
- if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
- self.isLandscape = YES;
- }else if(UIDeviceOrientationIsPortrait([UIDevice currentDevice].orientation)) {
- self.isLandscape = NO;
- }else{
- //NSLog(@"我就看看有木有第三种");
- }
- }
- - (void)setIsLandscape:(BOOL)isLandscape {
-
- if (_isLandscape == isLandscape) {
- return;
- }
-
- _isLandscape = isLandscape;
-
- if (isLandscape) {
- _originFrame = self.frame;
- CGFloat height = kSize.width;
- CGFloat width = kSize.height;
- CGRect frame = CGRectMake((height - width) / 2, (width - height) / 2, width, height);
- if (is_iPhoneX) {
- self.playerViewLeading.constant = kStatusHeight;
- self.playerViewAspect.constant = kSize.width-(kSize.height-kStatusHeight-kSafeAreaBottomHeight)*14/25;
- }else{
- self.playerViewLeading.constant = 0;
- self.playLeading.constant = 40;
- self.backLeading.constant = 40;
- self.playerViewAspect.constant = kSize.width-(kSize.height-kSafeAreaBottomHeight)*14/25;
- }
-
- self.playerViewTrailing.constant = kSafeAreaBottomHeight;
- //以下2种方式无效,更新self.playerView约束
- // mas_remakeConstraints/mas_updateConstraints wuxiao
- self.playProgressWidth.constant = kSize.height - 200 - kStatusHeight-kSafeAreaBottomHeight;;
- [UIView animateWithDuration:kVideoPlayerAnimationTimeinterval animations:^{
- self.frame = frame;
- self.transform = CGAffineTransformMakeRotation(M_PI_2);
-
- [self.mainView mas_remakeConstraints:^(MASConstraintMaker *make) {
- make.top.left.equalTo(@(0));
- make.width.equalTo(@(kSize.height));
- make.height.equalTo(@(kSize.width));
- }];
-
- [self layoutIfNeeded];
-
- self.downView.backgroundColor = self.topView.backgroundColor = RGBColor(89, 87, 90);
- [self.rotationButton setImage:[UIImage imageNamed:@"player_window_iphone"] forState:(UIControlStateNormal)];
-
- } completion:^(BOOL finished) {}];
-
- }else {
-
- self.playLeading.constant = 12;
- self.backLeading.constant = 12;
- self.playerViewLeading.constant = 0;
- self.playerViewTrailing.constant = 0;
- self.playerViewAspect.constant = 0;
- self.playProgressWidth.constant = kSize.width - 200;;
- [UIView animateWithDuration:kVideoPlayerAnimationTimeinterval animations:^{
- self.transform = CGAffineTransformIdentity;
- self.frame = _originFrame;
- [self.mainView mas_remakeConstraints:^(MASConstraintMaker *make) {
- make.top.left.equalTo(@(0));
- make.width.equalTo(@(kSize.width));
- make.height.equalTo(@(self.bounds.size.height));
- }];
-
- [self layoutIfNeeded];
-
- self.downView.backgroundColor = self.topView.backgroundColor = [UIColor clearColor];
- [self.rotationButton setImage:[UIImage imageNamed:@"player_fullScreen_iphone"] forState:(UIControlStateNormal)];
-
- } completion:^(BOOL finished) {}];
-
-
- }
-
- }
- #pragma mark - 初始化playerItem
- - (void)updatePlayerWithURL:(NSURL *)url {
- NSLog(@"updatePlayerWithURL: %@",url);
- // 创建要播放的资源
- _playerItem = [[AVPlayerItem alloc]initWithURL:url];
- // 播放当前资源
- [self.player replaceCurrentItemWithPlayerItem:_playerItem];
- [self addObserverAndNotification]; // 添加观察者,发布通知
- }
- /**
- * 添加观察者 、通知 、监听播放进度
- */
- - (void)addObserverAndNotification {
- [_playerItem addObserver:self forKeyPath:@"status" options:(NSKeyValueObservingOptionNew) context:nil]; // 观察status属性, 一共有三种属性
- [_playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil]; // 观察缓冲进度
- [self monitoringPlayback:_playerItem]; // 监听播放
- [self addNotification]; // 添加通知
- }
- // 观察播放进度
- - (void)monitoringPlayback:(AVPlayerItem *)item {
- __weak typeof(self)WeakSelf = self;
-
- // 播放进度, 每秒执行30次, CMTime 为30分之一秒
- _playTimeObserver = [_player addPeriodicTimeObserverForInterval:CMTimeMake(1, 30.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
- if (_touchMode != TouchPlayerViewModeHorizontal) {
- // 当前播放秒
- float currentPlayTime = (double)item.currentTime.value/ item.currentTime.timescale;
- // 更新slider, 如果正在滑动则不更新
- if (_isSliding == NO) {
- [WeakSelf updateVideoSlider:currentPlayTime];
- }
- } else {
- return;
- }
- }];
- }
- // 更新滑动条
- - (void)updateVideoSlider:(float)currentTime {
- self.playProgress.value = currentTime;
- self.beginLabel.text = [NSString convertTime:currentTime];
- }
- #pragma mark-
- #pragma mark 添加通知
- - (void)addNotification {
-
- //监听屏幕方向(这里没有在general里面配置landscape left/right 所以选择了这种方式)
- [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(orientationHandler) name:UIDeviceOrientationDidChangeNotification object:nil];
-
- // 播放完成通知
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
- //程序到前台
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(applicationWillEnterForeground)
- name:UIApplicationWillEnterForegroundNotification
- object:nil];
-
- //程序到后台
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(applicationDidEnterBackground)
- name:UIApplicationDidEnterBackgroundNotification
- object:nil];
-
-
- //程序挂起
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(applicationWillResignActive)
- name:UIApplicationWillResignActiveNotification
- object:nil];
-
- //程序复原
- [[NSNotificationCenter defaultCenter] addObserver:self
- selector:@selector(applicationDidBecomeActive)
- name:UIApplicationDidBecomeActiveNotification
- object:nil];
- }
- - (void)playbackFinished:(NSNotification *)notification {
- NSLog(@"视频播放完成通知");
- [self pause];
- _playerItem = [notification object];
- // 是否无限循环
- [_playerItem seekToTime:kCMTimeZero]; // 跳转到初始
- // [_player play]; // 是否无限循环
- }
- /**
- * 程序到前台
- */
- - (void)applicationWillEnterForeground {
- NSLog(@"applicationWillEnterForeground-play");
- [self play];
- }
- /**
- * 程序进入后台
- */
- - (void)applicationDidEnterBackground {
- NSLog(@"applicationDidEnterBackground-pause");
- [self pause];
- }
- /**
- * 程序挂起
- */
- - (void)applicationWillResignActive {
- NSLog(@"applicationWillResignActive-pause");
- [self pause];
- }
- /**
- *程序复原
- */
- - (void)applicationDidBecomeActive
- {
- NSLog(@"applicationDidBecomeActive-play");
- [self play];
- }
- #pragma mark-
- #pragma mark KVO - status
- - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context {
- AVPlayerItem *item = (AVPlayerItem *)object;
- if ([keyPath isEqualToString:@"status"]) {
- if (_isIntoBackground) {
- return;
- } else { // 判断status 的 状态
- AVPlayerStatus status = [[change objectForKey:@"new"] intValue]; // 获取更改后的状态
- if (status == AVPlayerStatusReadyToPlay) {
- NSLog(@"准备播放");
- // CMTime 本身是一个结构体
- CMTime duration = item.duration; // 获取视频长度
- NSLog(@"%.2f", CMTimeGetSeconds(duration));
- // 设置视频时间
- [self setMaxDuration:CMTimeGetSeconds(duration)];
- // 播放
- [self play];
- self.playButton.enabled = YES;
- self.playerButton.enabled = YES;
- self.playProgress.enabled = YES;
-
- } else if (status == AVPlayerStatusFailed) {
- NSLog(@"AVPlayerStatusFailed: %@",self.player.error.description);
- ShowMsg(@"播放失败,请退出重试");
- } else {
- NSLog(@"AVPlayerStatusUnknown");
- ShowMsg(@"未知错误");
- }
- }
-
- } else if ([keyPath isEqualToString:@"loadedTimeRanges"]) {
- NSTimeInterval timeInterval = [self availableDurationRanges]; // 缓冲时间
- CGFloat totalDuration = CMTimeGetSeconds(_playerItem.duration); // 总时间
- [self.loadedProgress setProgress:timeInterval / totalDuration animated:YES];
- }
- }
- // 设置最大时间
- - (void)setMaxDuration:(CGFloat)duration {
- self.playProgress.maximumValue = duration; // maxValue = CMGetSecond(item.duration)
- self.endLabel.text = [NSString convertTime:duration];
- }
- // 已缓冲进度
- - (NSTimeInterval)availableDurationRanges {
- NSArray *loadedTimeRanges = [_playerItem loadedTimeRanges]; // 获取item的缓冲数组
- // discussion Returns an NSArray of NSValues containing CMTimeRanges
-
- // CMTimeRange 结构体 start duration 表示起始位置 和 持续时间
- CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue]; // 获取缓冲区域
- float startSeconds = CMTimeGetSeconds(timeRange.start);
- float durationSeconds = CMTimeGetSeconds(timeRange.duration);
- NSTimeInterval result = startSeconds + durationSeconds; // 计算总缓冲时间 = start + duration
- return result;
- }
- #pragma mark - 返回
- - (IBAction)goBackAction:(id)sender {
-
- if (self.goBackBlock) {
- self.goBackBlock();
- }
- }
- #pragma mark-
- #pragma mark 播放 暂停
- - (IBAction)playOrStopAction:(id)sender {
- if (_isPlaying) {
- [self pause];
- } else {
- [self play];
- }
-
- // inspectorAnimation
- [self inspectorViewShow];
- }
- - (void)play {
- NSLog(@"lee-play");
- _isPlaying = YES;
- [_player play]; // 调用avplayer 的play方法
- [self.playButton setImage:[UIImage imageNamed:@"Stop"] forState:(UIControlStateNormal)];
- [self.playerButton setImage:[UIImage imageNamed:@"player_pause_iphone_window"] forState:(UIControlStateNormal)];
- [self.playerFullScreenButton setImage:[UIImage imageNamed:@"player_pause_iphone_fullscreen"] forState:(UIControlStateNormal)];
- }
- - (void)pause {
- NSLog(@"lee-pause");
- _isPlaying = NO;
- [_player pause];
- [self.playButton setImage:[UIImage imageNamed:@"Play"] forState:(UIControlStateNormal)];
- [self.playerButton setImage:[UIImage imageNamed:@"player_start_iphone_window"] forState:(UIControlStateNormal)];
- [self.playerFullScreenButton setImage:[UIImage imageNamed:@"player_start_iphone_fullscreen"] forState:(UIControlStateNormal)];
- }
- #pragma mark-
- #pragma mark 处理点击事件
- - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
- _touchMode = TouchPlayerViewModeNone;
- }
- //
- - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
- {
- if (_touchMode == TouchPlayerViewModeNone) {
- if (_isLandscape) { // 如果当前是横屏
- if (_isShowToolbar) {
- [self portraitHide];
- } else {
- [self portraitShow];
- }
- } else { // 如果是竖屏
- if (_isShowToolbar) {
- [self portraitHide];
- } else {
- [self portraitShow];
- }
- }
- }
- }
- //
- - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
-
- }
- #pragma mark-
- #pragma mark 滑块事件
- - (IBAction)playerSliderTouchDown:(id)sender {
- [self pause];
- }
- - (IBAction)playerSliderTouchUpInside:(id)sender {
- _isSliding = NO; // 滑动结束
- [self play];
- }
- // 不要拖拽的时候改变, 手指抬起来后缓冲完成再改变
- - (IBAction)playerSliderValueChanged:(id)sender {
-
- _isSliding = YES;
- [self pause];
-
- CMTime changedTime = CMTimeMakeWithSeconds(self.playProgress.value, 1.0);
- // NSLog(@"%.2f", self.playProgress.value);
- [_playerItem seekToTime:changedTime completionHandler:^(BOOL finished) {
- // 跳转完成后做某事
- }];
- }
- @end
|