2016-04-12 11 views
7

vado per creare AVPlayerItem attraverso AVURLAsset, il mio codice:AVPlayer bloccato il video, ma audio funziona

let asset = AVURLAsset(URL: safeURL, options: [AVURLAssetPreferPreciseDurationAndTimingKey: true]) 
    asset.loadValuesAsynchronouslyForKeys([assetKeyPlayable, self.assetKeyTracks, self.assetKeyHasProtectedContent]) { 
     () -> Void in 
     dispatch_async(dispatch_get_main_queue(), { 
      () -> Void in 
      // Use the AVAsset playable property to detect whether the asset can be played 
      if !asset.playable { 
       let localizedDescription = "Item cannot be played,Item cannot be played description" 
       let localizedFailureReason = "The assets tracks were loaded, but could not be made playable,Item cannot be played failure reason" 
       let userInfo = [NSLocalizedDescriptionKey: localizedDescription, NSLocalizedFailureReasonErrorKey: localizedFailureReason] 
       let error = NSError(domain: "domain", code: 0, userInfo: userInfo) 
       self.videoPlayerDelegate?.videoPlayer?(self, playerItemStatusDidFail: error) 
       self.cleanPlayer() 
       return 
      } 
      // At this point we're ready to set up for playback of the asset. Stop observing 
      if let _ = self.player?.currentItem { 
       self.cleanPlayer() 
      } 
      if asset.URL.absoluteString != safeURL.absoluteString { 
       return 
      } 
      var error: NSError? 
      let status = asset.statusOfValueForKey(self.assetKeyTracks, error: &error) 
      var playerItem = AVPlayerItem(URL: safeURL) 
      if status == .Loaded { 
       playerItem = AVPlayerItem(asset: asset) 
      } else { 
       // You should deal with the error appropriately.If Loaded fails, create an AVPlayerItem directly from the URL 
       playerItem = AVPlayerItem(URL: safeURL) 
      } 
      self.player = self.playerWithPlayerItem(playerItem) 
      self.registerMonitoring() 
      self.registerNotification() 
      self.addTimeObserver() 
      completionBlock?(loadURLString: playerURL.absoluteString) 
     }) 
    } 

Aggiungi il video AVPlayerLayer visualizzazione a mio avviso, il mio codice:

// MARK: - Proprietà

var player: AVPlayer? { 
    get { 
     return playerLayer.player 
    } 

    set { 
     playerLayer.player = newValue 
    } 
} 

var playerLayer: AVPlayerLayer { 
    return layer as! AVPlayerLayer 
} 

Quando si visualizza il video dopo il completamento del carico

self.videoPlayer?.loadPlayer({ 
     [weak self](loadURLString) in 
     if let strongSelf = self { 
      strongSelf.player = strongSelf.videoPlayer?.player 
      strongSelf.startPlay() 
     } 
    }) 

chiamata seekToTime metodo per specificare il gioco:

self.player?.currentItem?.seekToTime(CMTimeMakeWithSeconds(time, Int32(NSEC_PER_SEC)), toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero) { 
     [weak self] finished in 
     if let weakSelf = self { 
      if weakSelf.isPlaying { 
       weakSelf.videoPlayerDelegate?.videoPlayerDidplayerItemSeekToTime?(weakSelf) 
      } 
     } 
    } 

Alcune immagini dell'interfaccia bloccato:

enter image description here

Nella prima foto il suono è udibile, ma l'interfaccia è bloccato .

enter image description here

Nella seconda foto, le opere video, ma ottengo alcun suono.

La mia domanda:

Quando chiamo il metodo seekToTime al termine, a volte il video ha un suono, ma l'interfaccia è bloccata, di tanto in tanto le opere video. Ho provato a chiamare i metodi CALayersetNeedsDisplay, per aggiornare l'immagine AVPlayerLayer, ma questo non ha aiutato. Non so più cosa fare, sarei grato per ogni aiuto.

+1

Shannon; Non sono sicuro, ma forse il tuo set AVURLA sta andando fuori ambito qui; l'AVPlayer è un pezzo di codice notevolmente resiliente; e ti lascerà a volte sospeso piuttosto che al buio. – user3069232

+0

Ciò che avresti dovuto fare è creare un progetto demo davvero semplice, aggiungere un po 'di asset blando e duplicare il problema. Avresti potuto postare quel progetto su Dropbox ecc. E poi chiedere aiuto per il debug. –

risposta

2

Prova questo approccio come ho riscontrato lo stesso problema e risolverlo con questo approccio gentile.

player.pause() 
player.currentItem?.seek(to: CMTime(), completionHandler: { (_) in 
    player.play() 
}) 
0

Lo stesso codice di nferocious76 utente, ma in Objective C

AVPlayerItem *p = [player currentItem]; 
[p seekToTime:p.currentTime completionHandler:^(BOOL finished){ 
    if (finished){ 

     [self->player play]; 
    } 
}];