AVPlayer not working properly - Swift - swift

//Firstly my English very bad, I'm sorry...
I'm implementing AVPlayer my app. Player is working fine but if I play another videos many times Player is not working and only just this screen looks.
Here's my code
let player:AVPlayer?
override func viewDidLoad() {
super.viewDidLoad()
let videoFile = object?.objectForKey("video") as? PFFile
videoFile?.getFilePathInBackgroundWithBlock({ (filePath, error) in
if error == nil {
let videoURL = NSURL(fileURLWithPath: filePath!)
self.player = AVPlayer(URL: videoURL)
let playerController = AVPlayerViewController()
playerController.player = self.player
playerController.showsPlaybackControls = false
playerController.videoGravity = AVLayerVideoGravityResizeAspectFill
playerController.view.frame = self.videoView.bounds
self.videoView.addSubview(playerController.view)
self.addChildViewController(playerController)
self.player!.play()
} else {
print(error)
}
})
}

I don't understand the way you fetch the video object but you can try the following code. It works fine.
var player:AVPlayer! // this shouldn't be let.
override func viewDidLoad() {
super.viewDidLoad()
let query = PFQuery(className:"TestClass") //your classname in parse. Change it with your clas name
query.getObjectInBackgroundWithId("SALe4gX2nk") { // get the video file with id. Change it with your id.
(object: PFObject?, error: NSError?) -> Void in
let videoFile = object?.objectForKey("video") as? PFFile
let url = NSURL(string: (videoFile?.url)!)
self.player = AVPlayer(URL: url!)
let playerController = AVPlayerViewController()
playerController.player = self.player
playerController.showsPlaybackControls = false
playerController.videoGravity = AVLayerVideoGravityResizeAspectFill
playerController.view.frame = self.view.bounds
self.view.addSubview(playerController.view)
self.addChildViewController(playerController)
self.player!.play()
}
}

Related

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()
}

Iterating Videos

I am trying to get the player to iterate through an array of strings that reference the URL of videos. I can only get it to play one of the videos in the array, if I hardcode it in the code, but I cannot do it to iterate.
I have gotten to play one video while it is hard coded in but not iterate.
var playerArray = [AVQueuePlayer]()
var player = AVQueuePlayer()
// var URLSArray = [URL]()
var ItemArray = [AVPlayerItem]()
var videos = ["video1", "video2","video3"]
var playerController = AVPlayerViewController()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let videoNum = (self.videos.count-1)
// var URLSArray = [URL]()
// for n in 0...videoNum{
// let pathString = (Bundle.main.path(forResource: videos[n], ofType: "mov"))
// let StrToURL = NSURL(string: pathString!)
// URLSArray.append(StrToURL! as URL)
// }
var ItemArray = [AVPlayerItem]()
// var playerController = AVPlayerViewController()
for n in 0...videoNum{
let pathString = (Bundle.main.path(forResource: videos[n], ofType: "mov"))
//print(pathString!)
let StrToURL = URL(string: pathString!)
// print(StrToURL!)
// ItemArray = [AVPlayerItem(url: StrToURL!)]
ItemArray.append(AVPlayerItem(url:StrToURL!))
print(n)
print(ItemArray)
// let player = AVPlayer(playerItem: ItemArray[0])
player = AVQueuePlayer(items: [ItemArray[n]])
player.play()
}
// playerController.player = player
// present(playerController, animated: true) {
// player.play()
}
I want it to finish playing one video and move on to the next video in the array, how ever I hard code the video from the array it works but if I am trying to iterate it acts as if the URL isn't working. This is what it says 2019-06-14 13:08:44.718684-0400 Video[5439:1288491] NSURLConnection finished with error - code -1002
Declare only the player
var player = AVQueuePlayer()
In viewDidAppear map the string array to the URLs in the application bundle and then the URLs to the player items. Then create the queued player and start playing.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let videos = ["video1", "video2", "video3"]
let videoURLs = videos.compactMap{ Bundle.main.url(forResource: $0, withExtension: "mov")}
let itemArray = videoURLs.map{ AVPlayerItem(url: $0) }
player = AVQueuePlayer(items: itemArray)
player.play()
// playerController.player = player
// present(playerController, animated: true) {
// player.play()
// }
}

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()
}

NSNotificationCenter to AVQueuePlayer in swift

I added list of AVQueuePlayer to UITableViewCell. I added array of videos to AVQueuePlayer as follows:
if let urls = delegate.arrayVideofeedItemsList[indexPath.row] as? NSArray
{
let player = AVQueuePlayer()
for currentVideoObject in urls {
let avAsset = AVURLAsset(URL: NSURL(fileURLWithPath: "\(currentVideoObject)"))
avAsset.loadValuesAsynchronouslyForKeys(["playable", "tracks", "duration"], completionHandler: {
dispatch_async(dispatch_get_main_queue(), {
// self.enqueue(avAsset)
let item = AVPlayerItem(asset: avAsset)
player.insertItem(item, afterItem: nil)
})
})
}
let playerLayer = AVPlayerLayer(player: player)
// playerLayer.backgroundColor = UIColor.greenColor().CGColor
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
playerLayer.frame = CGRectMake(0, 0,SCREEN_WIDTH, 250)
cell.contentView.layer.addSublayer(playerLayer)
player.play()
player.actionAtItemEnd = AVPlayerActionAtItemEnd.Advance
player.volume = 0.0
NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerItemDidReachEnd:", name: AVPlayerItemDidPlayToEndTimeNotification,object:player.currentItem)
}
func playerItemDidReachEnd(notification: NSNotification) {
let p: AVPlayerItem = notification.object as! AVPlayerItem
p.seekToTime(kCMTimeZero)
}
I have three videos in AVQueuePlayer. Three videos are played sequentially but After completion of this first video is not playing. What I need to add to this ? Please help me to complete it.
Try to add this line after initializing player:
player.actionAtItemEnd = AVPlayerActionAtItemEnd.None

AVQueuePlayer video is not working in Swift

I am currently trying to implement advertisement with video in Swift. I tried to use AVPlayerViewController and AVQueuePlayer. However AVQueuePlayer is not playing the videos after first one finishes. Here is my code:
override func viewDidLoad() {
super.viewDidLoad()
var adItem = AVPlayerItem(URL: NSURL(string: adUrl!))
var videoItem = AVPlayerItem(URL: NSURL(string: videoUrl))
player = AVQueuePlayer(items: NSArray(objects: adItem,videoItem) as [AnyObject])
playerController = AVPlayerViewController()
playerController.player = player
self.addChildViewController(playerController)
self.view.addSubview(playerController.view)
playerController.view.frame = self.view.frame
}
Can you tell me what is my wrong? Any help would be appreciated.
Have you guys tried this?
let quePlayer = AVQueuePlayer.init(items: allVideos)
quePlayer.actionAtItemEnd = AVPlayerActionAtItemEnd.Advance
I have try this and it works with me
let url = NSURL(string: urlString as String)
self.player = AVPlayer(URL: url!)