如何关闭以前的AVPlayer和AVPlayerItem

问题描述 投票:6回答:3

我正在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()
    }

}

`

ios swift avplayer avplayeritem
3个回答
2
投票

我改编了@Anupam Mishra的Swift代码建议。最初它没有用,但最终我想我必须将playerLayer置于函数之外,然后在将播放器设置为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() } }

`

1
投票
为什么不只在播放器上使用replaceCurrentItemWithPlayerItem?您将为所有视频保留同一播放器。我认为这是一种更好的方法。

编辑: replaceCurrentItemWithPlayerItem必须在主线程上调用


0
投票
在进行下一首曲目之前,首先检查播放器是否有视频或音乐,要停止播放,请进行以下检查:

Swift Code-

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

Objective-C Code-

if (player.rate > 0 && !player.error) { [player setRate:0.0]; }
© www.soinside.com 2019 - 2024. All rights reserved.