亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Swift > 正文

swift4.0實現視頻播放、屏幕旋轉、倍速播放、手勢調節及鎖屏面板等功能實例

2020-03-09 17:42:29
字體:
來源:轉載
供稿:網友

前言

學習swift/81184.html">swift有段時間了,原來寫過一個基于 swift 3.0 的視頻播放,后來有同學聯系我說,在音頻鎖屏的情況下,無法用控制面板拖動進度條調節播放進度,所以又將原來的代碼拿過來重新整理了下也順便更新到了4.0版本。在把原來的代碼拿來的時候發現原來有好多地方都是錯誤的,原來在 OC 項目里面已經寫過一遍關于視頻播放的東西所以就按照原來的邏輯寫了 swift 版本,其實里面很多代碼我也是通過查找資料和看文檔拼湊出來的,對于 swift 的語句也是一知半解,希望各位看官多多包涵。

先來看一下實現的效果,一圖勝千言(第一張是 iOS 10系統,第二張是 iOS 11系統)。

swift4,視頻播放demo,ios,視頻播放,swift,屏幕旋轉

 swift4,視頻播放demo,ios,視頻播放,swift,屏幕旋轉

demo下載地址

工程介紹

簡單說一下工程結構,所有關于布局都是在Player文件夾下的MPlayerViewModel文件中,考慮到耦合度的原因,所以將視頻播放的所有 UI 布局全部抽離出來,在播放器 view 里將會頻繁看到一個叫viewModel的對象,它既 UI 布局也是布局控件的所有者。視頻播放的布局是基于SnapKit三方庫來布局了,因為在OC里用慣了Masonry所以工程里依然沿用這個庫。主要代碼是放到MPlayerView這個文件中的,其中還有一個由 OC 寫的DeviceTool文件主要用來做頁面強制旋轉用的,強制旋轉這一部分我現在還沒有更好的解決辦法只能橋接 OC 里的方法。

初始化播放器方法

視頻播放界面我用的是一個單例實現的,剛開始不是用單例實現,但是為了把代碼拆出來放到各自的功能區所以用單例實現是最好的方法。由于swift放棄了OC里的dispatch_once實現單例方法,swift3.0以后的單例寫法:

/// 創建播放器單例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方法必須實現required init方法,這么做也是為了安全,因為在OC里init方法并不能保證子類完成初始化,增加required“這是由初始化方法的完備性需求所決定的,以保證類型的安全。在創建視頻播放視圖有兩種創建方式:1.用單利創建。2.init 初始化 ,這兩種方法都可以達到視頻播放的效果。

1.單利初始化

self.playerView = MPlayerView.shared.initWithFrame(frame: self.view.frame, videoUrl: videoUrl, type: "VIDEO")

2.init 初始化

self.playerView = MPlayerView().initWithFrame(frame: CGRect.init(x: 0, y: 0, width: Screen_width, height: Screen_width * 9/16), videoUrl: videoUrl, type: "VIDEO")

手勢滑動及注意事項

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

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類型,倆者肯定不能想加算出結束滑動的距離,所以將double類型轉換成CMTime類型用以下方法:

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

如果是OC的話直接括號強轉類型即可實現。

知道滑動的距離和記錄滑動前的距離倆者想加即是當前位置,轉化成CMTime類型:

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

手勢是滑動了,但是進度條也是要跟著一起滑動的,有人說我把進度條刷新放到player的代理里面,手勢滑動完只需要把時間傳給播放器,播放器根據當前時間和總時間去更新進度條,這樣做也對,但是有一點就是,如果網速不好,手勢已經滑動到5分鐘了,而進度條還停留在1分鐘的地方,播放器緩存完畢了,進度條會瞬間跳到5分鐘,從而造成卡頓的假象體驗也不是很好,所以解決這個方法是手勢滑動的時候也更新進度條,但是手勢滑動的時候都是CMTime類型,怎么轉成Float類型,因為slider?.value是float類型??梢赃@樣:通過CMTimeGetSeconds方法得到一個Float64再通過Float.init方法得到一個float類型,看一下實現:

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

想查看整個過程可以看播放器手勢添加與創建這一塊,我已經用MARK:標記起來了。

設置控制面板信息

在視頻播放過程中,對視頻的監聽是必不可少的,監聽播放器狀態,播放器緩存...等,由于播放器比較簡單,功能較少,剛開始我只監聽了status屬性,后來我加上來loadedTimeRanges緩存狀態,緩存這部分的緩存進度計算我已經實現了,但是沒有用到只是簡單的打印了一下。

