Reality Composer - How to add a video on to an usdz object? - ios

I am trying to add a video onto the usdz object. The code which i am trying with is as below
class ViewController: UIViewController {
#IBOutlet var arView: ARView!
let panelName = "plane.usdz"
var playerLooper: AVPlayerLooper!
override func viewDidLoad() {
super.viewDidLoad()
let url = Bundle.main.url(forResource: "video1", withExtension: "mp4")
let playerItem = AVPlayerItem(url: url!)
let player = AVQueuePlayer()
playerLooper = AVPlayerLooper(player: player, templateItem: playerItem)
let material = VideoMaterial(avPlayer: player)
let anchor = AnchorEntity(world: [0,0,-2])
do {
let entity = try Entity.loadModel(named: panelName)
entity.model?.materials = [material]
anchor.addChild(entity)
arView.scene.anchors.append(contentsOf: [anchor])
} catch {
assertionFailure("Could not load the panel asset.")
}
player.play()
let config = ARWorldTrackingConfiguration()
arView.session.run(config)
}
}
Here i have created a usdz object "plane.usdz" on which i am trying to add a video "video1.mp4". I am able to add the video, but its playing in an inverted manner. How can i make it play properly?

Related

Issue displaying subviews above video | Swift 5

The login screen I am designing is near complete but fails to properly display both the username and password textfields once the view controller loads
The following function executes when the view loads - it properly plays the video and displays both the image and loginButton correctly, it appears to also appears to display the textfields for a split second until the video fully loads and plays.
func playVideo() {
guard let path = Bundle.main.path(forResource: "videoFile", ofType: "mp4") else {
return
}
let asset: AVAsset = AVAsset(url: URL(fileURLWithPath: path))
let playerItem = AVPlayerItem(asset: asset)
let queuePlayer = AVQueuePlayer(playerItem: playerItem)
self.playerLooper = AVPlayerLooper(player: queuePlayer, templateItem: playerItem)
let playerLayer = AVPlayerLayer(player: queuePlayer)
playerLayer.frame = self.view.bounds
playerLayer.videoGravity = .resizeAspectFill
self.videoLayer.layer.addSublayer(playerLayer)
queuePlayer.play()
videoLayer.bringSubviewToFront(img)
videoLayer.bringSubviewToFront(usernameTF)
videoLayer.bringSubviewToFront(passwordTF)
videoLayer.bringSubviewToFront(signinButton)
}
Any ideas what could be causing this?
You can change this code according to your need.
var player : AVPlayer?
var playerViewController : AVPlayerViewController?
func playLiveUrl(url:String){
let videoURL = URL(string: "http://bla blah.com")
self.player = AVPlayer(url: videoURL!)
self.playerViewController = AVPlayerViewController()
playerViewController?.player = self.player
playerViewController?.view.frame = self.topPlayerView.frame
playerViewController?.player?.play()
self.topPlayerView.addSubview(playerViewController?.view ?? UIView()) // Container topPlayerView which contains a player
}
var topPlayerView : UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .black
return view
}()

AVPlayerLayer says always nil

I don't understand why it is not working. I pass a videoURL trough a segue to a another ViewController. This works fine.
In the other ViewController I want to play the video. But for some reason it is not working.
I unwrap the URL with optional binding. But playerLayer does not accept the URL. It says always nil.
This is the URL: VideoURL Optional(file:///var/mobile/Containers/Data/Application/517BA864-F5CB-4E2C-BE54-D42555569266/Documents/3d.mov)
My code:
var player: AVPlayer?
var playerLayer: AVPlayerLayer?
var videoURL: URL?
func playVideo() {
if let _videoURL = videoURL {
player = AVPlayer(url: _videoURL)
playerLayer = AVPlayerLayer(layer: player!)
playerLayer?.frame = contentView.layer.bounds
playerLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.contentView.layer.addSublayer(playerLayer!)
player?.play()
}
Try creating an AVURLAsset and an AVPlayerItem. Then pass that AVPlayerItem into the AVPlayer rather than trying to use the URL init.
I tested this with a sample video I downloaded from here. Note there is no sound in this video.
import UIKit
import AVFoundation
class ViewController: UIViewController {
private let videoUrl = Bundle.main.url(forResource: "file_example_MOV_1920_2_2MB", withExtension: "mov")!
private var videoPlayer: AVPlayer?
private var playerLayer: AVPlayerLayer?
override func viewDidLoad() {
super.viewDidLoad()
playVideo()
}
func playVideo() {
let asset = AVURLAsset(url: videoUrl)
let primaryPlayerItem = AVPlayerItem(asset: asset)
let player = AVPlayer(playerItem: primaryPlayerItem)
let videoLayer = AVPlayerLayer(player: player)
videoLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
videoLayer.frame = view.bounds
view.layer.addSublayer(videoLayer)
videoPlayer = player
playerLayer = videoLayer
videoPlayer?.play()
}
}
Try the below code. It's working.
var player: AVPlayer!
var playerLayer: AVPlayerLayer!
func playVideo() {
if let url = videoURL {
do {
let item:AVPlayerItem = AVPlayerItem(url: url)
player = AVPlayer(playerItem: item)
playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = contentView.bounds
playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
self.contentView.layer.addSublayer(playerLayer)
player.play()
} catch {
print("Error1", error.localizedDescription)
}
}
}

Having my UIView go from one video to the next

I'm kinda new at this, Ive successfully embedded a video into a UIView. Got it to play automatically, without any controls. So far so good.
Now I want to be able to play the next video, and ideally the user can swipe and the next video will start playing... here's the code I have now;
#IBOutlet weak var videoView: UIView!
var player: AVPlayer!
var avpController = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
let filepath: String? = Bundle.main.path(forResource: "jordanreel", ofType: "mp4")
let fileURL = URL.init(fileURLWithPath: filepath!)
player = AVPlayer(url: fileURL)
avpController.player = player
avpController.view.frame.size.height = videoView.frame.size.height
avpController.view.frame.size.width = videoView.frame.size.width
avpController.showsPlaybackControls = false
avpController.player?.play()
self.videoView.addSubview(avpController.view) }
}

