AVPlayer不会激活playbackBufferEmpty,但也不会播放 [英] AVPlayer does not fire playbackBufferEmpty but does not play either

查看:829
本文介绍了AVPlayer不会激活playbackBufferEmpty,但也不会播放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用AVPlayer通过互联网播放音频直播。如果暂停时间超过1分钟,我想恢复播放。

I use AVPlayer to play an audio livestream via internet. I like to recover playback if it was paused for longer than 1 minute.

我打电话给 player.rate = 1.0 恢复。但是,如果流暂停> 1分钟,则不再播放。在这种情况下我需要重新创建AVPlayerItem以使其再次工作。

I call player.rate = 1.0 to resume. However if the stream was paused for >1 minute it does not play any more. I need to recreate AVPlayerItem in this case to make it work again.

所以我怎么能抓住这种情况,所以我知道播放没有恢复?


  • 我在 player.rate 上尝试了KVO。它虽然保持在 1.0 。玩家没有玩!

  • 我在 currentItem.playbackBufferEmpty 上尝试了KVO。但是在这种情况下不会调用它。

  • currentItem.status 不会切换到 .Failed 。它根本不会改变。

  • I tried KVO on player.rate. It stays at 1.0 though. The player is not playing!
  • I tried KVO on currentItem.playbackBufferEmpty. It is not called in this case though.
  • currentItem.status does not switch to .Failed. It does not change at all.

在这种情况下,AVPlayer似乎什么都不做。有什么想法吗?

The AVPlayer just seems to do nothing in this case. Any ideas?

我构建了一个Playground代码来证明这个问题:

I build a Playground code to demonstrate the issue:

import UIKit
import AVFoundation

// keep it running forever so it plays audio
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely(true)

class AVPlayerTest {

    let player = AVPlayer()
    let streamurl = NSURL(string: "http://detektor.fm/stream/mp3/musik/")!

    func startTest() {
        let item = AVPlayerItem(URL: streamurl)
        player.replaceCurrentItemWithPlayerItem(item)
        player.play()

        // give it some start time to build a buffer
        NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(timerTickedToPause), userInfo: nil, repeats: false)
    }

    @objc func timerTickedToPause(timer: NSTimer) {
        player.pause()
        // pause now for some time. 90s is not enough.
        NSTimer.scheduledTimerWithTimeInterval(120, target: self, selector: #selector(timerTickedToPlay), userInfo: nil, repeats: false)
    }

    @objc func timerTickedToPlay(timer: NSTimer) {
        // try to resume playback

        print(player.rate)

        player.play()

        print(player.rate)

        // check in some seconds if it recovered
        NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: #selector(timerTickedCheck), userInfo: nil, repeats: false)
    }

    @objc func timerTickedCheck(timer: NSTimer) {

        // it reports rate = 1.0 but is not playing here though!
        // there is no way to know for me it did not recover here!?
        print(player.rate)

        // recover by creating a new item works
        let item = AVPlayerItem(URL: streamurl)
        player.replaceCurrentItemWithPlayerItem(item)
        player.play()
    }
}

let test = AVPlayerTest()
test.startTest()


推荐答案

使用AVPlayer实例的 timeControlStatus 表示是否播放正在进行中,无限期暂停,或在等待适当的网络条件时暂停。

Use the timeControlStatus of the AVPlayer instance which "indicates whether playback is currently in progress, paused indefinitely, or suspended while waiting for appropriate network conditions."

let status = player.timeControlStatus

switch status {
case .paused:
    print("timeControlStatus.paused")

case .playing:
    print("timeControlStatus.playing")

case .waitingToPlayAtSpecifiedRate:
    print("timeControlStatus.waitingToPlayAtSpecifiedRate")
    if let reason = player.reasonForWaitingToPlay {

        switch reason {
        case .evaluatingBufferingRate:
            print("reasonForWaitingToPlay.evaluatingBufferingRate")

        case .toMinimizeStalls:
            print("reasonForWaitingToPlay.toMinimizeStalls")

        case .noItemToPlay:
            print("reasonForWaitingToPlay.noItemToPlay")

        default:
            print("Unknown \(reason)")
        }
    }

}

我有同样的问题但是在我的情况下,如果我在暂停状态下进入后台,则会发生这种情况。当我回到forground .play()不起作用。它会遇到waitingToPlayAtSpecifiedRate.evaluatingBufferingRate模式。
此时AVPlayerItem.status实例是readToPlay。

I have the same issue but in my case, it occurs if I go into background while in the paused state. When I come back to forground .play() does not work. It gets stuck the waitingToPlayAtSpecifiedRate.evaluatingBufferingRate mode. At that point the AVPlayerItem.status instance is readToPlay.

在收到startCommand的这个时候,我重置AVplayer以确定。但这似乎很笨拙。寻找更顺畅的解决方案。

At this time of writing whenever a startCommand is received I reset the AVplayer to be sure. But this seems clunky. Looking for a smoother solution.

这篇关于AVPlayer不会激活playbackBufferEmpty,但也不会播放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