Reputation: 958
I have a AVPlayer that displays a video from a url, this is how I set it up:
fileprivate func setUpPlayer(cardModel : CardModel){
cardModel.urlStrings?.forEach({ (urlstring) in
guard let url = URL(string: urlstring) else {
return
}
urlStrings.append(url)
})
player = AVPlayer(url: urlStrings[0])
playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = .resizeAspectFill
player.play()
self.playerView.layer.insertSublayer(playerLayer, at: 0).
}
As you can see at the beginning I create a list of urls, I want to display this urls whenever a touch event occurs:
This are the two snippets I created to display this list of video from the array of urls:
fileprivate func goToNextVideo(){
counter = counter + 1
counter = min(counter, cardModel!.urlStrings!.count - 1)
player = AVPlayer(url: urlStrings[counter])
playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = .resizeAspectFill
player.play()
}
fileprivate func goToPreviousVideo(){
counter = counter - 1
counter = max(0, counter)
player = AVPlayer(url: urlStrings[counter])
playerLayer = AVPlayerLayer(player: player)
playerLayer.videoGravity = .resizeAspectFill
player.play()
}
This implementation doesn't seem to work, when I go to the next video I can only hear the audio but can't see the video, do you know how can I play videos using AVPlayer from a list of urls?
Upvotes: 2
Views: 1017
Reputation: 2713
The following demo will play an array of video urls, forward and back. Unfortunately I could not get it to run in Xcode: 'error = AudioObjectRemovePropertyListenerBlock: can't remove a NULL listener proc' and I do not know how to fix the problem. However it runs ok using Terminal. You will need to add your own file paths to be converted to urls (or add video urls). Copy/paste the code into a file named 'videoPlayer.swift' and use the command line code shown below in Terminal.
/*
1. Add paths to video urls array
2. To run in Terminal:
swiftc videoPlayer.swift -framework Cocoa -o videoPlayer && ./videoPlayer
*/
import Cocoa
import AVKit
import AVFoundation
var videos = [URL]() // video url array
var count:Int = 3 // Starts on videos[3]
class AppDelegate: NSObject, NSApplicationDelegate {
var window:NSWindow!
var playerView:AVPlayerView!
@objc func playAction(_ sender:AnyObject ) {
let player = AVPlayer(url:videos[count])
playerView.player = player
player.play()
window.setTitleWithRepresentedFilename(videos[4].lastPathComponent)
print("index = \(count)")
}
@objc func forwardAction(_ sender:AnyObject ) {
if (count == videos.count - 1) {
count = 0
} else {
count = count + 1
}
print("index = \(count)")
let player = AVPlayer(url: videos[count])
playerView.player = player
player.play()
window.setTitleWithRepresentedFilename(videos[count].lastPathComponent)
}
@objc func backAction(_ sender:AnyObject ) {
if (count == 0) {
count = videos.count - 1
} else {
count = count - 1
}
print("index = \(count)")
let player = AVPlayer(url: videos[count])
playerView.player = player
player.play()
window.setTitleWithRepresentedFilename(videos[count].lastPathComponent)
}
func loadPlayList() {
videos.append(URL(fileURLWithPath:"/Users/xxxx/Movies/myVideo0.m4v"))
videos.append(URL(fileURLWithPath:"/Users/xxxx/Movies/myVideo1.m4v"))
videos.append(URL(fileURLWithPath:"/Users/xxxx/Movies/myVideo2.mp4"))
videos.append(URL(fileURLWithPath:"/Users/xxxx/Movies/myVideo3.mp4"))
videos.append(URL(fileURLWithPath:"/Users/xxxx/Movies/myVideo4.m4v"))
videos.append(URL(fileURLWithPath:"/Users/xxxx/Movies/myVideo5.mpg"))
for video in videos {
print(video)
}
print("total videos = \(videos.count)")
}
func buildMenu() {
let mainMenu = NSMenu()
NSApp.mainMenu = mainMenu
// **** App menu **** //
let appMenuItem = NSMenuItem()
mainMenu.addItem(appMenuItem)
let appMenu = NSMenu()
appMenuItem.submenu = appMenu
appMenu.addItem(withTitle: "Quit", action:#selector(NSApplication.terminate), keyEquivalent: "q")
}
func buildWnd() {
let _wndW : CGFloat = 500
let _wndH : CGFloat = 400
window = NSWindow(contentRect:NSMakeRect(0,0,_wndW,_wndH),styleMask:[.titled, .closable, .miniaturizable, .resizable], backing:.buffered, defer:false)
window.center()
window.title = "AVPlayer"
window.makeKeyAndOrderFront(window)
// **** AVPlayerView **** //
playerView = AVPlayerView(frame:NSMakeRect( 0, 60, _wndW, _wndH - 60))
playerView.autoresizingMask = [.width, .height]
window.contentView!.addSubview (playerView)
// **** Play Button **** //
let playBtn = NSButton (frame:NSMakeRect( 155, 10, 95, 24 ))
playBtn.bezelStyle = .rounded
playBtn.autoresizingMask = [.maxXMargin,.maxYMargin]
playBtn.title = "Play"
playBtn.action = #selector(self.playAction(_:))
window.contentView!.addSubview (playBtn)
// **** Forward Button **** //
let forwardBtn = NSButton (frame:NSMakeRect( 260, 10, 65, 24 ))
forwardBtn.bezelStyle = .rounded
forwardBtn.autoresizingMask = [.maxXMargin,.maxYMargin]
forwardBtn.title = "Fwd"
forwardBtn.action = #selector(self.forwardAction(_:))
window.contentView!.addSubview (forwardBtn)
// **** Backward Button **** //
let backBtn = NSButton (frame:NSMakeRect( 330, 10, 65, 24 ))
backBtn.bezelStyle = .rounded
backBtn.autoresizingMask = [.maxXMargin,.maxYMargin]
backBtn.title = "Back"
backBtn.action = #selector(self.backAction(_:))
window.contentView!.addSubview (backBtn)
// **** Quit btn **** //
let quitBtn = NSButton (frame:NSMakeRect( _wndW - 50, 10, 40, 40 ))
quitBtn.bezelStyle = .circular
quitBtn.autoresizingMask = [.minXMargin,.maxYMargin]
quitBtn.title = "Q"
quitBtn.action = #selector(NSApplication.terminate)
window.contentView!.addSubview(quitBtn)
}
func applicationDidFinishLaunching(_ notification: Notification) {
buildMenu()
buildWnd()
loadPlayList()
}
func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
return true
}
}
let appDelegate = AppDelegate()
// **** main.swift **** //
let app = NSApplication.shared
app.delegate = appDelegate
app.setActivationPolicy(.regular)
app.activate(ignoringOtherApps:true)
app.run()
Upvotes: 2