如何关闭以前的AVPlayer和AVPlayerItem

Tux*_*tle 6 ios avplayer swift avplayeritem

我正在Swift中制作一个iOS应用,该应用会在屏幕右上角的一小层中循环播放视频,以显示特定颜色项目的视频。用户然后在屏幕上点击相应的彩色项目。当他们这样做时,videoName变量将随机更改为下一种颜色,并触发相应的视频。如附件代码所示,我使用AVPlayer,AVPlayerItem提升,播放和循环播放视频没有问题。我遇到的问题是,无论何时显示下一个视频,上一个视频都会在其后面保持打开状态。此外,播放了16个视频后,播放器在我的iPad上完全消失了。我已经尝试过在此站点和其他站点中提出的许多建议,但是要么迅速发现它们存在问题,要么就不起作用。 所以问题:在我的代码中,我如何告诉它“嘿,下一个视频已开始播放,请删除上一个视频,并将其分层并释放内存,以便我可以根据需要播放任意数量的视频”?

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

}
Run Code Online (Sandbox Code Playgroud)

`

Tux*_*tle 4

我改编了 @Anupam Mishra 的 Swift 代码建议。一开始它不起作用,但最后我发现我必须将playerLayer放在函数之外,并在将player设置为nil后关闭playerLayer。还。我没有使用毫无疑问仍然有效的“if(player!.rate>0 ...)”,而是创建了一个变量开关来指示何时说“杀死玩家和图层”,如下所示。它可能不漂亮,但它有效! 以下内容是针对像我这样的绝对新手- 我从这次经历中学到的东西:在我看来,ios 设备只允许将 16 层添加到 viewController(或 superLayer)。因此,在使用播放器打开下一层之前,需要删除每一层,除非您确实希望同时运行 16 层。下面的这段代码实际上为您做了什么:这段代码在现有的 viewController 上创建一个可调整大小的层,并无限循环地播放捆绑包中的视频。当即将调用下一个视频时,当前视频和图层将被完全删除,释放内存,然后播放包含新视频的新图层。视频层的大小和位置可以使用playerLayer.frame=CGRectMake(left, top, width, height)参数完全自定义。 如何使其全部正常工作:假设您已将视频添加到捆绑包中,请为按钮点击创建另一个功能。在该函数中,首先调用“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()
 }
}
Run Code Online (Sandbox Code Playgroud)

`