基于AVPlayer封裝的視頻播放器

更新:2017.11.14

更新內(nèi)容:
1.可以由在指定區(qū)域播放喉钢,并切換到全屏模式滑凉,然后點(diǎn)擊切換按鈕切換到以前指定區(qū)域
2.優(yōu)化橫豎屏切換的代碼以及WLPlayerControlView內(nèi)存管理引起的崩潰問題

要點(diǎn)說明:WLPlayerView新增了父視圖和父視圖原尺寸的屬性芽世,在初始化播放器的時(shí)候最盅,只需要將父視圖以及父視圖原尺寸保存起來葵蒂,在橫豎屏切換的時(shí)候調(diào)用分類提供的
- (void)makeScreenToLandscape;
- (void)makeScreenToPortrait;
這兩個(gè)方法就可以實(shí)現(xiàn)所需要的功能担敌,具體的調(diào)用邏輯可以查看源碼

做這款播放器還是因?yàn)轫?xiàng)目需要郭宝,關(guān)于播放器的需求辞槐,大都相同,要么是可以小屏全屏切換粘室,要么是一開始播放就默認(rèn)橫屏榄檬,由于下一個(gè)版本項(xiàng)目需求變化,需要的是一開始播放就默認(rèn)全屏播放衔统,之前我所用的是ZFPlayer鹿榜,這個(gè)庫很強(qiáng)大,基本上囊括了常用的功能點(diǎn)锦爵,特別是全屏切換這塊舱殿,這個(gè)庫處理的很好,但是遺憾的是這款播放器沒有提供自動(dòng)全屏的功能险掀,我在這個(gè)庫的源碼中修改之后能實(shí)現(xiàn)所要的效果沪袭,但是改動(dòng)了源碼總歸是不美的,于是我就花費(fèi)一些時(shí)間樟氢,參考這個(gè)庫冈绊,依據(jù)需求,先實(shí)現(xiàn)自己項(xiàng)目中的需要為準(zhǔn):實(shí)現(xiàn)已進(jìn)入就橫屏播放的需要埠啃。項(xiàng)目中用了RAC焚碌,以及Masnory布局方式。

我寫的這個(gè)庫目前還是初級(jí)階段霸妹,許多功能都不完善,主要包括以下幾個(gè)要點(diǎn):

1.present以及push進(jìn)入播放控制器知押,一進(jìn)入就橫屏

2.可以控制暫停/播放叹螟,雙擊屏幕暫停/播放,單擊屏幕顯示控制皮膚/隱藏控制皮膚等

3.滑動(dòng)播放進(jìn)度條可以控制播放時(shí)間台盯,跳轉(zhuǎn)到指定位置播放

4.橫屏豎屏切換功能罢绽,狀態(tài)欄方向跟著橫屏豎屏而變化等

5.左右滑動(dòng)屏幕,實(shí)現(xiàn)快進(jìn)/快退功能

6.上下滑動(dòng)右邊半屏静盅,控制系統(tǒng)音量良价,滑動(dòng)左半屏控制系統(tǒng)亮度

具體的功能模塊就以上幾個(gè)寝殴,是一個(gè)功能單一,比較簡(jiǎn)單的播放控制器明垢,我會(huì)在以后慢慢完善它的功能
下面我簡(jiǎn)要說一下如何去引用蚣常,并且對(duì)去全屏這塊做簡(jiǎn)要描述(只針對(duì)presetn下)
我先放兩張效果圖:


Simulator Screen Shot - iPhone 6 Plus - 2017-11-13 at 10.28.38.png
Simulator Screen Shot - iPhone 6 Plus - 2017-11-13 at 10.28.47.png

項(xiàng)目默認(rèn)是豎屏顯示,只有在播放界面才默認(rèn)橫屏:
從首頁進(jìn)入到播放界面如下處理:

