Ios 如何在swift中制作循环视频

Ios 如何在swift中制作循环视频,ios,swift,loops,video,Ios,Swift,Loops,Video,我如何制作一个本地.mp4文件,在循环中没有声音播放,因此它只占用部分屏幕,没有用户控制。只是一个循环视频,有点像gif。我正在使用xcode,swift2 class ViewController: UIViewController { var playerViewController = AVPlayerViewController() var playerView = AVPlayer() override func viewDidLoad() {

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

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()

        }
    }
}

我制作了这个,它播放视频,但在全屏上,我不知道如何使它只占据部分屏幕,如何使它循环

视频结束时添加观察者可以使视频重播

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()
}

Swift 3.0中的替代版本:

添加以下属性:

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

fileprivate var playerObserver: Any?
将此添加到您的Denit中:

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、ViewDidDisplay、ViewDidFinishLayingOutSubview):


对于没有黑色闪光灯的无可视重复视频。使用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)
}

这是用Swift 5测试的,我在


谢谢,我该如何添加一个框架,而不是全屏播放?更新的ans如果helpsIt做了一个小动作,你可以访问ans!但这种循环并非天衣无缝。这在回放之间有一些差距这太棒了,谢谢!我认为我们应该将fileURL作为参数。func videoPlayerLayer(fileURL:URL)->avplayerlayer你太棒了!这真的帮了大忙!我所要做的就是更改cell.layer.addSublayer(cell.playerLayer!)
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)
}
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
    }
}