在對播放器status屬性監聽中加入了控制面板信息,是由MPNowPlayingInfoCenter來實現的,通過改變nowPlayingInfo里面對應的信息來更新面板信息,里面有好多屬性,比如MPMediaItemPropertyTitle設置音頻標題,MPMediaItemPropertyArtist作者、MPNowPlayingInfoPropertyElapsedPlaybackTime當前播放過的時間、MPMediaItemPropertyPlaybackDuration播放總時間等等。剛開始做的時候因為鎖屏要更新時間,而nowPlayingInfo又是一個字典類型的再加上需要更新界面布局的時間和進度條,直接將播放器時間強制轉換成 string 類型,所以將這一部分放到了時間觀察里面,因為時間觀察會一直進行所以鎖屏界面信息也會一直更新,這樣帶來一個問題就是鎖屏界面的圖片如果是網絡圖片,每1秒就要請求一下圖片而且要不斷的更新這樣帶來的結果可想而知。后來才知道,將MPNowPlayingInfoPropertyElapsedPlaybackTime屬性設置成self.player!.currentTime()播放器當前時間就會自動更新控制面板信息,調用的地方也很關鍵,必須放在播放器已經播放的監聽里面。

配置遠程控制顯示的信息

響應遠程控制是由MPRemoteCommandCenter來實現的,里面有很多屬性,比如:playCommand播放響應事件、pauseCommand 暫停響應事件、nextTrackCommand下一曲響應事件、likeCommand喜歡按鈕,類似網易云音樂的那個鎖屏,如果設置了likeCommand則dislikeCommand是上一首響應事件、previousTrackCommand上一首,外部拖動進度條是changePlaybackPositionCommand,系統有一個專門的方法來出來遠程拖動進度條響應事件:

