AVPlayerViewController inside a view is not showing the playback controls - ios

I am working with apple tv. I have a UIView inside my UIViewController. I am adding AVPlayerViewController as subview of my UIView. UIView's frame is CGRect(x: 50, y: 50, width: 1344, height: 756). I am setting AVPlayerViewController frame equals to my UIView's frame.
Issue is that video plays fine in its frame but the controls like pause, play, forward etc. are hidden and not working. But when I set frame as CGRect(x: 0, y: 0, width: 1920, height: 1080), controls are visible and working.
My code is as per below:
let url = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let item = AVPlayerItem(url: url!)
self.player = AVPlayer(playerItem: item)
self.avplayerController = AVPlayerViewController()
self.avplayerController.player = self.player
self.avplayerController.view.frame = videoPreviewLayer.frame
self.avplayerController.showsPlaybackControls = true
self.avplayerController.requiresLinearPlayback = true
self.addChildViewController(self.avplayerController)
self.view.addSubview(self.avplayerController.view)
self.avpController.player?.play()
Please help.

I managed to solve this using this code:
let player = AVPlayer(url: self.videoUrl!)
let avPlayerController = AVPlayerViewController()
avPlayerController.player = player;
avPlayerController.view.frame = self.videoPlayView.bounds;
self.addChildViewController(avPlayerController)
self.videoPlayView.addSubview(avPlayerController.view);
Now AVPlayerViewController shows most playback controls even as child to a uiview.
Courtesy:
https://www.techotopia.com/index.php/IOS_8_Video_Playback_using_AVPlayer_and_AVPlayerViewController

This is an expected behaviour:
AVPlayerViewController is designed such that when in full screen, the
full playback experience (scrubbing, info panel access, etc) are all
available. When in a space less than full screen, the assumption is
that it is just one of several interactive elements on screen, and
thus the view should not absorb all touch surface events as transport
control.
You can read more about this on this thread: https://forums.developer.apple.com/thread/19526

Related

Presenting UIView on AVPlayerViewController Fullscreen View

