How to embed a local video into a UIView in ios 12 - ios

The code I was using to embed a local video in a UIView isn't working on IOS 12. The audio is playing but I get a black screen.
from apple developer site:
Do not subclass AVPlayerViewController. Overriding this class’s methods is unsupported and results in undefined behavior.
the code works fine on IOS 11, any idea what do I need to change in the code?
thanks
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
var avPlayer: AVPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let filepath: String? = Bundle.main.path(forResource: "qidong", ofType: "mp4")
let fileURL = URL.init(fileURLWithPath: filepath!)
avPlayer = AVPlayer(url: fileURL)
let avPlayerController = AVPlayerViewController()
avPlayerController.player = avPlayer
avPlayerController.view.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
avPlayerController.showsPlaybackControls = false
avPlayerController.player?.play()
self.view.addSubview(avPlayerController.view)
}
}

You need to add the AVPlayerViewController as a child view controller so something like this:
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
var avPlayer: AVPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let filepath: String? = Bundle.main.path(forResource: "qidong", ofType: "mp4")
let fileURL = URL.init(fileURLWithPath: filepath!)
avPlayer = AVPlayer(url: fileURL)
let avPlayerController = AVPlayerViewController()
avPlayerController.player = avPlayer
avPlayerController.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
avPlayerController.showsPlaybackControls = false
avPlayerController.player?.play()
self.addChild(avPlayerController)
self.view.addSubview(avPlayerController.view)
avPlayerController.didMove(toParent: self)
}
If you are not doing that then the AVPlayerViewController is probably getting released early.
Another minor issue but don't use the size of the UIScreen but the frame of the view controllers view instead (or even better do something like use auto layout).

Related

Application tried to present modally a view controller that has a parent view controller crash

Thread 1: "Application tried to present modally a view controller <AVPlayerViewController: 0x15f83ee00> that has a parent view controller <ValorantAgentsApp.AbilitiesDetailsViewController: 0x15e918670>."
I get error when tried to play video in my app. My application crashes when it comes to the screen where I will play a video. I don't have a problem when I play the video with by pressing a button. But when I want to play as the screen loads, I get a crash.
import UIKit
import AVKit
import AVFoundation
import MediaPlayer
import MobileCoreServices
class AbilitiesDetailsViewController: UIViewController, AVPlayerViewControllerDelegate {
#IBOutlet var skillDetailsLabel: UILabel!
#IBOutlet var skillNameLabel: UILabel!
#IBOutlet var heroIconImageView: UIImageView!
var agentAbilitiesVideoURL = ""
var choosenAgentSkillName = ""
var choosenAbilitiesImages : UIImage?
override func viewDidLoad() {
skillNameLabel.text = choosenAgentSkillName
heroIconImageView.image = choosenAbilitiesImages
super.viewDidLoad()
playAbilitiesVideos()
}
func playAbilitiesVideos() {
let player = AVPlayer(url: URL(string: agentAbilitiesVideoURL)!)
let controller = AVPlayerViewController()
present(controller, animated: true) { }
controller.player = player
addChild(controller)
view.addSubview(controller.view)
controller.view.frame = CGRect(x: 50 , y: 50, width: 300, height: 300)
controller.player = player
controller.showsPlaybackControls = true
player.isClosedCaptionDisplayEnabled = false
player.play()
}
/*
#IBAction func playVideoUsingURL(_ sender: Any) {
playGlobalVideo()
}
func playGlobalVideo() {
guard let videoURL = URL(string: agentAbilitiesVideoURL) else {
return
}
let player = AVPlayer(url: videoURL)
let vc = AVPlayerViewController()
vc.player = player
present(vc, animated: true) {
player.play()
}
}
*/
}
This is my third screen and view controller.
either do:
view.addSubview(controller.view)
OR
present(controller, animated: true) { }
not both

Video player in iOS 13 and SWIFT 5 is not working

I am trying to create a simple video player using iOS 13 and SWIFT 5. Below you will see my few lines of code but when I run the app all I see is a blank screen. I hear the video but it is not until I rotate the screen that I even see a section of the video. In my project the "video" appears to be just a photo. The video is not even moving it is just the still image you see in the example below. I am new to iOS/SWIFT but this is the oddest problem I have encountered so far. What am I doing wrong?
ViewController:
import UIKit
import AVFoundation
class ViewController: UIViewController {
var playerLayer = AVPlayerLayer()
override func viewDidLoad() {
super.viewDidLoad()
playVideo()
}
func playVideo(){
let videoURL = URL(string: "https://www.radiantmediaplayer.com/media/bbb-360p.mp4")
let player = AVPlayer(url: videoURL!)
playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = .resizeAspect
self.view.layer.addSublayer(playerLayer)
player.play()
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
playerLayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
}
}
Give the frame for the playerLayer in playVideo method like this:
playerLayer.frame = view.bounds

