2016-06-29 2 views
0

Ich arbeite an TV-App mit Swift. Ich benutze AVPlayerViewController, um Video nach Apple Demo-App (UIKit Catalog (tvOS): Erstellen und Anpassen von UIKit Controls) zu spielen. Alles funktioniert gut, aber App Hintergrund in den Vordergrund während des Videos spielen dann vorwärts und rückwärts funktioniert nicht und das gleiche Problem erzeugt, wenn Benutzer in den Ruhezustand wechseln kann. Dieses Problem wird auch in der Apple Demo-App generiert.Vorwärts und rückwärts funktioniert nicht, wenn App Hintergrund in den Vordergrund während der Video-Wiedergabe in tvOS eingeben

Ich verstehe nicht, warum dieses Problem erzeugt. Bitte schlagen Sie mir vor, wie Sie es lösen können.

import UIKit 
    import Foundation 
    import AVKit 

    class ViewController: UIViewController ,AVPlayerViewControllerDelegate{ 
     let playerController = AVPlayerViewController() 
     var playerObj:AVPlayer! 
     var asset:AVAsset! 
     var playerItem:AVPlayerItem! 
     override func viewDidLoad() { 
      super.viewDidLoad() 
      // Do any additional setup after loading the view, typically from a nib. 
     self.playVideo("http://p.events-delivery.apple.com.edgesuite.net/1509pijnedfvopihbefvpijlkjb/m3u8/hls_vod_mvp.m3u8") 
     } 
    override func viewWillAppear(animated: Bool) { 
     playerController.delegate = self 
    } 
     //MARK:- Play Video Method. 
     func playVideo(videoURL:String) { 
      print("video URL========\(videoURL)") 

      self.asset = AVAsset(URL: NSURL(string: videoURL)!) as AVAsset 
      self.playerItem = AVPlayerItem(asset: self.asset) 
      self.playerObj = AVPlayer(playerItem: self.playerItem) 
      self.playerController.player = self.playerObj 
      playerController.view.frame = CGRectMake(0.0, 0.0, UIScreen.mainScreen().bounds.width, UIScreen.mainScreen().bounds.height) 
      playerController.delegate = self 
      self.view.addSubview(playerController.view) 
      self.playerController.showsPlaybackControls = true 
      self.playerItem.addObserver(self, forKeyPath: "status", options: NSKeyValueObservingOptions.New, context: nil) 
      self.playerController.player!.play() 
      //self.playerController.player!.play() 


     } 
     override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>){ 

      if object as? NSObject == playerItem && (keyPath! as NSString).isEqualToString("status") { 

       if (playerItem?.status == AVPlayerItemStatus.ReadyToPlay) { 
         print("Player Ready to play") 
       } 
       if (playerItem?.status == AVPlayerItemStatus.Failed) || (playerItem?.status == AVPlayerItemStatus.Unknown) { 

         print("Player getting play error") 
       } 
      } 
     } 


     override func didReceiveMemoryWarning() { 
      super.didReceiveMemoryWarning() 
      // Dispose of any resources that can be recreated. 
     } 


    } 
+0

Die Menge an Code-Kontext, die Sie gaben, ist nicht genug, um wirklich eine brauchbare Lösung für Sie entweder zu finden, weil ich den vollständigen Kontext nicht bestimmen kann. Aus meiner Erfahrung mit AVPlayer empfehle ich, dies als Klassenvariable zu definieren, aber es scheint, dass Sie dies stattdessen als Methodenvariable definieren. Wenn dies der Fall ist, ist es wahrscheinlich, dass Ihre Funktion den AVPlayer nicht festhält, wenn die Methode beendet wird. Apple schlägt sogar vor, dass Sie eine Klassenvariable für AVPlayer erstellen, um die AVPlayer-Referenz für den Lebenszyklus Ihrer Anwendung beizubehalten. – user1171911

+0

Ich wurde mit Klassenvariablen versucht, aber das Problem ist dasselbe. – vipulk617

