Day10 - 播放一段視頻的登錄頁面

效果圖

效果圖

<br />

1、UI布局

新建一個ImageView和兩個按鈕,分別設置背景、字體顏色

結構圖如圖

2、新建一個父類UIViewController,用來處理視頻加載,播放等相關屬性

因為文中的注釋寫的還算詳細了,就不做方法介紹了

//
//  PQLoginVideoViewController.swift
//  VideoLoginPage
//
//  Created by ios on 16/9/13.
//  Copyright ? 2016年 ios. All rights reserved.
//

import UIKit
import AVFoundation
import MediaPlayer
import AVKit

//三種填充方式
public enum PQVideoScalingMode{
    case Resize
    case ResizeAspect
    case ResizeAspectFill
}

class PQLoginVideoViewController: UIViewController {
    
    //播放器
    private let pq_moviePlayer = AVPlayerViewController()
    //聲音級別
    private var pq_moviePlayerSoundLevel: Float = 1.0
    //視頻路徑
    var pq_contentURL :NSURL = NSURL(){
        didSet{
            setMoviePlayer(pq_contentURL)
        }
    }
    //視頻大小
    var pq_videoFrame = CGRect()
    //開始時間
    var pq_startTime : CGFloat = 0.0
    //時長
    var pq_duration : CGFloat = 0.0
    //把view的背景顏色設置為默認黑色
    var pq_backgroundColor : UIColor = UIColor.blackColor(){
        didSet{
            view.backgroundColor = pq_backgroundColor
        }
    }
    //是否能聽到聲音
    var pq_sound : Bool = true{
        didSet{
            if pq_sound {
                pq_moviePlayerSoundLevel = 1.0
            }
            else{
                pq_moviePlayerSoundLevel = 0.0
            }
        }
    }
    //透明度
    var pq_alpha : CGFloat = CGFloat(){
        didSet{
            pq_moviePlayer.view.alpha = pq_alpha
        }
    }
    //是不是重復播放
    var pq_alwaysRepeat :Bool = true{
        didSet{
            if pq_alwaysRepeat {
                NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PQLoginVideoViewController.pqLoginVideoPlayEnd), name: AVPlayerItemDidPlayToEndTimeNotification, object: pq_moviePlayer.player?.currentItem)
            }
        }
    }
    //填充模式
    var pq_fillModel : PQVideoScalingMode = .ResizeAspectFill{
        didSet{
            switch pq_fillModel {
            case .Resize:
                pq_moviePlayer.videoGravity = AVLayerVideoGravityResize
            case .ResizeAspect:
                pq_moviePlayer.videoGravity = AVLayerVideoGravityResizeAspect
            case .ResizeAspectFill:
                pq_moviePlayer.videoGravity = AVLayerVideoGravityResizeAspectFill
            }
        }
    }
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    //設置視頻頁面大小,插入到最底層
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        pq_moviePlayer.view.frame = pq_videoFrame
        pq_moviePlayer.showsPlaybackControls = false
        view.insertSubview(pq_moviePlayer.view, atIndex: 0)
    }
    
    //視圖移除要把觀察者移除
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }
    
    // MARK - method
    //設置地址:然后把視頻拷貝到Doucument文件夾在,在進行播放
    private func setMoviePlayer(url : NSURL){
        //創建一個對象
        let videoCutter = PQVideoCutter()
        //使用子線程的方式把視頻拷貝到Doucments文件夾下
        videoCutter.cropVideoWithURL(videoURL: url, startTime: pq_startTime, duration: pq_duration) { (videoPath, error) in
            if let path = videoPath as NSURL?{
                //視頻拷貝完成了
                //1、設置播放地址
                //2、開始播放
                //3、設置聲音
                self.pq_moviePlayer.player = AVPlayer(URL: path)
                self.pq_moviePlayer.player?.play()
                self.pq_moviePlayer.player?.volume = self.pq_moviePlayerSoundLevel
            }
        }
    }
    
    //監聽播放完成了,再次播放 
    //1、時間歸零
    //2、開始播放
    @objc private func pqLoginVideoPlayEnd(){
        pq_moviePlayer.player?.seekToTime(kCMTimeZero)
        pq_moviePlayer.player?.play()
    }
}

3、寫一個類專門用來把視頻拷貝到Documents目錄下