Problem: I need to add a UIView on top of an AVPlayer in a way that it is still user-interactive. When I try to add it as Overlay Content, any user interactive button will not fire anymore (as it is behind the video control layer).
Desired effect: I'd like to be able to add an UIView on top of an AVPlayer so that it is kept on top of the whole view at all times even when it enters fullscreen mode.
Sample Code:
var view = UIView = {
let view = UIView()
view.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
view.backgroundColor = .red
return view
}
var player = AVPlayer(url: http://somewhere.com/video.format)
let controller = AVPlayerViewController()
controller.player = player
Apparently, the best way to solve this issue was just adding a touchable element into the AVPlayerController, which redirected any touch event to the respective selector.

make AVPlayer fill the entire screen

I have an app where I'd like a video to play in the background of a single view.
What I did is create an AVPlayer, add that to an AVPlayerLayer and add that as a sublayer to my view.
Then I set the frame and the videoGravity property:
self.player = AVPlayer(url: URL(fileURLWithPath: path))
let playerLayer = AVPlayerLayer(player: self.player)
self.layer.addSublayer(playerLayer)
playerLayer.frame = self.bounds
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
Now the video plays, except it doesn't fill the entire screen. It fills it's original size, but it doesn't stretch/scale.
Am I missing something? Why is my video not resizing?
Thanks.
Edit:
I added a screenshot and made the view purple for easier reference.
If you want to video to be stretch on the entire view, just delete the line
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
videoGravity default value is AVLayerVideoGravityResize
Update for Swift 5
playerLayer.videoGravity = .resizeAspectFill
Define the playerLayer.frame inside viewDidLayoutSubviews()
At the time you are defining the frames the final frames for the views were not yet calculated.

AVPlayer get rid of black bars/background at top & bottom (Swift)

Quick question, does anybody know how i can get rid of the black bars at the top and bottom of my video? I just started using AVPlayer and i'm just removing codes here and there in attempt to remove the black layers. Appreciate those who can help me, Thanks!
UIViewController
import UIKit
import AVKit
import AVFoundation
private var looper: AVPlayerLooper?
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let path = Bundle.main.path(forResource: "Innie-Kiss", ofType:"mp4")
let player = AVQueuePlayer(url: URL(fileURLWithPath: path!))
looper = AVPlayerLooper(player: player, templateItem: AVPlayerItem(asset: AVAsset(url: URL(fileURLWithPath: path!))))
let controller = AVPlayerViewController()
controller.player = player
let screenSize = UIScreen.main.bounds.size
let videoFrame = CGRect(x: 0, y: 200, width: screenSize.width, height: (screenSize.height - 130) / 2)
controller.view.frame = videoFrame
self.view.addSubview(controller.view)
player.play()
}
}
You need to set the videoGravity of the AVLayer. The default value is .resizeAspect which will preserve the aspect ratio with black bars on top/bottom or left/right. What you want is .resize
The AVLayer you need to set the videoGravity on is the layer property of your AVPlayer.
see this for more info: https://developer.apple.com/documentation/avfoundation/avplayerlayer/1388915-videogravity
#import AVKit
var playerController = AVPlayerViewController()
playerController.videoGravity = .resizeAspect
/*playerController.videoGravity = .resizeAspectFill*/
playerController.view.backgroundColor = UIColor.white //set color as per super or custom view.
Note: If you set the videoGravity of the AVPlayerViewController. The default value is .resizeAspect then it is possible to visibility of black color(default) in background if you wants this color would similar to your super view's color then you must set superview's or custom view's color to your playercontroller's view background color.
*Example:Suppose super view's or custom view's background color is white then playerController view's background color must be set as playerController.view.backgroundColor = UIColor.white *
Note :playerController's backgroundColor should not be set as UIColor.white ,always. It must me set as super view' background color.
If you set playerController.videoGravity = .resizeAspectFill then it will fill the player content to super view or custom view, here also no black color would be shown. So choose either .resizeAspect or resizeAspectFill as per your requirements.

AVPlayerLayer frame doesn't fit into UIView for video player

I'm trying to display a video with this code:
self.videoPlayer = AVPlayer.init(url: videoUrl as URL)
let playerLayer = AVPlayerLayer.init(player: self.videoPlayer)
self.videoPlayerView.layer.addSublayer(playerLayer)
playerLayer.frame = self.videoPlayerView.layer.bounds
self.videoPlayer.play()
but it does not appear inside of the UIView (i.e. self.videoPlayerView). It just shows a thin Rect at the middle of the screen as shown in the screenshot. How do I fix this?
screen shot
try this...
set the layer's frame to equal the view's frame
self.videoPlayer = AVPlayer.init(url: videoUrl as URL)
let playerLayer = AVPlayerLayer.init(player: self.videoPlayer)
self.videoPlayerView.layer.addSublayer(playerLayer)
playerLayer.frame = self.videoPlayerView.frame
self.videoPlayer.play()
Firstly the code is in Swift not Obective-C, I would change that tag! Secondly, how do you define the videoPlayerView frame? Thirdly, you change the frame of the playerLayer after it has already been added. Thus the frame will not change visually! Set the frame before you add it as a subLayer. Hope that helps.

AVPlayer subview resize when device is rotated

I am having a problem when the iPad is rotated the sub views frame needs to be changed to landscape as well.
The video is used as a landing screen on the home page and is played behind various elements on the page.
The problem is shown here
I currently have the code that detects if the screen is in landscape or horizontal which will be used to make the changes to the sub view if possible.
The player is set up using the code shown:
player = AVPlayer(URL: contentURL!)
player.actionAtItemEnd = .None
player.muted = true
let playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
playerLayer.zPosition = -1
playerLayer.frame = view.frame
view.layer.addSublayer(playerLayer)
player.play()
Any help would be appreciated, thank you.

Resources