150 votes

Mettre en boucle une vidéo avec AVFoundation AVPlayer ?

Existe-t-il un moyen relativement simple de mettre en boucle une vidéo dans AVFoundation ?

J'ai créé mon AVPlayer et mon AVPlayerLayer comme suit :

avPlayer = [[AVPlayer playerWithURL:videoUrl] retain];
avPlayerLayer = [[AVPlayerLayer playerLayerWithPlayer:avPlayer] retain];

avPlayerLayer.frame = contentView.layer.bounds;
[contentView.layer addSublayer: avPlayerLayer];

et ensuite je joue ma vidéo avec :

[avPlayer play];

La vidéo est bien diffusée mais s'arrête à la fin. Avec le MPMoviePlayerController, tout ce que vous avez à faire, c'est de régler sa fonction repeatMode à la bonne valeur. Il ne semble pas y avoir de propriété similaire sur AVPlayer. Il ne semble pas non plus y avoir de rappel pour me dire quand le film est terminé, afin que je puisse revenir au début et le relire.

Je n'utilise pas MPMoviePlayerController car il présente de sérieuses limitations. Je veux pouvoir lire plusieurs flux vidéo à la fois.

1 votes

Voir cette réponse pour un lien vers un code fonctionnel réel : stackoverflow.com/questions/7822808/

0voto

Nrv Points 125

Ce qui suit fonctionne pour moi dans WKWebView en swift 4.1 La partie principale du WKWebView dans WKwebviewConfiguration

wkwebView.navigationDelegate = self
wkwebView.allowsBackForwardNavigationGestures = true
self.wkwebView =  WKWebView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
wkwebView = WKWebView(frame: wkwebView.frame, configuration: config)
self.view.addSubview(wkwebView)
self.wkwebView.load(NSURLRequest(url: URL(string: self.getUrl())!) as URLRequest)

0voto

Gigantic Points 4447

Swift 4.2 dans Xcode 10.1.

Oui il existe un moyen relativement simple de faire tourner une vidéo en boucle en AVKit / AVFoundation en utilisant AVQueuePlayer() La technique Key-Value Observation (KVO) et un jeton pour celle-ci.

Cela fonctionne sans aucun doute pour un grand nombre de vidéos H.264/HEVC avec une charge minimale pour le CPU.

Voici un code :

import UIKit
import AVFoundation
import AVKit

class ViewController: UIViewController {

    private let player = AVQueuePlayer()
    let clips = ["01", "02", "03", "04", "05", "06", "07"]
    private var token: NSKeyValueObservation?
    var avPlayerView = AVPlayerViewController()

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

        self.addAllVideosToPlayer()
        present(avPlayerView, animated: true, completion: { self.player.play() })
    }

    func addAllVideosToPlayer() {
        avPlayerView.player = player

        for clip in clips {
            let urlPath = Bundle.main.path(forResource: clip, ofType: "m4v")!
            let url = URL(fileURLWithPath: urlPath)
            let playerItem = AVPlayerItem(url: url)
            player.insert(playerItem, after: player.items().last)

            token = player.observe(\.currentItem) { [weak self] player, _ in
                if self!.player.items().count == 1 { self?.addAllVideosToPlayer() }
            }
        }
    }
}

0voto

Sanan Points 11

Swift 5

import UIKit
import AVKit
import AVFoundation

class VideoViewControler: UIViewController {

    // init video background and its path
    var player: AVPlayer?
    let videoURL: NSURL = Bundle.main.url(forResource: "farmer_watering", withExtension: "mp4")! as NSURL

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white

        // begin implementing the avplayer
        player = AVPlayer(url: videoURL as URL)
        player?.actionAtItemEnd = .none
        player?.isMuted = true

        let playerLayer = AVPlayerLayer(player: player)
        playerLayer.videoGravity = AVLayerVideoGravity.resizeAspect
        playerLayer.zPosition = -1

        playerLayer.frame = view.frame

        view.layer.addSublayer(playerLayer)

        player?.play()

        // add observer to watch for video end in order to loop video
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(loopVideo),
            name: .AVPlayerItemDidPlayToEndTime,
            object: self.player?.currentItem
        )
    }

    // if video ends, will restart
    func playerItemDidReachEnd() {
        player?.seek(to: CMTime.zero)
    }

    // add this loop at the end, after viewDidLoad
    @objc func loopVideo() {
        playerItemDidReachEnd()
        player?.play()
    }
}

-1voto

Iyyappan Ravi Points 1903

Utilisez le code AVPlayerViewController ci-dessous, il fonctionne pour moi.

        let type : String! = "mp4"
        let targetURL : String? = NSBundle.mainBundle().pathForResource("Official Apple MacBook Air Video   YouTube", ofType: "mp4")

        let videoURL = NSURL(fileURLWithPath:targetURL!)

        let player = AVPlayer(URL: videoURL)
        let playerController = AVPlayerViewController()

        playerController.player = player
        self.addChildViewController(playerController)
        self.playView.addSubview(playerController.view)
        playerController.view.frame = playView.bounds

        player.play()

Tous les contrôles à montrer, j'espère que c'est utile

-2voto

Julz Points 1
/* "numberOfLoops" is the number of times that the sound will return to the beginning upon reaching the end. 
A value of zero means to play the sound just once.
A value of one will result in playing the sound twice, and so on..
Any negative number will loop indefinitely until stopped.
*/
@property NSInteger numberOfLoops;

Cette propriété est déjà définie dans AVAudioPlayer . J'espère que cela pourra vous aider. J'utilise Xcode 6.3.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X