【问题标题】:Can AVPlayer properly stream video files from an API endpoint?AVPlayer 可以从 API 端点正确流式传输视频文件吗?
【发布时间】:2020-10-07 15:46:17
【问题描述】:

我有一个 Xamarin iOS 应用程序,我想从支持 HTTP 范围请求的 API 端点流式传输视频。我已经在 SO 上查看了许多类似的问题,但无论我尝试什么,我似乎都无法让 AVPlayer 在完全下载视频文件之前开始播放视频文件。 我试过了:

  • KVO 在playbackLikelyToKeepUpplaybackBufferEmptyplaybackBufferEmpty 上播放视频,一旦它是ReadyToPlay
  • 在 AVPlayer 上设置 AutomaticallyWaitsToMinimizeStalling = false
  • 在 AVPlayerItem 上设置 CanUseNetworkResourcesForLiveStreamingWhilePaused = true 和 PreferredForwardBufferDuration = 1
  • 在 AVPlayer 上调用 PlayImmediatelyAtRate(1)

但是在视频开始播放之前文件仍然被完全下载,这会导致用户延迟。

是否可以让 AVPlayer 在完成下载之前开始播放视频文件,类似于 HTML 视频标签的做法?

这是我当前的代码:

    private void SetUpPlayer()
    {
        if (ViewModel.VideoStreamUrl == null)
        {
            return;
        }

        // See https://stackoverflow.com/questions/38865797/how-to-play-video-with-avplayerviewcontroller-avkit-in-xamarin-ios
        _aVPlayerItem = new AVPlayerItem(ViewModel.VideoStreamUrl)
        {
            CanUseNetworkResourcesForLiveStreamingWhilePaused = true,
            PreferredForwardBufferDuration = 1,
        };

        // See https://stackoverflow.com/questions/38867190/how-can-i-check-if-my-avplayer-is-buffering/38867386#38867386
        _playbackLikelyToKeepUpObserver?.Dispose();
        _playbackLikelyToKeepUpObserver = (NSObject)_aVPlayerItem.AddObserver("playbackLikelyToKeepUp",
            NSKeyValueObservingOptions.New,
            AVPlayerItem_BufferUpdated);

        _playbackBufferEmptyObserver?.Dispose();
        _playbackBufferEmptyObserver = (NSObject)_aVPlayerItem.AddObserver("playbackBufferEmpty",
            NSKeyValueObservingOptions.New,
            AVPlayerItem_BufferUpdated);

        _playbackBufferFullObserver?.Dispose();
        _playbackBufferFullObserver = (NSObject)_aVPlayerItem.AddObserver("playbackBufferFull",
            NSKeyValueObservingOptions.New,
            AVPlayerItem_BufferUpdated);

        _aVPlayer = new AVPlayer(_aVPlayerItem)
        {
            AutomaticallyWaitsToMinimizeStalling = false,
        };

        var playerViewController = new AVPlayerViewController
        {
            Player = _aVPlayer,
        };

        AddChildViewController(playerViewController);
        View.AddSubview(playerViewController.View);
        playerViewController.View.Frame = View.Frame;
        playerViewController.ShowsPlaybackControls = true;

        _aVPlayer.PlayImmediatelyAtRate(1);
    }

    private void AVPlayerItem_BufferUpdated(NSObservedChange obj)
    {
        ReportVideoBuffering();
    }

    private void ReportVideoBuffering()
    {
        bool isBufferEmpty = _aVPlayerItem != null && _aVPlayerItem.PlaybackBufferEmpty;
        Console.WriteLine($"Buffer empty? {isBufferEmpty}");
        Console.WriteLine($"Player status? {_aVPlayer.Status}");

        if (_aVPlayer.Status == AVPlayerStatus.ReadyToPlay)
        {
            Console.WriteLine($"Playing video.");
            _aVPlayer.Play();
        }
    }

【问题讨论】:

  • 您好,您的媒体流服务器使用什么类型的传输协议?如果AVPlayer不能直接处理流数据,可以集成第三方播放器播放。比如VLC播放器。这里是关于 RTMP 的原生讨论:stackoverflow.com/questions/35312591/…
  • 感谢@JuniorJiang-MSFT 我正在尝试使用范围请求标头和 http 216 部分响应从 Web api 端点流式传输 mp4 文件。例如,这与 html 视频标签完美配合,但看起来 AVPlayer 不支持。我目前正在研究其他方法。
  • 好吧,web api是否是https地址?
  • 生产端点是 https。将 AVPlayer 直接指向我们在 Azure Blob 存储 (https) 中的资产的流式处理 url 不起作用。
  • 这很奇怪。 Azure Web 服务器中 mp4 文件的大小是否很大?一般来说,iOS在玩之前需要一些时间准备。时间长短取决于文件的大小。

标签: ios xamarin


【解决方案1】:

这个问题的简单答案是否定的,AVPlayer 不支持使用 http 范围请求和部分内容 (206) 响应的流式传输。在我们的案例中,我们决定使用 Azure 媒体服务来提供一个流式端点,然后我们可以在 iPad 应用程序和网络上使用它。

【讨论】:

    猜你喜欢
    • 2011-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-25
    • 2020-11-21
    • 2016-01-05
    • 1970-01-01
    相关资源
    最近更新 更多