视频播放(一)

开始篇,我们用AVFoundation中的AVPlayer配合AVPlayerLayer进行播放,但是我们不能控制其暂停/继续、进度条显示及进度拖动、已播时间/总时长显示,这些都没有,所以我们定制一个XIB来包装AVPlayer和AVPlayerLayer

完整代码见 https://github.com/targetcloud/VideoPlayer1

未封装使用没有进度、时间等

import UIKit
import AVFoundation

class ViewController: UIViewController {
    
    lazy var player: AVPlayer = {
        let url = URL(string: "http://v1.mukewang.com/57de8272-38a2-4cae-b734-ac55ab528aa8/L.mp4")
        let player = AVPlayer(url: url!)
        return player
    }()
    
    var layer: AVPlayerLayer?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        layer = AVPlayerLayer(player: player)
        view.layer.addSublayer(layer!)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        player.play()
    }

    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        layer?.frame = view.layer.bounds
    }
    
}


封装(XIB形式),有进度、时间等

//
//  videoPlayer1.swift
//  videoPlayer1
//
//  Created by targetcloud on 2016/11/29.
//  Copyright © 2016年 targetcloud. All rights reserved.
//

import UIKit
import AVFoundation

class videoPlayer1: UIView {

    var playerItem : AVPlayerItem? {
        didSet{
            player?.replaceCurrentItem(with: playerItem)
            player?.play()
        }
    }
    var player : AVPlayer?
    var playerLayer : AVPlayerLayer?
    var isShowToolView : Bool?
    var progressTimer : Timer?
    
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var toolView: UIView!
    @IBOutlet weak var timeLabel: UILabel!
    @IBOutlet weak var progressSlider: UISlider!
    @IBOutlet weak var playOrPauseBtn: UIButton!
    
    class func playerView()->videoPlayer1{
       return Bundle.main.loadNibNamed("videoPlayer1", owner: nil, options: nil)?.first as! videoPlayer1
    }
    
    override func awakeFromNib() {
        player = AVPlayer()
        playerLayer = AVPlayerLayer(player: player)
        imageView.layer.addSublayer(playerLayer!)
        toolView.alpha = 0
        isShowToolView = false
        progressSlider.setThumbImage(UIImage(named:"thumbImage"), for: .normal)
        progressSlider.setMaximumTrackImage(UIImage(named:"MaximumTrackImage"), for: .normal)
        progressSlider.setMinimumTrackImage(UIImage(named:"MinimumTrackImage"), for: .normal)
        removeProgressTimer()
        addProgressTimer()
        playOrPauseBtn.isSelected = true
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        playerLayer?.frame = bounds
    }
    
    func removeProgressTimer(){
        progressTimer?.invalidate()
        progressTimer = nil
    }
    
    func addProgressTimer(){
        progressTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(videoPlayer1.updateProgressInfo), userInfo: nil, repeats: true)
        RunLoop.main.add(progressTimer!, forMode: RunLoopMode.commonModes)
    }
    
    func updateProgressInfo(){
        timeLabel.text = stringWithCurrentTime(CMTimeGetSeconds((player?.currentTime())!),CMTimeGetSeconds((player?.currentItem?.duration)!))
        progressSlider.value = Float(CMTimeGetSeconds((player?.currentTime())!) / CMTimeGetSeconds((player?.currentItem?.duration)!))
    }
    
    func stringWithCurrentTime(_ currentTime:TimeInterval,_ duration:TimeInterval)->String{
        let dMin = Int(duration) / 60
        let dSec = Int(duration) % 60
        let durationString = String(format:"%02ld:%02ld",dMin,dSec)
        let cMin = Int(currentTime) / 60
        let cSec = Int(currentTime) % 60
        let currentString = String(format:"%02ld:%02ld",cMin,cSec)
        return currentString + "/" + durationString
    }
    
    @IBAction func playOrPause(_ sender: UIButton) {
        sender.isSelected = !sender.isSelected
        if sender.isSelected{
            player?.play()
            addProgressTimer()
        }else{
            player?.pause()
            removeProgressTimer()
        }
    }
    
    @IBAction func switchOrientation(_ sender: UIButton) {
        sender.isSelected = !sender.isSelected
        
    }
    
    @IBAction func startSlider(_ sender: UISlider) {
        removeProgressTimer()
    }
    
    @IBAction func slider(_ sender: UISlider) {
        addProgressTimer()
        let currentTime = TimeInterval(Float(CMTimeGetSeconds((player?.currentItem?.duration)!)) * progressSlider.value);
        player?.seek(to: CMTimeMakeWithSeconds(currentTime, Int32(NSEC_PER_SEC)), toleranceBefore:kCMTimeZero, toleranceAfter:kCMTimeZero)
    }
    
    @IBAction func sliderValueChanged(_ sender: UISlider) {
        let currentTime  = TimeInterval(Float(CMTimeGetSeconds((player?.currentItem?.duration)!)) * progressSlider.value);
        let duration : TimeInterval = CMTimeGetSeconds((player?.currentItem?.duration)!);
        timeLabel.text = stringWithCurrentTime(currentTime ,duration)
    }
    
    @IBAction func tapAction(_ sender: UITapGestureRecognizer) {
        UIView.animate(withDuration: 0.5, animations: { () -> Void in
            if self.isShowToolView!{
                self.toolView.alpha = 0
                self.isShowToolView = false
            }else{
                self.toolView.alpha = 1
                self.isShowToolView = true
            }
        })
    }

}

使用如下:

//
//  ViewController.swift
//  videoPlayer1
//
//  Created by targetcloud on 2016/11/29.
//  Copyright © 2016年 targetcloud. All rights reserved.
//

import UIKit
import AVFoundation

class ViewController: UIViewController {

    var playerView:videoPlayer1?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        playerView = videoPlayer1.playerView()
        self.view.addSubview(playerView!)
        
        let url = URL(string:"http://v1.mukewang.com/57de8272-38a2-4cae-b734-ac55ab528aa8/L.mp4")//
        let item = AVPlayerItem(url : url!)
        playerView?.playerItem = item
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        playerView?.frame = view.bounds
    }

}

没有封装与封装后的效果对比(图1之前,图2图3之后)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值