Why does my AVPlayerViewController not show playback controls? - ios

My AVPlayerViewController does not show the video controls even though .showsPlaybackControls is set to true. This started with iOS 16 and the weird thing is .showsPlaybackControls = false will dismiss the controls visible when they're visible through clicking on the video.
var playerController = AVPlayerViewController()
var playerItem = AVPlayerItem(asset: assetComp)
player = AVPlayer(playerItem: playerItem)
playerController.player = player
playerController.showsPlaybackControls = true
self.view.addSubview(playerController.view)
self.addChild(playerController)
player.play()

Related

Video not play in AVPlayer or safari but play in chrome

I have open AVPlayer to play the video by url link, but video not play in player and also not play in safari but video play on chrome browser.
My code is >>>>>>>>>
if url != nil {
let player = AVPlayer(url: url!)
player.allowsExternalPlayback = true
let playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = .resizeAspectFill
player.play()
}
Try this >>>
let player = AVPlayer(url: url)
player.rate = 1
playerViewController.player = player
playerViewController.view.frame = self.view.frame
playerViewController.showsPlaybackControls = true
addChild(playerViewController)
self.view.addSubview(playerViewController.view)
playerViewController.didMove(toParent: self)
It is work fine .

How to properly show multiple videos in the same avPlayerLayer

What I'm trying to achieve?
I'm showing users a subview with integrated page control. I want to show three different videos on the same subview.
How I implemented avPlayer?
First step:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
avPlayerLayer.frame = (WelcomeView?.video.layer.bounds)!
}
First video aligned perfectly in the middle of my view with this snippet of code:
WelcomeView?.frame.size.width = deviceScreen.frame.size.width
WelcomeView?.frame.size.height = deviceScreen.frame.size.height
WelcomeView?.video.layer.cornerRadius = 15
WelcomeView?.video.clipsToBounds = true
WelcomeView?.gradient.layer.cornerRadius = 25
WelcomeView?.gradient.clipsToBounds = true
WelcomeView?.label.addShadow()
let theURL = Bundle.main.url(forResource:"welcome1", withExtension: "MP4")
avPlayer = AVPlayer(url: theURL!)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspect
avPlayer.volume = 0
avPlayer.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer.currentItem)
WelcomeView?.video.frame = (WelcomeView?.video.layer.bounds)!
WelcomeView?.video.layer.insertSublayer(self.avPlayerLayer, at: 0)
WelcomeView?.tapNext.addTarget(self, action: #selector(GalleryViewController.nextOutboarding(sender:)))
self.view.addSubview(WelcomeView!)
avPlayer.play()
Second step (when user clicks on the button next and when I'm trying to show different video on the same subview):
#objc func nextOutboarding(sender: UITapGestureRecognizer) {
WelcomeView?.pageControl.currentPage += 1
if WelcomeView?.pageControl.currentPage == 1 {
avPlayer.pause()
avPlayerLayer.removeFromSuperlayer()
let theURL = Bundle.main.url(forResource:"welcome2", withExtension: "MP4")
avPlayer = AVPlayer(url: theURL!)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspect
avPlayer.volume = 0
avPlayer.actionAtItemEnd = .none
NotificationCenter.default.addObserver(self,
selector: #selector(playerItemDidReachEnd(notification:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: avPlayer.currentItem)
WelcomeView?.video.frame = (WelcomeView?.video.layer.bounds)!
WelcomeView?.video.layer.insertSublayer(self.avPlayerLayer, at: 0)
self.view.addSubview(WelcomeView!)
avPlayer.play()
}
}
My problem:
When I'm trying to show second video on the same avPlayerLayer - my video has different alignment (basically not in the middle anymore).
Any tips? Thank you.
First of all, create new AvPlayerItem.
var playerItem:AVPlayerItem?
Then use replaceCurrentItem function.
playerItem = AVPlayerItem(url: theURL!)
avPlayer.replaceCurrentItem(with: playerItem)
That's it. Now you can reuse existing avPlayer.
Instead of adding new subview with AVPlayerLayer every time user clicks next, you should reuse the AVPlayerLayer that you've already added to play the next video. In your code, you're trying to add the WelcomeView again as the subview but it's already is a subview and the previous layer has all the properties that you've set to it and you don't need to repeat that.
#objc func nextOutboarding(sender: UITapGestureRecognizer) {
WelcomeView?.pageControl.currentPage += 1
if WelcomeView?.pageControl.currentPage == 1 {
avPlayer.pause()
let theURL = Bundle.main.url(forResource:"welcome2", withExtension: "MP4")
avPlayer = AVPlayer(url: theURL!)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayer.play()
}
}

How to play video in fullscreen size in portrait mode?

I want to play some video in splash screen in portrait mode - full screen.
Is that possible? please guide me through a proper solution.
I'm looking for swift solution
create a subclass of UIView, with a AVPlayer and a function createBackground:
import AVFoundation
class BackgroundVideo: UIView {
var player: AVPlayer?
func createBackground(name: String, type: String) { }
}
then your createBackground might be something like:
func createBackground(name: String, type: String) {
guard let path = Bundle.main.path(forResource: name, ofType: type) else { return }
player = AVPlayer(url: URL(fileURLWithPath: path))
player?.actionAtItemEnd = AVPlayerActionAtItemEnd.none;
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.frame
playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.layer.insertSublayer(playerLayer, at: 0)
player?.seek(to: kCMTimeZero)
player?.play()
}
then you may add more stuff, such as observing notifications:
AVPlayerItemDidPlayToEndTime for implementing a video loop.
UIApplicationWillEnterForeground for controlling the video loop, after resuming from background.
finally you might attach this BackgroundView, wherever you need: fake splash screen, home screen, and so on...
SWIFT 3.0
You can not do that in default splash screen but you can do some workaround to acheive this.
First of all you should take first frame of your video which will be image.
You can do that using photoshop or by any other graphics tool.
Now you can set it to you default splash screen in UIImageView.
Now make a UIViewController and launch that as initial view controller.
And below is the code to play video
private func playFullScreenVideo() {
// drag your video file in project
// check if video file is available,if not return
guard let path = Bundle.main.path(forResource: "video", ofType:"mp4") else {
debugPrint("video.mp4 missing")
return
}
// create instance of videoPlayer with video path
let videoPlayer = AVPlayer(url: URL(fileURLWithPath: path))
// create instance of playerlayer with videoPlayer
let playerLayer = AVPlayerLayer(player: videoPlayer)
// set its videoGravity to AVLayerVideoGravityResizeAspectFill to make it full size
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
// add it to your view
playerLayer.frame = self.view.frame
playerView.layer.addSublayer(playerLayer)
// start playing video
videoPlayer?.play()
}
Let me know if having any trouble in this
Inside didFinishLaunch method of app delegate
let splashScreenVC = viewController(withIdentifier: "identifier", inStoryboard: "storyboard:) as? SplashViewController
window?.rootViewController = splashScreenVC
Inside the view controller SplashViewController, you can play video in viewDidLoad method.
func playVideo() {
guard let videoPath = Bundle.main.path(forResource: "Redtaxi-splash", ofType:"mov") else {
return
}
let videoURL = URL(fileURLWithPath: videoPath)
let player = AVPlayer(url: videoURL)
playerViewController = AVPlayerViewController()
playerViewController?.player = player
playerViewController?.showsPlaybackControls = false
playerViewController?.view.frame = view.frame
playerViewController?.view.backgroundColor = .white
playerViewController?.view.contentMode = .scaleAspectFill
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying(note:)),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)
view.addSubview((playerViewController?.view)!)
playerViewController?.player?.play()
}

