AVFoundation | 封裝一個好用的視頻播放器

一:簡介

AVFoundation是蘋果在iOS和OS X系統中用於處理基於時間的媒體數據的Objective-C框架. 供使用者來開發媒體類型的應用程序。git

video.png

上圖是iOS系統下媒體應用的結構層. AVKit框架用於簡化媒體應用的建立過程,若是你只須要看電影,那麼使用這個就能夠了, UKit能夠支持簡單的錄製功能 . 而更多功能須要低層級框架支持.下面簡單介紹下AVFoundation內最主要的支撐框架和其提供的功能。github

  • CoreAudio : 處理全部音頻事件.是由多個框架整合在一塊兒的總稱,爲音頻和MIDI內容的錄製,播放和處理提供相應接口.設置能夠針對音頻信號進行徹底控制,並經過Audio Units來構建一些複雜的音頻處理.有興趣的能夠單獨瞭解一下這個框架。緩存

  • CoreMedia: 是AVFoundation所用到低層級媒體管道的一部分.提供音頻樣本和視頻幀處理所需的低層級數據類型和接口。bash

  • CoreAnimation: 動畫相關框架, 封裝了支持OpenGL和OpenGL ES功能的ObjC各類類. AVFoundation能夠利用CoreAnimation讓開發者可以在視頻的編輯和播放過程當中添加動畫和圖片效果。微信

下面我就和你們詳細的分享一下,如何使用AVFoundation來實現一個好用的視頻播放器。若是好用或者對你有所幫助,不要忘了關注點個贊呦!!!session

二:實現思路分析

  1. 視頻控制界面實現app

  2. 用於視頻顯示的View建立框架

  3. 視頻數據下載器FBYVideoDownload建立ide

  4. 播放、暫停、橫豎屏操做方法實現源碼分析

  5. 監聽播放進度

  6. 控制存儲緩衝範圍

  7. 拖動滑塊,控制快進快退

  8. 定義臨時文件路徑

  9. 定義緩存文件夾路徑

  10. 發起視頻路徑網路請求方法

  11. 播放結束設置

  12. 先後視頻播放控制

三:實現源碼分析

根據實現思路分析,一步步進行編碼實現:

1. 視頻控制界面實現

- (FBYVideoPlayerView *)videoPlayControl{
    if (!_videoPlayControl) {
        _videoPlayControl = [[FBYVideoPlayerView alloc] initWithFrame:self.backgroundView.bounds];
        [self.backgroundView addSubview:_videoPlayControl];
        
    }
    return _videoPlayControl;
}
複製代碼

2. 用於視頻顯示的View建立

- (UIView *)videoShowView{
    if (!_videoShowView) {
        _videoShowView = [[UIView alloc] init];
        _videoShowView.layer.masksToBounds = YES;
        [self.backgroundView addSubview:_videoShowView];
    }
    return _videoShowView;
}
複製代碼

3. 視頻數據下載器FBYVideoDownload建立

@property(nonatomic, weak) id <FBYVideoDownloadDelegate> delegate;

//定義初始化方法 傳入videoUrl參數(NSString)
- (instancetype)initWithURL:(NSString *)videoUrl withDelegate:(id)delegate;

//開始下載
- (void)start;
//暫停
- (void)suspend;
//關閉
- (void)cancel;
複製代碼

4. 播放、暫停、橫豎屏操做方法實現

//全屏
        [_videoPlayControl setFullScreenButtonClick_block:^{
            if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(videoPlayerDidFullScreenButtonClick)]) {
                [weakSelf.delegate videoPlayerDidFullScreenButtonClick];
            }
        }];
        //播放/暫停
        [_videoPlayControl setPlayButtonClick_block:^(BOOL play) {
            if (play) {
                [weakSelf.player play];
            }else{
                [weakSelf.player pause];
            }
            weakSelf.playButtonState = !weakSelf.playButtonState;
        }];
複製代碼

5. 監聽播放進度

self.timeObserve = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        CGFloat current = CMTimeGetSeconds(time);
        CGFloat total = CMTimeGetSeconds(weakSelf.currentPlayerItem.duration);
        CGFloat progress = current / total;
        
        weakSelf.videoPlayControl.currentTime = current;
        weakSelf.videoPlayControl.playValue = progress;
        
        if (weakSelf.isCanToGetLocalTime) {
            weakSelf.localTime = [weakSelf getLocalTime];
        }
        NSInteger timeNow = [weakSelf getLocalTime];
        if (timeNow - weakSelf.localTime > 1.5) {
            [weakSelf.videoPlayControl videoPlayerDidBeginPlay];
            weakSelf.isCanToGetLocalTime = YES;
        }
    }];
