AVFoundation的樂趣

今天我們拿 AVFoundation 的冰山一角來闡述一下我個人的喜好秋泳!相信每個人都會用 iPhoneiPad 來觀看“視頻”倡缠,優(yōu)酷米母、愛奇藝、搜狐毡琉?嗯铁瞒!還有 Youtube

原文點擊這里:http://www.zengxianhua.com/2016/02/19/avfoundationde-le-qu/

現(xiàn)在的產(chǎn)品體驗已經(jīng)足以讓我們玩的爽桅滋,也可以玩的 High慧耍!

于是我開始研究他們的細節(jié)身辨,果然不錯,在體驗和兼容性上確實有一定的難度芍碧。

不想用 MPMoviePlayerController 的同學煌珊,都會想到 AVFoundation 去自定義,其實重載 MPMoviePlayerController 也可以 自定義UI泌豆,但我還是喜歡自己琢磨定庵。

我想用自己寫的播放器來看視頻,可以嗎踪危?當然我就這么干了蔬浙!

先理解幾個名稱的基本概念。

AVPLayer

我理解的官方解釋:你可以使用 AVPlayer 對象實現(xiàn)控制和自定義UI的單個或多個播放贞远。

這意味著你項目如果有多個播放的需求畴博,這不就幫你解決了嗎?

AVPlayer支持本地與遠程的多媒體文件蓝仲,正好俱病,我本意就是可以緩存到本地看,也可以在線看袱结。

我們需要怎樣呈現(xiàn)可視內(nèi)容呢亮隙?

AVPlayerLayer

我理解的官方解釋:APLayerLayerCALayer 的子類,AVPLayer可以通過它指導(dǎo)視頻輸出和可視化垢夹。

那音頻需要嗎咱揍?沒有可視化內(nèi)容,使用 AVPlayer 就可以播放啦棚饵!

AVAsset

我理解的官方解釋:AVAsset是定時的視聽媒體,它可以是視頻掩完、影片噪漾、歌曲、播客節(jié)目且蓬;可以是本地或者遠程的欣硼;也可以是限定或者非限定的流;

AVPlayerItem

我理解的官方解釋:協(xié)調(diào)AVPlayer和AVAsset恶阴,同樣具有AVPlayerItemTrack對象诈胜,可以控制音量、播放速率等等冯事。

基本實現(xiàn)流程

了解 AVPlayer焦匈、AVPlayerLayerAVPlayerItem昵仅、AVAsset 基本概念之后缓熟,那如何定制自己的播放器呢累魔?

  • 第一步首先需要一個展示的容器,繼承 UIView够滑,隨你喜歡取個類名唄垦写!( VideoLayerView )做以下操作:

      .h
      @property (nonatomic, strong) AVPlayer *player;
      @property (nonatomic, readonly) AVPlayerLayer *playerLayer;
    
      @property (nonatomic, copy) NSString *videoFillMode;
    
      .m
      + (Class)layerClass {
          return [AVPlayerLayer class];
      }
    
      - (void)commit {
          self.playerLayer.backgroundColor = [[UIColor blackColor] CGColor];
          self.videoFillMode = AVLayerVideoGravityResizeAspect;
      }
    
      - (instancetype)initWithFrame:(CGRect)frame {
          self = [super initWithFrame:frame];
          if (self) {
              [self commit];
          }
          return self;
      }
    
      - (void)awakeFromNib {
          [self commit];
      }
    
      - (void)setPlayer:(AVPlayer *)player {
          [(AVPlayerLayer *)[self layer] setPlayer:player];
      }
    
      - (AVPlayer *)player {
          return [(AVPlayerLayer *)[self layer] player];
      }
    
      - (AVPlayerLayer *)playerLayer {
          return (AVPlayerLayer *)self.layer;
      }
    
      - (void)setVideoFillMode:(NSString *)videoFillMode {
          [self playerLayer].videoGravity = videoFillMode;
      }
    
      - (NSString *)videoFillMode {
          return [self playerLayer].videoGravity;
      }
    
  • 第二步創(chuàng)建 AVAsset 進行加載多媒體文件