//
//  PQVideoCutter.swift
//  VideoLoginPage
//
//  Created by ios on 16/9/14.
//  Copyright ? 2016年 ios. All rights reserved.
//

import UIKit
import AVFoundation

extension String{
    var convert : NSString  { return  (self as NSString) }
    
}

class PQVideoCutter: NSObject {
    func cropVideoWithURL(videoURL url : NSURL,startTime :CGFloat,duration : CGFloat,completion:((videoPath : NSURL? ,error : NSError?) -> Void)?){
        
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_async(dispatch_get_global_queue(priority, 0)) { 
            let asset = AVURLAsset(URL: url, options: nil)
            let exportSession = AVAssetExportSession(asset: asset, presetName: "AVAssetExportPresetHighestQuality")
            let paths :NSArray = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, .UserDomainMask, true)
            var outputURL = paths.objectAtIndex(0) as! String
            let manager = NSFileManager.defaultManager()
            do{
                try manager.createDirectoryAtPath(outputURL, withIntermediateDirectories: true, attributes: nil)
            }catch{
                
            }
            
            
            outputURL = outputURL.convert.stringByAppendingPathComponent("output.mp4")
            do{
                try manager.removeItemAtPath(outputURL)
            }catch{
                
            }
            
            if let exportSession = exportSession as AVAssetExportSession?{
                exportSession.outputURL = NSURL(fileURLWithPath: outputURL)
                exportSession.shouldOptimizeForNetworkUse = true
                exportSession.outputFileType = AVFileTypeMPEG4
                let start = CMTimeMakeWithSeconds(Float64(startTime), 600)
                let time = CMTimeMakeWithSeconds(Float64(duration), 600)
                let range = CMTimeRangeMake(start, time)
                exportSession.timeRange = range
                exportSession.exportAsynchronouslyWithCompletionHandler({ 
                    switch exportSession.status{
                    case .Completed:
                        completion?(videoPath: exportSession.outputURL,error: nil)
                    case .Failed:
                        print("Failed - \(exportSession.error)")
                    case .Cancelled:
                        print("Cancelled - \(exportSession.error)")
                    default :
                        print("other error")
                    }
                })
            }
        }
    }
}

4、然后在ViewController中繼承剛才寫的父類

//
//  ViewController.swift
//  VideoLoginPage
//
//  Created by ios on 16/9/13.
//  Copyright ? 2016年 ios. All rights reserved.
//

import UIKit

class ViewController: PQLoginVideoViewController {

    @IBOutlet weak var registerBtn: UIButton!
    @IBOutlet weak var loginBtn: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        view.backgroundColor = UIColor.blackColor()
        setupVideoBackground()
    }
    
    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        registerBtn.layer.cornerRadius = 5
        loginBtn.layer.cornerRadius = 5
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    private func setupVideoBackground() {
        
        let url = NSURL.fileURLWithPath(NSBundle.mainBundle().pathForResource("moments", ofType: "mp4")!)
        
        pq_videoFrame = view.frame
        pq_fillModel = .ResizeAspectFill
        pq_alwaysRepeat = true
        pq_sound = true
        pq_startTime = 2.0
        pq_alpha = 0.8
        
        pq_contentURL = url
        view.userInteractionEnabled = false
     
        print(NSHomeDirectory())
    }

}


所有代碼都已經粘貼上來了!

Demo - VideoLoginPage

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容

  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結起來就是把...
    Dove_iOS閱讀 27,197評論 30 471
  • 1.OC里用到集合類是什么? 基本類型為:NSArray,NSSet以及NSDictionary 可變類型為:NS...
    輕皺眉頭淺憂思閱讀 1,392評論 0 3
  • *7月8日上午 N:Block :跟一個函數塊差不多,會對里面所有的內容的引用計數+1,想要解決就用__block...
    炙冰閱讀 2,512評論 1 14
  • 當拿起筆想記錄一些點點滴滴、令人感動而難忘的時候,心里總會有一些忐忑。是啊,誰沒有故事,但不一定每個人都酒...
    稻九閱讀 217評論 0 0
  • 北漂族之歌 20171112 我們都有一個美好的夢, 來自全國各地四面八方, 東西南北中, 為了追求嶄新的...
    泥瓦匠長青閱讀 292評論 0 0