我正在Swift中制作一个iOS应用程序,它在屏幕右上角的一个小层中循环播放视频,显示特定彩色项目的视频。然后用户点击屏幕上相应的彩色项目。当它们执行时,videoName变量随机更改为下一个颜色,并触发相应的视频。我可以使用AVPlayer,AVPlayerItem来提升,播放和循环播放视频,如附带的代码所示。 我被困住的地方是,无论何时显示下一个视频,之前的视频都会保持打开状态。此外,播放了16个视频后,播放器完全消失在我的iPad上。我已尝试过在本网站和其他网站上提出的许多建议,但要么swift发现它们有问题,要么就是不行。 所以问题:在我的代码中,如何告诉它“嘿,下一个视频已经开始播放,删除之前的视频及其图层并释放内存,以便我可以根据需要播放尽可能多的视频”?< /强>
//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()
}
}
`
答案 0 :(得分:1)
我改编了@Anupam Mishra的Swift代码建议。它起初并没有起作用,但最终我认为我必须将playerLayer带到该功能之外并在我将玩家设置为nil之后关闭playerLayer。也。而不是使用&#39; if(player!.rate&gt; 0 ...)&#39;毫无疑问它仍然可以工作,我创建了一个变量开关来指示何时说&#34;杀死玩家和层&#34;如下所示。它可能不漂亮,但它的工作原理! 以下是针对像我这样的绝对新手 - 我从这次经历中学到了什么:在我看来,ios设备只允许将16层添加到viewController(或superLayer)。因此,在使用其播放器打开下一个图层之前,需要删除每个图层,除非您确实希望一次运行16个图层。 此代码实际上适用于您:此代码在现有的viewController上创建一个可调整大小的图层,并在无限循环中播放来自您的包的视频。当即将调用下一个视频时,将完全删除当前视频和图层,释放内存,然后播放带有新视频的新图层。视频图层大小和位置可使用playerLayer.frame = CGRectMake(左,顶部,宽度,高度)参数完全自定义。 如何完成所有工作:假设您已将视频添加到自己的捆绑包中,请为按钮点击创建另一个功能。在该功能中,首先调用&#39; stopPlayer()&#39;功能,更改&#39; videoName&#39;变量到您想要的新视频名称,然后调用&#39; showVideo()&#39;功能。 (如果您需要更改视频扩展程序,请将&#39; videoExtension&#39;从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 :(得分:0)
为什么不在播放器上使用SELECT [Position], [TeamName], [Played], [Wins], [Loss], [Draws], [Points], [Goals_Scored], [Goals_Against], [Goal_Difference], [LeagueID]
FROM League_Table
?您将为所有视频保留相同的播放器。我认为这是一种更好的方法。
编辑: replaceCurrentItemWithPlayerItem
必须在主线程上调用
答案 2 :(得分: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];
}