open func addTarget(handler: @escaping (MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus) -> Any

大概控制面板能用到的這些信息差不多也就這么多,如果想了解更多的可以看一下文檔或者查閱資料。

屏幕旋轉問題

一個視頻播放實現起來并不困難,只要處理好player與platitem就行了。最難的就是,如果手機屏幕旋轉,怎么能讓視頻跟著屏幕自適應呢,我在工程里面通過UIDevice變化添加的是屏幕旋轉監聽:

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

如果用戶把屏幕旋轉關掉,就是控制中心那個開關,用戶旋轉屏幕,怎么能讓畫面跟著跑呢,我百度的很多資料,試了也很多方法,但是都不理想,用的還是OC的代碼,因為swift里面移除了NSInvocation屬性,用的依然是OC的屏幕強制旋轉,只能使用橋接文件:

//這個方法是在網上找的+ (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 兩個參數已經被selector和target占用[invocation setArgument:&val atIndex:2];[invocation invoke]; }}

因為做的是視頻播放,所以進入后臺后視頻會暫停,這個屬于正?,F象,如果在視頻模式下,進入后臺利用控制面板是無法將視頻播放的,如果在音頻模式下,進入后臺利用控制面板是可以讓視頻播放的。大概就介紹這么多,一言半句也說得不是很明白,如果還有不明白的知識點可以去demo中自己去查,我也是一個初學者里面很多東西都是查資料得來的并不能保證其內容的正確性。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到swift教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情一区二区三区高清视频| 国产又爽又黄的激情精品视频| 欧美一区亚洲一区| 精品夜色国产国偷在线| 国产69精品久久久久99| 91理论片午午论夜理片久久| 亚洲欧美日韩爽爽影院| 久久精品在线播放| 免费91麻豆精品国产自产在线观看| 亚洲一区二区三区在线免费观看| 国模私拍视频一区| 亚洲色图50p| 最近2019中文免费高清视频观看www99| 日韩一区二区欧美| 精品国产欧美成人夜夜嗨| 91最新在线免费观看| 国产精品网站视频| 国产精品丝袜视频| 91在线国产电影| xvideos成人免费中文版| 91精品啪在线观看麻豆免费| 久久久久日韩精品久久久男男| 亚洲成人教育av| 日韩欧美在线第一页| 欧美激情精品久久久久久蜜臀| 亚洲女人天堂成人av在线| 中文字幕亚洲欧美日韩2019| 91精品国产综合久久久久久久久| 国产一区二区三区直播精品电影| 亚洲免费中文字幕| 国产精品毛片a∨一区二区三区|国| 日韩一区二区三区在线播放| 国产欧美日韩91| 日韩精品在线私人| 狠狠久久五月精品中文字幕| 日韩av影视综合网| 欧美日韩国产精品一区二区三区四区| 久久久久久久久亚洲| 久久免费高清视频| 国内精品美女av在线播放| 91美女片黄在线观看游戏| 久久久久久久国产精品视频| 国产精品视频自在线| 日韩激情在线视频| 欧美性猛交xxxx免费看漫画| 国产综合在线观看视频| 2018中文字幕一区二区三区| 俺去了亚洲欧美日韩| 国产成人aa精品一区在线播放| 51精品在线观看| 色狠狠av一区二区三区香蕉蜜桃| 狠狠躁天天躁日日躁欧美| 色老头一区二区三区在线观看| 午夜精品久久久久久99热| 国产精品三级久久久久久电影| 欧美xxxx14xxxxx性爽| 97久久精品视频| 日韩免费高清在线观看| 久久久久日韩精品久久久男男| 播播国产欧美激情| 国产成人鲁鲁免费视频a| 久久av中文字幕| 久久久久久中文字幕| 国产成人亚洲综合91精品| 亚洲精品中文字幕有码专区| 亚洲精品自拍第一页| 日av在线播放中文不卡| 91精品国产高清久久久久久91| 精品福利免费观看| 午夜精品久久久久久久白皮肤| 日韩电影免费观看中文字幕| 亚洲国产精品网站| 欧美日韩成人免费| 91夜夜揉人人捏人人添红杏| 欧美电影免费观看大全| 国产精品永久免费视频| 国产一区二区三区在线视频| 国自产精品手机在线观看视频| 国产精品久久久久久久久久免费| 久久久久久久久久国产| 欧美一区二区视频97| 69影院欧美专区视频| 亚洲国产天堂网精品网站| 国产福利精品av综合导导航| 日韩av在线电影网| 日韩精品免费综合视频在线播放| 久久久久久伊人| 久久久久久国产三级电影| 亚洲国产精品一区二区久| 色午夜这里只有精品| 国产精品99久久99久久久二8| 色悠悠国产精品| 亚洲国产婷婷香蕉久久久久久| 日韩av在线播放资源| 国产成人久久精品| 日韩动漫免费观看电视剧高清| 日韩中文字幕网址| 国产精品wwwwww| 奇米影视亚洲狠狠色| 亚洲精品第一国产综合精品| 不卡av日日日| 一区二区欧美久久| 国产99在线|中文| 国产精品亚洲视频在线观看| 精品视频9999| 91精品久久久久久久久中文字幕| 国产午夜精品免费一区二区三区| 97av在线影院| 亚洲精品国产suv| 青青草原成人在线视频| 欧洲亚洲免费在线| 日韩精品久久久久久福利| 最近2019免费中文字幕视频三| 国产精品激情av在线播放| 欧美成人自拍视频| 国产日韩欧美中文在线播放| 2019中文字幕在线免费观看| 亚洲欧洲激情在线| 欧美电影免费播放| 国产精品亚洲激情| 91高清在线免费观看| 国产精品网站大全| 亚洲综合最新在线| 欧美在线xxx| 国产成+人+综合+亚洲欧洲| 国产精品亚洲第一区| 91禁国产网站| 欧美黑人xxxⅹ高潮交| 久久欧美在线电影| 国产综合福利在线| 精品视频在线导航| 国产精品久久久久久av福利软件| 精品露脸国产偷人在视频| 精品欧美一区二区三区| 亚洲国产成人精品久久久国产成人一区| 欧美贵妇videos办公室| 亚洲欧美一区二区三区在线| 搡老女人一区二区三区视频tv| 国产成人精品免费久久久久| 国产欧美日韩丝袜精品一区| 91久久在线视频| 久久久影视精品| 久久久影视精品| 欧美在线视频观看| 日本精品久久久久影院| 久久久精品2019中文字幕神马| 成人高h视频在线| 欧美激情精品久久久久久久变态| 久久精品国产99国产精品澳门| 国产精品精品视频一区二区三区| 97视频国产在线| 亚洲成人动漫在线播放| 日韩av免费看| 88xx成人精品| 性欧美视频videos6一9| 久久精品在线视频| 日本在线观看天堂男亚洲| 日韩视频永久免费观看| 国产日韩在线一区| 欧美成人激情图片网| 欧美伦理91i| 国产精品久久久久久久久久东京| 亚洲精品久久久久久久久久久久久| 亚洲成人黄色在线|