Create VideoPlayer With Custom Size in Swift 3

i want to show .mov file in custom size. i have an xib file for my controller.
thats top view is subclass of UIView. i want to show video in this view.
there is my code for create video view. but there is problem in size of my video player. how can solve this problem.
there is my code :
private func playVideo() {
guard let path = Bundle.main.path(forResource: "video_2017-06-30_15-49-05", ofType:"mov") else {
debugPrint("video.m4v not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
let avPlayerLayer = AVPlayerLayer(player: player)
avPlayerLayer.frame = videoView.layer.frame
videoView.layer.insertSublayer(avPlayerLayer, at: 0)
}
If you want a native player to be added to your view with the seek bar and play pause button then use following code:
private func playVideo() {
guard let path = Bundle.main.path(forResource: "SampleVideo", ofType:"mp4") else {
debugPrint("video.m4v not found")
return
}
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
playerController.view.frame = videoView.bounds
videoView.addSubview(playerController.view)
player.play()
}
and if you want just the video to be played in your view with AVPlayerLayer then you can do something like below:
var player : AVPlayer!
var avPlayerLayer : AVPlayerLayer!
#IBOutlet weak var videoView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
guard let path = Bundle.main.path(forResource: "SampleVideo", ofType:"mp4") else {
debugPrint("video.m4v not found")
return
}
player = AVPlayer(url: URL(fileURLWithPath: path))
avPlayerLayer = AVPlayerLayer(player: player)
avPlayerLayer.videoGravity = AVLayerVideoGravity.resize
videoView.layer.addSublayer(avPlayerLayer)
playVideo()
}
override func viewDidLayoutSubviews() {
avPlayerLayer.frame = videoView.layer.bounds
}
private func playVideo() {
player.play()
}
This worked perfect for me hope it works for you :)

Seamless looping Video using AVPlayer- Swift

I am using AVPlayer to play local video in background using loop and video is playing fine but after finishing video it takes pause to play video in loop. I have tried many methods and also seen many post on stack overflow but i failed to find appropriate solution. I am using Swift3.
Code is here :
var videoplayer :AVPlayer = AVPlayer()
override func viewDidLoad() {
super.viewDidLoad()
let path = Bundle.main.path(forResource: "background4", ofType: "mp4")
videoplayer = AVPlayer(url: URL(fileURLWithPath: path!))
videoplayer.volume = 0
videoplayer.actionAtItemEnd = AVPlayerActionAtItemEnd.none;
let playerLayer = AVPlayerLayer(player: videoplayer)
playerLayer.frame = self.view.frame
playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
if (videoplayer.rate != 0) {
print("playing videoplayer")
self.blurBgImage.isHidden = true
}
playerLayer.zPosition = -1
videoplayer.rate = 0
videoplayer.play()
self.blurBgImage.layer.addSublayer(playerLayer)
NotificationCenter.default.addObserver(forName: .AVPlayerItemDidPlayToEndTime, object: videoplayer.currentItem, queue: nil, using: { (_) in
DispatchQueue.main.async {
let t1 = CMTimeMake(5, 100)
self.videoplayer.seek(to: t1)
self.videoplayer.play()
}
})
}
I have also tried AVPlayerLooper.
Code is :
var playerLooper: NSObject?
var playerLayer:AVPlayerLayer!
var queuePlayer: AVQueuePlayer?
func playVideo(_ filmName: String){
if let path = Bundle.main.path(forResource: filmName, ofType: "mp4") let url = URL(fileURLWithPath: path)
if #available(tvOS 10.0, *) {
let playerItem = AVPlayerItem(url: url as URL)
self.videoplayer = AVQueuePlayer(items: [playerItem])
self.playerLayer = AVPlayerLayer(player: self.videoplayer)
self.playerLooper = AVPlayerLooper(player: self.videoplayer as! AVQueuePlayer, templateItem: playerItem)
self.blurBgImage.layer.addSublayer(playerLayer!)
self.playerLayer?.frame = self.view.frame
self.videoplayer.volume = 10
self.videoplayer.play()
} else {
videoplayer = AVPlayer(url: url)
videoplayer.play()
loopVideo(videoplayer)
}
}
}
What should i do for seamless looping? Thanks in Advance.
FYI there is sample code here: https://developer.apple.com/library/content/samplecode/avloopplayer/Introduction/Intro.html
#matt's deleted answer works fine for me (on device / simulator) for iOS 10+ devices:
Use AVPlayerLooper. That is exactly what it is for.
https://developer.apple.com/reference/avfoundation/avplayerlooper
Basically it implements AVQueuePlayer for you, constantly updating the
queue so that it never ends.
It seamlessly loops without any white/black blip.
E.g.
private var looper: AVPlayerLooper?
...
let queuePlayer = AVQueuePlayer(playerItem: item)
looper = AVPlayerLooper(player: queuePlayer, templateItem: item)
videoPlayerLayer.player = queuePlayer
If you end up doing this in a reusable cell (e.g. UICollectionView), then make sure you disable looping before cell re-use or you'll get some obscure crashes:
looper?.disableLooping()

Resources