1

TVos のアプリでビデオを再生しています。AVPlayerViewController を使用してビデオを再生しています。しかし、Apple TV リモコンの [メニュー] ボタンを押すと、元のビュー コントローラーに戻りますが、ビデオは引き続き再生され、8 秒または 10 秒後に割り当てが解除されます。これは本当に悪いバグで、私は数日間これに固執しています。どんな助けでも大歓迎です。

ビューコントローラーのコードは次のとおりです。

import Foundation
import UIKit
import AVKit


class ViewController : UIViewController {


    var avplayerVC : AVPlayerViewController?
    var recentlyWatchedTimer : NSTimer?
    var lessonToWatch : Lesson?


    override func viewDidLoad() {
        super.viewDidLoad()


        if let urlVideo = lessonToWatch?.lessonurl {

            let activityIndicator = UIActivityIndicatorView(frame: CGRectMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0, 30.0, 30.0))
            let asset : AVURLAsset = AVURLAsset(URL: NSURL.init(string: urlVideo)!, options: nil)
            let keys = ["playable"];
            avplayerVC = AVPlayerViewController()

            weak var weakSelf = self

            asset.loadValuesAsynchronouslyForKeys(keys) { () -> Void in
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    weakSelf!.avplayerVC?.player =  AVPlayer(playerItem: AVPlayerItem(asset: asset))
                    weakSelf!.avplayerVC?.player?.seekToTime(kCMTimeZero)


                    print("Status 1: " +  "\(self.avplayerVC?.player?.status.rawValue)")
                    print(self.view?.frame)
                    // doesn't work

                    weakSelf!.avplayerVC?.view.frame =  self.view.frame
                    activityIndicator.stopAnimating()
                    activityIndicator.removeFromSuperview()
                    weakSelf!.view.addSubview((self.avplayerVC?.view!)!)
                    weakSelf!.avplayerVC?.player?.play()
                    weakSelf!.recentlyWatchedTimer = NSTimer.scheduledTimerWithTimeInterval(20.0, target: self, selector: "addToRecentlyWatched" , userInfo: nil, repeats: false)
                                    })
            }

            print("In LessonPlayViewController View Did Load")
            self.view.addSubview(activityIndicator)
            activityIndicator.startAnimating()
        }

    }


    func addToRecentlyWatched() {
        if let lesson = lessonToWatch {
            DataManager.sharedInstance.addRecentlyWatch(lesson)
        }
        recentlyWatchedTimer?.invalidate()
    }

    deinit {
        print("deinit")
        avplayerVC?.view.removeFromSuperview()
        avplayerVC?.player = nil
        avplayerVC = nil
    }

    // MARK : AVPlayerViewControllerDelegate


}
4

2 に答える 2

0

selfへのすべての参照がweakクロージャ内にあることを確認するには、キャプチャ リストを使用する必要があります。次に、 a を使用しguardて、クロージャー内で参照がまだ有効であることを確認します。

import Foundation
import UIKit
import AVKit
import AVFoundation


class ViewController : UIViewController {


    var avplayerVC : AVPlayerViewController?
    var recentlyWatchedTimer : NSTimer?
    var lessonToWatch : Lesson?


    override func viewDidLoad() {
        super.viewDidLoad()


        if let urlVideo = lessonToWatch?.lessonurl {

            let activityIndicator = UIActivityIndicatorView(frame: CGRectMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0, 30.0, 30.0))
            let asset : AVURLAsset = AVURLAsset(URL: NSURL.init(string: urlVideo)!, options: nil)
            let keys = ["playable"];
            avplayerVC = AVPlayerViewController()

            asset.loadValuesAsynchronouslyForKeys(keys) { [weak self] in
                dispatch_async(dispatch_get_main_queue()) { [weak self] in
                    guard let vc = self, playerVC = vc.avplayerVC else {
                        return
                    }

                    playerVC.player = AVPlayer(playerItem: AVPlayerItem(asset: asset))
                    playerVC.player?.seekToTime(kCMTimeZero)


                    print("Status 1: " +  "\(playerVC.player?.status.rawValue)")
                    print(vc.view?.frame)
                    // doesn't work

                    playerVC.view.frame = vc.view.frame
                    activityIndicator.stopAnimating()
                    activityIndicator.removeFromSuperview()
                    vc.view.addSubview(playerVC.view)
                    playerVC.player?.play()
                    vc.recentlyWatchedTimer = NSTimer.scheduledTimerWithTimeInterval(20.0, target: vc, selector: "addToRecentlyWatched" , userInfo: nil, repeats: false)
                }
            }

            print("In LessonPlayViewController View Did Load")
            self.view.addSubview(activityIndicator)
            activityIndicator.startAnimating()
        }

    }


    func addToRecentlyWatched() {
        if let lesson = lessonToWatch {
            DataManager.sharedInstance.addRecentlyWatch(lesson)
        }
        recentlyWatchedTimer?.invalidate()
    }

    deinit {
        print("deinit")
        avplayerVC?.view.removeFromSuperview()
        avplayerVC?.player = nil
        avplayerVC = nil
    }

    // MARK : AVPlayerViewControllerDelegate


}

キャプチャ リストの詳細: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID57

編集

また、View Controller を離れるときにビデオの再生を明示的に停止する必要があり、割り当て解除の一環として再生を停止することをプレーヤーに依存しないように注意してください。つまり、viewDidDisappearまたは同様です。

于 2015-11-26T21:38:32.120 に答える
0

非同期コールバック ブロック内のすべての場所で weakSelf を使用したいのですが、一度に self.view.frame を出力しています。

于 2015-11-26T21:28:50.280 に答える