Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AVPlayer too long and with delay to readyToPlay and play server music in swift

Tags:

I tried to buffer and immediately play remote url audio with swift language.

but problem is with long time to readyToPlay case and play.

for example a sound url takes about 12 to 15 second to run.

this is my code :

var asset: AVAsset! var player: AVPlayer! var playerItem: AVPlayerItem!  private var playerItemContext = 0  let requiredAssetKeys = [ "playable","hasProtectedContent"] 

let url = URL(string: "http://sound_link.mp3")! asset = AVAsset(url: url)  playerItem = AVPlayerItem(asset: asset,                               automaticallyLoadedAssetKeys: requiredAssetKeys) playerItem.addObserver(self,                        forKeyPath: #keyPath(AVPlayerItem.status),                        options: [.old, .new],                        context: &playerItemContext)  player = AVPlayer(playerItem: playerItem) 

that according to this (ExploringAVFoundation) documentation've done that

and for handle that player is ready to player to play i use observeValue func :

override func observeValue(forKeyPath keyPath: String?,of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {     guard context == &playerItemContext else {         super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)         return     }      if keyPath == #keyPath(AVPlayerItem.status) {         let status: AVPlayerItemStatus         if let statusNumber = change?[.newKey] as? NSNumber {             status = AVPlayerItemStatus(rawValue: statusNumber.intValue)!         } else {             status = .unknown         }         // Switch over status value         switch status {         case .readyToPlay:             print("readyToPlay \(status.rawValue)")             player.play() // here play remote sound         case .failed:             print("readyToPlay \(status.rawValue)")         case .unknown:             print("failed \(status.rawValue)")         }      } } 

and this is returned log :

2017-02-08 13:44:00.626036 [15144:3747850] [aqme] 255: AQDefaultDevice (1): skipping input stream 0 0 0x0 readyToPlay 1 2017-02-08 13:44:02.631182 [15144:3747850] [aqme] 255: AQDefaultDevice (173): skipping input stream 0 0 0x0 

in above log , take 4 sec to appear readyToPlay 1 then take 10 sec to play sound

sever speed is good and i tried to play server sound in Android and max time to buffer and play sound is about 3 sec.(in Android application) but in IOS buffering and play sound totally , totally take about 15 sec!

Thanks for your attention

like image 656
Saeid Avatar asked Feb 08 '17 10:02

Saeid


2 Answers

Try to use this:

player.automaticallyWaitsToMinimizeStalling = false 
like image 83
Vladyslav Zavalykhatko Avatar answered Sep 19 '22 11:09

Vladyslav Zavalykhatko


Try to instantiate your avPlayerItem with URL and then fetch other assets in global thread , I think the problems happens because avPlayer is trying to fetch assets in main UI thread I had the same problem when I was trying to read subtitle options from avAssets it took 5-6 seconds more to load the movie in my player.

This is how I solved my problem (in Swift 2), I hope it helps:

            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {             let avMediaSelectionGroup : AVMediaSelectionGroup? = self.container.player.currentItem?.asset.mediaSelectionGroupForMediaCharacteristic(AVMediaCharacteristicLegible)             dispatch_async(dispatch_get_main_queue(), {                  if  (avMediaSelectionGroup != nil && (avMediaSelectionGroup!.options.count != 0) && avMediaSelectionGroup?.options[0].valueForKey("title") != nil)                 {                   // show hide subtitle button                 }              })          }) 
like image 29
MohyG Avatar answered Sep 17 '22 11:09

MohyG