Cómo reproducir video con AVPlayerViewController (AVKit) en Swift


164

¿Cómo se reproduce un video con AV Kit Player View Controller en Swift?

override func viewDidLoad() {
        super.viewDidLoad()
        let videoURLWithPath = "http://****/5.m3u8"
        let videoURL = NSURL(string: videoURLWithPath)
        playerViewController = AVPlayerViewController()

        dispatch_async(dispatch_get_main_queue()) {
            self.playerViewController?.player = AVPlayer.playerWithURL(videoURL) as AVPlayer
        }
    }

Para usar AVPlayer(no tiene los controles), vea esta respuesta .
Suragch

Respuestas:


532

Swift 3.x - 5.x

Necesario: importar AVKit , importar AVFoundation

El marco de AVFoundation es necesario incluso si usa AVPlayer

Si desea usar AVPlayerViewController :

let videoURL = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let player = AVPlayer(url: videoURL!)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
    playerViewController.player!.play()
}

o simplemente AVPlayer :

let videoURL = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4")
let player = AVPlayer(url: videoURL!)
let playerLayer = AVPlayerLayer(player: player)
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
player.play()

Es mejor poner este código en el método: anular func viewDidAppear (_ animated: Bool) o en algún lugar después.


C objetivo

AVPlayerViewController :

NSURL *videoURL = [NSURL URLWithString:@"https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"];
AVPlayer *player = [AVPlayer playerWithURL:videoURL];
AVPlayerViewController *playerViewController = [AVPlayerViewController new];
playerViewController.player = player;
[self presentViewController:playerViewController animated:YES completion:^{
  [playerViewController.player play];
}];

o simplemente AVPlayer :

NSURL *videoURL = [NSURL URLWithString:@"https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"];
AVPlayer *player = [AVPlayer playerWithURL:videoURL];
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
playerLayer.frame = self.view.bounds;
[self.view.layer addSublayer:playerLayer];
[player play];

@pikis Gracias por el ejemplo de código. Extraño, probamos el AVPlayerController tal como está escrito y obtuvimos un SIGABRT en: [self presentViewController: playerViewController animated: YES complete: nil];
Praxiteles

@Praxiteles, funciona en iOS8 o posterior, tal vez sea la razón.
pkis

8
También se requiere importación AVFoundation para mí
Rich Fox

1
@ Nick89, AVPlayer funciona correctamente con enlaces directos, pero si necesita usar servicios como YouTube, Vimeo, etc. (que tienen enlaces indirectos), debe usar su propia biblioteca o SDK. (por ejemplo, para YouTube: guía ).
pkis

2
El orden de las instrucciones es importante, también necesitaba importar AVKit
htafoya

30

Prueba esto, definitivamente funciona para Swift 2.0

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

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

    player.play()  

1
Gracias. El addChildViewController lo hizo incrustado justo lo que quiero. :)
SDW

1
La incrustación funciona perfectamente, pero ¿cómo manejará los cambios de orientación? Digamos que el jugador toma la mitad de la pantalla en el retrato y el controlador de vista sólo es compatible con el retrato pero el vídeo puede verse en vertical pero como la mayoría de aplicaciones hacer e .. youtube, vimeo, etc
Abid Hussain

Nota: addChildViewController es necesario. Lo intenté sin eso y luego casi funciona: se reproduce una vez, se expande a pantalla completa. Pero no vuelve a jugar ni sale del modo de pantalla completa. Entonces el controlador de vista infantil es necesario.
n13

self.addChildViewController(playerController)es ahora self.addChild(playerController)FYI
Marquis103

12

Prueba esto

var player:AVPlayer!
var avPlayerLayer:AVPlayerLayer = AVPlayerLayer(player: player)
avPlayerLayer.frame = CGRectMake(your frame)
self.view.layer .addSublayer(avPlayerLayer)
var steamingURL:NSURL = NSURL(string:playerURL)
player = AVPlayer(URL: steamingURL)
player.play()

Cuando ejecuto este código, obtengo el controlador de vista vacío
orazz

@ ¿Una persona que configuró el marco avPlayerLayer?
Ramesh

1
@Oneperson ok establezca esto avPlayerLayer.frame = CGRectMake (50,50,100,100)
Ramesh

code var player: AVPlayer! var playerItem: AVPlayerItem !; var avPlayerLayer: AVPlayerLayer = AVPlayerLayer (jugador: jugador) avPlayerLayer.frame = CGRectMake (50,50,100,100) self.view.layer .addSublayer (avPlayerLayer) deja videoURLWithPath = "http: //*****/45.m steamingURL: NSURL = NSURL (string: videoURLWithPath) player = AVPlayer (URL: steamingURL) player.play () code
orazz

@Oneperson edge.tolkun.tv/45.m3u8 no funciona. puedes dar tu url completa
Ramesh

11

Swift 3.0 Código fuente completo:

