2016-04-12 5 views
7

ich AVPlayerItem durch AVURLAsset, meinen Code zu erstellen gehen:AVPlayer steckte Video, aber Audio arbeitet

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) 
     }) 
    } 

hinzufügen AVPlayerLayer Anzeige Video in meiner Ansicht, meinen Code:

// MARK: - Objekt

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

    set { 
     playerLayer.player = newValue 
    } 
} 

var playerLayer: AVPlayerLayer { 
    return layer as! AVPlayerLayer 
} 

Wenn Video nach Beendigung des Ladens anzeigt

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

Anruf seekToTime Methode, das Spiel zu bestimmen:

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) 
      } 
     } 
    } 

Einige Bilder der stuck-Schnittstelle:

enter image description here

Im ersten Bild ist der Ton hörbar, aber die Schnittstelle steckt .

enter image description here

Im zweiten Bild, Videoarbeiten, aber ich bekomme keinen Ton.

Meine Frage:

Wenn ich die seekToTime Methode nach Abschluss nennen, manchmal das Video hat Klang, aber die Schnittstelle steckt, gelegentlich die Videoarbeiten. Ich versuchte, die CALayersetNeedsDisplay Methoden aufzurufen, um das AVPlayerLayer Bild zu aktualisieren, aber das half nicht. Ich weiß nicht mehr, was ich tun soll, ich wäre dankbar für jede Hilfe.

+1

Shannon; Ich bin mir nicht sicher, aber vielleicht geht Ihr AVURLAsset hier aus dem Rahmen; der AVPlayer ist ein bemerkenswert widerstandsfähiger Code; und wird dich eher hängen lassen als manchmal im Dunkeln. – user3069232

+0

Was Sie hätten tun sollen, ist ein wirklich einfaches Demo-Projekt erstellt, etwas mildes Asset hinzugefügt und das Problem dort dupliziert. Sie hätten dieses Projekt auf Dropbox usw. veröffentlichen können und dann um Hilfe gebeten, es zu debuggen. –

Antwort

2

Versuchen Sie diesen Ansatz, da ich das gleiche Problem angetroffen habe und es durch diesen freundlichen Ansatz zu lösen.

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

Der gleiche Code des Benutzers nferocious76 aber in Objective C

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

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