无法停止AVPlayer

40
我正在使用Swift测试AVPlayer与音频流URL的使用。它有play()pause()方法,但问题是,只有暂停,流仍然被缓存在设备中。
这是我的测试代码:
import UIKit
import AVFoundation

class ViewController: UIViewController {

    let player = AVPlayer(URL: NSURL(string: "http://streaming.radio.rtl.fr/rtl-1-48-192")!)

    @IBOutlet weak var btnPlay: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()            
    }

    @IBAction func btnPress(sender: AnyObject) {
        if (btnPlay.titleLabel?.text == "Play") {
            initPlayer()
            btnPlay.setTitle("Stop", forState: UIControlState.Normal)
        } else {
            stopPlayer()
            btnPlay.setTitle("Play", forState: UIControlState.Normal)
        }
    }

    func initPlayer()  {
        player.play()
    }

    func stopPlayer() {
        // player.currentItem = nil // Last thing I tried, but generate an error
        player.pause()
    }
}

尝试某些操作时出现的问题:

player = nil :“无法将类型为 'NilLiteralConvertible' 的值分配给类型为 'AVPlayer' 的值”

player.currentItem = nil :“无法分配给属性:'currentItem' 是只读属性”


我尝试了所有方法,甚至使用了AVQueuePlayer,但没有实际效果(显然,因为在我的情况下只有一个项目)。

如何停止AVPlayer销毁它的实例


4
player = nil 表示将播放器对象本身设置为 nil,而 player.currentItem = nil 表示将当前播放项设置为 nil。 - JAL
@JAL,player是AVPlayer的一个实例,所以我不能直接这样做。请查看函数stopPlayer(),我已经测试过了。 - w3spi
当您尝试将播放器设置为nil时,出现了什么错误?此外,您是否尝试过像我建议的那样删除播放器的currentItem? - JAL
@JAL,请查看我的更新的问题。 - w3spi
@JAL 我总是混淆这两个。谢谢你让我填补这个重要的空白! - w3spi
显示剩余2条评论
3个回答

66
从这个帖子中,我找到了在离开或开始新的播放器之前完全停止AVPlayer的最佳解决方案。
videoPlayer.replaceCurrentItemWithPlayerItem(nil)

[更新] 针对 SWIFT 3:
player.replaceCurrentItem(with: nil)

2023年的注意事项。对于排队玩家来说,这是...
qp = AVQueuePlayer()
...
qp.removeAllItems()

这是正确的答案。请批准回答者。 - James Bush
你知道如何在销毁 ViewController 后继续播放音频吗?我们已经创建了 AVPlayer 的实例。 - Pramod Tapaniya
1
这个有效!对于Swift3:videoPlayer.replaceCurrentItem(with: nil)。 - BenHedges
谢谢 @taynguyen,你帮我省了很多时间。 - Cloy
这绝对是答案。 - Lance Samaria

30
如果您将player声明为可选变量,那么您可以将玩家设置为nil以取消分配它。这是一个愚蠢的例子,但它展示了会发生什么:
import UIKit
import AVFoundation

class ViewController: UIViewController {

    @IBOutlet weak var btnPlay: UIButton!

    var player:AVPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func btnPress(sender: AnyObject) {
        if (btnPlay.titleLabel?.text == "Play") {
            initPlayer()
            btnPlay.setTitle("Stop", forState: UIControlState.Normal)
        } else {
            stopPlayer()
            btnPlay.setTitle("Play", forState: UIControlState.Normal)
        }
    }

    func initPlayer()  {
        if let play = player {
            print("playing")
            play.play()
        } else {
            print("player allocated")
            player = AVPlayer(URL: NSURL(string: "http://streaming.radio.rtl.fr/rtl-1-48-192")!)
            print("playing")
            player!.play()
        }
    }

    func stopPlayer() {
        if let play = player {
            print("stopped")
            play.pause()
            player = nil
            print("player deallocated")
        } else {
            print("player was already deallocated")
        }
    }
}

谢谢您的答案。我相信您的解决方案是有效的,但是当重新进入“initPlayer()”函数时如何重新分配玩家? - w3spi
@EricAya 你知道如何在销毁了UIViewController并创建了AVPlayer实例后继续播放音频吗? - Pramod Tapaniya

10

SWIFT 3 版本:

player.replaceCurrentItem(with: nil)

1
player.pause()player.replaceCurrentItem(with: nil) - Krishna Kirana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接