複製代碼

6. 監聽播放器的狀態

[self.currentPlayerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
複製代碼

7. 監聽當前的緩衝進度

[self.currentPlayerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
複製代碼

8. 監聽到當前沒有緩衝數據

[self.currentPlayerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
複製代碼

9. 控制存儲緩衝範圍

- (void)playForActivity{
    if (self.playButtonState) {
        [self.player play];
    }
    self.isBufferEmpty = NO;
    self.isPlaying = YES;
    [self.videoPlayControl videoPlayerDidBeginPlay];
}
複製代碼

10. 拖動滑塊,控制快進快退

//拖動滑塊
[_videoPlayControl setSliderTouchEnd_block:^(CGFloat time) {
            [weakSelf seekToTimePlay:time];
        }];
        
//快進快退
[_videoPlayControl setFastFastForwardAndRewind_block:^(CGFloat time) {
            [weakSelf seekToTimePlay:time];
        }];
複製代碼

11. 定義臨時文件路徑

self.videoTempPath = [NSString tempFilePathWithFileName:videoName];
複製代碼

12. 定義緩存文件夾路徑

self.videoCachePath = [NSString cacheFilePathWithName:videoName];
複製代碼

13. 發起視頻路徑網路請求方法

- (void)sendHttpRequst
{
    [_fileHandle seekToEndOfFile];
    NSURL *url = [NSURL URLWithString:_videoUrl];
    NSMutableURLRequest *requeset = [NSMutableURLRequest requestWithURL:url];
    
    //指定頭信息  當前已下載的進度
    [requeset setValue:[NSString stringWithFormat:@"bytes=%ld-", _curruentLength] forHTTPHeaderField:@"Range"];
    
    //建立請求
    NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:requeset];
    self.dataTask = dataTask;
    
    //發起請求
    [self.dataTask resume];
}
複製代碼

14. 播放結束設置

- (void)playerItemDidPlayToEnd:(NSNotification *)notification{
    //從新開始播放
    __weak typeof(self) weak_self = self;
    [self.player seekToTime:CMTimeMake(0, 1) completionHandler:^(BOOL finished) {
        __strong typeof(weak_self) strong_self = weak_self;
        if (!strong_self) return;
        [strong_self.player play];
    }];
}
複製代碼

15. 先後視頻播放控制

//進入後臺
- (void)appDidEnterBackground{
    if (self.stopWhenAppDidEnterBackground) {
        [self pauseVideo];
    }
}
//進入前臺
- (void)appDidEnterForeground{
    [self playVideo];
}
複製代碼

五:項目實際使用

1. 下載demo

下載demo,將demo中FBYVideoData文件夾引入項目中。

2. 在項目中引入FBYVideoPlayer並繼承FBYVideoPlayerDelegate代理

#import "FBYVideoPlayer.h"

@interface ViewController ()<FBYVideoPlayerDelegate>

@property (nonatomic ,strong) FBYVideoPlayer *videoPlayer;
@property (nonatomic ,strong) UIView *videoPlayBGView;
@property (nonatomic ,copy)   NSString*videoUrl;

@end
複製代碼

3. 初始化建立基層view

self.videoPlayBGView = [[UIView alloc] initWithFrame:CGRectMake(0, 90, SCREEN_WIDTH, SCREEN_WIDTH * 0.6)];
self.videoPlayBGView.backgroundColor = [UIColor blackColor];
    [self.view addSubview:self.videoPlayBGView];
複製代碼

4. 初始化調用視頻播放方法

self.videoPlayer = [[FBYVideoPlayer alloc] init];
self.videoPlayer.delegate = self;
[self.videoPlayer playWithUrl:self.videoUrl showView:self.videoPlayBGView];
複製代碼

5. 初始化調用視頻播放方法

self.videoPlayer = [[FBYVideoPlayer alloc] init];
self.videoPlayer.delegate = self;
[self.videoPlayer playWithUrl:self.videoUrl showView:self.videoPlayBGView];
複製代碼

本篇文章demo源碼:

關注 【網羅開發】微信公衆號,回覆【97】即可領取。 網羅天下方法,方便你我開發,更多iOS技術乾貨等待領取,全部文檔會持續更新,歡迎關注一塊兒成長!

但願能夠幫助你們,若有問題可加QQ技術交流羣: 668562416 若是哪裏有什麼不對或者不足的地方,還望讀者多多提意見或建議

如需轉載請聯繫我,通過受權方可轉載,謝謝

本篇已同步到我的博客:FBY展菲


歡迎關注個人公衆號:網羅開發

相關文章
相關標籤/搜索