如何在swift中制作循环视频

时间:2016-01-25 10:17:52

标签: ios swift loops video

如何在循环中制作没有声音播放的本地.mp4文件,因此它只会占用部分屏幕并且没有用户控件。只是一个循环视频,有点像gif。我使用xcodeswift2

class ViewController: UIViewController {

    var playerViewController = AVPlayerViewController()
    var playerView = AVPlayer()

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

    }

    override func viewDidAppear(animated: Bool) {
        var fileURL = NSURL(fileURLWithPath: "/Users/Mantas/Desktop/123/123/video-1453562323.mp4.mp4")
        playerView = AVPlayer(URL: fileURL)

        playerViewController.player = playerView

        self.presentViewController(playerViewController, animated: true){

            self.playerViewController.player?.play()

        }
    }
}

我做了这个,它播放视频,但在全屏幕上,我不知道如何使它只占用屏幕的一部分以及如何使其循环

4 个答案:

答案 0 :(得分:6)

Swift 3.0中的替代版本:

添加以下属性:

fileprivate var player: AVPlayer? {
    didSet { player?.play() }
}

fileprivate var playerObserver: Any?

将此添加到你的deinit:

deinit {
    guard let observer = playerObserver else { return }
    NotificationCenter.default.removeObserver(observer)
}

添加此功能:

func videoPlayerLayer() -> AVPlayerLayer {
    let fileURL = URL(fileURLWithPath: mediaPath)
    let player = AVPlayer(url: fileURL)
    let resetPlayer = {
        player.seek(to: kCMTimeZero)
        player.play()
    }
    playerObserver = NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem, queue: nil) { notification in
        resetPlayer()
    }
    self.player = player
    return AVPlayerLayer(player: player)
}

然后根据您的意愿添加到您的图层(viewDidLoad,viewDidAppear,viewDidFinishLayingOutSubviews):

let playerLayer = videoPlayerLayer()
playerLayer.frame = view.bounds
view.layer.insertSublayer(playerLayer, at: 0)

答案 1 :(得分:4)

在视频播放完毕后添加观察者可以重播视频

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear()

    var fileURL = NSURL(fileURLWithPath: "/Users/Mantas/Desktop/123/123/video-1453562323.mp4.mp4")
    playerView = AVPlayer(URL: fileURL)

    NSNotificationCenter.defaultCenter().addObserver(self,
    selector: "playerItemDidReachEnd:",
    name: AVPlayerItemDidPlayToEndTimeNotification,
    object: self.playerView.currentItem) // Add observer

    playerViewController.player = playerView

    //amend the frame of the view
    self.playerViewController.player.frame = CGRectMake(0, 0, 200, 200)
    //reset the layer's frame, and re-add it to the view
    var playerLayer: AVPlayerLayer =   AVPlayerLayer.playerLayerWithPlayer(self.playerView)
    playerLayer.frame = videoHolderView.bounds
    videoHolderView.layer.addSublayer(playerLayer)

    /* Full Screen
    self.presentViewController(playerViewController, animated: true){

        self.playerViewController.player?.play()

    }  */
}

func playerItemDidReachEnd(notification: NSNotification) {
   self.playerView.seekToTime(kCMTimeZero)
   self.playerView.play()
}

答案 2 :(得分:1)

对于没有黑色闪光的无缝重复视频。像这样使用AVPlayerLooper:

private var player: AVQueuePlayer!
private var playerLayer: AVPlayerLayer!
private var playerItem: AVPlayerItem!
private var playerLooper: AVPlayerLooper!

override func viewDidLoad(){
    super.viewDidLoad()

    let path = Bundle.main.path(forResource: "background_cloudy", ofType: "mov")
    let pathURL = URL(fileURLWithPath: path!)
    let duration = Int64( ( (Float64(CMTimeGetSeconds(AVAsset(url: pathURL).duration)) *  10.0) - 1) / 10.0 )

    player = AVQueuePlayer()
    playerLayer = AVPlayerLayer(player: player)
    playerItem = AVPlayerItem(url: pathURL)
    playerLooper = AVPlayerLooper(player: player, templateItem: playerItem,
                                  timeRange: CMTimeRange(start: kCMTimeZero, end: CMTimeMake(duration, 1)) )
    playerLayer.videoGravity = AVLayerVideoGravity.resizeAspectFill
    playerLayer.frame = view.layer.bounds
    view.layer.insertSublayer(playerLayer, at: 1)
}

答案 3 :(得分:0)

这是用 Swift 5 测试的,我在 https://gist.github.com/lanserxt/33fd8c479185cba181497315299e0e31

中发现
import UIKit
import AVFoundation

class LoopedVideoPlayerView: UIView {

    fileprivate var videoURL: URL?
    fileprivate var queuePlayer: AVQueuePlayer?
    fileprivate var playerLayer: AVPlayerLayer?
    fileprivate var playbackLooper: AVPlayerLooper?

    func prepareVideo(_ videoURL: URL) {
    
        let playerItem = AVPlayerItem(url: videoURL)
            
        self.queuePlayer = AVQueuePlayer(playerItem: playerItem)
        self.playerLayer = AVPlayerLayer(player: self.queuePlayer)
        guard let playerLayer = self.playerLayer else {return}
        guard let queuePlayer = self.queuePlayer else {return}
        self.playbackLooper = AVPlayerLooper.init(player: queuePlayer, templateItem: playerItem)
            
        playerLayer.videoGravity = .resizeAspectFill
        playerLayer.frame = self.frame
        self.layer.addSublayer(playerLayer)
    }

    func play() {
        self.queuePlayer?.play()
    }

    func pause() {
        self.queuePlayer?.pause()
    }

    func stop() {
        self.queuePlayer?.pause()
        self.queuePlayer?.seek(to: CMTime.init(seconds: 0, preferredTimescale: 1))
    }

    func unload() {
        self.playerLayer?.removeFromSuperlayer()
        self.playerLayer = nil
        self.queuePlayer = nil
        self.playbackLooper = nil
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func layoutSubviews() {
        self.playerLayer?.frame = self.bounds
    }
}