AVP Player의 재생 상태 확인
그들이 그들을 죽었는지 아닌지 알 수 있는 방법이 있습니까?AVPlayer
재생이 지연되었거나 끝에 도달했습니까?
다음을 사용하여 재생 중임을 알 수 있습니다.
AVPlayer *player = ...
if ((player.rate != 0) && (player.error == nil)) {
// player is playing
}
스위프트 3 확장:
extension AVPlayer {
var isPlaying: Bool {
return rate != 0 && error == nil
}
}
iOS10에는 현재 이를 위한 내장 속성이 있습니다. timeControlStatus
예를 들어 이 기능은 상태에 따라 vPlayer를 재생하거나 일시 중지하고 재생/일시 중지 버튼을 적절하게 업데이트합니다.
@IBAction func btnPlayPauseTap(_ sender: Any) {
if aPlayer.timeControlStatus == .playing {
aPlayer.pause()
btnPlay.setImage(UIImage(named: "control-play"), for: .normal)
} else if aPlayer.timeControlStatus == .paused {
aPlayer.play()
btnPlay.setImage(UIImage(named: "control-pause"), for: .normal)
}
}
두 번째 질문과 관련하여, vPlayer가 끝에 도달했는지 확인하려면 알림을 설정하는 것이 가장 쉽습니다.
NotificationCenter.default.addObserver(self, selector: #selector(self.didPlayToEnd), name: .AVPlayerItemDidPlayToEndTime, object: nil)
예를 들어, 비디오가 끝날 때 비디오의 시작 부분으로 되감고 일시 중지 단추를 재생으로 재설정할 수 있습니다.
@objc func didPlayToEnd() {
aPlayer.seek(to: CMTimeMakeWithSeconds(0, 1))
btnPlay.setImage(UIImage(named: "control-play"), for: .normal)
}
이러한 예제는 사용자가 직접 컨트롤을 만들 때 유용하지만 AVPlayerViewController를 사용하는 경우에는 컨트롤이 기본으로 제공됩니다.
Apple을 통해 항목의 끝에 도달하는 알림을 받는 방법
[[NSNotificationCenter defaultCenter]
addObserver:<self>
selector:@selector(<#The selector name#>)
name:AVPlayerItemDidPlayToEndTimeNotification
object:<#A player item#>];
재생을 추적하려면 다음을 수행할 수 있습니다.
addPeriodicTimeObserverForInterval:queue:usingBlock: 또는 addBoundaryTimeObserverForTimes:queue:usingBlock:를 사용하여 "AVPlayer 객체에서 플레이헤드 위치 변경 추적".
예는 Apple 제품입니다.
// Assume a property: @property (retain) id playerObserver;
Float64 durationSeconds = CMTimeGetSeconds([<#An asset#> duration]);
CMTime firstThird = CMTimeMakeWithSeconds(durationSeconds/3.0, 1);
CMTime secondThird = CMTimeMakeWithSeconds(durationSeconds*2.0/3.0, 1);
NSArray *times = [NSArray arrayWithObjects:[NSValue valueWithCMTime:firstThird], [NSValue valueWithCMTime:secondThird], nil];
self.playerObserver = [<#A player#> addBoundaryTimeObserverForTimes:times queue:NULL usingBlock:^{
// Passing NULL for the queue specifies the main queue.
NSString *timeDescription = (NSString *)CMTimeCopyDescription(NULL, [self.player currentTime]);
NSLog(@"Passed a boundary at %@", timeDescription);
[timeDescription release];
}];
rate
비디오가 재생 중인지 확인하는 방법이 아닙니다(정지될 수 있음).의 문서화에서rate
:
원하는 재생 속도를 나타냅니다. 0.0은 "일시 중지됨"을 의미하고, 1.0은 현재 항목의 자연스러운 속도로 재생하고 싶은 욕구를 나타냅니다.
키워드 "재생 욕구" - 속도가 비디오가 재생 중임을 의미하지는 않습니다.
이후의 은 iOS 10.0을 사용하는 입니다.AVPlayerTimeControlStatus
은 서관찰수있에서 관찰할 수 .AVPlayer
timeControlStatus
소유물.
iOS 10.0(9.0, 8.0 등) 이전의 솔루션은 자신만의 솔루션을 롤하는 것입니다.비율은 비디오가 일시 중지되었음을 의미합니다. 비디오가 재생 중이거나 정지되었음을 의미합니다.
통해 를 알 수 .func addPeriodicTimeObserver(forInterval interval: CMTime, queue: DispatchQueue?, using block: @escaping (CMTime) -> Void) -> Any
은 현재 을 록은현플시반환다니로 합니다.CMTime
그서비면자의 .lastTime
) 및 (블록에서 수신한 시간) 및currentTime
(블록이 방금 보고한 시간) 플레이어가 재생 중인지 또는 정지 상태인지 알 수 있습니다.를 들어, 만약에 들어만, 약를.lastTime == currentTime
그리고.rate != 0.0
그러면 플레이어가 정지합니다.
은 다른사지바와같이한, 끝여확부다것인다표니같시로 표시됩니다.AVPlayerItemDidPlayToEndTimeNotification
.
Swift의 경우:
AV Player:
let player = AVPlayer(URL: NSURL(string: "http://www.sample.com/movie.mov"))
if (player.rate != 0 && player.error == nil) {
println("playing")
}
업데이트:
player.rate > 0
상태가 로 변경됨player.rate != 0
왜냐하면 비디오가 반대로 재생되면 줄리안이 지적해준 덕분에 부정적일 수 있기 때문입니다.
참고: 위 (Maz) 답변과 동일하게 보일 수 있지만 Swift에서 '!player.error'는 컴파일러 오류를 제공하므로 Swift에서 'player.error == nil'을 사용하여 오류를 확인해야 합니다. (오류 속성이 'Boole' 유형이 아니기 때문에)
AV 오디오 플레이어:
if let theAudioPlayer = appDelegate.audioPlayer {
if (theAudioPlayer.playing) {
// playing
}
}
AVQuePlayer:
if let theAudioQueuePlayer = appDelegate.audioPlayerQueue {
if (theAudioQueuePlayer.rate != 0 && theAudioQueuePlayer.error == nil) {
// playing
}
}
보다 안정적인 대안NSNotification
플레이어의 관찰자로 자신을 추가하는 것입니다.rate
소유물.
[self.player addObserver:self
forKeyPath:@"rate"
options:NSKeyValueObservingOptionNew
context:NULL];
그런 다음 관찰된 속도에 대한 새 값이 0인지 확인합니다. 이는 끝에 도달하거나 버퍼가 비어 있어 재생이 중지된 경우와 같은 이유로 인해 중지되었음을 의미합니다.
- (void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary<NSString *,id> *)change
context:(void *)context {
if ([keyPath isEqualToString:@"rate"]) {
float rate = [change[NSKeyValueChangeNewKey] floatValue];
if (rate == 0.0) {
// Playback stopped
} else if (rate == 1.0) {
// Normal playback
} else if (rate == -1.0) {
// Reverse playback
}
}
}
위해서rate == 0.0
case, 정확히 무엇이 재생을 중지하게 했는지 알기 위해 다음과 같은 검사를 수행할 수 있습니다.
if (self.player.error != nil) {
// Playback failed
}
if (CMTimeGetSeconds(self.player.currentTime) >=
CMTimeGetSeconds(self.player.currentItem.duration)) {
// Playback reached end
} else if (!self.player.currentItem.playbackLikelyToKeepUp) {
// Not ready to play, wait until enough data is loaded
}
마지막에 도달하면 플레이어를 중지시키는 것을 잊지 마십시오.
self.player.actionAtItemEnd = AVPlayerActionAtItemEndPause;
현재 swift 5에서는 플레이어가 재생 중인지 일시 중지되었는지 확인하는 가장 쉬운 방법은 .timeControlStatus 변수를 확인하는 것입니다.
player.timeControlStatus == .paused
player.timeControlStatus == .playing
maz의 답변을 기반으로 한 신속한 확장
extension AVPlayer {
var isPlaying: Bool {
return ((rate != 0) && (error == nil))
}
}
Maxkonov의 Swift 버전의 답변은 다음과 같습니다.
player.addObserver(self, forKeyPath: "rate", options: NSKeyValueObservingOptions.New, context: nil)
그리고.
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
if keyPath == "rate" {
if let rate = change?[NSKeyValueChangeNewKey] as? Float {
if rate == 0.0 {
print("playback stopped")
}
if rate == 1.0 {
print("normal playback")
}
if rate == -1.0 {
print("reverse playback")
}
}
}
}
감사합니다 maxkonovalov!
목표 C의 답변
if (player.timeControlStatus == AVPlayerTimeControlStatusPlaying) {
//player is playing
}
else if (player.timeControlStatus == AVPlayerTimeControlStatusPaused) {
//player is pause
}
else if (player.timeControlStatus == AVPlayerTimeControlStatusWaitingToPlayAtSpecifiedRate) {
//player is waiting to play
}
player.timeControlStatus == AVPlayer.TimeControlStatus.playing
플레이어가 다음과 같은 타이머로 재생 중인지 확인할 수 있습니다.
let playerObserver = self.player.addPeriodicTimeObserver(forInterval: CMTimeMakeWithSeconds(1, preferredTimescale: 1), queue: DispatchQueue.main, using: { [weak self] time in
if self?.player.timeControlStatus == .playing {
debugPrint("#player - info: isPlaying")
self?.playButton.isSelected = true
} else if self?.player.timeControlStatus == .paused {
debugPrint("#player - info: isPaused")
self?.playButton.isSelected = false
} else if self?.player.timeControlStatus == .waitingToPlayAtSpecifiedRate {
debugPrint("#player - info: isWaiting") //Buffering
}
})
언급URL : https://stackoverflow.com/questions/5655864/check-play-state-of-avplayer
'programing' 카테고리의 다른 글
Ruby에서 메서드를 매개 변수로 전달 (0) | 2023.06.02 |
---|---|
CLI를 사용하여 구성 요소를 삭제하는 가장 좋은 방법은 무엇입니까? (0) | 2023.06.02 |
Xcode - 다운로드할 수 있는 dSYM이 없습니다. (0) | 2023.06.02 |
루비에서 __FILE_은 무엇을 의미합니까? (0) | 2023.06.02 |
셸에서 사용하는 파일 아이콘 가져오기 (0) | 2023.06.02 |