এভিপ্লেয়ারের প্লে স্টেট পরীক্ষা করুন


106

কোনও AVPlayerপ্লেব্যাক থেমে গেছে বা শেষে পৌঁছেছে কি না জানার কোনও উপায় আছে ?

উত্তর:


57

কোনও আইটেমের শেষে পৌঁছানোর জন্য বিজ্ঞপ্তি পেতে ( অ্যাপলের মাধ্যমে ):

[[NSNotificationCenter defaultCenter] 
      addObserver:<self>
      selector:@selector(<#The selector name#>)
      name:AVPlayerItemDidPlayToEndTimeNotification 
      object:<#A player item#>];

এবং খেলতে ট্র্যাক করতে আপনি এটি করতে পারেন:

"একটি এভিপ্লেয়ার অবজেক্টে প্লেহেডের অবস্থানে পরিবর্তনগুলি ট্র্যাক করুন" অ্যাডপরিওডিকটাইমসাইবারসভারফোর্ডইন্টারভাল : ক্যু: ইউজব্লক: অথবা অ্যাডবাউন্ডারিটাইমঅবসভারওয়ারফর্মটাইমস: সারি: ব্যবহারব্লক:

অ্যাপল থেকে উদাহরণ:

// 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];
}];

খেলার খেলার স্থিতি পরীক্ষা করতে আপনি বুলিয়ান পতাকাটি ছুঁড়ে ফেলতে পারেন।
moonman239

আপনি যদি প্লেয়ারের আইটেমটি পরিবর্তন করেন তবে বিজ্ঞপ্তিগুলি সমস্যার কারণ হতে পারে, উদাহরণস্বরূপ, সহ -replaceCurrentItemWithPlayerItem:এবং এটি সঠিকভাবে পরিচালনা করেন না। আমার জন্য আরও নির্ভরযোগ্য উপায় হল AVPlayerকেভিও ব্যবহার করে স্থিতি ট্র্যাক করা । : আরও বিস্তারিত জানার জন্য নিচে আমার উত্তর দেখুন stackoverflow.com/a/34321993/3160561
maxkonovalov

2
ত্রুটির বিজ্ঞপ্তিও দরকার? AVPlayerItemFailedToPlayToEndTimeNotification
টুলমেকারস্টেভ

332

আপনি এটি ব্যবহার করে এটি খেলতে বলতে পারেন:

AVPlayer *player = ...
if ((player.rate != 0) && (player.error == nil)) {
    // player is playing
}

সুইফট 3 এক্সটেনশন:

extension AVPlayer {
    var isPlaying: Bool {
        return rate != 0 && error == nil
    }
}

29
অগত্যা, এটি প্লেয়ার ফাইলে কোনও ত্রুটির কারণে স্টলগুলি এমন পরিস্থিতিগুলি পরিচালনা করে না। কিছু কঠিন উপায় খুঁজে পেয়েছি ...
ডার্মোট

7
ডেরমোট যেমন বলেছিলেন, আপনি যদি বিমান মোডে থাকাকালীন কিছু খেলতে চেষ্টা করেন, তখনও AVPlayer রেটটি সেট করা থাকে 1.0, যেহেতু এটি খেলার ইচ্ছাটি বোঝায়।
ফাই

4
এভিপ্লেয়ারের একটি ত্রুটিযুক্ত সম্পত্তি রয়েছে, কেবল এটি পরীক্ষা করে দেখুন যে এটি শূন্য নয় পাশাপাশি চেকটিও হার 0 নয়
জেমস ক্যাম্পবেল

23
নোট করুন যে উত্তরটি ডার্মোট পরিস্থিতি রোধ করতে আপডেট করা হয়েছে। সুতরাং এই এক আসলে কাজ করে।
jomafer

2
ভিডিও ফুটেজ বিপরীতে ( - [AVPlayer setRate:-1.0]) খেললে কাজ করা হবে না , কারণ -1.00 এর চেয়ে কম
জুলিয়ান এফ ওয়েইনার্ট

49

আইওএস 10-তে, এর জন্য এখন একটি বিল্ট ইন প্রোপার্টি রয়েছে: টাইমকন্ট্রোলস্ট্যাটাস

উদাহরণস্বরূপ, এই ফাংশনটি এপ্লেয়ারের স্থিতির উপর নির্ভর করে প্লে করে বা বিরতি দেয় এবং প্লে / বিরতি বোতামটি যথাযথভাবে আপডেট করে।

@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 ব্যবহার করেন তবে নিয়ন্ত্রণগুলি অন্তর্নির্মিত হয়।


আইওএস 10+ এর জন্য ব্যবহার করা সহজ
টেকনারড

2
সুইট ৪.২
শন

21

rateহয় না একটি ভিডিও করা আছে কিনা চেক করতে উপায় বাজানো (এটা স্থগিত পারে)। এর ডকুমেন্টেশন থেকে rate:

প্লেব্যাকের পছন্দসই হার নির্দেশ করে; 0.0 এর অর্থ "বিরাম দেওয়া", 1.0 বর্তমান আইটেমটির প্রাকৃতিক হারে খেলার ইচ্ছাটি নির্দেশ করে।

মূল শব্দগুলি "খেলার ইচ্ছা" - একটি হারের 1.0অর্থ ভিডিওটি প্লে হচ্ছে না।

আইওএস 10.0 থেকে সমাধানটি হ'ল ব্যবহার করা AVPlayerTimeControlStatusযা AVPlayer timeControlStatusসম্পত্তিতে লক্ষ্য করা যায় ।

