当前位置: > > > Swift - 使用AVKit播放本地视频,在线视频(AVPlayerViewController)

Swift - 使用AVKit播放本地视频,在线视频(AVPlayerViewController)

(本文代码已升级至Swift4)

原来我们可以使用 Media Player 框架 MPMoviePlayerController 来播放视频、音频。但自iOS9.0起,这个将会被废除,所以苹果建议使用 AVKitAVPlayerViewController 来代替。

1,单独使用 AVPlayer

这个可以在当前视图中添加一个视频播放窗口,位置大小可设置,但不带播放控制器。所以如果需要控制视频播放状态的话,就需要自己在页面上添加按钮,写相应的控制方法了。
import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //定义一个视频文件路径
        let filePath = Bundle.main.path(forResource: "hangge", ofType: "mp4")
        let videoURL = URL(fileURLWithPath: filePath!)
        //定义一个视频播放器,通过本地文件路径初始化
        let player = AVPlayer(url: videoURL)
        //设置大小和位置(全屏)
        let playerLayer = AVPlayerLayer(player: player)
        playerLayer.frame = self.view.bounds
        //添加到界面上
        self.view.layer.addSublayer(playerLayer)
        //开始播放
        player.play()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

2,视频播放完毕响应

我们可以定义一个 AVPlayerItem,当视频播放完毕后它会发送一个 AVPlayerItemDidPlayToEndTime 通知。我们可以监听这个通知,在响应事件中做一些后续工作(比如关闭播放器、播放下一个视频等)
import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidLoad()
        
        //定义一个视频文件路径
        let filePath = Bundle.main.path(forResource: "hangge", ofType: "mp4")
        let videoURL = URL(fileURLWithPath: filePath!)
        //定义一个playerItem,并监听相关的通知
        let playerItem = AVPlayerItem(url: videoURL)
        NotificationCenter.default.addObserver(self,
                           selector: #selector(playerDidFinishPlaying),
                           name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,
                           object: playerItem)
        //定义一个视频播放器,通过playerItem径初始化
        let player = AVPlayer(playerItem: playerItem)
        //设置大小和位置(全屏)
        let playerLayer = AVPlayerLayer(player: player)
        playerLayer.frame = self.view.bounds
        //添加到界面上
        self.view.layer.addSublayer(playerLayer)
        //开始播放
        player.play()
    }
    
    //视频播放完毕响应
    @objc func playerDidFinishPlaying() {
        print("播放完毕!")
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


3,使用AVPlayerViewController

这个类似于原来的 MPMoviePlayerController,使用时是会切换到新的视图控制器页面上,同时会有播放、暂停、进度选择等播放控制器。
import UIKit
import AVKit
import AVFoundation

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidLoad()
        
        //定义一个视频文件路径
        let filePath = Bundle.main.path(forResource: "hangge", ofType: "mp4")
        let videoURL = URL(fileURLWithPath: filePath!)
        //定义一个视频播放器,通过本地文件路径初始化
        let player = AVPlayer(url: videoURL)
        let playerViewController = AVPlayerViewController()
        playerViewController.player = player
        self.present(playerViewController, animated: true) {
            playerViewController.player!.play()
        }
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}


4,播放在线视频

前面两个样例都是播放本地视频,要播放网络视频使用如下代码:
let videoURL =  URL(string: "http://hangge.com/demo.mp4")!
let player = AVPlayer(url: videoURL)
//.........
评论10
  • 10楼
    2017-09-20 15:14

    请问怎么停止播放和关闭这个视图啊。播放完之后就停在那了,也找不到代理方法。

    站长回复

    播放完毕会有相关的通知,我在文章里补充了相关内容,你可以看下。

  • 9楼
    2017-07-30 15:46

    請問单独使用AVPlayer要怎麼設置橫屏呢

    站长回复

    你指的是只能横屏显示,还是可以横竖屏动态切换。
    (1)只允许横屏。项目可以这么设置:Swift - 让StoryBoard设计视图,程序运行时都使用横屏形式
    (2)想要横竖屏动态切换。可以使用自适应弹性布局,原理参考我的这篇文章:Swift - 使用Auto Layout和Size Classes实现页面自适应弹性布局

  • 8楼
    2017-04-11 10:14
    丁丁

    第二段程式碼少了設定frame,所以跑出來畫面會不正常

    站长回复

    第二个不用设置frame的,因为使用的是AVPlayerViewController,弹出后便是全屏显示。

  • 7楼
    2016-05-13 09:55
    aaaa

    我的文件在啊,但是确实找不到诶

    站长回复

    那奇怪了。你再检查下配置(下图),视频文件确定编译打包进来了?


  • 6楼
    2016-05-04 20:14
    aaaa

    为什么我的程序执行到 filepath的时候,他报错是空值啊

    站长回复

    应该是没找到文件,你看下视频文件在不在,路径是否正确,编译时是否打包进来。

  • 5楼
    2016-05-04 09:47
    小曹

    航哥,你好,flv 格式的视频怎么加载播放呢??MP4的可以播放,但是加载flv的就不行了

    站长回复

    确实是这样的,AVKit不支持flv格式的视频播放。

  • 4楼
    2016-05-02 13:11
    半夏

    为什么我播放网络视频有问题呢?是不是有什么需要注意的地方呢?
    http://v1.mukewang.com/a45016f4-08d6-4277-abe6-bcfd5244c201/L.mp4视频是没问题的,
    请站长赐教。。。

    站长回复

    我测试了下视频可以播放,你看下是不是http请求安全策略没加,参考我的这篇文章:Swift - 网络请求报App Transport Security has blocked a cleartext错

  • 3楼
    2016-04-30 19:14
    mapanguan

    编译运行报错了,不能理解为什么会出现这种错误,求大神指点
    let filePath = NSBundle.mainBundle().pathForResource("demo", ofType:"mp4")
    let videoUrl = NSURL(fileURLWithPath: filePath!)
    let player = AVPlayer(URL: videoUrl)

    // let playerLayer = AVPlayerLayer(player: player)
    // playerLayer.frame = self.view.bounds
    // self.view.layer.addSublayer(playerLayer)
    // player.play()

    let playerViewController = AVPlayerViewController()
    playerViewController.player = player
    self.presentViewController(playerViewController, animated: true) {
    playerViewController.player!.play()
    }


    2016-04-30 19:10:19.182 AVPlayer[5195:695673] Warning: Attempt to present <AVPlayerViewController: 0x7fc0d1842600> on <AVPlayer.ViewController: 0x7fc0d0f2d6d0> whose view is not in the window hierarchy!

    站长回复

    应该是你把这个代码写到了viewDidLoad()方法里面,如果想要页面加载完毕后就打开AVPlayerViewController播放视频,可以将代码放在viewDidAppear()方法中。<br>

    这个报错原因同我以前写的另一篇文章是一样的:Swift - whose view is not in the window hierarchy 问题解决方法

  • 2楼
    2016-04-27 09:41
    黑木宁

    关于AVPlayerViewController 的控制能再讲讲么 全屏缩放 播放暂停什么的

    站长回复

    AVPlayerViewController自带控制器的啊,播放暂停什么的不需要我们再写代码。

  • 1楼
    2016-04-26 22:37

    每天都在关注航哥写的博文,支持航哥,写的非常好

    站长回复

    谢谢你的支持和鼓励,我会继续创作下去的。