Put buttons over PlayerLayer - Swift - Programmatically - swift

I have a UIView which Is supposed to play a video using AVPlayerLayer and AVPlayer.
I set the player in this way:
fileprivate func setUpPlayer(){
let urlPathString = Bundle.main.path(forResource: "dance", ofType: "mp4")
if let videoURL = urlPathString{
let url = URL(fileURLWithPath: videoURL)
player = AVPlayer(url: url)
playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = .resizeAspectFill
self.playerView.layer.addSublayer(playerLayer)
self.playerView.layer.masksToBounds = true
}
}
override func layoutSubviews() {
self.layer.cornerRadius = 15
playerLayer.frame = self.bounds
self.setupShadow(opacity: 0.6, radius: 6, offset: CGSize.init(width: 0, height: 0), color: .darkGray)
}
The problem is that no matter how many subviews I set over the PlayerView, the video actually goes over everything hiding all the subviews I set before.
Do you know how I can put buttons or actually other UIViews over AVPlayerLayer without it actually hiding them?

Change
self.playerView.layer.addSublayer(playerLayer)
to
self.playerView.layer.insertSublayer(playerLayer, at: 0)

Related

resize frame for video in iphone and ipad

I want to create an application for iPhone and iPad and my app contains video which not full screen I put the video in a frame with this code
private func playVideo() {
guard let path = Bundle.main.path(forResource: "ch", ofType:"mp4") else {
debugPrint("video.mp4 not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
let controller = AVPlayerViewController()
controller.player = player
controller.view.frame = CGRect(x: 1, y: 40, width: self.view.bounds.width - 2, height: 280)
self.view.addSubview(controller.view)
self.addChild(controller)
player.play()
}
and I set the hight 280 and It is good for iPhone devices
but I want to set the frame hight 550 on iPad devices and can't, anyone help me, thanks.
You should set a calculated height based on device height.
Something like,
controller.view.frame = CGRect(x: 1, y: 40, width: self.view.bounds.width - 2,
height: UIScreen.main.bounds.size.height * 0.66)

Local Video have a Sound in background after leaving view controller

I want to play a local video in a frame not fullscreen, the video will play but when I go to the next view controller by pressing a button ,the video's sound will continue in background ,and here is my code, can anyone help me how to stop video's sound? thanks
playVideo()
}
private func playVideo() {
guard let path = Bundle.main.path(forResource: "a", ofType:"mp4") else {
debugPrint("video.m4v not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
let controller=AVPlayerViewController()
controller.player=player
controller.view.frame = CGRect(x: 1, y: 40, width: self.view.bounds.width - 2, height: 280)
self.view.addSubview(controller.view)
self.addChild(controller)
player.play()

Layout coordinates for a video-texture object in SceneKit with Swift

I'm working on creating an SCNNode instance that consists of an SCNPlane - type geometry, with a video playing on the surface of the node. This is what I have so far:
let plane = SCNPlane(width: 5, height: 5)
node = SCNNode(geometry: plane)
GlobalScene.shared.rootNode.addChildNode(node!)
let urlStr = Bundle.main.path(forResource: "test", ofType: "mov")
videoURL = NSURL(fileURLWithPath: urlStr!)
player = AVPlayer(playerItem: AVPlayerItem(url: videoURL! as URL))
let videoNode = SKVideoNode(avPlayer: player!)
player?.actionAtItemEnd = .none
let spritescene = SKScene(size: CGSize(width: 122, height: 431))
videoNode.size.width=spritescene.size.width
videoNode.size.height=spritescene.size.height
spritescene.addChild(videoNode)
plane.firstMaterial?.diffuse.contents = spritescene
The overall functionality so far works great! What I'm trying to figure out is, how to I get the node's ENTIRE surface to be made up of the video ? So far, I've only gotten it to appear in the single corner shown below:
EDIT: it looks like the issue is that I'm only setting the first material of the plane node (rather than all of them...) which is why I'm seeing the other 3 "quadrants" as blank.
EDIT2: That first conclusion may not be correct - if I set:
plane.firstMaterial?.diffuse.contents = NSColor.green
I get the following result:
So...why won't that work when applying the contents of a SpriteKit scene?
Using a SKScene and a SKVideoNode is not necessary. You can directly set the AVPlayer as the contents of a SCNMaterialProperty instance. This will allow for better performance and will avoid having to deal with scaling and positioning the SpriteKit elements.
With the help of this gist, I was able to solve my issue; which ended up involving both scaling the video node properly, as well as setting the position properly. My working code is below:
GlobalScene.shared.rootNode.addChildNode(node!)
let urlStr = Bundle.main.path(forResource: "test", ofType: "mov")
videoURL = NSURL(fileURLWithPath: urlStr!)
player = AVPlayer(playerItem: AVPlayerItem(url: videoURL! as URL))
videoSpriteKitNode = SKVideoNode(avPlayer: player!)
player?.actionAtItemEnd = .none
NotificationCenter.default.addObserver(
self,
selector: #selector(self.playerItemDidReachEnd),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: player?.currentItem)
let spriteKitScene = SKScene(size: CGSize(width: 1276.0 / 2.0, height: 712.0 / 2.0))
videoSpriteKitNode?.size.width=spriteKitScene.size.width
videoSpriteKitNode?.size.height=spriteKitScene.size.height
node?.geometry?.firstMaterial?.diffuse.contentsTransform = SCNMatrix4Translate(SCNMatrix4MakeScale(1, -1, 1), 0, 1, 0)
videoSpriteKitNode?.position = CGPoint(x: spriteKitScene.size.width / 2.0, y: spriteKitScene.size.height / 2.0)
videoSpriteKitNode?.size = spriteKitScene.size
videoSpriteKitNode?.play()
spriteKitScene.addChild(videoSpriteKitNode!)
plane?.firstMaterial?.diffuse.contents = spriteKitScene

Custom Controls are not displaying in MobileVLCKit media player

I am using MobileVLCKit in my swift project. I am using cocoapod MobileVLCKit-prod(2.7). I want to add video controls to player. This is the my code.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let filePath = Bundle.main.url(forResource: "bunny", withExtension: "webm")
self.mediaPlayer.media = VLCMedia(url: filePath)
self.mediaPlayer.drawable = self.view
self.addVideoControls()
self.mediaPlayer.play()
}
func addVideoControls() {
let videoControls = MPVolumeView(frame: CGRect(x: 0, y: 0, width: self.view.frame.maxX, height: 60.0))
videoControls.backgroundColor = UIColor.blue
let videoView = self.mediaPlayer.drawable as! UIView
videoView.addSubview(videoControls)
videoView.bringSubview(toFront: videoControls)
}
VLC team provided explore is not compiling. How to customize the video player.please understand me what is the wrong in my code.

How to remove layers i added playing AVplayer Swift

I have an app that reenter the same view bunch of times creating a layer for an mp4 video everytime, creating a memory creep because the layers aren't getting removed, or at least that is my guess. How could i remove the layers that are added?
override func viewWillAppear(animated: Bool) {
let videoURL: NSURL = NSBundle.mainBundle().URLForResource("info2", withExtension: "mp4")!
mygtukas = AVPlayer(URL: videoURL)
mygtukas?.actionAtItemEnd = .None
mygtukas?.muted = true
let playerLayer = AVPlayerLayer(player: mygtukas)
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
playerLayer.zPosition = 1
playerLayer.frame = CGRect(x:20.0, y: 703.0, width: 36.0, height: 36.0)
view.layer.addSublayer(playerLayer)
mygtukas?.play()
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "loopVideo",
name: AVPlayerItemDidPlayToEndTimeNotification,
object:nil)
}
This should work:
Make the playerLayer a class instance and try the following.
Call inside loopVideo method:
playerLayer.removeFromSuperlayer()