আইওএস 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


18

এর আরও নির্ভরযোগ্য বিকল্প 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। যদি এই ত্রুটিটি ঘটে থাকে তবে শেষের সময়টিতে পৌঁছাবে না। বা মাজ এর উত্তর পড়া, আপনার কোডে একটি পরীক্ষা করুন player.error != nilযা ক্ষেত্রে প্লেব্যাক ত্রুটির কারণে "শেষ" হয়েছে।
টুলমেকারস্টেভ

বিটিডাব্লু, আপনি এনএসএনটিফিকেশন ব্যবহার সম্পর্কে "নির্ভরযোগ্য" কি পেলেন AVPlayerItemDidPlayToEndTimeNotification?
টুলমেকারস্টেভ

টুলমেকস্টেভ, আপনার নোটের জন্য ধন্যবাদ, আমার উত্তরটিতে ত্রুটি যুক্ত করা হয়েছে। নির্ভরযোগ্য বিজ্ঞপ্তি না দেওয়ার জন্য - সংগ্রহের দৃশ্যে পুনরাবৃত্তি এবং পুনরায় ব্যবহারযোগ্য প্লেয়ারের দৃষ্টিভঙ্গি প্রয়োগ করার সময় আমি নিজেই এই বিষয়টি জুড়ে এসেছি এবং কেভিও বিষয়গুলিকে আরও স্পষ্ট করে তুলেছে, কারণ এটি একে অপরের সাথে হস্তক্ষেপ না করে বিভিন্ন খেলোয়াড়ের বিজ্ঞপ্তিগুলি ছাড়াই এটিকে আরও স্থানীয় রাখার অনুমতি দেয়।
ম্যাককোনোভালভ

17

জন্য সুইফট :

এভিপ্লেয়ার :

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কারণ ভিডিওটি যদি বিপরীতে খেলছে তবে তা জুলিয়ানকে উল্লেখ করার জন্য নেতিবাচক ধন্যবাদ হতে পারে ।
দ্রষ্টব্য : এটি উপরের (মাজারের) উত্তরের মতো দেখতে পারে তবে সুইফটে 'প্লেয়ার.অরর' আমাকে একটি সংকলক ত্রুটি দিচ্ছিল তাই আপনাকে সুইফটে 'প্লেয়ার.অরার == নীল' ব্যবহার করে ত্রুটিটি পরীক্ষা করতে হবে because কারণ ত্রুটির সম্পত্তি 'বুল' ধরণের নয়)

AVAudioPlayer:

if let theAudioPlayer =  appDelegate.audioPlayer {
   if (theAudioPlayer.playing) {
       // playing
   }
}

AVQueuePlayer:

if let theAudioQueuePlayer =  appDelegate.audioPlayerQueue {
   if (theAudioQueuePlayer.rate != 0 && theAudioQueuePlayer.error == nil) {
       // playing
   }
}

2
AVPlayer! = AVAudioPlayer
27:44

2
ক্যাভেটস: এই উত্তরের দু'বছর পূর্বে যে উত্তরটি দেখানো হয়েছিল তার উপরে উল্লিখিত সমস্তগুলি।
ড্যান রোজনস্টার্ক

1
@ ইয়ার আমি উপরের উত্তরটিও আপত্তিযুক্ত জানি তবে এটি দ্রুত এবং সুইফ্টের জন্য! এই স্ট্যাক ওভারফ্লো অ্যাপ্লিকেশন :)
অক্স

আমার উদ্বেগটি হ'ল আমি জানি না যে প্লেয়ার.অরর আসলে ঠিক কাজ করে না।
ড্যান রোজনস্টার্ক

1
ভিডিও ফুটেজ বিপরীতে ( player.rate = -1.0) খেললে কাজ করা হবে না , কারণ -1.0 0 এর চেয়ে কম হয়
জুলিয়ান এফ ওয়েইনার্ট

9

মাজের উত্তরের উপর ভিত্তি করে সুইফট এক্সটেনশন

extension AVPlayer {

    var isPlaying: Bool {
        return ((rate != 0) && (error == nil))
    }
}

6

ম্যাক্সকোনোলোভের উত্তরের সুইফ্ট সংস্করণটি হ'ল:

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! তবে ভিউ কখন শুরু হবে (শেষ হবে না) তা আমার জানতে হবে। কোন উপায় আছে যে?
সিজারে

3

বর্তমানে সুইফট 5 এর সাথে প্লেয়ারটি খেলছে বা বিরতি দেওয়া হয়েছে কিনা তা পরীক্ষা করার সবচেয়ে সহজ উপায়টি .টাইমকন্ট্রোলস্ট্যাটাস ভেরিয়েবলটি পরীক্ষা করা ।

player.timeControlStatus == .paused
player.timeControlStatus == .playing

1

উত্তর হ'ল উদ্দেশ্য সি

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
}

0
player.timeControlStatus == AVPlayer.TimeControlStatus.playing

1
এই প্রদত্ত উত্তরটি সঠিক হতে পারে, তবে এটি একটি ব্যাখ্যা থেকে উপকৃত হতে পারে । কোডের উত্তরগুলিকে "ভাল" উত্তর হিসাবে বিবেচনা করা হয় না। আমি কীভাবে একটি ভাল উত্তর লিখতে পারি তার জন্য এখানে কিছু গাইডলাইন রয়েছে ? পর্যালোচনা থেকে ।
MyNameIsCaleb
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.