Looking to add an image overlay to this video I have playing in fullscreen. I was wondering what the best route would be to achieve this? This will be a PNG image with transparency. Thanks for any help in advance!
import UIKit
import AVKit
import AVFoundation
class videoViewController: UIViewController, UIApplicationDelegate{
var videoPlayer: AVPlayer!
var playerLayer: AVPlayerLayer?
override func viewDidLoad() {
super.viewDidLoad()
let path = NSBundle.mainBundle().pathForResource("video", ofType:"mp4")
let url = NSURL(fileURLWithPath: path!)
let playerItem = AVPlayerItem(URL: url)
self.videoPlayer = AVPlayer(playerItem: playerItem)
self.playerLayer = AVPlayerLayer(player: self.videoPlayer)
self.playerLayer!.frame = self.view.frame
self.videoPlayer!.play()
self.view.layer.addSublayer(self.playerLayer!)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("continueVideo:"), name: "continueVideo", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("playerDidReachEnd:"), name: AVPlayerItemDidPlayToEndTimeNotification, object:nil)
}
func playerDidReachEnd(notification: NSNotification) {
self.videoPlayer.seekToTime(kCMTimeZero)
self.videoPlayer.play()
}
func continueVideo(notification: NSNotification) {
self.videoPlayer.play()
}
func applicationWillResignActive(application: UIApplication) {
videoPlayer.pause()
}
func applicationDidBecomeActive(application: UIApplication) {
videoPlayer.play()
}
func applicationDidEnterBackground(application: UIApplication) {
videoPlayer.pause()
}
func applicationWillEnterForeground(application: UIApplication) {
videoPlayer.play()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Related
I have splash screen as a short mov video for my application and I use AVPlayer (code below) for that. It stopped working with the IOS 14 physical device, while on the simulator it works fine. Could you help with that?
import UIKit
import AVKit
import AVFoundation
class PlayerVC: UIViewController, AVAudioPlayerDelegate {
lazy var player: AVPlayer = {
let fileName = "test"
let path = Bundle.main.path(forResource: fileName, ofType: "mov")!
let videoURL = URL(fileURLWithPath: path)
let player = AVPlayer(url: videoURL)
return player
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(viewTapped)))
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.shouldRasterize = true
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
player.play()
NotificationCenter.default.addObserver(self, selector: #selector(self.playerDidFinishPlaying(sender:)), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)
}
#objc func playerDidFinishPlaying(sender: NSNotification) {
loadRootVC()
}
private func loadRootVC() {
dismiss(animated: false, completion: nil)
self.onVideoFinished();
}
#objc func viewTapped() {
loadRootVC()
}
deinit {
NotificationCenter.default.removeObserver(self)
}
}
I have an initial screen with a button on it which when you press it a video plays. Then once the film has ended I want the video to close and it to go to a different screen. At the moment I am able to make the button play the video and then when the video ends make the video close but it returns to the initial screen. Can some help? I have pasted my code below.
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
let playerViewController = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func playButton(_ sender: AnyObject) {
let movieURL = Bundle.main.url(forResource: "video", withExtension: "mp4")!
let player = AVPlayer(url: movieURL as URL)
playerViewController.player = player
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerViewController.player?.currentItem)
self.present(playerViewController, animated: true) {
self.playerViewController.player!.play()
}
}
#objc func playerDidFinishPlaying(note: NSNotification) {
self.playerViewController.dismiss(animated: true)
}
}
What do you mean by "finished"?
is it mean the video is ended or user close the viewcontroller or other?
for when the video finish, you need to use NotificationCenter
func playVideo(url: URL) {
let playerItem = AVPlayerItem(asset: AVURLAsset(url: someVideoUrl))
NotificationCenter.default.addObserver(self, selector: #selector(playerItemDidPlayToEndTime), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerItem)
self.player.replaceCurrentItem(with: playerItem)
self.player.play()
}
func playerItemDidPlayToEndTime() {
// load next video or something
}
for when user close AVPlayerViewController,
you can check AVPlayerViewControllerDelegate , it have several method that may fulfill your need
I want to end up applying this code to make my app look a little nicer when users are logging into their social media accounts. I've tried the following code already but my app seems to crash as soon as the mp4 ends.
import UIKit
import AVFoundation
class ViewController: UIViewController {
var avPlayer: AVPlayer!
var avPlayerLayer: AVPlayerLayer!
var paused: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
let theURL = Bundle.main.url(forResource: "Yeet", withExtension: "mp4")
avPlayer = AVPlayer(url: theURL!)
avPlayerLayer = AVPlayerLayer(player: avPlayer)
avPlayerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
avPlayer.volume = 0
avPlayer.actionAtItemEnd = AVPlayer.ActionAtItemEnd.none
avPlayerLayer.frame = view.layer.bounds
view.backgroundColor = UIColor.clear;
view.layer.insertSublayer(avPlayerLayer, at: 0)
NotificationCenter.default.addObserver(self, selector: Selector(("playerItemDidReachEnd:")), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: avPlayer.currentItem)
}
#objc func playerItemDidReachEnd(notification: NSNotification) {
let p: AVPlayerItem = notification.object as! AVPlayerItem
p.seek(to: CMTime.zero)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidDisappear(animated)
avPlayer.play()
paused = false
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
avPlayer.pause()
paused = true
}
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Have you tried using AVPlayerLooper?
Looks like #iwasrobbed has a solution for iOS 10+ devices. Here's the example code:
private var looper: AVPlayerLooper?
...
let queuePlayer = AVQueuePlayer(playerItem: item)
looper = AVPlayerLooper(player: queuePlayer, templateItem: item)
videoPlayerLayer.player = queuePlayer
To disable the loop after leaving the view, add this piece of code in the end:
looper?.disableLooping()
I am making a simple iPad app to play a movie when a button is pressed. The movie plays and when the movie is finished I want to close AVPlayerView so it goes back to the main screen.
Currently when the video finishes it stays on the last frame.
My ViewController.Swift at the moment.
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
//MARK : Properties
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
//MARK: Actions
#IBAction func playButton(_ sender: AnyObject) {
let movieURL = Bundle.main.url(forResource: "ElephantSeals", withExtension: "mov")!
let player = AVPlayer(url: movieURL as URL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
// player.actionAtItemEnd = playerViewController.dismiss(animated: true)
}
}
As you can see, I think there might be something in actionAtItemEnd, but I'm not sure how to implement it.
Thank you.
This is working code in swift 5.3 and iOS 14.2, try this and let me know...:)
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
let playerViewController = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func playButton(_ sender: AnyObject) {
let movieURL = Bundle.main.url(forResource: "ElephantSeals", withExtension: "mp4")!
let player = AVPlayer(url: movieURL as URL)
playerViewController.player = player
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerViewController.player?.currentItem)
self.present(playerViewController, animated: true) {
self.playerViewController.player!.play()
}
}
#objc func playerDidFinishPlaying(note: NSNotification) {
self.playerViewController.dismiss(animated: true)
}
}
You can download sample project for same from here
https://github.com/deepakiosdev/AVPlayerViewControllerDemo
Swift 4
let playerController = AVPlayerViewController()
private func playVideo() {
guard let path = Bundle.main.path(forResource: "p810", ofType:"mp4") else {
debugPrint("video.m4v not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
playerController.player = player
NotificationCenter.default.addObserver(self, selector: #selector(playerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: playerController.player?.currentItem)
present(playerController, animated: true) {
player.play()
}
}
#objc func playerDidFinishPlaying(note: NSNotification) {
playerController.dismiss(animated: true, completion: nil)
}
Using NSNotificationCenter you can do this .
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.playerDidFinishPlaying), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: videoPlayer!.currentItem)
#objc func playerDidFinishPlaying(note: NSNotification) {
// here you can do your dismiss controller logic
AVPlayerViewController.dismiss(animated: true)
print("Video Finished")
}
here is objective c code
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(nextVideo:) name:AVPlayerItemDidPlayToEndTimeNotification object:playerViewController.player.currentItem];
Invoke AVPlayerViewControllerDelegate.
In viewDidLoad initialize the delegate and implement this method
func playerViewControllerDidStopPictureInPicture(AVPlayerViewController) {
AVPlayerViewController.dismiss(animated: true)
}
https://developer.apple.com/reference/avkit/avplayerviewcontrollerdelegate
I've got some problems with video on my app's background.
Here is my program code:
import UIKit
import AVKit
import AVFoundation
class IntroViewController: UIViewController {
var player: AVPlayer?
override func viewDidLoad() {
super.viewDidLoad()
let videoURL: NSURL = NSBundle.mainBundle().URLForResource("intro", withExtension: "mov")!
player = AVPlayer(URL: videoURL)
player?.actionAtItemEnd = .None
player?.muted = false
let playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
playerLayer.zPosition = -1
playerLayer.frame = view.frame
view.layer.addSublayer(playerLayer)
player?.play()
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "loopVideo",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: nil)
}
func loopVideo() {
player?.seekToTime(kCMTimeZero)
player?.play()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
After launching my program, the Music app is muted. How do I fix it?
And one more question: after returning to this screen from home screen, without closing the app, video stops. Where is the problem?