Playing video on login page as full screen

I want to play background video on login screen on swift 3.0. But when I run program, video do not working as full screen. It is workingHow can I fix this ? Here is the storyboard picture.
enter code here
import UIKit
import AVFoundation
class ViewController: UIViewController {
var Player: AVPlayer!
var PlayerLayer: AVPlayerLayer!
var frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let URL:NSURL = NSURL(string: "https://firebasestorage.googleapis.com/v0/b/pattyapp-34c16.appspot.com/o/dog1.mp4?alt=media&token=98ab3c41-c645-4535-a70b-41511b5df602")!
Player = AVPlayer.init(url: URL as URL)
PlayerLayer = AVPlayerLayer(player: Player)
PlayerLayer.videoGravity = AVLayerVideoGravityResizeAspect
PlayerLayer.frame.size = frame.size
Player.actionAtItemEnd = AVPlayerActionAtItemEnd.none
Player.isMuted = true
Player.play()
view.layer.insertSublayer(PlayerLayer, at: 0)
NotificationCenter.default.addObserver(self, selector: #selector(playerItemReachEnd(notification:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: Player.currentItem)
}
func playerItemReachEnd(notification: NSNotification) {
Player.seek(to: kCMTimeZero)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Play video into background you can use the following list of 3rd party library to resolve your problem.
VideoSplashKit
HAPlayerView
Video You are trying to play has dimensions different from layer size. I'd recommend You to try
PlayerLayer.videoGravity = AVLayerVideoGravityResize
or
PlayerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill

problems while playing video from s3 using AVplayer

Hi all i am trying to play a video from s3 using Avplayer. Now if i play the video, the video starts playback after the whole video is buffered. so I added player.automaticallyWaitsToMinimizeStalling = false, but now the video automatically pauses
import UIKit
import AVFoundation
import AVKit
class ViewController: UIViewController {
var player: AVPlayer!
var item : AVPlayerItem!
override func viewDidLoad() {
super.viewDidLoad()
item = AVPlayerItem(url: URL(string: "https://cent-churchconnect.s3-ap-southeast-2.amazonaws.com/cent-churchconnect/testAdmin/eb8cc8b5-80e0-468a-a2c9-979cf1b5ac76_toystory.mp4")!)
player = AVPlayer(playerItem: item)
let controller = AVPlayerViewController()
present(controller, animated: true) { _ in }
controller.player = player
addChildViewController(controller)
view.addSubview(controller.view)
controller.view.frame = CGRect(x: 0, y: 50, width: self.view.frame.size.width, height: 300)
controller.player = player
controller.showsPlaybackControls = true
if #available(iOS 10.0, *) {
player.automaticallyWaitsToMinimizeStalling = false
player.play()
} else {
// Fallback on earlier versions
}
}
}
I had the same issue below steps worked for me,
Try to use method func playImmediately(atRate:) and make sure the property player.automaticallyWaitsToMinimizeStalling = false is set properly.
Use method func playImmediately(atRate:) instead of func play()
I used the cocoa pod https://github.com/piemonte/Player.
You can use the delegate methods to control the playback.

MPMoviePlayerController Stops Playing After 5 seconds - Swift

I have a video I'm trying to play using MPMoviePlayerController and it loads fine, but cuts out after 5 seconds. I found this post, but it isn't really applicable for swift.
MPMoviePlayerController stops playing the video after 5s
Here is my code.
import MediaPlayer
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var moviePlayer: MPMoviePlayerController?
let url = NSURL(string: "http://path/to/video.m3u8")
moviePlayer = MPMoviePlayerController(contentURL: url)
if let player = moviePlayer {
player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)
player.view.sizeToFit()
player.scalingMode = MPMovieScalingMode.None
player.movieSourceType = MPMovieSourceType.Streaming
//player.repeatMode = MPMovieRepeatMode.One
player.play()
self.view.addSubview(player.view)
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "metadataUpdated",
name: MPMoviePlayerTimedMetadataUpdatedNotification,
object: nil)
}
}
Could your moviePlayer be going out of scope? Have you tried making it a member variable?
moviePlayer is a local variable of viewDidLoad, so once that function finishes, I don't see any reason why your player would not be deallocated.
If you instead make it a variable of the class, its lifetime will be extended to match your class's lifetime.
something like
class ViewController: UIViewController {
var player: MPMoviePlayerController?
override func viewDidLoad() {
// ...
self.player = MPMoviePlayerController(contentURL: url) // won't go out of scope at end of viewDidLoad()
// ...
}

Resources