iOS 圖解一個功能很全的視訊播放器的使用
大家好, 上一次我分享了一個視訊播放器(SJVideoPlayer), 今天我再給大家分享一下它的使用圖解, 希望大家喜歡. 對了, 本專案除了全屏手勢hook了一下nav的push方法, 其它功能都對原始專案無任何侵害. 您可以放心的使用(全屏手勢如果不順心也可以方便的移除).
上一次分享的文章連結: https://www.jianshu.com/p/4c2a493fb4bf
下面請看這款用心寫的播放器吧. 就從最簡單的開始吧?
播放資源的初始化及三板斧
- 播放器在普通檢視上播放:
/// 以下為示例:
_videoPlayer = [SJVideoPlayer player];
_videoPlayer.view.frame = CGRectMake(0, 20, 375, 375 * 9/16.0); // 可以使用AutoLayout, 這裡為了簡便設定的Frame.
[self.view addSubview:_videoPlayer.view];
// 初始化資源
_videoPlayer.URLAsset = [[SJVideoPlayerURLAsset alloc] initWithURL:[NSURL URLWithString:@"http://..."]];
// 當然也可以指定開始時間. 如下, 從第20秒開始播放
// _videoPlayer.URLAsset = [[SJVideoPlayerURLAsset alloc] initWithURL:[NSURL URLWithString:@"http://..."] specifyStartTime:20.0];
- 播放器在UITableViewCell或UICollectionViewCell中播放:
/// 以下為示例:
/// UICollectionView同UITableView初始化一致, 所以此處僅展示UITableView的示例.
- (void)clickedPlayBtnOnTabCell:(SJVideoListTableViewCell *)cell playerSuperview:(UIView *)playerSuperview {
// 1. 建立一個播放資源
SJPlayModel *playModel =
[SJPlayModel UITableViewCellPlayModelWithPlayerSuperviewTag:playerParentView.tag // 請務必設定tag, 且不能等於0. 由於重用機制, 當檢視滾動時, 播放器需要通過此tag尋找其父檢視
atIndexPath:[self.tableView indexPathForCell:cell]
tableView:self.tableView];
SJVideoPlayerURLAsset *asset =
[[SJVideoPlayerURLAsset alloc] initWithURL:[NSURL URLWithString:@"http://..."]
playModel:playModel];
// 2. 設定資源標題
asset.title = @"DIY心情轉盤 #手工##手工製作##賣包子嘍##1塊1個##賣完就撤#";
// 3. 預設情況下, 小屏時不顯示標題, 全屏後才會顯示, 這裡設定一直顯示標題
asset.alwaysShowTitle = YES;
_videoPlayer = [SJVideoPlayer player];
[playerSuperview addSubview:_videoPlayer.view];
[_videoPlayer.view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.offset(0);
}];
// 設定資源
_videoPlayer.URLAsset = asset;
}
-
播放器在tableHeaderView上播放:
/// 以下為示例:
__weak typeof(self) _self = self;
// table header btn clicked event.
self.tableHeaderView.clickedPlayBtnExeBlock = ^(TableHeaderView * _Nonnull playerSuperview) {
__strong typeof(_self) self = _self;
if ( !self ) return;
// 1. 建立一個播放資源
SJVideoPlayerURLAsset *asset =
[[SJVideoPlayerURLAsset alloc] initWithURL:[NSURL URLWithString:@"https://..."]
playModel:[SJPlayModel UITableViewHeaderViewPlayModelWithPlayerSuperview:playerSuperview tableView:self.tableView]];
// 2. 設定資源標題
asset.title = @"DIY心情轉盤 #手工##手工製作#";
// 3. 預設情況下, 小屏時不顯示標題, 全屏後才會顯示, 這裡設定一直顯示標題
asset.alwaysShowTitle = YES;
self.videoPlayer = [SJVideoPlayer player];
[playerSuperview addSubview:self.videoPlayer.view];
[self.videoPlayer.view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.offset(0);
}];
// 設定資源
self.videoPlayer.URLAsset = asset;
};
-
播放器在UICollectionViewCell中播放, 同時UICollectionView在tableHeaderView中:
/// 以下為示例:
__weak typeof(self) _self = self;
_tableHeaderView.clickedPlayBtnExeBlock = ^(TableHeaderView *view, UICollectionView *collectionView, NSIndexPath *indexPath, UIView *playerSuperview) {
__strong typeof(_self) self = _self;
if ( !self ) return;
// 1. 建立一個播放資源
SJPlayModel *playModel = [SJPlayModel UICollectionViewNestedInUITableViewHeaderViewPlayModelWithPlayerSuperviewTag:playerSuperview.tag atIndexPath:indexPath collectionView:collectionView tableView:self.tableView];
SJVideoPlayerURLAsset *asset =
[[SJVideoPlayerURLAsset alloc] initWithURL:[NSURL URLWithString:@"https://..."]
playModel:playModel];
// 2. 設定資源標題
asset.title = @"DIY心情轉盤 #手工##手工製作#";
// 3. 預設情況下, 小屏時不顯示標題, 全屏後才會顯示, 這裡設定一直顯示標題
asset.alwaysShowTitle = YES;
self.videoPlayer = [SJVideoPlayer player];
[playerSuperview addSubview:self.videoPlayer.view];
[self.videoPlayer.view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.offset(0);
}];
// 設定資源
self.videoPlayer.URLAsset = asset;
};
-
播放器在UICollectionCell中播放, 同時UICollectionView在UITableViewCell中:
/// 以下為示例:
- (void)clickedPlayWithTableViewCell:(NestedTableViewCell *)tabCell
playerSuperview:(UIView *)playerSuperview
collectionViewCellIndexPath:(NSIndexPath *)collectionViewCellIndexPath
collectionView:(UICollectionView *)collectionView {
// 1. 建立一個播放資源
NSIndexPath *tabCellIndexPath = [self.tableView indexPathForCell:tabCell];
SJPlayModel *playModel = [SJPlayModel UICollectionViewNestedInUITableViewCellPlayModelWithPlayerSuperviewTag:playerSuperview.tag atIndexPath:collectionViewCellIndexPath collectionViewTag:collectionView.tag collectionViewAtIndexPath:tabCellIndexPath tableView:self.tableView];
SJVideoPlayerURLAsset *asset =
[[SJVideoPlayerURLAsset alloc] initWithURL:[NSURL URLWithString:@"https://..."]
playModel:playModel];
// 2. 設定資源標題
asset.title = @"DIY心情轉盤 #手工##手工製作#";
// 3. 預設情況下, 小屏時不顯示標題, 全屏後才會顯示, 這裡設定一直顯示標題
asset.alwaysShowTitle = YES;
self.videoPlayer = [SJVideoPlayer player];
[playerSuperview addSubview:self.videoPlayer.view];
[self.videoPlayer.view mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.offset(0);
}];
// 設定資源
self.videoPlayer.URLAsset = asset;
}
資源三板斧
- 資源重新整理. 在播放一個資源時, 可能有一些意外情況導致播放失敗(如網路環境差). 此時當使用者點選重新整理按鈕, 我們需要對當前的資源(Asset)進行重新整理. SJVideoPlayer提供了直接的方法去重新整理, 不需要開發者再重複的去建立新的Asset.
/// 以下為示例:
// 對當前資源進行重新整理, 嘗試重新播放視訊
[_videoPlayer refresh];
- 記錄某個播放位置. 我們有時候想儲存某個視訊的播放記錄, 以便下次, 能夠從指定的位置進行播放. 那什麼時候儲存合適呢? 最好的時機就是資源被釋放時. SJVideoPlayer提供了每個資源在Dealloc中, 都進行的回撥, 如下:
/// 以下為示例:
// 每個資源dealloc時的回撥
_videoPlayer.assetDeallocExeBlock = ^(__kindof SJBaseVideoPlayer * _Nonnull videoPlayer) {
// .....
};
- 續播. 在播放時, 我們可能需要切換介面, 而希望視訊能夠在下一個介面無縫的進行播放. 針對此種情況 SJVideoPlayerURLAsset 提供了便利的初始化方法. 請看片段:
- (instancetype)initWithOtherAsset:(SJVideoPlayerURLAsset *)otherAsset
playModel:(__kindof SJPlayModel *)playModel;
/// 以下為示例:
// 新介面的播放器, 資源初始化:
_videoPlayer = [SJVideoPlayer player];
_videoPlayer.view.frame = CGRectMake(0, 20, 375, 375 * 9/16.0); // 可以使用AutoLayout, 這裡為了簡便設定的Frame.
[self.view addSubview:_videoPlayer.view];
// 初始化資源
_videoPlayer.URLAsset = [SJVideoPlayerURLAsset initWithOtherAsset:otherAsset playModel:[SJPlayModel playModel....];
是的, otherAsset即為上一個頁面播放的Asset, 只要用它進行初始化即可實現續播功能. 同時可以發現, 初始化時, 除了需要一個otherAsset, 其他方面同開始的示例一模一樣.
請看下圖:
優雅自如的旋轉
對於旋轉, 我們開發者肯定需要絕對的控制, 例如: 設定自動旋轉所支援方向. 能夠主動+自動旋轉, 而且還需要能在適當的時候禁止自動旋轉. 旋轉前後的回撥等等... 放心這些功能都有, 我挨個給大家介紹一下:
先說說何為自動旋轉. 其實就是播放器根據當前裝置的方向, 進行自動旋轉.
- 設定自動旋轉所支援方向, SJVideoPlayer自動旋轉支援的方向如下:
/// 自動旋轉所支援的方向
typedef NS_ENUM(NSUInteger, SJAutoRotateSupportedOrientation) {
SJAutoRotateSupportedOrientation_All,
SJAutoRotateSupportedOrientation_Portrait = 1 << 0,
SJAutoRotateSupportedOrientation_LandscapeLeft = 1 << 1, // UIDeviceOrientationLandscapeLeft
SJAutoRotateSupportedOrientation_LandscapeRight = 1 << 2, // UIDeviceOrientationLandscapeRight
};
以上為自動旋轉時, 所支援的方向, 播放器預設為SJAutoRotateSupportedOrientation_All
. 當我們不想讓播放器旋轉到某個方向時, 可以如下設定:
/// 以下為示例:
// 例如設定播放器只能在全屏方向上旋轉
_videoPlayer.supportedOrientation = SJAutoRotateSupportedOrientation_LandscapeLeft | SJAutoRotateSupportedOrientation_LandscapeRight;
- 主動旋轉. 當我們想主動旋轉時, 大概分為以下三點:
- 主動旋轉. 播放器旋轉到使用者當前的裝置方向或小屏.
- 主動旋轉到指定方向.
- 主動旋轉完成後的回撥.
請看以下方法, 分別對應以上三點:
- (void)rotate;
- (void)rotate:(SJOrientation)orientation animated:(BOOL)animated;
- (void)rotate:(SJOrientation)orientation animated:(BOOL)animated completion:(void (^ _Nullable)(__kindof SJBaseVideoPlayer *player))block;
// 呼叫示例:
[_videoPlayer rotate]; // 主動旋轉, 讓播放器旋轉到使用者當前的裝置方向或小屏.
- 旋轉前後的回撥. 我們在播放一個視訊時, 小屏播的時候, 狀態列的style一般為UIStatusBarStyleDefault. 但是全屏播放視訊時, 狀態列就得變成UIStatusBarStyleLightContent, 看下圖對比:
-
額, 我們趕緊說回撥吧, 狀態列還是變成白的好一點. 旋轉前的回撥以及旋轉後的回撥如下:
/// 旋轉前的回撥
@property (nonatomic, copy, nullable) void(^viewWillRotateExeBlock)(__kindof SJBaseVideoPlayer *player, BOOL isFullScreen);
/// 旋轉後的回撥
@property (nonatomic, copy, nullable) void(^viewDidRotateExeBlock)(__kindof SJBaseVideoPlayer *player, BOOL isFullScreen);
/// 以下為示例:
// 旋轉前的示例(我常用旋轉前的block, 旋轉後的block基本沒用過?):
// 1. 設定播放器旋轉前的回撥.
_videoPlayer.viewWillRotateExeBlock = ^(SJVideoPlayer * _Nonnull player, BOOL isFullScreen) {
__strong typeof(_self) self = _self;
if ( !self ) return ;
[UIView animateWithDuration:0.25 animations:^{
[self setNeedsStatusBarAppearanceUpdate];
}];
};
// 2. 根據控制層的顯示狀態 去控制狀態列的顯示和隱藏
- (BOOL)prefersStatusBarHidden {
// 全屏播放時, 使狀態列根據控制層顯示或隱藏
if ( self.videoPlayer.isFullScreen ) return !self.videoPlayer.controlLayerAppeared;
return NO;
}
// 3. 如果播放器為全屏顯示時, 返回狀態列的style為UIStatusBarStyleLightContent, 小屏返回 UIStatusBarStyleDefault
- (UIStatusBarStyle)preferredStatusBarStyle {
// 全屏播放時, 使狀態列變成白色
if ( self.videoPlayer.isFullScreen ) return UIStatusBarStyleLightContent;
return UIStatusBarStyleDefault;
}
- 禁止自動旋轉. 這個功能是必須有的, 如果不禁止旋轉, 請看圖:
SJVideoPlayer可以通過如下方式禁止自動旋轉:
// 禁止自動旋轉.
_videoPlayer.disableAutoRotation = YES;
這裡有兩點需要注意: 1. 返回時要記得恢復自動旋轉. 2. 禁止自動旋轉後, 手動點選全屏按鈕, 還是可以旋轉的.
- 禁止任何旋轉. 也就是鎖屏. 請看圖:
請注意: 在鎖屏狀態下, 此時不管是主動旋轉, 還是自動旋轉, 都將不觸發. 程式碼如下:
/// 鎖屏
_videoPlayer.lockedScreen = YES;
- 還有一些其他便利的屬性, 如下:
/// 是否是全屏
@property (nonatomic, readonly) BOOL isFullScreen;
/// 當前播放器的方向
@property (nonatomic) SJOrientation orientation;
/// 當前播放器旋轉到的裝置方向
@property (nonatomic, readonly) UIInterfaceOrientation currentOrientation;
播放的控制
SJVideoPlayer的常規播放控制大概有: 靜音, 自動播放, 使播放, 使暫停, 使停止, 使重播.
哦, 對了還有亮度, 聲音, 速率(rate)這些的設定. 並且都有相應的回撥. 程式碼我就不貼了, 一看就明白了.
我再介紹一下其他的控制功能:
- 後臺播放視訊, 這個功能我引用自: https://juejin.im/post/5a38e1a0f265da4327185a26, 大家可以給點個❤️鼓勵一下作者. 我將這個功能整合到了SJVideoPlayer播放器中, 如下:
/**
關於後臺播放視訊, 引用自: https://juejin.im/post/5a38e1a0f265da4327185a26
當您想在後臺播放視訊時:
1. 需要設定 videoPlayer.pauseWhenAppDidEnterBackground = NO; (該值預設為YES, 即App進入後臺預設暫停).
2. 前往 `TARGETS` -> `Capability` -> enable `Background Modes` -> select this mode `Audio, AirPlay, and Picture in Picture`
*/
@property (nonatomic) BOOL pauseWhenAppDidEnterBackground;
// 示例:
_videoPlayer.pauseWhenAppDidEnterBackground = YES; // 請記得按上述註釋的步驟配置
- 播放完畢的回撥. 我們有時候希望能夠重複的播放一個視訊. 這時可能需要監聽當前的視訊有沒有播放結束. SJVideoPlayer 提供了播放視訊完畢後的回撥, 程式碼如下:
__weak typeof(self) _self = self;
_videoPlayer.playDidToEndExeBlock = ^(__kindof SJBaseVideoPlayer * _Nonnull player) {
__strong typeof(_self) self = _self;
if ( !self ) return ;
[player replay];
}
如上, 當播放完畢時, 播放器呼叫 replay 方法, 讓其從頭重新開始播放.
網路狀態變更時的提示
有時候我們需要能夠友好的告訴客戶當前的網路狀態發生了改變, 畢竟流量是要錢的. 我們繼續看圖:
這些提示, 我都做了本地化處理, 支援的語言有: 中文/繁體/英文. 開發者也可以自己定義想要的提示. 後面我會介紹SJVideoPlayer全域性的配置類, 它可以配置各個控制元件的圖片, slider, 本地化的一些提示等等.
夜已深, 請看下回
由於內容比較多, 就介紹到這裡吧(熬夜到1點了... 明天還要上班?), 下一篇我會介紹全域性的配置類, 還有如何無縫的替換掉原始控制層, 同時保留自己想要的控制層(切換器).
對了最後嘮叨一下, 懇請尊重開源作者的勞動成果, 引用或參照還請註明來源. 謝謝.
另外這是我的聯絡方式, 希望與您交流:
專案地址: https://github.com/changsanjiang/SJVideoPlayer
我的郵箱: changsanjiang@gmail.com
如果您有什麼建議, 望請聯絡我!
相關文章
- 分享一個功能很全的視訊播放器播放器
- ArtVideoPlayer:一個靈活的視訊播放器IDE播放器
- 使用VideoView做個實用的視訊播放器IDEView播放器
- AVFoundation | 封裝一個好用的視訊播放器封裝播放器
- 很全很全的JavaScript的模組講解JavaScript
- 2.1 萬 Star!一個開源免費、功能強大的視訊播放器庫播放器
- 一個高自由度的Flutter 視訊播放器Flutter播放器
- "MPlayer+TextureView" : 封裝一個視訊播放器的 "SDK"View封裝播放器
- 功能齊全的視訊編輯軟體
- iOS--React Native視訊播放器外掛iOSReact Native播放器
- 鍵盤各個鍵的功能圖解 電腦鍵盤全圖詳細圖解
- IOS 整合 Bilibili IJKPlayer播放器,播放rtmp視訊流iOS播放器
- 功能齊全的jquery圖片檢視器外掛jQuery
- 一個強悍而優美的Android視訊播放器Android播放器
- Mac視訊播放器哪個好用?Mac播放器
- iOS 獲取視訊圖片iOS
- iOS拍個小視訊iOS
- React Native 原生檢視封裝全解析:視訊播放器示例React Native封裝播放器
- MPV 播放器:Linux 下的極簡視訊播放器播放器Linux
- vs2017使用vlc視訊播放器播放器
- 製作的自媒體短視訊很模糊?教你3個方法,讓視訊變清晰
- Mac強大的視訊播放器:InfuseMac播放器
- elasticsearch APM功能全解 一Elasticsearch
- 批量將一個視訊新增到多個視訊中的背景,一鍵生成視訊背景
- 部分 Android 手機硬壓視訊和 IOS 播放器不相容的問題AndroidiOS播放器
- Infuse PRO for Mac(強大的視訊播放器)Mac播放器
- Infuse PRO for Mac(強大的視訊播放器)Mac播放器
- 《iOS之導航控制器的使用圖解》iOS圖解
- (轉載)iOS中獲取某個檢視的截圖iOS
- 一個WPF開發的、介面簡潔漂亮的音訊播放器音訊播放器
- ffmpeg播放器實現詳解 - 視訊顯示播放器
- 視訊播放器工具Infuse播放器
- 阿里雲視訊播放器阿里播放器
- 自定義視訊播放器播放器
- 從零開始仿寫一個抖音App——基於FFmpeg的極簡視訊播放器APP播放器
- 收藏一個《視訊錄製的教程》
- 在手機端使用拍照功能上傳圖片的功能的解決文案
- win10自帶視訊播放器在哪_怎麼開啟win10自帶的視訊播放器Win10播放器