我有一个视频播放作为我的登陆视图控制器的背景,每当我退出应用程序然后重新进入,视频冻结,直到我要么去另一个视图然后回来,或者只是重新启动应用程序将一起它正常发挥。即使应用程序退出并重新进入,如何让它继续播放?
这是逻辑:
import UIKit
import AVFoundation
class FirstViewController: UIViewController {
var player: AVPlayer?
override func viewDidLoad() {
super.viewDidLoad()
let path = NSBundle.mainBundle().pathForResource("sunny", ofType: "mp4")
player = AVPlayer(URL: NSURL(fileURLWithPath: path!))
player!.actionAtItemEnd = AVPlayerActionAtItemEnd.None;
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.frame
playerLayer.videoGravity = AVLayerVideoGravityResize
self.view.layer.insertSublayer(playerLayer, atIndex: 0)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.playerItemDidReachEnd), name: AVPlayerItemDidPlayToEndTimeNotification, object: player!.currentItem)
player!.seekToTime(kCMTimeZero)
player!.play()
}
func playerItemDidReachEnd() {
player!.seekToTime(kCMTimeZero)
}
}
答案 0 :(得分:1)
首先,您需要在VideoCutter.swift文件中创建一个名为VideoCutter的类:
import UIKit
import AVFoundation
extension String {
var convert: NSString { return (self as NSString) }
}
public class VideoCutter: NSObject {
public func cropVideoWithUrl(videoUrl url: NSURL, startTime: CGFloat, duration: CGFloat, completion: ((videoPath: NSURL?, error: NSError?) -> Void)?) {
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
let asset = AVURLAsset(URL: url, options: nil)
let exportSession = AVAssetExportSession(asset: asset, presetName: "AVAssetExportPresetHighestQuality")
let paths: NSArray = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
var outputURL = paths.objectAtIndex(0) as! String
let manager = NSFileManager.defaultManager()
do {
try manager.createDirectoryAtPath(outputURL, withIntermediateDirectories: true, attributes: nil)
} catch _ {
}
outputURL = outputURL.convert.stringByAppendingPathComponent("sunny.mp4")
do {
try manager.removeItemAtPath(outputURL)
} catch _ {
}
if let exportSession = exportSession as AVAssetExportSession? {
exportSession.outputURL = NSURL(fileURLWithPath: outputURL)
exportSession.shouldOptimizeForNetworkUse = true
exportSession.outputFileType = AVFileTypeMPEG4
let start = CMTimeMakeWithSeconds(Float64(startTime), 600)
let duration = CMTimeMakeWithSeconds(Float64(duration), 600)
let range = CMTimeRangeMake(start, duration)
exportSession.timeRange = range
exportSession.exportAsynchronouslyWithCompletionHandler { () -> Void in
switch exportSession.status {
case AVAssetExportSessionStatus.Completed:
completion?(videoPath: exportSession.outputURL, error: nil)
case AVAssetExportSessionStatus.Failed:
print("Failed: \(exportSession.error)")
case AVAssetExportSessionStatus.Cancelled:
print("Failed: \(exportSession.error)")
default:
print("default case")
}
}
}
dispatch_async(dispatch_get_main_queue()) {
}
}
}
}
然后你需要在VideoSplashViewController.swift文件中创建一个类VideoSplashViewController
:
import UIKit
import MediaPlayer
import AVKit
public enum ScalingMode {
case Resize
case ResizeAspect
case ResizeAspectFill
}
public class VideoSplashViewController: UIViewController {
private let moviePlayer = AVPlayerViewController()
private var moviePlayerSoundLevel: Float = 1.0
public var contentURL: NSURL = NSURL() {
didSet {
setMoviePlayer(contentURL)
}
}
public var videoFrame: CGRect = CGRect()
public var startTime: CGFloat = 0.0
public var duration: CGFloat = 0.0
public var backgroundColor: UIColor = UIColor.blackColor() {
didSet {
view.backgroundColor = backgroundColor
}
}
public var sound: Bool = true {
didSet {
if sound {
moviePlayerSoundLevel = 1.0
}else{
moviePlayerSoundLevel = 0.0
}
}
}
public var alpha: CGFloat = CGFloat() {
didSet {
moviePlayer.view.alpha = alpha
}
}
public var alwaysRepeat: Bool = true {
didSet {
if alwaysRepeat {
NSNotificationCenter.defaultCenter().addObserver(self,
selector: "playerItemDidReachEnd",
name: AVPlayerItemDidPlayToEndTimeNotification,
object: moviePlayer.player?.currentItem)
}
}
}
public var fillMode: ScalingMode = .ResizeAspectFill {
didSet {
switch fillMode {
case .Resize:
moviePlayer.videoGravity = AVLayerVideoGravityResize
case .ResizeAspect:
moviePlayer.videoGravity = AVLayerVideoGravityResizeAspect
case .ResizeAspectFill:
moviePlayer.videoGravity = AVLayerVideoGravityResizeAspectFill
}
}
}
override public func viewDidAppear(animated: Bool) {
moviePlayer.view.frame = videoFrame
moviePlayer.showsPlaybackControls = false
view.addSubview(moviePlayer.view)
view.sendSubviewToBack(moviePlayer.view)
}
override public func viewWillDisappear(animated: Bool) {
super.viewDidDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
private func setMoviePlayer(url: NSURL){
let videoCutter = VideoCutter()
videoCutter.cropVideoWithUrl(videoUrl: url, startTime: startTime, duration: duration) { (videoPath, error) -> Void in
if let path = videoPath as NSURL? {
let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
dispatch_async(dispatch_get_main_queue()) {
self.moviePlayer.player = AVPlayer(URL: path)
self.moviePlayer.player?.play()
self.moviePlayer.player?.volume = self.moviePlayerSoundLevel
}
}
}
}
}
override public func viewDidLoad() {
super.viewDidLoad()
}
override public func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func playerItemDidReachEnd() {
moviePlayer.player?.seekToTime(kCMTimeZero)
moviePlayer.player?.play()
}
}
最后,在你的FirstViewController中:
import UIKit
class FirstViewController: VideoSplashViewController {
override func viewDidLoad() {
super.viewDidLoad()
setupVideoBackground()
}
func setupVideoBackground() {
let url = NSURL.fileURLWithPath(NSBundle.mainBundle().pathForResource("sunny", ofType: "mp4")!)
videoFrame = view.frame
fillMode = .ResizeAspectFill
alwaysRepeat = true
sound = true
startTime = 2.0
alpha = 0.8
contentURL = url
view.userInteractionEnabled = false
}
}
答案 1 :(得分:0)
在ViewController类中使用此解决方法:
override func viewDidLoad() {
super.viewDidLoad()
...
NotificationCenter.default.addObserver(self,
selector: #selector(willEnterForeground),
name: NSNotification.Name.UIApplicationWillEnterForeground,
object: nil)
}
func willEnterForeground() {
player!.play()
}
希望对任何人都有帮助。祝你好运!
答案 2 :(得分:0)
Swift 4 在AppDelegate.swift中
func applicationDidEnterBackground(_ application: UIApplication) {
if let item = yourAVPlayer.currentItem {
if item.tracks.first!.assetTrack.hasMediaCharacteristic(AVMediaCharacteristic.visual) {
item.tracks.first!.isEnabled = false
}
}
}
func applicationWillEnterForeground(_ application: UIApplication) {
if let item = yourAVPlayer.currentItem {
if item.tracks.first!.assetTrack.hasMediaCharacteristic(AVMediaCharacteristic.visual) {
item.tracks.first!.isEnabled = true
}
}
}
当然不要忘记打开TARGETS - >能力 - >背景模式 - >音频,AirPlay和画中画,并在AppDelegate中输入所需的AVAudioSession。