AVPlayer ,black screen after video is over - swift

i have black screen after video is over, but i would like to be redirect to another storyboard when video is over.
Could somebody help me with this.
Thanks you
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
playVideo()
}
private func playVideo() {
guard let path = Bundle.main.path(forResource: "Kristinka", ofType:"m4v") else {
debugPrint("video.m4v not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.showsPlaybackControls = false
playerController.player = player
present(playerController, animated: true) {
player.play()
}
}
}

You need to detect when the item you're playing has reached the end. To do that, you can add an observer. For example:
func finishedVideo(_ notification: NSNotification) {
print("Animation did finish")
}
private func playVideo() {
guard let path = Bundle.main.path(forResource: "Kristinka", ofType:"m4v") else {
debugPrint("video.m4v not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.showsPlaybackControls = false
playerController.player = player
present(playerController, animated: true) {
NotificationCenter.default.addObserver(self,
selector: #selector(finishedVideo(_:)),
name: .AVPlayerItemDidPlayToEndTime,
object: player?.currentItem)
player.play()
}
}
And I dug this code up on this very related question. There's a lot of related/duplicate answers if you do a search.

Related

how to have separate videos that play with separate buttons

can anyone please help me, I am trying to add separate buttons to play separate videos in the same view controller but I don't know how to.
this is my code, how do I do this?
import UIKit
import AVKit
class ViewController: UIViewController {
#IBAction func Town(_ sender: Any) {
if let path = Bundle.main.path(forResource: "grey", ofType: "mov") {
let video = AVPlayer(url: URL(fileURLWithPath: path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
self.present(videoPlayer, animated: true, completion: {
video.play()
})
}
func viewDidLoad() {
super.viewDidLoad()
}
}
}
To play 2 videos simultaneously in same viewController, you need to create 2 separate views and 2 respective buttons in your Storyboard.
Remaining functionality will go inside your IBActions.
Please use following code:
class VideoPlaybackViewController: UIViewController {
#IBOutlet weak var videoView1: UIView!
#IBOutlet weak var videoView2: UIView!
#IBAction func playFirstVideo(_ sender: Any) {
guard let path = Bundle.main.path(forResource: "640", ofType: "mov") else {
print("Video Source Not Found")
return
}
playVideo(playbackURL: URL(fileURLWithPath: path), playerView: videoView1)
}
#IBAction func playSecondVideo(_ sender: Any) {
guard let path = Bundle.main.path(forResource: "720", ofType: "mov") else {
print("Video Source Not Found")
return
}
playVideo(playbackURL: URL(fileURLWithPath: path), playerView: videoView2)
}
func playVideo(playbackURL: URL, playerView: UIView) {
let player = AVPlayer(url: playbackURL)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = playerView.bounds
playerView.layer.addSublayer(playerLayer)
player.play()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
}
Please see the screen with this implementation
I used this code and it worked perfectly
import UIKit
import AVKit
class ViewController: UIViewController {
#IBOutlet weak var videoView1: UIButton!
#IBOutlet weak var videoView2: UIButton!
#IBAction func playFirstVideo(_ sender: Any) {
if let path = Bundle.main.path(forResource: "grey", ofType: "mov") {
let video = AVPlayer(url: URL(fileURLWithPath: path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
self.present(videoPlayer, animated: true, completion: {
video.play()
})
}
}
#IBAction func playSecondVideo(_ sender: Any) {
if let path = Bundle.main.path(forResource: "go", ofType: "mov") {
let video = AVPlayer(url: URL(fileURLWithPath: path))
let videoPlayer = AVPlayerViewController()
videoPlayer.player = video
self.present(videoPlayer, animated: true, completion: {
video.play()
})
}
}
}

How to make a video loop in Xcode swift 5?

I am trying to get a video background in my app and I have written the following code. It runs one time and then stops. How do I make the video repeat forever? Thanks in advance.
#IBOutlet weak var videoLayer: UIView!
override func viewDidLoad() {
super.viewDidLoad()
playBackgroundVideo()
}
func playBackgroundVideo(){
guard let path = Bundle.main.path(forResource: "City", ofType: "MOV") else {
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.bounds
playerLayer.videoGravity = .resizeAspectFill
self.videoLayer.layer.addSublayer(playerLayer)
player.play()
}
#objc func playerItemDidReachEnd(notification: Notification) {
let p: AVPlayerItem = notification.object as! AVPlayerItem
p.seek(to: .zero)
}
}
Try adding a notification listener to trigger the playerItemDidReachEnd code.
You do this by involving a NotificationCenter.default.addObserver in your setup.
Did not test your code, but you want a setup like this example:
#IBOutlet weak var videoLayer: UIView!
var player: AVPlayer!
override func viewDidLoad()
{
super.viewDidLoad()
playBackgroundVideo()
}
func playBackgroundVideo()
{
guard let path = Bundle.main.path(forResource: "City", ofType: "MOV") else{ return }
player = AVPlayer(url: URL(fileURLWithPath: path))
let playerLayer = AVPlayerLayer(player: player)
//# add a Listener
NotificationCenter.default.addObserver( self,
selector: #selector(playerItemDidReachEnd),
name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
object: nil)
playerLayer.frame = self.view.bounds
playerLayer.videoGravity = .resizeAspectFill
self.videoLayer.layer.addSublayer(playerLayer)
player.play()
}
#objc func playerItemDidReachEnd(notification: Notification)
{
player.seek(to: CMTime.zero)
player.play()
}

Can't solve this? How would you fix this? "Variable binding in a condition requires an initializer" and "Expected '{' after 'if' condition"

The title summarized my problem. I'm new to coding and I don't understand how to solve the problem.
I've tried pretty much all I know.
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
#IBOutlet weak var PowerLVLlabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func randomNumber(_ sender: Any) {
let randomNumber = Int.random(in: 1000...10000)
PowerLVLlabel.text = String(randomNumber)
if case { randomNumber; >=9000 == (true);
func playVideo() {
guard let path = Bundle.main.path(forResource: "over 9000", ofType:"mp4") else {
debugPrint("over 9000.mp4 not found")
return
}
{let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
present(playerController, animated: true) }
{player.play()
}
try this:
func playVideo(){
guard let path = Bundle.main.path(forResource: "over 9000", ofType:"mp4") else {
debugPrint("over 9000.mp4 not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
present(playerController, animated: true)
player.play()
}
#IBAction func randomNumber(_ sender: Any) {
let randomNumber = Int.random(in: 1000...10000)
PowerLVLlabel.text = String(randomNumber)
if randomNumber >= 9000{
playVideo()
}
}
You need to get playVideo function out of randomNumber and remove some un needed ; and {}
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet weak var powerLVLlabel: UILabel!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func playVideo() {
guard let path = Bundle.main.path(forResource: "over 9000", ofType:"mp4") else {
debugPrint("over 9000.mp4 not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
present(playerController, animated: true)
player.play()
}
#IBAction func randomNumber(_ sender: Any) {
let randomNumber = Int.random(in: 1000...10000)
powerLVLlabel.text = String(randomNumber)
if randomNumber >= 9000 {
playVideo()
}
}
}

Play video from Download URL

I have a URL :- "http://fitnation.theclientdemos.com:9000/media/uploads/videoplayback_3_JtVCHi1"
When I run this URL on browser, My VDO starts downloads.
Please help to play this video in a view (let view name is:- vdoView)
For this I am trying below code:-
import UIKit
import AVKit
import AVFoundation
class VideoViewController: UIViewController {
#IBOutlet weak var vdoView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
getVideo()
}
func getVideo(){
let videoURL = URL(string: "http://fitnation.theclientdemos.com:9000/media/uploads/videoplayback_3_JtVCHi1")
let player = AVPlayer(url: videoURL!)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.vdoView.bounds
self.vdoView.layer.addSublayer(playerLayer)
player.play()
}
First you have to import AVKit, import AVFoundation
Using AVPlayer
if let url = URL(string: "http://fitnation.theclientdemos.com:9000/media/uploads/videoplayback_3_JtVCHi1"){
let player = AVPlayer(url: url)
let controller=AVPlayerViewController()
controller.player=player
controller.view.frame = self.view.frame
self.view.addSubview(controller.view)
self.addChildViewController(controller)
player.play()
}
It's better to put this code into the method: override func viewDidAppear(_ animated: Bool) or somewhere after.
override func viewDidLoad()
{
let videoURL = NSURL(string: "http://fitnation.theclientdemos.com:9000/media/uploads/videoplayback_3_JtVCHi1")
let player = AVPlayer(url: videoURL! as URL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
You should try it like this
func getVideo(){
let videoURL = URL(string: "http://fitnation.theclientdemos.com:9000/media/uploads/videoplayback_3_JtVCHi1")
// Create an AVAsset
let videoAsset = AVAsset(url: videoURL!)
// Create an AVPlayerItem with asset
let videoPlayerItem = AVPlayerItem(asset: videoAsset)
// Initialize player with the AVPlayerItem instance.
let player = AVPlayer(playerItem: videoPlayerItem)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.vdoView.bounds
self.vdoView.layer.addSublayer(playerLayer)
player.play()
}
And you should update your plist file to allow the contents from http: Refer here
*All you need is change your code to this:
import AVFoundation
class your class name
var player: AVPlayer?
func playAudio() {
guard let url = URL.init(string: "http://192.168.100.184:9050/uploads/sound/file/1/a1b19343-f785-4d48-b7d5-1abe26c03ff3.mp3" ) else { return }
player = AVPlayer.init(url: url)
}
and at the end call the func in IBAction body*
just like the code below:
#IBAction play (sender: Any) {
playAudio()
}

AVPlayer is not working when I'm trying to use with this YTVimeoExtractor

When I try to play the video through the AVPlayer, the video loads for some time(the loading symbol appears at the top of the player) then suddenly it stops and the play icon with a crossover is shown. Don't know what is wrong? I can get the video informations but I can't make the video to play.
I will show what I have done. Could anyone answer my question, help is much appreciated.
import UIKit
import AVKit
import AVFoundation
class ViewController: UIViewController {
var playerVC : AVPlayerViewController!
var playerItem : AVPlayerItem!
var player : AVPlayer!
var playerLayer: AVPlayerLayer!
#IBOutlet weak var videoURL: UITextField!
#IBOutlet weak var videoTitle: UILabel!
#IBAction func playVideo(sender: AnyObject) {
YTVimeoExtractor.sharedExtractor().fetchVideoWithVimeoURL(self.videoURL.text!, withReferer: nil, completionHandler: {(video, error) -> Void in
if video != nil {
// https://vimeo.com/165891648
self.videoTitle.text = video?.title
print("hello: \(self.videoTitle.text)")
let url = NSURL(string: self.videoURL.text!)
// let url = NSURL.init(fileURLWithPath: self.videoURL.text!)
self.playerItem = AVPlayerItem.init(URL: url!)
self.player = AVPlayer.init(playerItem: self.playerItem)
self.playerVC = AVPlayerViewController.init();
self.playerVC.player = self.player;
self.player.currentItem!.playbackLikelyToKeepUp
self.presentViewController(self.playerVC, animated: true) { () -> Void in
self.playerVC.player?.play()
}
}else {
let alert = UIAlertController(title: error!.localizedDescription, message: error!.localizedFailureReason, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: nil))
self.presentViewController(alert, animated: true, completion: nil)
}
})
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func viewDidAppear(animated: Bool) {
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This is the one I get on the simulator.
I used this https://github.com/lilfaf/YTVimeoExtractor one to do this sample project. You can try it out and let me know.
I had the same issue and fix using this way:
#IBAction func btnDownload_touchUpInside(_ sender: UIButton) {
YTVimeoExtractor.shared().fetchVideo(withVimeoURL: self.videoURL.text!, withReferer: nil, completionHandler: {(video, error) -> Void in
if video != nil {
self.videoTitle.text = video?.title
if let streamUrls = video?.streamURLs
{
var streamURL: String?
var streams : [String:String] = [:]
for (key,value) in streamUrls {
streams["\(key)"] = "\(value)"
print("\(key) || \(value)")
}
if let large = streams["720"]
{
streamURL = large
}
else if let high = streams["480"]
{
streamURL = high
}
else if let medium = streams["360"]
{
streamURL = medium
}
else if let low = streams["270"]
{
streamURL = low
}
if let url = streamURL
{
Alamofire.download(url, to: { (temporaryURL, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
if let directoryURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0] as? NSURL {
let fileName = response.suggestedFilename!
let finalPath = directoryURL.appendingPathComponent(fileName)
self.downloadedVideoPath = finalPath?.absoluteString
return (finalPath!, DownloadRequest.DownloadOptions(rawValue: 2))
}
}).downloadProgress(closure: { (progress) in
print("Progress: \(progress.fractionCompleted)")
})
}
}
}
})
}
#IBAction func btnPlayOffLine_touchUpInside(_ sender: UIButton) {
YTVimeoExtractor.shared().fetchVideo(withVimeoURL: self.videoURL.text!, withReferer: nil, completionHandler: {(video, error) -> Void in
if video != nil {
let videoURL = NSURL(string: self.downloadedVideoPath!)
let player = AVPlayer(url: videoURL! as URL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
})
}
#IBAction func btnPlayOnLine_touchUpInside(_ sender: UIButton) {
YTVimeoExtractor.shared().fetchVideo(withVimeoURL: self.videoURL.text!, withReferer: nil, completionHandler: {(video, error) -> Void in
if video != nil {
self.videoTitle.text = video?.title
if let streamUrls = video?.streamURLs
{
var streamURL: String?
var streams : [String:String] = [:]
for (key,value) in streamUrls {
streams["\(key)"] = "\(value)"
print("\(key) || \(value)")
}
if let large = streams["720"]
{
streamURL = large
}
else if let high = streams["480"]
{
streamURL = high
}
else if let medium = streams["360"]
{
streamURL = medium
}
else if let low = streams["270"]
{
streamURL = low
}
if let url = streamURL
{
let videoURL = NSURL(string: url)
let player = AVPlayer(url: videoURL! as URL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
}
}
}
})
}
}