+0

Ich würde immer noch wagen zu sagen, dass Ihre Klasse den Delegaten für den Empfang von Forward- und Back-Nachrichten freigibt. Dies könnte bedeuten, dass Ihre Klasse nicht zugewiesen wird, wenn die Anwendung in den Hintergrund tritt. Um dies zu beheben, erstelle ich normalerweise eine Singleton-Klasse, um meine Audio-/Video-Wiedergabe zu verwalten, so dass ich garantieren kann, dass meine App für den gesamten Lebenszyklus der Anwendung stark auf meinem AVPlayer hält. – user1171911

Antwort

0

dies ausprobieren ... wahrscheinlich nicht die „beste“ Lösung, aber es zeigt, was ich rede den View-Controller-Lebenszyklus in Bezug auf.

Seitlicher Hinweis, ich würde vorschlagen, dass Sie immer super.viewWillAppear (animiert) innerhalb Ihrer überschriebenen Funktionen für den View-Controller aufrufen.

import UIKit 
import Foundation 
import AVKit 
import AVFoundation 

class ViewController: UIViewController ,AVPlayerViewControllerDelegate{ 
    let playerController = AVPlayerViewController() 
    var playerObj:AVPlayer = AVPlayer() 
    var asset:AVAsset! 
    var playerItem:AVPlayerItem! 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
    } 
override func viewWillAppear(animated: Bool) { 
    super.viewWillAppear(animated) // always call this 
    playerController.delegate = self 
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(setDelegateOnForground), name: "application_forgrounded", object: nil) 
} 

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) // always call this 
    // check the player rate if 0 means it's paused/not playing 

wenn playerObj.rate == 0 { playvideo ("http://p.events-delivery.apple.com.edgesuite.net/1509pijnedfvopihbefvpijlkjb/m3u8/hls_vod_mvp.m3u8") } } // MARK: - Video abspielen Methode. func playVideo (videoURL: String) { drucken ("video URL ======== (videoURL)") self.asset = AVAsset (URL: NSURL (string: videoURL)!) Als AVAsset self. playerItem = AVPlayerItem (Asset: self.asset) self.playerObj = AVPlayer (playerItem: self.playerItem) self.playerController.player = self.playerObj playerController.view.frame = CGRectMake (0.0, 0.0, UIScreen.mainScreen () .bounds.width, UIScreen.mainScreen() bounds.height) self.view.addSubview (playerController.view) self.playerController.showsPlaybackControls = true self.playerItem.addObserver (self, forKeyPath. "status", Optionen: NSKeyValueObservingOptions.New, Kontext: nil) self.playerC ontroller.player! .play() //self.playerController.player!.play()

} 

func setDelegateOnForground() { 
    playerController.delegate = self 
} 
override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>){ 

    if object as? NSObject == playerItem && (keyPath! as NSString).isEqualToString("status") { 

     if (playerItem?.status == AVPlayerItemStatus.ReadyToPlay) { 
      print("Player Ready to play") 
     } 
     if (playerItem?.status == AVPlayerItemStatus.Failed) || (playerItem?.status == AVPlayerItemStatus.Unknown) { 

      print("Player getting play error") 
     } 
    } 
} 


override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

}

in Ihrem AppDelegate.swift in

func applicationDidBecomeActive(application: UIApplication) { 
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 
    NSNotificationCenter.defaultCenter().postNotification(NSNotification(name: "application_forgrounded", object: nil)) 
} 

Diese Garantie wird den Stellen Sie Ihren Stellvertreter ein

+0

Dieser Code funktioniert nicht. Wenn App einen Hintergrund in den Vordergrund einträgt, wird viewWillAppear nicht aufgerufen. – vipulk617

+0

bearbeitet meine Antwort tut mir leid, dass. – user1171911

+0

so nach der Veröffentlichung der richtigen Version, es funktioniert für mich. Ich kann mit der Überspringfunktion im Video hin- und herspringen – user1171911

Verwandte Themen