Impossible to stop AVPlayer

34,536

Solution 1

If you declare player as an optional variable, you can then set the player to nil to deallocate it.

Silly example but it shows what happens:

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")
        }
    }
}

Solution 2

From this post I found the best solution to completely stop AVPlayer before you leave or start a new player:

videoPlayer.replaceCurrentItemWithPlayerItem(nil)

[Update] For SWIFT 3:

player.replaceCurrentItem(with: nil)

Solution 3

SWIFT 3 Version:

player.replaceCurrentItem(with: nil)
Share:
34,536
w3spi
Author by

w3spi

Updated on July 30, 2022

Comments

  • w3spi
    w3spi almost 2 years

    I am currently testing the use of AVPlayer with audio streaming url, using Swift. There are play() and pause() methods, but the problem is that, pausing only, the stream remains cached in the device.

    Here is my test code :

    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()
        }
    }
    

    Here are the issues when trying somethings :

    player = nil : "Cannot assign a value of type 'NilLiteralCOnvertible' to a value of type 'AVPlayer'"

    player.currentItem = nil : "Cannot assign to property: 'currentItem' is a get-only property"


    I tried everything, even through AVQueuePlayer without any effective result. (obviously, since I only have one item in my case).

    How to stop AVPlayer or destroy his instance ?

  • w3spi
    w3spi over 8 years
    Thank you for your answer. I'm sure your solution works, but so how to reallocate the player when re-enter in function initPlayer() ?
  • James Bush
    James Bush almost 8 years
    This is the correct answer. Please award the answerer with your approval.
  • Pramod Tapaniya
    Pramod Tapaniya about 7 years
    @EricAya have you know how to play continues audio after destroyed that ViewController on we have created instance of AVPlayer.
  • Pramod Tapaniya
    Pramod Tapaniya about 7 years
    Have you know how to play continues audio after destroyed that ViewController on we have created instance of AVPlayer.
  • BenHedges
    BenHedges over 6 years
    This works! For swift3: videoPlayer.replaceCurrentItem(with: nil)
  • Krishna Kirana
    Krishna Kirana about 6 years
    player.pause() player.replaceCurrentItem(with: nil)
  • Cloy
    Cloy about 4 years
    Thanks @taynguyen saved a lot of my time
  • Lance Samaria
    Lance Samaria over 3 years
    this is definitely the answer