How to close the previous AVPlayer and AVPlayerItem

I am making an iOS application in Swift that plays a video in a loop on a small layer in the upper right corner of the screen that displays a video of a specific color element. then the user clicks the corresponding color element on the screen. when they do this, the videoName variable randomly changes to the next color, and the corresponding video starts. I have no problem boosting, playing and playing back videos using AVPlayer, AVPlayerItem, as shown in the attached code. Where I am stuck is that whenever the next video is displayed, the previous ones remain behind it. In addition, after playing 16 videos, the player completely disappears on my iPad. I tried many suggestions presented on this and other sites, but it either quickly detects a problem with them or it just doesn’t work. So the question is: in my code here, how can I say "hey, the next video started playing, delete the previous video and its layer and free up memory so that I can play as many videos as I need"?

//set variables for video play
var playerItem:AVPlayerItem?
var player:AVPlayer?

//variables that contain video file path, name and extension
var videoPath = NSBundle.mainBundle().resourcePath!
var videoName = "blue"
let videoExtension = ".mp4"

//DISPLAY VIDEO
func showVideo(){

        //Assign url path
        let url = NSURL(fileURLWithPath: videoPath+"/Base.lproj/"+videoName+videoExtension)
        playerItem = AVPlayerItem(URL: url)
        player=AVPlayer(playerItem: playerItem!)
        let playerLayer=AVPlayerLayer(player: player!)

        //setplayser location in uiview and show video
        playerLayer.frame=CGRectMake(700, 5, 350, 350)
        self.view.layer.addSublayer(playerLayer)
        player!.play()

     // Add notification to know when the video ends, then replay   it again.  THIS IS A CONTINUAL LOOP
     NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: player!.currentItem, queue: nil)
    { notification in
        let t1 = CMTimeMake(5, 100);
        self.player!.seekToTime(t1)
        self.player!.play()
    }

}

`

+4
source share
3 answers

@Anupam Mishra Swift. , , , , playerLayer , . . 'if (player!.rate > 0...)', , , , , , " ", . , ! , . : , ios 16 viewController ( ). , , , 16 . , :, viewController . , , , . playerLayer.frame = CGRectMake (, , , ). : , , . stopPlayer(), "videoName" , , "showVideo()". ( , "videoExtension" let var.

`

//set variables for video play
var playerItem:AVPlayerItem?
var player:AVPlayer?
var playerLayer = AVPlayerLayer()  //NEW playerLayer var location

//variables that contain video file path, name and extension
var videoPath = NSBundle.mainBundle().resourcePath!
var videoName = "blue"
let videoExtension = ".mp4"

var createLayerSwitch = true   /*NEW switch to say whether on not to create the layer when referenced by the closePlayer and showVideo functions*/

//DISPLAY VIDEO
func showVideo(){

    //Assign url path
    let url = NSURL(fileURLWithPath: videoPath+"/Base.lproj/"+videoName+videoExtension)
    playerItem = AVPlayerItem(URL: url)
    player=AVPlayer(playerItem: playerItem!)
    playerLayer=AVPlayerLayer(player: player!) //NEW: remove 'let' from playeLayer here.

    //setplayser location in uiview and show video
    playerLayer.frame=CGRectMake(700, 5, 350, 350)
    self.view.layer.addSublayer(playerLayer)
    player!.play()

    createLayerSwitch = false  //NEW switch to tell if a layer is already created or not.  I set the switch to false so that when the next tapped item/button references the closePlayer() function, the condition is triggered to close the player AND the layer

 // Add notification to know when the video ends, then replay it again without a pause between replays.  THIS IS A CONTINUAL LOOP
 NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: player!.currentItem, queue: nil)
 { notification in
    let t1 = CMTimeMake(5, 100);
    self.player!.seekToTime(t1)
    self.player!.play()
 }
}
    //NEW function to kill the current player and layer before playing the next  video
func closePlayer(){
 if (createLayerSwitch == false) {
   player!.pause()
   player = nil
   playerLayer.removefromsuperlayer()
 }
}

`

0

replaceCurrentItemWithPlayerItem ? . , .

: replaceCurrentItemWithPlayerItem

0

, , - , -

Swift Code -

if (player!.rate>0 && player!.error == nil)
            {
                player!.pause();
                player = nil
            }

Objective-C -

if (player.rate>0 && !player.error)
    {
        [player setRate:0.0];
    }
0
source

All Articles