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()
}
Related
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 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.
I received video from node sever in chunks of data. But video does not play in AVPlayer. Here is my code.
let videoUrl = http://staging.teemo.me/api/video/stream/sample12.MOV
playVideo(path:videoUrl, self)
func playVideo(path:String, controller:UIViewController){
let yourFinalVideoURL = path
try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: [])
if (yourFinalVideoURL != "") {
let player = AVPlayer(url: NSURL(fileURLWithPath: yourFinalVideoURL) as URL)
let playerController = AVPlayerViewController()
playerController.player = player
controller.present(playerController, animated: true) {
//player.play()
if #available(iOS 10.0, *) {
player.playImmediately(atRate: 1.0)
} else {
player.play()
}
}
}
}
The follow code works for me:
let videoURL = URL(string: "Some url")
let player = AVPlayer(url: videoURL!)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player!.play()
}
However when I tried to use your url it doesn't work.
I added the NSAppTransportSecurity in .plist, but it didn't work either.
It is obvious that you have a problem with the url, try to change the extension of the file sample12.MOV to sample12.mp4
I try to loop a video in a TV OS app with the AVPlayerLooper because this should get rid of the pause/hicup when playing the video again. I watched the WWDC2016 video https://developer.apple.com/videos/play/wwdc2016/503/ and try to implement the code but it doesn't loop.
I have one PlayerViewController which inherits AVPlayerViewController. I put the code to let the video loop. If I have the following code, it shows nothing. If I change the second line to self.queuePlayer = AVQueuePlayer(playerItem:playerItem), it only plays once.
let playerItem = AVPlayerItem(url: url as URL)
self.queuePlayer = AVQueuePlayer() //I declared this as a variable in the view controller
self.playerLayer = AVPlayerLayer(player: self.queuePlayer) //I declared this as a variable in the view controller
let playerLooper = AVPlayerLooper(player: self.queuePlayer!, templateItem: playerItem)
self.view.layer.addSublayer(self.playerLayer!)
self.playerLayer?.frame = self.view.frame
self.queuePlayer?.play()
Have any of you succeeded in playing looped video with the latest AVPlayerLooper?
I fixed the problem myself.
The playerLooper must be a member variable in the class otherwise it doesn't work because a local variable is gone after the method has been called. So I put this line at the beginning of the class to declare it. I didn't declare it as an AVPlayerLooper because this is only for tvos10.0 and newer versions. I want my class to be adaptive to tvos9.0.
This is my working code.
var playerLooper: NSObject?
var playerLayer:AVPlayerLayer!
var queuePlayer: AVQueuePlayer?
func playVideo(_ filmName: String){
if let path = Bundle.main.path(forResource: filmName, ofType: "mov") {
let url = URL(fileURLWithPath: path)
if #available(tvOS 10.0, *) {
// Use a new player looper with the queue player and template item
let playerItem = AVPlayerItem(url: url as URL)
self.player = AVQueuePlayer(items: [playerItem])
self.playerLayer = AVPlayerLayer(player: self.player)
self.playerLooper = AVPlayerLooper(player: self.player! as! AVQueuePlayer, templateItem: playerItem)
self.view.layer.addSublayer(self.playerLayer!)
self.playerLayer?.frame = self.view.frame
self.player?.play()
} else {
// Fallback on earlier versions, this solution has hicup at end
player = AVPlayer(url: url)
player?.play()
loopVideo(player!)
}
}
}
func loopVideo(_ videoPlayer: AVPlayer) {
NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: nil) { notification in
if(!self.isStopped){
videoPlayer.seek(to: kCMTimeZero)
videoPlayer.play()
}
}
}
Objective-C version:
#implementation ViewController
{
// As explained in accepted answer, the playerLooper must be a
// member (I put everything as member for simplicity):
AVPlayerItem *_playerItem;
AVQueuePlayer *_player;
AVPlayerLooper *_playerLooper;
AVPlayerLayer *_playerLayer;
}
- (void)viewDidLoad {
[super viewDidLoad];
// ...
NSString *videoFile = [[NSBundle mainBundle] pathForResource:#"example" ofType:#"mov"];
NSURL *videoURL = [NSURL fileURLWithPath:videoFile];
_playerItem = [AVPlayerItem playerItemWithURL:videoURL];
_player = [AVQueuePlayer queuePlayerWithItems:#[_playerItem]];
_playerLooper = [AVPlayerLooper playerLooperWithPlayer:_player templateItem:_playerItem];
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
_playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:_playerLayer];
[_player play];
}
Swift 5 custom class for playing a video looped without any glitches
import Foundation
import AVKit
class VideoPlayerLooped {
public var videoPlayer:AVQueuePlayer?
public var videoPlayerLayer:AVPlayerLayer?
var playerLooper: NSObject?
var queuePlayer: AVQueuePlayer?
func playVideo(fileName:String, inView:UIView){
if let path = Bundle.main.path(forResource: fileName, ofType: "mov") {
let url = URL(fileURLWithPath: path)
let playerItem = AVPlayerItem(url: url as URL)
videoPlayer = AVQueuePlayer(items: [playerItem])
playerLooper = AVPlayerLooper(player: videoPlayer!, templateItem: playerItem)
videoPlayerLayer = AVPlayerLayer(player: videoPlayer)
videoPlayerLayer!.frame = inView.bounds
videoPlayerLayer!.videoGravity = AVLayerVideoGravity.resizeAspectFill
inView.layer.addSublayer(videoPlayerLayer!)
videoPlayer?.play()
}
}
func remove() {
videoPlayerLayer?.removeFromSuperlayer()
}
}
Usage:
let videoHolder = UIView()
videoHolder.frame = CGRect(x: 0, y: 0, width: 200, height: 200)
var myVideoPlayerLooped = VideoPlayerLooped()
videoPlayerLooped.playVideo(video: "myLocalMovFile", inView: videoHolder)
The problem with your implementation is that you are declaring the AVPlayerLayer on function level whereas it should be declared on class level.
This file is not playing as an mp3 file, I am not sure where I messed up in my code. The println statement is printed.
let urlString = "http://anything2mp3.com/system/files/mp3/Siberian%20Husky%20gets%20ICE%20POOL%20Extended_q1zY1dp1_ig_youtube.mp3"
#IBAction func tempPlay(sender: AnyObject) {
println("runningtemp")
let url = NSURL(string: urlString)
var avPlayer = AVPlayer(URL: url)
avPlayer.play()
}
You just need to declare your AVPlayer out of your IBAction.
let urlString = "http://anything2mp3.com/system/files/mp3/Siberian%20Husky%20gets%20ICE%20POOL%20Extended_q1zY1dp1_ig_youtube.mp3"
var avPlayer:AVPlayer!
#IBAction func tempPlay(sender: AnyObject) {
if let url = NSURL(string: urlString) {
avPlayer = AVPlayer(URL: url)
avPlayer.play()
}
}