import UIKit
    import AVKit
    import AVFoundation

    class ViewController: UIViewController,AVPlayerViewControllerDelegate
    {
        var playerController = AVPlayerViewController()


        @IBAction func Play(_ sender: Any)
        {
            let path = Bundle.main.path(forResource: "video", ofType: "mp4")

            let url = NSURL(fileURLWithPath: path!)

            let player = AVPlayer(url:url as URL)

            playerController = AVPlayerViewController()


            NotificationCenter.default.addObserver(self, selector: #selector(ViewController.didfinishplaying(note:)),name:NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: player.currentItem)

            playerController.player = player

            playerController.allowsPictureInPicturePlayback = true

            playerController.delegate = self

            playerController.player?.play()

            self.present(playerController,animated:true,completion:nil)
        }

        func didfinishplaying(note : NSNotification)
        {
            playerController.dismiss(animated: true,completion: nil)
            let alertview = UIAlertController(title:"finished",message:"video finished",preferredStyle: .alert)
            alertview.addAction(UIAlertAction(title:"Ok",style: .default, handler: nil))
            self.present(alertview,animated:true,completion: nil)
        }


        func playerViewController(_ playerViewController: AVPlayerViewController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) {
                let currentviewController =  navigationController?.visibleViewController

                if currentviewController != playerViewController
                {
                    currentviewController?.present(playerViewController,animated: true,completion:nil)
                }


            }
    }

Hola ronak, ¡gracias por presentar a los observadores rápidamente para manejar el final del video! No logré que funcionara creando el AVPlayerViewController con el código proporcionado por la respuesta sobre el tuyo (primer fragmento de código), ¿qué es diferente? ¿Qué me perdí o debería implementar para que el observador en sus métodos funcione?
Manu

6

C objetivo

Esto solo funciona en Xcode 7

Ir a .harchivo e importar AVKit/AVKit.hy AVFoundation/AVFoundation.h. Luego vaya a .mpresentar y agregue este código:

NSURL *url=[[NSBundle mainBundle]URLForResource:@"arreg" withExtension:@"mp4"];
AVPlayer *video=[AVPlayer playerWithURL:url];
AVPlayerViewController *controller=[[AVPlayerViewController alloc]init];
controller.player=video;
[self.view addSubview:controller.view];
controller.view.frame=self.view.frame;
[self addChildViewController:controller];
[video play];

4

Usando MPMoviePlayerController:

 import UIKit
 import MediaPlayer

 class ViewController: UIViewController {

     var streamPlayer : MPMoviePlayerController =  MPMoviePlayerController(contentURL: NSURL(string:"video url here"))
     override func viewDidLoad() {
         super.viewDidLoad()
         streamPlayer.view.frame = self.view.bounds
         self.view.addSubview(streamPlayer.view)

         streamPlayer.fullscreen = true
         // Play the movie!
         streamPlayer.play()
}
}

Usando AVPlayer:

import AVFoundation

var playerItem:AVPlayerItem?
var player:AVPlayer?

override func viewDidLoad() {
        super.viewDidLoad() 
      let url = NSURL(string: "url of the audio or video") 
      playerItem = AVPlayerItem(URL: url!)
      player=AVPlayer(playerItem: playerItem!)
      let playerLayer=AVPlayerLayer(player: player!)
      playerLayer.frame=CGRectMake(0, 0, 300, 50)
      self.view.layer.addSublayer(playerLayer)
}

Tengo un botón de reproducción para manejar el toque del botón.

playButton.addTarget(self, action: "playButtonTapped:", forControlEvents: .TouchUpInside)

func playButtonTapped(sender: AnyObject) {
        if player?.rate == 0
        {
            player!.play()
            playButton.setImage(UIImage(named: "player_control_pause_50px.png"), forState: UIControlState.Normal)
        } else {
            player!.pause()
            playButton.setImage(UIImage(named: "player_control_play_50px.png"), forState: UIControlState.Normal)
        }
    }

He agregado un observador que escucha AVPlayerItemDidPlayToEndTimeNotification.

override func viewWillAppear(animated: Bool) {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "finishedPlaying:", name: AVPlayerItemDidPlayToEndTimeNotification, object: playerItem)
    }

