ios - Best way to prevent AVPlayer playing more than one track at a time -
i'm using avplayer play streaming audio , prevent playing more 1 audio track @ time. what's best way this? approach entirely programmatic -- don't use storyboard. when url sent viewcontroller (vc, delegate) sets new instance of player -- , think problem, i'm not sure. thanks.
//this routine returns url control vc (delegate) func selectedaudio(_ audiourl:string?) { if let urlstring = audiourl { setupplayer(urlstring) } } //single button toggles between play/pause func playorpausetouched() { if isplaying { pauseplayer() } else { playplayer() } } func playplayer() { if player == nil || selectedtrackname != currenttracklabel.text{ if let urlstring = selectedaudiourl { setupplayer(urlstring) currenttracklabel.text = "playing: \(selectedtrackname ?? "")" } } player?.play() isplaying = true playpausebutton.setimage(uiimage(named: "pause"), for: .normal) activityindicatorview.startanimating() } func pauseplayer() { player?.pause() isplaying = false playpausebutton.setimage(uiimage(named: "play"), for: .normal) } func setupplayer(_ urlstring:string) { if let url = url(string:urlstring) { player = avplayer(url: url) let playerlayer = avplayerlayer(player: player) player?.addobserver(self, forkeypath: "currentitem.loadedtimeranges", options: .new, context: nil) let interval = cmtime(value: 1, timescale: 5) //gives smooth thumb movement w/short clips player?.addperiodictimeobserver(forinterval: interval, queue: dispatchqueue.main, using: { (progresstime) in let seconds = cmtimegetseconds(progresstime) let secondsstring = string(format: "%02d", int(seconds.truncatingremainder(dividingby: 60))) let minutesstring = string(format: "%02d", int(seconds / 60)) self.currenttimelabel.text = "\(minutesstring):\(secondsstring)" if let duration = self.player?.currentitem?.duration { let durationseconds = cmtimegetseconds(duration) self.audioslider.value = float(seconds / durationseconds) } }) } }
my opinion use kvo
notify current state of avplayeritem
.
means state
identify current item playing, pushed, buffering or finish play.
so should take 1 flag
handle current item state
.
ex.
- set flag true when item playing
- set flag false when item finish play.
- when tap on button play item check flag
if flag == false
start playing item otherwise not.
second way:
use notificationcenter
below
notificationcenter.default.addobserver(self, selector: selector(("playerdidfinishplaying:")), name: nsnotification.name.avplayeritemdidplaytoendtime, object: player.currentitem)
and below automatically call when item finish playing
func playerdidfinishplaying(note: nsnotification) { print("item finished playing ") // set flag here }
and managed flag same.
Comments
Post a Comment