@weakify(self);
    [[self.playButton rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(id x) {
        @strongify(self);
        WLPlayerController *playerC = [[WLPlayerController alloc] init];
        [self presentViewController:playerC animated:YES completion:nil];
    }];

在播放界面主要是控制進(jìn)入就橫屏顯示痊银,我是這樣處理的:

進(jìn)入播放器有兩種模式抵蚊,一種是present,一種是push溯革,我這里用的是tabbar+navigation+控制器的模式贞绳,默認(rèn)整個(gè)項(xiàng)目界面是豎屏,只有在播放界面才是橫屏致稀,下面我簡(jiǎn)要說明一下對(duì)于這兩種模式下的控制冈闭,我搜索資料有對(duì)這兩種區(qū)別去控制的,我也嘗試了下網(wǎng)上給的方法抖单,發(fā)現(xiàn)present很好弄萎攒,但是Push的坑很多,我這里是直接對(duì)兩種模式都有效果的臭猜,摘要代碼配置如下:

1.設(shè)置tabbarController分類躺酒,在分類中實(shí)現(xiàn)以下幾個(gè)方法

// 是否支持自動(dòng)轉(zhuǎn)屏
- (BOOL)shouldAutorotate {
    UIViewController *vc = self.viewControllers[self.selectedIndex];
    if ([vc isKindOfClass:[UINavigationController class]]) {
        UINavigationController *nav = (UINavigationController *)vc;
        return [nav.topViewController shouldAutorotate];
    } else {
        return [vc shouldAutorotate];
    }
}

// 支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    UIViewController *vc = self.viewControllers[self.selectedIndex];
    if ([vc isKindOfClass:[UINavigationController class]]) {
        UINavigationController *nav = (UINavigationController *)vc;
        return [nav.topViewController supportedInterfaceOrientations];
    } else {
        return [vc supportedInterfaceOrientations];
    }
}

// 默認(rèn)的屏幕方向(當(dāng)前ViewController必須是通過模態(tài)出來的UIViewController(模態(tài)帶導(dǎo)航的無效)方式展現(xiàn)出來的,才會(huì)調(diào)用這個(gè)方法)
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    UIViewController *vc = self.viewControllers[self.selectedIndex];
    if ([vc isKindOfClass:[UINavigationController class]]) {
        UINavigationController *nav = (UINavigationController *)vc;
        return [nav.topViewController preferredInterfaceOrientationForPresentation];
    } else {
        return [vc preferredInterfaceOrientationForPresentation];
    }
}

2.設(shè)置導(dǎo)航控制器分類蔑歌,實(shí)現(xiàn)如下幾個(gè)方法:

- (BOOL)shouldAutorotate {
    return self.topViewController.shouldAutorotate;
}
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return self.topViewController.supportedInterfaceOrientations;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return self.topViewController.preferredInterfaceOrientationForPresentation;
}

3.所有的控制器繼承于這個(gè)基類羹应,在視頻播放控制器中單獨(dú)設(shè)置:
基類中默認(rèn)豎屏模式:

    return YES;
}

- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationPortrait;
}
- (UIStatusBarStyle)preferredStatusBarStyle {
    return  UIStatusBarStyleDefault;
}
- (BOOL)prefersStatusBarHidden {
    return NO;
}

播放器中如下設(shè)置:


// 支持哪些屏幕方向
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskLandscapeRight;
}

- (BOOL)prefersStatusBarHidden {
    return NO;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
    return UIInterfaceOrientationLandscapeRight;
}

- (BOOL)shouldAutorotate {
    return YES;
}

另外我在UIViewController的分類中提供了present和Push下實(shí)現(xiàn)橫屏和豎屏切換的方法,具體的方法如下:

