                 return nil
             }
             self.f = {
-                let vc = AVPlayerViewController()
-                vc.player = AVPlayer(url: url)
-                DispatchQueue.main.async {
-                    Kitchen.navigationController.pushViewController(vc, animated: true)
-                }
+                startPlayback(url: url)
             }
         default:
             return nil

import UIKit
import TVMLKitchen

struct Action {
    private var f: (()->())?
    func run() {
        f?()
    }
    init?(string: String) {
        let ss = string.components(separatedBy: ",")
        guard ss.count == 2 else {

    }
}

func startPlayback(url: URL) {
    DispatchQueue.global().async {

        let vc = AVPlayerViewController()

        /*
        This is extremely expensive if url points at monolithic mp4.
        So we're doing this in background.
        You should do like this if you need to handle error case.
        ```
        let asset = AVURLAsset(url: url)
        asset.loadValuesAsynchronously(forKeys: [playableKey, statusKey]) {
        // start playback
        }
        ```
        */
        vc.player = AVPlayer(url: url)
        DispatchQueue.main.async {
            // Navigation should be in main thread.
            Kitchen.navigationController.pushViewController(vc, animated: true)
        }
    }
}

private func xmlString() -> String {
    guard let url = Bundle.main.url(forResource: "sample", withExtension: "xml"),
        let data = try? Data(contentsOf: url) else {
        fatalError()
