Swift 4 & Xcode 10. 在应用启动时播放视频,完成后显示视图控制器
Swift 4 & Xcode 10. Play video on app launch, when complete, reveal view controller
首先,我是 Xcode 10 和 Swift 4 的新手,我在这里搜索过但没有找到有效的代码。
我追求的是:
启动应用程序播放本地存储的视频(称为 "launchvideo")。
完成视频 display/move 到故事板 ID 为 "menu"
的 UIviewcontroller
到目前为止,我有我的主导航控制器及其链接视图控制器。
我猜我需要一个 UIview 来保存要在此页面上播放的视频?
有没有人可以帮助一个新人?
谢谢
您必须在 launchvideoVC 上加载视频,如下面 swift 4 及更高版本
import AVFoundation
import AVKit
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
initVideo()
}
func initVideo(){
do {
try AVAudioSession.sharedInstance().setCategory(.ambient, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
let path = Bundle.main.path(forResource: "yourlocalvideo", ofType:"mp4");
player = AVPlayer(url: NSURL(fileURLWithPath: path!) as URL)
NotificationCenter.default.addObserver(self, selector: #selector(launchvideoVC.itemDidFinishPlaying(_:)), name: .AVPlayerItemDidPlayToEndTime, object: player?.currentItem)
DispatchQueue.main.async(execute: {() -> Void in
let playerLayer = AVPlayerLayer(player: self.player)
playerLayer.frame = self.view.bounds
playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
playerLayer.zPosition = 1
self.view.layer.addSublayer(playerLayer)
self.player?.seek(to: CMTime.zero)
self.player?.play()
})
}
@objc func itemDidFinishPlaying(_ notification: Notification?) {
//move to whatever UIViewcontroller with a storyboard ID of "menu"
}
我认为这可能对您有所帮助。
编码愉快:)
首先从常规选项卡的项目设置中将启动屏幕故事板更改为主故事板。
创建一个视图控制器,名称如下,并编写代码实现AVPlayer播放视频。
import UIKit
import AVFoundation
class VideoLaunchVC: UIViewController {
func setupAVPlayer() {
let videoURL = Bundle.main.url(forResource: "Video", withExtension: "mov") // Get video url
let avAssets = AVAsset(url: videoURL!) // Create assets to get duration of video.
let avPlayer = AVPlayer(url: videoURL!) // Create avPlayer instance
let avPlayerLayer = AVPlayerLayer(player: avPlayer) // Create avPlayerLayer instance
avPlayerLayer.frame = self.view.bounds // Set bounds of avPlayerLayer
self.view.layer.addSublayer(avPlayerLayer) // Add avPlayerLayer to view's layer.
avPlayer.play() // Play video
// Add observer for every second to check video completed or not,
// If video play is completed then redirect to desire view controller.
avPlayer.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 1) , queue: .main) { [weak self] time in
if time == avAssets.duration {
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as! ViewController
self?.navigationController?.pushViewController(vc, animated: true)
}
}
}
//------------------------------------------------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
}
//------------------------------------------------------------------------------
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.setupAVPlayer() // Call method to setup AVPlayer & AVPlayerLayer to play video
}
}
Main.Storyboard:
项目启动屏幕文件:
另见以下视频:
首先,您创建了一个带有视图的新视图控制器,并将您的启动屏幕故事板从“常规”选项卡中的项目设置更改为“主故事板”。
并将您的视频添加到文件夹中。
然后只需将我的以下代码添加到您的启动屏幕视图控制器中:
import UIKit
import MediaPlayer
import AVKit
class LaunchViewController: UIViewController {
fileprivate var rootViewController: UIViewController? = nil
var player: AVPlayer?
var playerController = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
showSplashViewController()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func playVideo() {
let videoURL = NSURL(string: "videoplayback")
player = AVPlayer(url: videoURL! as URL)
let playerController = AVPlayerViewController()
playerController.player = player
self.addChildViewController(playerController)
// Add your view Frame
playerController.view.frame = self.view.frame
// Add subview in your view
self.view.addSubview(playerController.view)
player?.play()
}
private func loadVideo() {
//this line is important to prevent background music stop
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
} catch { }
let path = Bundle.main.path(forResource: "videoplayback", ofType:"mp4")
let filePathURL = NSURL.fileURL(withPath: path!)
let player = AVPlayer(url: filePathURL)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.frame
playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
playerLayer.zPosition = -1
self.view.layer.addSublayer(playerLayer)
player.seek(to: kCMTimeZero)
player.play()
}
func showSplashViewControllerNoPing() {
if rootViewController is LaunchViewController {
return
}
loadVideo()
}
/// Simulates an API handshake success and transitions to MapViewController
func showSplashViewController() {
showSplashViewControllerNoPing()
delay(6.00) {
self.showMenuNavigationViewController()
}
}
public func delay(_ delay:Double, closure:@escaping ()->()) {
DispatchQueue.main.asyncAfter(
deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}
/// Displays the MapViewController
func showMenuNavigationViewController() {
guard !(rootViewController is Home) else { return }
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let nav = storyboard.instantiateViewController(withIdentifier: "homeTab") as! Home
nav.willMove(toParentViewController: self)
addChildViewController(nav)
if let rootViewController = self.rootViewController {
self.rootViewController = nav
rootViewController.willMove(toParentViewController: nil)
transition(from: rootViewController, to: nav, duration: 0.55, options: [.transitionCrossDissolve, .curveEaseOut], animations: { () -> Void in
}, completion: { _ in
nav.didMove(toParentViewController: self)
rootViewController.removeFromParentViewController()
rootViewController.didMove(toParentViewController: nil)
})
} else {
rootViewController = nav
view.addSubview(nav.view)
nav.didMove(toParentViewController: self)
}
}
override var prefersStatusBarHidden : Bool {
switch rootViewController {
case is LaunchViewController:
return true
case is Home:
return false
default:
return false
}
}
}
首先,我是 Xcode 10 和 Swift 4 的新手,我在这里搜索过但没有找到有效的代码。
我追求的是: 启动应用程序播放本地存储的视频(称为 "launchvideo")。 完成视频 display/move 到故事板 ID 为 "menu"
的 UIviewcontroller到目前为止,我有我的主导航控制器及其链接视图控制器。 我猜我需要一个 UIview 来保存要在此页面上播放的视频?
有没有人可以帮助一个新人? 谢谢
您必须在 launchvideoVC 上加载视频,如下面 swift 4 及更高版本
import AVFoundation
import AVKit
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
initVideo()
}
func initVideo(){
do {
try AVAudioSession.sharedInstance().setCategory(.ambient, mode: .default)
try AVAudioSession.sharedInstance().setActive(true)
} catch {
print(error)
}
let path = Bundle.main.path(forResource: "yourlocalvideo", ofType:"mp4");
player = AVPlayer(url: NSURL(fileURLWithPath: path!) as URL)
NotificationCenter.default.addObserver(self, selector: #selector(launchvideoVC.itemDidFinishPlaying(_:)), name: .AVPlayerItemDidPlayToEndTime, object: player?.currentItem)
DispatchQueue.main.async(execute: {() -> Void in
let playerLayer = AVPlayerLayer(player: self.player)
playerLayer.frame = self.view.bounds
playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
playerLayer.zPosition = 1
self.view.layer.addSublayer(playerLayer)
self.player?.seek(to: CMTime.zero)
self.player?.play()
})
}
@objc func itemDidFinishPlaying(_ notification: Notification?) {
//move to whatever UIViewcontroller with a storyboard ID of "menu"
}
我认为这可能对您有所帮助。 编码愉快:)
首先从常规选项卡的项目设置中将启动屏幕故事板更改为主故事板。
创建一个视图控制器,名称如下,并编写代码实现AVPlayer播放视频。
import UIKit
import AVFoundation
class VideoLaunchVC: UIViewController {
func setupAVPlayer() {
let videoURL = Bundle.main.url(forResource: "Video", withExtension: "mov") // Get video url
let avAssets = AVAsset(url: videoURL!) // Create assets to get duration of video.
let avPlayer = AVPlayer(url: videoURL!) // Create avPlayer instance
let avPlayerLayer = AVPlayerLayer(player: avPlayer) // Create avPlayerLayer instance
avPlayerLayer.frame = self.view.bounds // Set bounds of avPlayerLayer
self.view.layer.addSublayer(avPlayerLayer) // Add avPlayerLayer to view's layer.
avPlayer.play() // Play video
// Add observer for every second to check video completed or not,
// If video play is completed then redirect to desire view controller.
avPlayer.addPeriodicTimeObserver(forInterval: CMTime(seconds: 1, preferredTimescale: 1) , queue: .main) { [weak self] time in
if time == avAssets.duration {
let vc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as! ViewController
self?.navigationController?.pushViewController(vc, animated: true)
}
}
}
//------------------------------------------------------------------------------
override func viewDidLoad() {
super.viewDidLoad()
}
//------------------------------------------------------------------------------
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.setupAVPlayer() // Call method to setup AVPlayer & AVPlayerLayer to play video
}
}
Main.Storyboard:
项目启动屏幕文件:
另见以下视频:
首先,您创建了一个带有视图的新视图控制器,并将您的启动屏幕故事板从“常规”选项卡中的项目设置更改为“主故事板”。
并将您的视频添加到文件夹中。
然后只需将我的以下代码添加到您的启动屏幕视图控制器中:
import UIKit
import MediaPlayer
import AVKit
class LaunchViewController: UIViewController {
fileprivate var rootViewController: UIViewController? = nil
var player: AVPlayer?
var playerController = AVPlayerViewController()
override func viewDidLoad() {
super.viewDidLoad()
showSplashViewController()
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func playVideo() {
let videoURL = NSURL(string: "videoplayback")
player = AVPlayer(url: videoURL! as URL)
let playerController = AVPlayerViewController()
playerController.player = player
self.addChildViewController(playerController)
// Add your view Frame
playerController.view.frame = self.view.frame
// Add subview in your view
self.view.addSubview(playerController.view)
player?.play()
}
private func loadVideo() {
//this line is important to prevent background music stop
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)
} catch { }
let path = Bundle.main.path(forResource: "videoplayback", ofType:"mp4")
let filePathURL = NSURL.fileURL(withPath: path!)
let player = AVPlayer(url: filePathURL)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.frame
playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
playerLayer.zPosition = -1
self.view.layer.addSublayer(playerLayer)
player.seek(to: kCMTimeZero)
player.play()
}
func showSplashViewControllerNoPing() {
if rootViewController is LaunchViewController {
return
}
loadVideo()
}
/// Simulates an API handshake success and transitions to MapViewController
func showSplashViewController() {
showSplashViewControllerNoPing()
delay(6.00) {
self.showMenuNavigationViewController()
}
}
public func delay(_ delay:Double, closure:@escaping ()->()) {
DispatchQueue.main.asyncAfter(
deadline: DispatchTime.now() + Double(Int64(delay * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}
/// Displays the MapViewController
func showMenuNavigationViewController() {
guard !(rootViewController is Home) else { return }
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let nav = storyboard.instantiateViewController(withIdentifier: "homeTab") as! Home
nav.willMove(toParentViewController: self)
addChildViewController(nav)
if let rootViewController = self.rootViewController {
self.rootViewController = nav
rootViewController.willMove(toParentViewController: nil)
transition(from: rootViewController, to: nav, duration: 0.55, options: [.transitionCrossDissolve, .curveEaseOut], animations: { () -> Void in
}, completion: { _ in
nav.didMove(toParentViewController: self)
rootViewController.removeFromParentViewController()
rootViewController.didMove(toParentViewController: nil)
})
} else {
rootViewController = nav
view.addSubview(nav.view)
nav.didMove(toParentViewController: self)
}
}
override var prefersStatusBarHidden : Bool {
switch rootViewController {
case is LaunchViewController:
return true
case is Home:
return false
default:
return false
}
}
}