基于swift3.0實現(xiàn)視頻播放拆撼、屏幕旋轉(zhuǎn)自適應(yīng)容劳、倍速播放、手勢調(diào)節(jié)進度音量等功能

最近在學(xué)習(xí)swift,恰巧現(xiàn)在負責(zé)的項目中有關(guān)于視頻播放的一些東西,就想著用swift去實現(xiàn),視頻播放在原OC項目中已實現(xiàn)基本功能,所以就模仿OC去寫swift視頻播放,在寫的過程中發(fā)現(xiàn)與OC的實現(xiàn)方法出入還是比較大的,網(wǎng)上關(guān)于swift視頻播放資料不是很全面,所以想給大家分享一下知識點情萤。

demo下載地址

先來看一下實現(xiàn)的效果鸭蛙,沒實現(xiàn)效果我知道同學(xué)肯定看不下去

播放演示.gif

簡單說一下工程結(jié)構(gòu),所有關(guān)于播放的東西以及布局都是在AVPlayer文件夾下筋岛,視頻播放的布局是基于SnapKit三方庫來布局了娶视,因為在OC里用慣了Masonry所以工程里依然沿用這個庫。因為項目里面有線路切換和音視頻切換功能睁宰,肪获,如果你有未加密的視頻鏈接或者音頻鏈接直接把sdk刪掉也是可以的,也是可以正常播放的柒傻。

關(guān)鍵代碼是放在MPlayerView這個文件中孝赫,輔助視圖布局的三個文件分別是:RateView音視頻倍速切換ResolutionView高清度切換SwitchCircuitView線路切換。

剛開始做的時候红符,把所有的功能代碼都全部放入MPlayerView這個文件中青柄,發(fā)現(xiàn)耦合度太多,代碼可讀性差预侯,所以我將代碼拆出來各自負責(zé)的模塊放入各自的功能致开,比如高清度切換功能,實現(xiàn)的功能就是放在ResolutionView文件下萎馅。

在這里就不貼太多的代碼双戳,我將在本文末放demo的下載地址。現(xiàn)在就簡單聊一下實現(xiàn)過程吧糜芳。視頻播放界面我用的是一個單例實現(xiàn)的飒货,剛開始不是用單例實現(xiàn)魄衅,但是為了把代碼拆出來放到各自的功能區(qū)所以用單例實現(xiàn)是最好的方法。由于swift放棄了OC里的dispatch_once實現(xiàn)單例方法塘辅,swift3.0以后的單例寫法:

/// 創(chuàng)建播放器單例
static let shared = MPlayerView()
private override init(frame: CGRect) {
    super.init(frame: frame)
 }
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

在swift3.0之后重寫init方法必須實現(xiàn)required init方法晃虫,這么做也是為了安全,因為在OC里init方法并不能保證子類完成初始化莫辨,增加required“這是由初始化方法的完備性需求所決定的傲茄,以保證類型的安全。

由于swift里面有嚴(yán)格的類型檢查沮榜,就比如在做手勢滑動的時候盘榨,手勢剛開始滑動的時候肯定需要記錄一下當(dāng)前播放器的位置我在項目中是定義的sumTime屬性是一個CMTime類型,如果在OC里大可不必這樣蟆融,來看一下swift與OC代碼的區(qū)別

swift寫法

/// 給sumTime初值
let time = self.player?.currentTime()
self.sumTime = CMTimeMake((time?.value)!, (time?.timescale)!)

OC寫法

// 給sumTime初值
CMTime time = self.player.currentTime;
self.sumTime  = time.value/time.timescale;

滑動的距離是一個Double類型草巡,而self.sumTime是CMTime類型,倆者肯定不能想加算出結(jié)束滑動的距離型酥,所以將double類型轉(zhuǎn)換成CMTime類型用以下方法:

CMTime.init(seconds: Double.init(value/200), preferredTimescale: CMTimeScale(NSEC_PER_SEC))

如果是OC的話直接括號強轉(zhuǎn)類型即可實現(xiàn)山憨。

知道滑動的距離和記錄滑動前的距離倆者想加即是當(dāng)前位置,轉(zhuǎn)化成CMTime類型:

self.sumTime = CMTimeAdd(self.sumTime!, addend)

手勢是滑動了弥喉,但是進度條也是要跟著一起滑動的郁竟,有人說我把進度條刷新放到player的代理里面,手勢滑動完只需要把時間傳給播放器由境,播放器根據(jù)當(dāng)前時間和總時間去更新進度條棚亩,這樣做也對,但是有一點就是虏杰,如果網(wǎng)速不好讥蟆,手勢已經(jīng)滑動到5分鐘了,而進度條還停留在1分鐘的地方纺阔,播放器緩存完畢了瘸彤,進度條會瞬間跳到5分鐘,從而造成卡頓的假象體驗也不是很好笛钝,所以解決這個方法是手勢滑動的時候也更新進度條质况,但是手勢滑動的時候都是CMTime類型,怎么轉(zhuǎn)成Float類型玻靡,因為slider?.value是float類型结榄。可以這樣:通過CMTimeGetSeconds方法得到一個Float64再通過Float.init方法得到一個float類型啃奴,看一下實現(xiàn):

let sliderTime = CMTimeGetSeconds(self.sumTime!)/CMTimeGetSeconds(totalMovieDuration)
self.slider?.value = Float.init(sliderTime)

