IOS 無限迴圈小視訊播放
其實這篇部落格是順著上一篇視訊錄製的部落格一起寫的,但是感覺放在一起太長了,不太好閱讀,所以把它分成兩部分了。
錄製完視訊後,我們想在錄製視訊的預覽層上無限迴圈播放我們的小視訊,是不是很炫酷,這時候我們就有三中選擇了:
1.MPMoviePlayerController
2.AVPlayer
3.AVAssetReader+AVAssetReaderTrackOutput
但是我們這個預覽層是自定義的喔,所以MPMoviePlayerController只能馬上給篩選掉了,所以用,那麼我們就要用到 AVPlayer 了,雖然上 AVPlayer 最多隻能建立16個,效能上不及用 AVAssetReader+AVAssetReaderTrackOutput 方法好,但是對於這麼個視訊小播放也是足夠的了。(PS:接下來博主會寫一篇關於如何用AVAssetReader+AVAssetReaderTrackOutput來實現播放視訊)
AVPlayer
AVPlayer本身並不能顯示視訊,而且它也不像MPMoviePlayerController有一個view屬性。如果AVPlayer要顯示必須建立一個播放器層AVPlayerLayer用於展示,播放器層繼承於CALayer,
有了AVPlayerLayer之新增到控制器檢視的layer中即可。要使用AVPlayer首先了解一下幾個常用的類:
AVAsset:主要用於獲取多媒體資訊,是一個抽象類,不能直接使用。
AVURLAsset:AVAsset的子類,可以根據一個URL路徑建立一個包含媒體資訊的AVURLAsset物件。
AVPlayerItem:一個媒體資源管理物件,管理者視訊的一些基本資訊和狀態,一個AVPlayerItem對應著一個視訊資源。
我們先來熟悉一下 AVPlayer 的這些類
那麼運用AVPlayer播放視訊的步驟如下:
1.建立 AVPlayerItem ,用來例項化AVPlayer並監控視訊的狀態
- (AVPlayer *)player
{
if (!_player ) {
AVPlayerItem *playerItem = [self getPlayItem];
_player = [[AVPlayer alloc]initWithPlayerItem:playerItem];
// 可以利用 AVPlayerItem 對這個視訊的狀態進行監控
}
return _player;
}
- (AVPlayerItem *)getPlayItem
{
NSString *cachePath=[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *savePath=[cachePath stringByAppendingPathComponent:MOVIEPATH];
NSURL *saveUrl=[NSURL fileURLWithPath:savePath];
// 通過檔案 URL 來例項化 AVPlayerItem
AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:saveUrl];
return playerItem;
}
2.通過AVPlayer 建立預覽層(AVPlayerLayer)並新增到可視的圖層上播放
AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
playerLayer.frame = _viewContrain.bounds;
playerLayer.videoGravity=AVLayerVideoGravityResizeAspectFill;//視訊填充模式
[_viewContrain.layer addSublayer:playerLayer];
[self.player play];
3.通過 KVO 來監聽視訊的屬性,檢視是否播放完成,播放長度為多小,緩衝了多少等等
/** * 給播放器新增進度更新 */
-(void)addProgressObserver{
AVPlayerItem *playerItem=self.player.currentItem;
UIProgressView *progress=self.progress; //這裡設定每秒執行一次
[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
float current=CMTimeGetSeconds(time);
float total=CMTimeGetSeconds([playerItem duration]);
NSLog(@"當前已經播放%.2fs.",current);
if (current) {
[progress setProgress:(current/total) animated:YES];
}
}];
}
#pragma mark - KVO
/** * 給AVPlayerItem新增監控 *
* @param playerItem AVPlayerItem物件 */
-(void)addObserverToPlayerItem:(AVPlayerItem *)playerItem{
//監控狀態屬性,注意AVPlayer也有一個status屬性,通過監控它的status也可以獲得播放狀態
[playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
//監控網路載入情況屬性
[playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}
-(void)removeObserverFromPlayerItem:(AVPlayerItem *)playerItem{
[playerItem removeObserver:self forKeyPath:@"status"];
[playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
}
/** * 通過KVO監控播放器狀態 *
* @param keyPath 監控屬性
* @param object 監視器
* @param change 狀態改變
* @param context 上下文 */
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
AVPlayerItem *playerItem=object;
if ([keyPath isEqualToString:@"status"]) {
AVPlayerStatus status= [[change objectForKey:@"new"] intValue];
if(status==AVPlayerStatusReadyToPlay){
NSLog(@"正在播放...,視訊總長度:%.2f",CMTimeGetSeconds(playerItem.duration));
}
}
else if([keyPath isEqualToString:@"loadedTimeRanges"])
{
NSArray *array=playerItem.loadedTimeRanges;
CMTimeRange timeRange = [array.firstObject CMTimeRangeValue];//本次緩衝時間範圍
float startSeconds = CMTimeGetSeconds(timeRange.start);
float durationSeconds = CMTimeGetSeconds(timeRange.duration);
NSTimeInterval totalBuffer = startSeconds + durationSeconds;//緩衝總長度
NSLog(@"共緩衝:%.2f",totalBuffer);
}
}
到此,我們就把 AVPlayer 視訊播放的方法建立完畢了。
那麼我們在視訊錄製完成的時候呼叫播放視訊的方法了
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(@"---- 錄製結束 ----");
}
- (void)completeHandle
{
// 完成後不斷播放
[_captureVideoPreviewLayer removeFromSuperlayer];
// 播放視訊
// 1.建立播放層
// 這裡為什麼要呼叫延遲1.0秒呢,我們說過用 AVCaptureMovieFileOutput 來錄製視訊,是邊錄邊寫的,即使是錄製完成了,真實的是視訊還在寫,大概時間是延遲1.2秒左右。
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 在此方法呼叫建立 AVPlayer 播放視訊的第二部
2.通過AVPlayer 建立預覽層(AVPlayerLayer)並新增到可視的圖層上播放
[self addNotification];
});
}
新增視訊播放完後的監控來迴圈播放視訊
/**
* 新增播放器通知
*/
-(void)addNotification{
//給AVPlayerItem新增播放完成通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}
-(void)removeNotification{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
/**
* 播放完成通知
*
* @param notification 通知物件
*/
-(void)playbackFinished:(NSNotification *)notification{
NSLog(@"視訊播放完成.");
// 播放完成後重複播放
// 跳到最新的時間點開始播放
[_player seekToTime:CMTimeMake(0, 1)];
[_player play];
}
@end
心如止水,奮力前行
相關文章
- 無限for迴圈(死迴圈)
- iOS-無限迴圈輪播圖iOS
- Java無限迴圈問題Java
- javascript無限迴圈滾動JavaScript
- iOS無限迴圈輪播圖(只使用三個imageView)iOSView
- iOS開發系列--無限迴圈的圖片瀏覽器iOS瀏覽器
- 短視訊直播原始碼,自定義圖片或視訊的迴圈播放原始碼
- iOS開發:Swift實現的輪播圖、無限迴圈檢視控制元件iOSSwift控制元件
- iOS視訊播放(二)iOS
- 從視訊提取迴圈播放式GIF動畫的演算法動畫演算法
- ViewPager實現左右無限迴圈滑動Viewpager
- goldwave 迴圈播放Go
- C# WPF 用MediaElement控制元件實現視訊迴圈播放C#控制元件
- 原生js系列之無限迴圈輪播元件JS元件
- android可以無限迴圈滑動的ViewPagerAndroidViewpager
- AlloyTouch之無限迴圈select外掛
- iOS開發:音訊播放、錄音、視訊播放、拍照、視訊錄製iOS音訊
- 視訊播放–踩坑小計
- 視訊播放--踩坑小計
- iOS AVPlayer之無縫切換播放(類似今日頭條視訊播放效果)iOS
- iOS開發系列--音訊播放、錄音、視訊播放、拍照、視訊錄製(轉)iOS音訊
- 華碩bios退出不了迴圈怎麼辦 華碩開機無限進入bios怎麼退出iOS
- iOS 視訊播放的簡單使用iOS
- [iOS]C語言技術視訊-06-程式迴圈結構(for{})iOSC語言
- 小程式播放當前視訊關閉其他視訊
- AirDrop無限迴圈攻擊,你的iPhone還好嗎?AIiPhone
- ThinkPHP 無限遞迴PHP遞迴
- iOS迴圈引用iOS
- iOS之視訊的三種播放方式iOS
- jQuery 迴圈播放的指示燈jQuery
- 直播系統app原始碼,垂直,水平無限迴圈滑動APP原始碼
- iOS拍個小視訊iOS
- 小程式自定義音訊元件,帶滾動條,IOS迴圈失效問題音訊元件iOS
- 無迴圈 JavaScriptJavaScript
- win10無限迴圈自動修復怎麼辦_win10開機無限迴圈自帶修復失敗重啟如何解決Win10
- win10自動修復失敗無限迴圈怎麼辦_win10開機自動修復失敗無限迴圈如何解決Win10
- 理解 vue-router的beforeEach無限迴圈的問題Vue
- iOS開發 webview禁止視訊全屏播放iOSWebView