जवाबों:
किसी आइटम के अंत तक पहुंचने के लिए अधिसूचना प्राप्त करना ( Apple के माध्यम से ):
[[NSNotificationCenter defaultCenter]
addObserver:<self>
selector:@selector(<#The selector name#>)
name:AVPlayerItemDidPlayToEndTimeNotification
object:<#A player item#>];
और खेलने के लिए ट्रैक कर सकते हैं:
"एवीप्लेयर ऑब्जेक्ट में प्लेहेड की स्थिति में परिवर्तन को ट्रैक करें" का उपयोग करके addPeriodicTimeObserverForInterval: कतार: usingBlock: या addBoundaryTimeObserverForTimesTimes 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];
}];
-replaceCurrentItemWithPlayerItem:
, और इसे ठीक से हैंडल नहीं करने पर सूचनाएँ समस्याएँ पैदा कर सकती हैं । मेरे लिए एक अधिक विश्वसनीय तरीका AVPlayer
केवीओ का उपयोग करके स्थिति को ट्रैक करना है । अधिक जानकारी के लिए नीचे दिए गए मेरे जवाब देखें: stackoverflow.com/a/34321993/3160561
AVPlayerItemFailedToPlayToEndTimeNotification
आप बता सकते हैं कि यह प्रयोग करके खेल रहा है:
AVPlayer *player = ...
if ((player.rate != 0) && (player.error == nil)) {
// player is playing
}
स्विफ्ट 3 एक्सटेंशन:
extension AVPlayer {
var isPlaying: Bool {
return rate != 0 && error == nil
}
}
- [AVPlayer setRate:-1.0]
), क्योंकि -1.0
0. से कम है
IOS10 में, अब इसके लिए एक अंतर्निहित संपत्ति है: timeControlStatus
उदाहरण के लिए, यह फ़ंक्शन खेलता है या यह स्थिति के आधार पर एवीलेयर को रोक देता है और प्ले / पॉज़ बटन को उचित रूप से अपडेट करता है।
@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)
}
}
आपके दूसरे प्रश्न के रूप में, यह जानने के लिए कि क्या एवरप्ले अंत तक पहुँच गया है, सबसे आसान काम एक अधिसूचना स्थापित करना होगा।
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 का उपयोग करते हैं, तो नियंत्रण में निर्मित होते हैं।
rate
यह जांचने का तरीका नहीं है कि कोई वीडियो चल रहा है (यह रुक सकता है)। के प्रलेखन से rate
:
प्लेबैक की वांछित दर इंगित करता है; 0.0 का अर्थ है "रुका हुआ", 1.0 वर्तमान वस्तु की प्राकृतिक दर से खेलने की इच्छा को दर्शाता है।
कुंजी शब्द "खेलने के लिए इच्छा" - की दर 1.0
मतलब यह नहीं है वीडियो खेल रहा है।
IOS 10.0 के बाद से समाधान का उपयोग करना है AVPlayerTimeControlStatus
जिसे AVPlayer
timeControlStatus
संपत्ति पर देखा जा सकता है ।
IOS 10.0 (9.0, 8.0 आदि) से पहले समाधान अपने स्वयं के समाधान को रोल करना है। दर का 0.0
मतलब है कि वीडियो रोक दिया गया है। जब rate != 0.0
इसका मतलब है कि वीडियो या तो खेल रहा है या ठप है।
आप खिलाड़ी के समय को देखकर अंतर का पता लगा सकते हैं: func addPeriodicTimeObserver(forInterval interval: CMTime, queue: DispatchQueue?, using block: @escaping (CMTime) -> Void) -> Any
ब्लॉक वर्तमान खिलाड़ी समय को वापस लौटाता है CMTime
, इसलिए lastTime
(उस समय जो ब्लॉक से अंतिम बार प्राप्त हुआ था) की तुलना और currentTime
(ब्लॉक ने अभी रिपोर्ट की है) यह बताएगा कि खिलाड़ी खेल रहा है या नहीं। उदाहरण के लिए, यदि lastTime == currentTime
और rate != 0.0
फिर, खिलाड़ी रुक गया है।
जैसा कि दूसरों ने नोट किया है, यह पता लगाना कि क्या प्लेबैक समाप्त हो गया है द्वारा इंगित किया गया है AVPlayerItemDidPlayToEndTimeNotification
।
एक और अधिक विश्वसनीय विकल्प यह NSNotification
है कि अपने आप को खिलाड़ी की rate
संपत्ति में पर्यवेक्षक के रूप में जोड़ें ।
[self.player addObserver:self
forKeyPath:@"rate"
options:NSKeyValueObservingOptionNew
context:NULL];
फिर देखें कि क्या मनाया गया दर के लिए नया मान शून्य है, जिसका अर्थ है कि प्लेबैक किसी कारण से बंद हो गया है, जैसे अंत तक पहुंचना या खाली बफर के कारण रुकना।
- (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
मामला है, पता है कि वास्तव में बंद करने के लिए प्लेबैक का कारण बना, तो आप निम्नलिखित जांच कर सकते हैं:
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;
AVPlayerItemFailedToPlayToEndTimeNotification
। यदि यह त्रुटि होती है, तो अंतिम समय तक कभी नहीं पहुंचेगा। या maz के उत्तर को पढ़ते हुए, अपने कोड को चेक के लिए जोड़ें player.error != nil
, जिसमें त्रुटि के कारण प्लेबैक "समाप्त" हो गया है।
AVPlayerItemDidPlayToEndTimeNotification
?
के लिए स्विफ्ट :
AVPlayer :
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's) उत्तर के समान दिखाई दे सकता है, लेकिन Swift में 'player.error' मुझे एक संकलक त्रुटि दे रहा था, इसलिए आपको Swift में 'player.error == nil' का उपयोग करके त्रुटि की जांच करनी होगी। (क्योंकि त्रुटि संपत्ति 'बूल' प्रकार का नहीं है)
AVAudioPlayer:
if let theAudioPlayer = appDelegate.audioPlayer {
if (theAudioPlayer.playing) {
// playing
}
}
AVQueuePlayer:
if let theAudioQueuePlayer = appDelegate.audioPlayerQueue {
if (theAudioQueuePlayer.rate != 0 && theAudioQueuePlayer.error == nil) {
// playing
}
}
player.rate = -1.0
), क्योंकि -1.0 0. से कम है
Maz द्वारा जवाब के आधार पर स्विफ्ट विस्तार
extension AVPlayer {
var isPlaying: Bool {
return ((rate != 0) && (error == nil))
}
}
Maxkonovalov के उत्तर का स्विफ्ट संस्करण यह है:
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")
}
}
}
}
धन्यवाद मैक्सकोनोवालोव!
nil
! लेकिन मुझे यह जानना चाहिए कि जब दृश्य शुरू होता है (समाप्त नहीं होता है)। ऐसा करने का कोई तरीका?
उत्तर उद्देश्य सी है
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