你的是遠程地址?我的是本地路徑彰触?OMG梯投,這些都不是問題

    NSURL *mediaURL = [NSURL URLWithString:mediaPath];

    if (!mediaURL || ![mediaURL scheme]) {
         mediaURL = [NSURL fileURLWithPath:mediaPath];
    }

    AVURLAsset *urlAsset = [AVURLAsset URLAssetWithURL:mediaURL options:nil];

    AVURLAsset 是 AVAsset的子類
  • 第三步通過 AVAssetloadValuesAsynchronouslyForKeys: completionHandler: 方法得到 AVPlayerItem,我們暫時只需要playable况毅、 duration 這兩個key分蓖,這里是異步加載數(shù)據(jù),你需要判斷加載的狀態(tài)俭茧。整理如下:

      NSArray *keys = @[@“playable", @“duration"];
      __weak typeof(self.mediaAsset) weakAsset = urlAsset;
      [urlAsset loadValuesAsynchronouslyForKeys:keys completionHandler:^{
          dispatch_async(dispatch_get_main_queue(), ^{
          // check the keys
          for (NSString *key in keys) {
             NSError *error = nil;
             AVKeyValueStatus keyStatus = [weakAsset statusOfValueForKey:key error:&error];
             if (keyStatus == AVKeyValueStatusFailed) {
                NSLog(@"error (%@)", [[error userInfo] objectForKey:AVPlayerItemFailedToPlayToEndTimeErrorKey]);
                return;
             }
         }
    
         // check playable
         if (!weakAsset.playable) {
             return;
         }
    
         // get AVPlayerItem
         AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:weakAsset];
         });
      }];
    
  • 第四步通過異步得到的 AVPlayerItem 進行創(chuàng)建AVPlayer

      AVPlayer *player = [AVPLayer playerWithPlayerItem:playerItem];
      VideoLayerView *layerView = [[VideoLayerView alloc] initWithFrame:frame];
      layerView.player = player;
      [player play];
    

這樣就初步完成播放本地咆疗、遠程多媒體的播放器了,如果想趕上大公司的產(chǎn)品體驗母债,還需好好打磨一下午磁。

期待下一回的優(yōu)化唄!

下一期:打造一個上百Star的開源庫

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末毡们,一起剝皮案震驚了整個濱河市迅皇,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌衙熔,老刑警劉巖登颓,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異红氯,居然都是意外死亡框咙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門痢甘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來喇嘱,“玉大人,你說我怎么就攤上這事塞栅≌咄” “怎么了?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵放椰,是天一觀的道長作烟。 經(jīng)常有香客問我,道長砾医,這世上最難降的妖魔是什么拿撩? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮如蚜,結(jié)果婚禮上绷雏,老公的妹妹穿的比我還像新娘头滔。我一直安慰自己,他們只是感情好涎显,可當我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布坤检。 她就那樣靜靜地躺著,像睡著了一般期吓。 火紅的嫁衣襯著肌膚如雪早歇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天讨勤,我揣著相機與錄音箭跳,去河邊找鬼。 笑死潭千,一個胖子當著我的面吹牛谱姓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播刨晴,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼屉来,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了狈癞?” 一聲冷哼從身側(cè)響起茄靠,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蝶桶,沒想到半個月后慨绳,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡真竖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年脐雪,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片恢共。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡战秋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出旁振,到底是詐尸還是另有隱情,我是刑警寧澤涨岁,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布拐袜,位于F島的核電站,受9級特大地震影響梢薪,放射性物質(zhì)發(fā)生泄漏蹬铺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一秉撇、第九天 我趴在偏房一處隱蔽的房頂上張望甜攀。 院中可真熱鬧秋泄,春花似錦、人聲如沸规阀。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谁撼。三九已至歧胁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間厉碟,已是汗流浹背喊巍。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留箍鼓,地道東北人崭参。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像款咖,于是被迫代替她去往敵國和親何暮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,877評論 2 345

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