add AVPlayerViewController view to external window

I want to programmatically add an AVPlayerViewController view to an external window from an iPad. The problem is that when adding it, the player view says "This video is playing on the TV"
example code:
let player = AVPlayer(url: someUrl)
//these two properties seem to have no effect
//player.usesExternalPlaybackWhileExternalScreenIsActive = true/false
//player.allowsExternalPlayback = true/false
let viewController = AVPlayerViewController()
viewController.player = player
viewController.view.frame = frame
externalWindow.addSubview(viewController.view)
player.play()
Is there a way to add the video view myself to the external window so I can decide the size?
If you want to control the size of the AVPlayerViewController you can use the layer or you can add it as a childViewController
Using Layer
let videoURL = URL(url to your file)
let player = AVPlayer(url: videoURL!)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
player.play()
In the above code the frame can be adjusted as per the requirement.
Using ChildViewController:
let videoURL = URL(fileURLWithPath: videoPath)
let player = AVPlayer(url: videoURL)
let playerViewController = AVPlayerViewController()
playerViewController.view.frame = CGRect(give the appropriate size)
playerViewController.player = player
self.addChildViewController(playerViewController)
self.view.addSubview(playerViewController.view)
playerViewController.didMove(toParentViewController: self)
Let me know if this helps!! or anything else is needed.

Video not opening when button is clicked in Swift 3/4?

I am trying to build an app where I have a button and when you click on a button it should open the video. But for some reason, the button is being tapped but not opening the video. Can any one check, what I have done wrong. The video is in my Folder Directory in Xcode.
Code:
var playerview = AVPlayer()
var playerviewcontroller = AVPlayerViewController()
#IBAction func playBtnTapped(_ sender: Any) {
//print("btn tapped")
let videoURL = URL(string: "Promo.mp4")
let player = AVPlayer(url: videoURL!)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
player.play()
}
I got it to solved by doing and using the AVPlayerViewController:
let videoURL = Bundle.main.url(forResource: "Promo", withExtension: ".mp4")
let player = AVPlayer(url: videoURL!)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
Try this as url:
Bundle.main.url(forResource: "Promo", withExtension: ".mp4")

Resources