- (void)makeScreenToLandscape {
    [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeRight;
    CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:duration];
    if (self.navigationController) {
        self.view.transform = CGAffineTransformMakeRotation(M_PI*(90)/180.0);
        self.view.frame = CGRectMake(0, 0,  [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
    }else {
        self.view.transform = CGAffineTransformIdentity;
        self.view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    }
    [UIView commitAnimations];
    [[NSNotificationCenter defaultCenter] postNotificationName:wl_makeScreenToLandscapeNotificationName object:nil];
}
- (void)makeScreenToPortrait {
    [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationPortrait;
    CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:duration];
    if (self.navigationController) {
        self.view.transform = CGAffineTransformIdentity;
        self.view.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);
    }else {
        self.view.transform = CGAffineTransformMakeRotation(-M_PI*(90)/180.0);
        self.view.frame = CGRectMake(0, 0,  [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
    }
    [UIView commitAnimations];
    [[NSNotificationCenter defaultCenter] postNotificationName:wl_makeScreenToPortraitNotificationName object:nil];
}

在這里我遇到一個(gè)坑次屠,改變狀態(tài)欄方向之后园匹,我一開始改變的是self.navigationController.view.bounds,結(jié)果會(huì)發(fā)現(xiàn)切換之間存在布局錯(cuò)亂劫灶,后來查了許久裸违,發(fā)現(xiàn)frame的x,y值出現(xiàn)負(fù)值,導(dǎo)致整體布局錯(cuò)亂本昏,于是我改成了改變frame值就解決了

具體的調(diào)用方式供汛,demo中有介紹,可以下載demo進(jìn)行嘗試與驗(yàn)證

關(guān)于其他的控制邏輯涌穆,在后續(xù)會(huì)進(jìn)一步實(shí)現(xiàn)怔昨,下面附上我的github源碼地址,有需要的伙伴們可以自行下載,使用過程遇到問題的歡迎留言評(píng)論宿稀,謝謝

特別說明:在適配iPad的時(shí)候趁舀,發(fā)現(xiàn)了一個(gè)重大問題,我所有設(shè)置強(qiáng)制豎屏的條件都不管用了祝沸,而且矮烹,在橫屏豎屏的時(shí)候混亂了越庇,經(jīng)查閱資料,最終解決了奉狈,解決方法是卤唉,將General->Deployment Info中的Requires Full Screen勾選選中

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市嘹吨,隨后出現(xiàn)的幾起案子搬味,更是在濱河造成了極大的恐慌,老刑警劉巖蟀拷,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碰纬,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡问芬,警方通過查閱死者的電腦和手機(jī)悦析,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來此衅,“玉大人强戴,你說我怎么就攤上這事〉舶埃” “怎么了骑歹?”我有些...
    開封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)墨微。 經(jīng)常有香客問我道媚,道長(zhǎng),這世上最難降的妖魔是什么翘县? 我笑而不...
    開封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任最域,我火速辦了婚禮,結(jié)果婚禮上锈麸,老公的妹妹穿的比我還像新娘镀脂。我一直安慰自己,他們只是感情好忘伞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開白布薄翅。 她就那樣靜靜地躺著,像睡著了一般氓奈。 火紅的嫁衣襯著肌膚如雪匿刮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天探颈,我揣著相機(jī)與錄音,去河邊找鬼训措。 笑死伪节,一個(gè)胖子當(dāng)著我的面吹牛光羞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播怀大,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了妄呕?” 一聲冷哼從身側(cè)響起帜乞,我...
    開封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蓖康,沒想到半個(gè)月后铐炫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蒜焊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年倒信,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泳梆。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鳖悠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出优妙,到底是詐尸還是另有隱情乘综,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布套硼,位于F島的核電站卡辰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏熟菲。R本人自食惡果不足惜看政,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望抄罕。 院中可真熱鬧允蚣,春花似錦、人聲如沸呆贿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽做入。三九已至冒晰,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間竟块,已是汗流浹背壶运。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留浪秘,地道東北人蒋情。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓埠况,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親棵癣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辕翰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

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

  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件狈谊、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,095評(píng)論 4 62
  • 8月7日迎來今年的立秋節(jié)氣喜命,立秋一般預(yù)示著炎熱的夏天即將過去,秋天即將來臨河劝。立秋(節(jié)氣)以后壁榕,秋后下一次雨涼快一次...
    引領(lǐng)緣夢(mèng)閱讀 244評(píng)論 0 0
  • 昨夜在漫散的睡意中我想起了外公,外公年事已高丧裁,有些糊涂了护桦,也不如往常那般與我親切。這幾年回家的次數(shù)越來越少煎娇,每...
    你不知道的Anne閱讀 357評(píng)論 1 2
  • 零度打卡Day24 主題閱讀:精進(jìn)之道 采銅的精進(jìn)之道 導(dǎo)圖筆記之一: 導(dǎo)圖筆記之二: 努力一點(diǎn)二庵,是為了看清自己最...
    零度2013閱讀 174評(píng)論 0 0