想查看整個過程可以看播放器手勢添加與創(chuàng)建這一塊,我已經(jīng)用MARK:標(biāo)記起來了雄妥。

一個視頻播放實現(xiàn)起來并不困難最蕾,只要處理好playerplatitem就行了依溯。最難得就是,如果手機屏幕旋轉(zhuǎn)瘟则,怎么能讓視頻跟著屏幕自適應(yīng)呢黎炉,我在工程里面通過UIDevice變化添加的是屏幕旋轉(zhuǎn)監(jiān)聽:

/**
  *  監(jiān)聽設(shè)備旋轉(zhuǎn)通知
  */
 private func listeningRotating()  {
        UIDevice.current.beginGeneratingDeviceOrientationNotifications()
        NotificationCenter.default.addObserver(self, selector: #selector(onDeviceOrientationChange), name:NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}

如果用戶把屏幕旋轉(zhuǎn)關(guān)掉,就是控制中心那個開關(guān)醋拧,用戶旋轉(zhuǎn)屏幕慷嗜,怎么能讓畫面跟著跑呢,我百度的很多資料丹壕,試了也很多方法庆械,但是都不理想,用的還是OC的代碼菌赖,因為swift里面移除了NSInvocation屬性缭乘,用的依然是OC的屏幕強制旋轉(zhuǎn),只能使用橋接文件:

+ (void)interfaceOrientation:(UIInterfaceOrientation)orientation{
    if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
        SEL selector = NSSelectorFromString(@"setOrientation:");
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
        [invocation setSelector:selector];
        [invocation setTarget:[UIDevice currentDevice]];
        int val  = orientation;
        // 從2開始是因為0 1 兩個參數(shù)已經(jīng)被selector和target占用
        [invocation setArgument:&val atIndex:2];
        [invocation invoke];
    }
}

大概就介紹這么多吧,主要就是記錄一下自己的學(xué)習(xí)過程,如果還有不明白的知識點可以去demo中自己去查.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末琉用,一起剝皮案震驚了整個濱河市堕绩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌邑时,老刑警劉巖奴紧,帶你破解...
    沈念sama閱讀 221,888評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異晶丘,居然都是意外死亡黍氮,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,677評論 3 399
  • 文/潘曉璐 我一進店門铣口,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滤钱,“玉大人,你說我怎么就攤上這事脑题〖祝” “怎么了?”我有些...
    開封第一講書人閱讀 168,386評論 0 360
  • 文/不壞的土叔 我叫張陵叔遂,是天一觀的道長他炊。 經(jīng)常有香客問我,道長已艰,這世上最難降的妖魔是什么痊末? 我笑而不...
    開封第一講書人閱讀 59,726評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮哩掺,結(jié)果婚禮上凿叠,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好盒件,可當(dāng)我...
    茶點故事閱讀 68,729評論 6 397
  • 文/花漫 我一把揭開白布蹬碧。 她就那樣靜靜地躺著,像睡著了一般炒刁。 火紅的嫁衣襯著肌膚如雪恩沽。 梳的紋絲不亂的頭發(fā)上下翎,一...
    開封第一講書人閱讀 52,337評論 1 310
  • 那天糯钙,我揣著相機與錄音,去河邊找鬼含思。 笑死城瞎,一個胖子當(dāng)著我的面吹牛渤闷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播全谤,決...
    沈念sama閱讀 40,902評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼肤晓,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了认然?” 一聲冷哼從身側(cè)響起补憾,我...
    開封第一講書人閱讀 39,807評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎卷员,沒想到半個月后盈匾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,349評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡毕骡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,439評論 3 340
  • 正文 我和宋清朗相戀三年削饵,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片未巫。...
    茶點故事閱讀 40,567評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡窿撬,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出叙凡,到底是詐尸還是另有隱情劈伴,我是刑警寧澤,帶...
    沈念sama閱讀 36,242評論 5 350
  • 正文 年R本政府宣布握爷,位于F島的核電站跛璧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏新啼。R本人自食惡果不足惜追城,卻給世界環(huán)境...
    茶點故事閱讀 41,933評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望燥撞。 院中可真熱鬧座柱,春花似錦迷帜、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,420評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锋玲,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間涵叮,已是汗流浹背惭蹂。 一陣腳步聲響...
    開封第一講書人閱讀 33,531評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留割粮,地道東北人盾碗。 一個月前我還...
    沈念sama閱讀 48,995評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像舀瓢,于是被迫代替她去往敵國和親廷雅。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,585評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫京髓、插件航缀、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,120評論 4 61
  • 一芥玉、他的秘密 他們的愛情,在她的眼里是完美的备图。 工作中灿巧,他上進,生活中揽涮,他細心耐心抠藕,每逢紀(jì)念日,給她買的禮物都是她...
    念衡閱讀 1,360評論 4 17
  • 4月23日閉幕的北京電影節(jié)的展映影片中蒋困,《末代皇帝》的4K修復(fù)版可謂最受矚目的熱門影片之一盾似。 意大利名導(dǎo)貝納爾多·...
    雪城不下雪閱讀 525評論 0 2
  • T
    EXC_BAD_ACCESS閱讀 162評論 0 0
  • 今天 洪洪我是非常擔(dān)心的 我也沒有跑過全馬吖 怎么敢推送跑全馬技巧的文章呢 “故事與三位男神有關(guān)” 男神是誰? 故...
    洪hong閱讀 1,894評論 0 5