我使用播放器设置了一个视频播放器(使用AVFoundation).我正在尝试访问和操作视频的currentTime,但是,库只提供视频的持续时间而不是currentTime.
我正在调整Player的演示项目.
请查看下面的"更新"部分而不是此处:
一位朋友告诉我,我可以使用这种方法,但在这种情况下,我无法真正了解如何调整这种方法.
[NSTimer scheduledTimerWithInterval:1.0 target:self selector:@selector(refreshCurrentTimeTextField) userInfo:nil repeats:YES] -(void)refreshCurrentTimeTextField { NSTimeInterval currentTime; QTMovie *movie = [movieView movie]; QTGetTimeInterval([movie currentTime], ¤tTime); int hours = currentTime/3600; int minutes = (currentTime/60) % 60; int seconds = currentTime % 60; NSString *timeLabel; if(hours > 0) { timeLabel = [NSString stringWithFormat:@"%02i:%02i:%02i", hours, minutes, seconds]; } else { timeLabel = [NSString stringWithFormat:@"%02i:%02i", minutes, seconds]; } [yourTextField setStringValue:timeLabel]; }
如果你们中的任何人使用或偶然发现这个库,有没有办法获得currentTime?有没有其他方法来访问/操纵视频的当前时间?
更新:
有人显然为这里的等效库PBJVideoPlayer提供了导入和连接Objective-C的UISlider的代码.但我无法在Swift for Player上采用相同的方法.
来自链接的片段:
diff --git a/Pods/PBJVideoPlayer/Source/PBJVideoPlayerController.m b/Pods/PBJVideoPlayer/Source/PBJVideoPlayerController.m index be6a7d1..51a420e 100644 --- a/Pods/PBJVideoPlayer/Source/PBJVideoPlayerController.m +++ b/Pods/PBJVideoPlayer/Source/PBJVideoPlayerController.m @@ -81,6 +81,8 @@ static NSString * const PBJVideoPlayerControllerReadyForDisplay = @"readyForDisp float _volume; } +@property (nonatomic, strong) UISlider *slider; + @end @implementation PBJVideoPlayerController @@ -93,6 +95,16 @@ static NSString * const PBJVideoPlayerControllerReadyForDisplay = @"readyForDisp #pragma mark - getters/setters +- (UISlider *)slider { + if (_slider == nil) { + _slider = [[UISlider alloc] initWithFrame:CGRectZero]; + _slider.minimumValue = 0.0; + _slider.maximumValue = 0.0; + _slider.continuous = YES; + } + return _slider; +} + - (void)setVideoFillMode:(NSString *)videoFillMode { if (_videoFillMode != videoFillMode) { @@ -311,6 +323,59 @@ static NSString * const PBJVideoPlayerControllerReadyForDisplay = @"readyForDisp NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; [nc addObserver:self selector:@selector(_applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil]; [nc addObserver:self selector:@selector(_applicationDidEnterBackground:) name:UIApplicationDidEnterBackgroundNotification object:nil]; + + self.slider.hidden = YES; + [self.slider addTarget:self action:@selector(moveScrubber:) forControlEvents:UIControlEventValueChanged]; + [self.view addSubview:self.slider]; + + __weak typeof(self) weak = self; + CMTime intervalSeconds = CMTimeMakeWithSeconds(0.25f, NSEC_PER_SEC); + [_player addPeriodicTimeObserverForInterval:intervalSeconds + queue:dispatch_get_main_queue() + usingBlock:^(CMTime time) { + [weak syncScrubber]; + }]; +} + +- (void)syncScrubber +{ + CMTime duration = _player.currentItem.duration; + if (CMTIME_IS_INVALID(duration)) { + self.slider.maximumValue = 0.0; + } else { + Float64 seconds = CMTimeGetSeconds(duration); + if (isfinite(seconds)) { + self.slider.maximumValue = seconds; + Float64 current = CMTimeGetSeconds([_player currentTime]); + self.slider.value = current; + } + } +} + +- (void)moveScrubber:(UISlider *)slider +{ + CMTime duration = _player.currentItem.duration; + if (CMTIME_IS_INVALID(duration)) { + self.slider.maximumValue = 0.0; + } else { + Float64 seconds = CMTimeGetSeconds(duration); + if (isfinite(seconds)) { + self.slider.maximumValue = seconds; + [_player seekToTime:CMTimeMakeWithSeconds(slider.value, NSEC_PER_SEC)]; + } + } +} + +- (void)viewDidAppear:(BOOL)animated +{ + [super viewDidAppear:animated]; + + CGRect sliderRect = self.view.frame; + sliderRect.origin.y = sliderRect.size.height - 40; + sliderRect.size.height = 40; + sliderRect.origin.x = self.view.frame.size.width/4.0; + sliderRect.size.width = self.view.frame.size.width/2.0; + self.slider.frame = sliderRect; } - (void)viewDidDisappear:(BOOL)animated @@ -402,11 +467,13 @@ typedef void (^PBJVideoPlayerBlock)(); case PBJVideoPlayerPlaybackStateStopped: { [self playFromBeginning]; + self.slider.hidden = YES; break; } case PBJVideoPlayerPlaybackStatePaused: { [self playFromCurrentTime]; + self.slider.hidden = YES; break; } case PBJVideoPlayerPlaybackStatePlaying: @@ -414,6 +481,7 @@ typedef void (^PBJVideoPlayerBlock)(); default: { [self pause]; + self.slider.hidden = NO; break; } } @@ -511,6 +579,14 @@ typedef void (^PBJVideoPlayerBlock)(); _videoView.playerLayer.backgroundColor = [[UIColor blackColor] CGColor]; [_videoView.playerLayer setPlayer:_player]; _videoView.playerLayer.hidden = NO; + + CMTime duration = _playerItem.duration; + if (CMTIME_IS_INVALID(duration)) { + self.slider.maximumValue = 0.0; + } else { + Float64 seconds = CMTimeGetSeconds(duration); + self.slider.maximumValue = seconds; + } break; } case AVPlayerStatusFailed:
Nitin Gohel.. 7
我只是运行GitHub项目,我通过以下代码修复它:
在您的Player.swift类中.
player.addPeriodicTimeObserverForInterval(CMTimeMake(1, 100), queue: dispatch_get_main_queue()) { [unowned self] time in let timeString = String(format: "%02.2f", CMTimeGetSeconds(time)) print("time is \(timeString)") self.delegate?.playerPlaybackstimer(timeString) }
上面的方法添加了 public convenience init() {
功能,所以看起来像:
public convenience init() { self.init(nibName: nil, bundle: nil) self.player = AVPlayer() self.player.actionAtItemEnd = .Pause self.player.addObserver(self, forKeyPath: PlayerRateKey, options: ([NSKeyValueObservingOptions.New, NSKeyValueObservingOptions.Old]) , context: &PlayerObserverContext) self.playbackLoops = false self.playbackFreezesAtEnd = false self.playbackState = .Stopped self.bufferingState = .Unknown player.addPeriodicTimeObserverForInterval(CMTimeMake(1, 100), queue: dispatch_get_main_queue()) { [unowned self] time in let timeString = String(format: "%02.2f", CMTimeGetSeconds(time)) print("time is \(timeString)") self.delegate?.playerPlaybackstimer(timeString) } }
之后我创建一个Delegate方法,public protocol PlayerDelegate: class
如下所示:
public protocol PlayerDelegate: class { func playerReady(player: Player) func playerPlaybackStateDidChange(player: Player) func playerBufferingStateDidChange(player: Player) func playerPlaybackWillStartFromBeginning(player: Player) func playerPlaybackDidEnd(player: Player) func playerPlaybackstimer(NSString: String) }
现在进入你的ViewController.swift
班级并添加以下功能:
func playerPlaybackstimer(NSString: String) { print("currunt time \(NSString)") }
现在运行您的项目并享受.
我只是运行GitHub项目,我通过以下代码修复它:
在您的Player.swift类中.
player.addPeriodicTimeObserverForInterval(CMTimeMake(1, 100), queue: dispatch_get_main_queue()) { [unowned self] time in let timeString = String(format: "%02.2f", CMTimeGetSeconds(time)) print("time is \(timeString)") self.delegate?.playerPlaybackstimer(timeString) }
上面的方法添加了 public convenience init() {
功能,所以看起来像:
public convenience init() { self.init(nibName: nil, bundle: nil) self.player = AVPlayer() self.player.actionAtItemEnd = .Pause self.player.addObserver(self, forKeyPath: PlayerRateKey, options: ([NSKeyValueObservingOptions.New, NSKeyValueObservingOptions.Old]) , context: &PlayerObserverContext) self.playbackLoops = false self.playbackFreezesAtEnd = false self.playbackState = .Stopped self.bufferingState = .Unknown player.addPeriodicTimeObserverForInterval(CMTimeMake(1, 100), queue: dispatch_get_main_queue()) { [unowned self] time in let timeString = String(format: "%02.2f", CMTimeGetSeconds(time)) print("time is \(timeString)") self.delegate?.playerPlaybackstimer(timeString) } }
之后我创建一个Delegate方法,public protocol PlayerDelegate: class
如下所示:
public protocol PlayerDelegate: class { func playerReady(player: Player) func playerPlaybackStateDidChange(player: Player) func playerBufferingStateDidChange(player: Player) func playerPlaybackWillStartFromBeginning(player: Player) func playerPlaybackDidEnd(player: Player) func playerPlaybackstimer(NSString: String) }
现在进入你的ViewController.swift
班级并添加以下功能:
func playerPlaybackstimer(NSString: String) { print("currunt time \(NSString)") }
现在运行您的项目并享受.