I implemented a code to check if AVPlayer deallocates. Unfortunately it does not. Do I miss something?
func testPlayerDealloc() {
var player: AVPlayer? = AVPlayer()
weak var weakPlayer = player
weak var weakPlayerItem: AVPlayerItem?
let urlString = "http://csm-e.cds1.yospace.com/csm/extlive/yospace02,hlssample.m3u8"
if let player = player, let url = URL(string: urlString) {
let playerItem = AVPlayerItem(url: url)
weakPlayerItem = playerItem
player.replaceCurrentItem(with: playerItem)
}
player?.replaceCurrentItem(with: nil)
player = nil
XCTAssertNil(weakPlayer)
XCTAssertNil(weakPlayerItem)
}
At the end both, the weakPlayer and the weakPlayerItem are not nil.
Related
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?
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)
}
}
}
I have a video which I want to download from a server and stream it in a fixed view.
I've set a UIView in my storyboard with fixed constraints, and here is what I've done in code:
#IBOutlet weak var videoView: UIView!
var player: AVPlayer!
var avpController = AVPlayerViewController()
And in my viewDidLoad I've done this:
let url = URL(string:myURL)
player = AVPlayer(url: url!)
avpController.player = player
avpController.videoGravity = AVLayerVideoGravity.resizeAspect.rawValue
self.addChildViewController(avpController)
avpController.view.frame = videoView.frame
self.containerView.addSubview(avpController.view)
videoView.layer.masksToBounds = true
My problem is my video is not with the size that I've set to videoView and in every device my video is in a different size. In some devices, the video height is larger than the height that I've set and it overlays the items that I have below videoView. How can I play video in a view in a right way?
If you want to use AVPlayerViewController:
let videoURL = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let player = AVPlayer(url: videoURL!)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
For AVPlayer:
let videoURL = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let player = AVPlayer(url: videoURL!)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
player.play()
the only way to add a video to a UIView with fixed constraints in storyboard, was this :
let url = URL(string:myURL)
player = AVPlayer(url: url!)
avpController.player = player
avpController.view.frame.size.height = videoView.frame.size.height
avpController.view.frame.size.width = videoView.frame.size.width
self.videoView.addSubview(avpController.view)
I hope other can use this! :)
You can try to use AVPlayerLayer in a AVPlayer.
let player = AVPlayer(url: video) // your video url
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = videoView.bounds
videoView.layer.addSublayer(playerLayer)
player.play()
This is how you can add and remove player in uiview.
var player: AVPlayer?
var playerController: AVPlayerViewController?
func removePlayer() {
player?.pause()
player = nil
playerController?.player?.pause()
playerController?.player = nil
if let view = playerController?.view {
videoView.willRemoveSubview(view)
}
playerController?.view.removeFromSuperview()
playerController = nil
}
func setVideo(url: URL) {
removePlayer()
player = AVPlayer(url: url)
playerController = AVPlayerViewController()
playerController?.player = player
self.videoView.addSubview((playerController?.view)!)
playerController?.view.frame = CGRect(x: 0, y: 0, width: self.videoView.bounds.width, height: self.videoView.bounds.height)
// player.play()
}
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()
var url:NSURL! = NSURL(string: "http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8")
var playItem:AVPlayerItem! = AVPlayerItem(URL: url);
var player:AVPlayer! = AVPlayer(playerItem: playItem);
var playerLayer:AVPlayerLayer! = AVPlayerLayer(player: player);
self.view.layer.addSublayer(playerLayer);
player.play()
when i run these code, there will be crash, could anyone told me how to use AVKit to playback the video? Thx ^ ^
try this:
//stream url
let movieUrl:NSURL? = NSURL (string: "http://YOUR URL")
if let url = movieUrl {
self.avPlayer = AVPlayer(URL: url)
self.avPlayerViewController.player = self.avPlayer
}
//Button action
#IBAction func live(sender: UIButton) {
self.presentViewController(self.avPlayerViewController, animated: true) { () -> Void in
self.avPlayerViewController.player?.play()
}