【问题标题】:AVPlayerLayer slow instantiationAVPlayerLayer 慢实例化
【发布时间】:2016-06-29 09:58:25
【问题描述】:

注意:我接受 Xamarin.iOS、Objective-C 或 Swift 中的任何答案。如果您在阅读 Xamarin 代码方面需要帮助,我可以为您解决,但考虑到此处代码的“复杂性”应该没问题。

我怀疑我的AVPlayerLayer 会减慢我的进程。

我在我的控制器中嵌入了一个视频/音频播放器,使用 ViewDidLoad 中的以下代码:

    void SetupLayer()
    {
        _layer = AVPlayerLayer.FromPlayer(_player);
        _layer.Frame = PlayerViewContainer.Bounds;
        _layer.Player = _player;
        _layer.BackgroundColor = UIColor.Black.CGColor;
        _layer.VideoGravity = AVLayerVideoGravity.ResizeAspect;

        //This is a UIView
        PlayerViewContainer.Layer.InsertSublayer(_layer, 0);
    }

除此之外,在我自己的控制器(包含播放器)的构造函数中:

        public void SetUrls(string mediaUrl, string coverUrl = null)
        {
            CoverUrl = string.IsNullOrEmpty(coverUrl) ? string.Empty : coverUrl;
            MediaUrl = mediaUrl;

            AVUrlAsset asset = new AVUrlAsset(new NSUrl(MediaUrl));
            AVPlayerItem item = new AVPlayerItem(asset);

            _isVideo = item.Asset.Tracks.Length != 1;

            _player = new AVPlayer(item);
        }

这是在ViewDidLoad 和构造函数中调用的唯一相关代码。被移除的部分应该没有任何影响(设置文本、加载资产等等)。

现在我面临的问题是加载“大”(大,我的意思不是超过 4 小时的视频流。通常它们大约 4 分钟长。 ) 文件占用大量时间。最多 4 秒。在构造函数(SetUrls 函数)中介于 0.5-1.5 之间,在 ViewDidLoad 中介于 1.5-2.5 之间(SetupLayer 函数)。

我已经计时了,并且删除这些方法大大减少了延迟到一些不错的东西(但我显然没有图像或不好的结果)。

我使用以下代码与原生播放器进行了比较:

            _item = AVPlayerItem.FromUrl(url);
            _player = new AVPlayer(_item);

            _controller = new AVPlayerViewController();
            _controller.Player = _player;

            this.PresentViewController(_controller, true, _player.Play);

它会立即加载。并不是说 4 秒的加载更均匀,而是总共用时不到 4 秒。

考虑到它可能在动画期间加载,并且在显示播放器时屏幕仍然是黑色并且没有播放任何内容,我会说原生控制器在大约 1-2 秒内完成了这项工作(而其中一半是可能在动画期间)。

在动画/显示任何东西之前,我的会做所有事情。唯一的好处是视频可以尽快播放,没有黑屏。缺点是控制器的加载时间很长。

注意:在加载期间,我的 UI 完全被阻止。这让我相信它发生在 UI 线程上,也许它不应该发生。

我的问题是:

  • 我的瓶颈在哪里?我显然做错了什么。
  • 我应该做些什么不同的事情?也许是我在自己的控制器中加载播放器的方式?
  • 如何异步加载这些组件以避免阻塞 UI 线程?是否足以减少加载时间?或者简单地说,它甚至允许这样做吗?

【问题讨论】:

    标签: ios xamarin avplayer avplayerviewcontroller avplayerlayer


    【解决方案1】:

    Radin 的回答帮助了我,我也遇到了同样的问题。此链接有更多信息 - https://developer.apple.com/reference/avfoundation/avasynchronouskeyvalueloading/1387321-loadvaluesasynchronously

    import UIKIT
    import AVFoundation
    
    typealias VideoDownloadResponse = (Bool, AVPlayerLayer?) -> Void
    
    func loadVideoFromURL(urlString: String, onCompletion: @escaping VideoDownloadResponse) {
    
        if let url = URL(string: urlString) as URL? {
            let asset = AVURLAsset(url: url)
            // Load the asset's "playable" key
            asset.loadValuesAsynchronously(forKeys: ["playable"]) {
                var error: NSError? = nil
                let status = asset.statusOfValue(forKey: "playable", error: &error)
                switch status {
    
                case .loaded:
                    // Sucessfully loaded, continue processing
                    // Build the player
                    let playerItem = AVPlayerItem(asset: asset)
                    let player = AVPlayer(playerItem: playerItem)
                    let layer = AVPlayerLayer(player: player)
                    //send it back to be shown in the UI
                    DispatchQueue.main.async(execute: {
                        onCompletion(true, layer)
                    })
    
                case .failed:
                    // Examine NSError pointer to determine failure
                    DispatchQueue.main.async(execute: {
                        onCompletion(false, nil)
                    })
                default:
                    // Handle all other cases
                    DispatchQueue.main.async(execute: {
                        onCompletion(false, nil)
                    })
                }
            }
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      将您的方法转换为异步并在创建资产后立即调用await asset.LoadValuesTaskAsync(new string[] { @"playable" });。这将预加载视频不会阻塞用户界面。

      【讨论】:

      • 它没有改变任何东西:(
      猜你喜欢
      • 2011-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-07
      • 1970-01-01
      相关资源
      最近更新 更多