override func viewWillDisappear(animated: Bool) {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

Cuando finalice la reproducción de video / audio, reinicie la imagen del botón y la notificación

  func finishedPlaying(myNotification:NSNotification) {
        playButton.setImage(UIImage(named: "player_control_play_50px.png"), forState: UIControlState.Normal)

        let stopedPlayerItem: AVPlayerItem = myNotification.object as! AVPlayerItem
        stopedPlayerItem.seekToTime(kCMTimeZero)
    }

2
MPMoviePlayerController está en desuso y probablemente ya no deberíamos usarlo.
Skywalker

¿Puede dar un ejemplo que no use URL, por ejemplo, usando un video local?
nyxee

4

¿Un error (?!) en iOS10 / Swift3 / Xcode 8?

if let url = URL(string: "http://devstreaming.apple.com/videos/wwdc/2016/102w0bsn0ge83qfv7za/102/hls_vod_mvp.m3u8"){
    let playerItem = AVPlayerItem(url: url)
    let player = AVPlayer(playerItem: playerItem)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame=CGRect(x: 10, y: 10, width: 300, height: 300)
    self.view.layer.addSublayer(playerLayer)
}

no funciona (vaciar rect ...)

esto funciona:

if let url = URL(string: "http://devstreaming.apple.com/videos/wwdc/2016/102w0bsn0ge83qfv7za/102/hls_vod_mvp.m3u8"){

            let player = AVPlayer(url: url)
            let controller=AVPlayerViewController()
            controller.player=player
            controller.view.frame = self.view.frame
            self.view.addSubview(controller.view)
            self.addChildViewController(controller)
            player.play()
        }

Misma URL ...


agregue esta línea: player.play()después: self.view.layer.addSublayer(playerLayer)e intente nuevamente
orazz

4

Swift 3:

import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {

    @IBOutlet weak var viewPlay: UIView!
    var player : AVPlayer?

    override func viewDidLoad() {
        super.viewDidLoad()

        let url : URL = URL(string: "http://static.videokart.ir/clip/100/480.mp4")!
        player = AVPlayer(url: url)
        let playerLayer = AVPlayerLayer(player: player)
        playerLayer.frame = self.viewPlay.bounds
        self.viewPlay.layer.addSublayer(playerLayer)

    }

    @IBAction func play(_ sender: Any) {
        player?.play()
    }

    @IBAction func stop(_ sender: Any) {
        player?.pause()
    }

}

¿Dónde en tu respuesta usaste AVPlayerViewController?
AnBisw

1

Esto funcionó para mí en Swift 5

Acabo de agregar un video de muestra al proyecto desde Videos de muestra

Se agregaron botones de acción para reproducir videos del sitio web y locales con el siguiente ejemplo de código rápido

import UIKit
import AVKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        //TODO : Make Sure Add and copy "SampleVideo.mp4" file in project before play
    }

    @IBAction func playWebVideo(_ sender: Any) {

        guard let url = URL(string: "https://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4") else {
            return
        }
        // Create an AVPlayer, passing it the HTTP Live Streaming URL.
        let player = AVPlayer(url: url)
        let controller = AVPlayerViewController()
        controller.player = player
        present(controller, animated: true) {
            player.play()
        }
    }

    @IBAction func playLocalVideo(_ sender: Any) {

        guard let path = Bundle.main.path(forResource: "SampleVideo", ofType: "mp4") else {
            return
        }
        let videoURL = NSURL(fileURLWithPath: path)

        // Create an AVPlayer, passing it the local video url path
        let player = AVPlayer(url: videoURL as URL)
        let controller = AVPlayerViewController()
        controller.player = player
        present(controller, animated: true) {
            player.play()
        }
    }

}

0

Swift 5

  @IBAction func buttonPressed(_ sender: Any) {
    let videoURL = course.introductionVideoURL
    let player = AVPlayer(url: videoURL)
    let playerViewController = AVPlayerViewController()
    playerViewController.player = player

    present(playerViewController, animated: true, completion: {

        playerViewController.player!.play()
    })

// aquí el curso incluye un archivo de modelo, dentro de él he dado la url, así que llamo a la función del modelo usando la función del curso.

// también IntroductionVideoUrl es una URL que he declarado dentro del modelo.

 var introductionVideoURL: URL

Alternativamente, también puede usar el siguiente código en lugar de llamar a la función desde el modelo

Reemplace este código

  let videoURL = course.introductionVideoURL

con

  guard let videoURL = URL(string: "https://something.mp4) else {
        return

0
let videoUrl = //URL: Your Video URL

//Create player first using your URL
let yourplayer = AVPlayer(url: videoUrl)

//Create player controller and set it’s player
let playerController = AVPlayerViewController()
playerController.player = yourplayer


//Final step To present controller  with player in your view controller
present(playerController, animated: true, completion: {
   playerController.player!.play()
})

0

Swift 5.0

Mejorado de la respuesta @ingconti. Esto funcionó para mí.

 if let url = URL(string: "urUrlString"){
            let player = AVPlayer(url: url)
            let avController = AVPlayerViewController()
            avController.player = player
            // your desired frame
            avController.view.frame = self.view.frame
            self.view.addSubview(avController.view)
            self.addChild(avController)
            player.play()
        }

0

Swift 5+

En primer lugar, debe definir 2 variables globalmente dentro de su controlador de vista.

var player: AVPlayer!
var playerViewController: AVPlayerViewController!

Aquí estoy agregando jugador a la vista deseada.

@IBOutlet weak var playerView: UIView!

Luego agregue el siguiente código al método viewDidLoad .

let videoURL = URL(string: "videoUrl")
self.player = AVPlayer(url: videoURL!)
self.playerViewController = AVPlayerViewController()
playerViewController.player = self.player
playerViewController.view.frame = self.playerView.frame
playerViewController.player?.pause()
self.playerView.addSubview(playerViewController.view)

Si no está definiendo player y playerViewController a nivel mundial, no podrá incrustar player.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.