English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Spiegazione dettagliata dell'encapsulation di un riproduttore video semplice in iOS

前言

如果仅仅是播放视频两者的使用都非常简单,但是相比MediaPlayer,AVPlayer对于视频播放的可控制性更强一些,可以通过自定义的一些控件来实现视频的播放暂停等等。因此这里使用AVPlayer的视频播放。

视频播放器布局

首先使用xib创建CLAVPlayerView继承UIView用来承载播放器,这样我们在外部使用的时候,直接在控制器View或者Cell上添加CLAVPlayerView即可,至于播放器播放或者暂停等操作交给CLAVPlayerView来管理。下面来看一下CLAVPlayerView的结构。


CLAVPlayerView的结构

CLAVPlayerView的布局很简单,重点在于约束的添加和控件层次关系,添加约束只要自己挨个细心添加就没有问题,需要注意控件的层次关系,从上图中可以看出四个控件是分先后顺序平行添加在CLAVPlayerView上的,要注意他们的层次关系,避免相互遮挡。

视频播放器实现

布局完成之后,就是实现播放器功能,我们把播放器功能大致分为四部分来完成

一. 通过播放按钮实现视频播放。

首先CLAVPlayerView加载时需要将播放器layer添加到imageView的layer上,此时蒙版和底部工具条一定都是隐藏的,点击中间播放按钮,视频开始播放并隐藏播放按钮。因此我们需要在CLAVPlayerView的awakeFromNib方法中,在加载CLAVPlayerView时对其做一些处理。

1、初始化AVPlayer和AVPlayerLayer,并将AVPlayerLayer添加到imageView的layer上,在layoutSubviews中设置playerLayer的frame

// 初始化player 和playerLayer
self.player = [[AVPlayer alloc]init];
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
// imageView上添加playerLayer
[self.imageView.layer addSublayer:self.playerLayer];
-(void)layoutSubviews
{
 [super layoutSubviews];
 self.playerLayer.frame = self.imageView.bounds;
}

2、Crea AVPlayerItem in base all'URL del video da riprodurre

NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4"];
self.playerItem = [AVPlayerItem playerItemWithURL:url];

3、Imposta il punto di origine del Slider e le immagini del punto massimo e minimo

//Impostazione del Slider
[self.progressSlider setThumbImage:[UIImage imageNamed:@"thumbImage"] forState:UIControlStateNormal];
[self.progressSlider setMaximumTrackImage:[UIImage imageNamed:@"MaximumTrackImage"] forState:UIControlStateNormal];
[self.progressSlider setMinimumTrackImage:[UIImage imageNamed:@"MinimumTrackImage"] forState:UIControlStateNormal];

4、Aggiungi il gesture tap a imageView, cliccando su imageView viene visualizzata la barra degli strumenti

//Aggiunta di gesture a imageView
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
[self.imageView addGestureRecognizer:tap];

Attenzione:Se si utilizza xib per aggiungere gesture a imageView, è necessario ottenere l'oggetto firstObject dell'array restituito da loadNibNamed per ottenere la View di xib, se si ottiene l'oggetto lastObject, si ottiene il gesture tap, e si riceve un errore di tap gesture object senza metodo View.

5、其他控件显示以及状态的设置

// 隐藏遮盖版
self.coverView.hidden = YES;
// 设置工具栏状态
self.toolView.alpha = 0;
self.isShowToolView = NO;
// 设置工具栏播放按钮状态
self.playOrPauseBtn.selected = NO;

这盖板只有播放完毕之后显现,点击重播之后又隐藏,因此使用hidden直接隐藏即可,而工具栏需要重复显示,并且我们为了能让工具栏的显示有动画效果,这里通过设置toolView的alpha来显示或隐藏工具栏,并通过isShowToolView来记录toolView的显示或隐藏。

6、中间播放按钮的点击

- (IBAction)playOrPauseBigBtnClick:(UIButton *)sender {
 // 隐藏中间播放按钮,工具栏播放按钮为选中状态
 sender.hidden = YES;
 self.playOrPauseBtn.selected = YES;
 // 替换播放内容
 [self.player replaceCurrentItemWithPlayerItem:self.playerItem];
 [self.player play];
 [self addProgressTimer];
}

此时,当我们点击中间播放按钮播放器就可以播放视频了。

二. 工具条的显示与隐藏

在播放状态时,当点击imageView,就会弹出底部工具条,可以查看当前播放的时间,视频总时间或进行暂停视频、全屏播放等操作。如果没有操作,工具栏会在5秒之后自动隐藏。而当未播放状态时,点击imageView和中间播放按钮效果一样,开始播放视频。

1、添加定时器,5秒钟之后隐藏底部工具条,并提供移除定时器的方法。

/** toolView显示时开始计时,5s后隐藏toolView */
-(void)addShowTime
{
 self.showTime = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(upDateToolView) userInfo:nil repeats:NO];
 [[NSRunLoop mainRunLoop]addTimer:self.showTime forMode:NSRunLoopCommonModes];
}
/** Nascondere toolView */
-(void)upDateToolView
{
 self.isShowToolView = !self.isShowToolView;
 [UIView animateWithDuration:0.5 animations:^{
  self.toolView.alpha = 0;
 }] completion:nil];
}
/** Rimuovere il timer */
-(void)removeShowTime
{
 [self.showTime invalidate];
 self.showTime = nil;
}

2. Implementazione del metodo di tap per imageView, qui ci sono diverse situazioni: quando il video non è in riproduzione, il tap sull'imageView non mostra la barra degli strumenti, ma è uguale al tap sul pulsante di riproduzione centrale, e inizia a riprodurre il video. Durante la riproduzione, il tap sull'imageView mostra la barra degli strumenti, e se a quel punto si preme il pulsante di pausa nella barra degli strumenti, la riproduzione si ferma, la barra degli strumenti non scompare e si ricomincia a riprodurre il video, e la barra degli strumenti scompare entro 5 secondi.

/** Metodo di tap per imageView */
-(void)tapAction:(UITapGestureRecognizer *)tap
{
 // Quando lo stato di riproduzione è sconosciuto, il tap sull'imageView è equivalente al tap sul pulsante di riproduzione centrale, e inizia a riprodurre il video
 if (self.player.status == AVPlayerStatusUnknown) {
  [self playOrPauseBigBtnClick:self.playOrPauseBigBtn];
  return;
 }
 // Registrare lo stato di visualizzazione o nascosto della barra degli strumenti inferiore
 self.isShowToolView = !self.isShowToolView;
 // Se necessario mostrare la barra degli strumenti, aggiungere l'animazione di visualizzazione
 if (self.isShowToolView){
  [UIView animateWithDuration:0.5 animations:^{
   self.toolView.alpha = 1;
  }] completion:nil];
  // Quando il pulsante di riproduzione della barra degli strumenti è in stato di riproduzione, aggiungere il timer e nascondere la barra degli strumenti dopo 5 secondi
  if (self.playOrPauseBtn.selected) {
   [self addShowTime];
  }
 // Se necessario nascondere la barra degli strumenti, rimuovere il timer e nascondere la barra degli strumenti
 }else{
  [self removeShowTime];
  [UIView animateWithDuration:0.5 animations:^{
   self.toolView.alpha = 0;
  }] completion:nil];
 }
}

3. Il pulsante di riproduzione/pausa nella barra degli strumenti deve essere gestito, quando è in stato di pausa, il valore alpha della barra degli strumenti deve essere impostato a 1 e il timer rimosso. Quando si ricomincia a riprodurre il video, il timer deve essere aggiunto di nuovo per iniziare a contare, e dopo 5 secondi la barra degli strumenti scompare. Il codice dettagliato sarà mostrato nel dettaglio della sincronizzazione del tempo di riproduzione, del Slider e della riproduzione del video.

3. Sincronizzazione del tempo di riproduzione, del Slider e della riproduzione del video

La barra degli strumenti inferiore deve sincronizzare il tempo di riproduzione, il tempo totale del video e lo spostamento del Slider con il tempo di riproduzione del video.

1. Add timers for video playback and the Slider, calling to update the time label and Slider slider every 1 second

 /** Add slider timer */
 -(void)addProgressTimer
 {
  self.progressTimer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(updateProgressInfo) userInfo:nil repeats:YES];
  [[NSRunLoop mainRunLoop]addTimer:self.progressTimer forMode:NSRunLoopCommonModes];
 }
 /** Remove slider timer */
 -(void)removeProgressTimer
 {
  [self.progressTimer invalidate];
  self.progressTimer = nil;
 }
 /** Update slider and timeLabel */
 - (void)updateProgressInfo
 {
 NSTimeInterval currentTime = CMTimeGetSeconds(self.player.currentTime);
  NSTimeInterval durationTime = CMTimeGetSeconds(self.player.currentItem.duration);
  self.timeLabel.text = [self timeToStringWithTimeInterval:currentTime];
  self.allTimeLabel.text = [self timeToStringWithTimeInterval:durationTime];
  self.progressSlider.value = CMTimeGetSeconds(self.player.currentTime) / CMTimeGetSeconds(self.player.currentItem.duration);
  if (self.progressSlider.value == 1) {
   [self removeProgressTimer];
   self.coverView.hidden = NO;
  } 
 }

The current playback time and total time obtained are of type CMTime, which need to be converted to NSTimeInterval and seconds to minutes and time, and the conversion method is extracted

/** Convert the playback time and total time methods */
-(NSString *)timeToStringWithTimeInterval:(NSTimeInterval)interval;
{
 NSInteger Min = interval / 60;
 NSInteger Sec = (NSInteger)interval % 60;
 NSString *intervalString = [NSString stringWithFormat:@"%02ld:%02ld",Min,Sec];
 return intervalString;
}

2, Quando si clicca sul pulsante di riproduzione centrale per iniziare la riproduzione, aggiungi il timer per sincronizzare l'aggiornamento del tempo di riproduzione e dello slider, quando si clicca sul pulsante di pausa nella barra degli strumenti durante la riproduzione, è necessario sospendere la riproduzione del video, rimuovere il timer e aggiungere nuovamente il timer e iniziare la riproduzione quando si ricomincia.

/** Evento di clic del pulsante di pausa sulla toolView */
- (IBAction)playOrPauseBtnClick:(UIButton *)sender {
 // Il pulsante di stato di riproduzione selected è YES, lo stato di pausa selected è NO.
 sender.selected = !sender.selected;
 if (!sender.selected) {
  self.toolView.alpha = 1;
  [self removeShowTime];
  [self.player pause];
  [self removeProgressTimer];
 }else{
  [self addShowTime];
  [self.player play];
  [self addProgressTimer];
 }
}

3, Riproduzione di video a salti dello slider

Occorre ascoltare tre fasi: pressione, trascinamento (cambio di dati) e rilascio. Quando si preme, rimuovere il timer, durante il trascinamento calcolare il tempo di riproduzione corrente in base al valore trascinato e mostrarlo nel label, e quando si rilascia calcolare il tempo di riproduzione corrente e saltare al tempo di riproduzione corrente per riprodurre.

/** Eventi di trascinamento e clic dello slider */
- (IBAction)touchDownSlider:(UISlider *)sender {
 // Rimuovi l'ascoltatore quando si preme
 [self removeProgressTimer];
 [self removeShowTime];
}
- (IBAction)valueChangedSlider:(UISlider *)sender {
 // Calcola il tempo di riproduzione corrispondente al punto trascinato dello slider
 NSTimeInterval currentTime = CMTimeGetSeconds(self.player.currentItem.duration) * sender.value;
 self.timeLabel.text = [self timeToStringWithTimeInterval:currentTime];
}
- (IBAction)touchUpInside:(UISlider *)sender {
 [self addProgressTimer];
 // Calcolare il tempo di riproduzione corrispondente al trascinamento del slider
 NSTimeInterval currentTime = CMTimeGetSeconds(self.player.currentItem.duration) * sender.value;
 // seekToTime: Saltare alla riproduzione del tempo corrente
 [self.player seekToTime:CMTimeMakeWithSeconds(currentTime, NSEC_PER_SEC) toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
 [self addShowTime];
}

Quarto. Implementazione del pulsante di ripetizione e del pulsante di riproduzione a schermo intero

1. Nella funzione di aggiornamento del Slider chiamata ogni secondo dal timer, verificare se il video è stato riprodotto completamente e mostrare la View di copertura, mentre l'implementazione del pulsante di riproduzione è in realtà impostare il valore di Slider a 0 e richiamare il metodo di rilascio del click sul Slider, impostare il tempo di riproduzione corrente a 0, nascondere la View di copertura e chiamare il pulsante di riproduzione centrale per iniziare la riproduzione.

/** Click del pulsante di riproduzione */
- (IBAction)repeatBtnClick:(UIButton *)sender {
 self.progressSlider.value = 0;
 [self touchUpInside:self.progressSlider];
 self.coverView.hidden = YES;
 [self playOrPauseBigBtnClick:self.playOrPauseBigBtn];
}

2. Implementazione della riproduzione a schermo intero

Per la riproduzione a schermo intero è necessario creare un controller di riproduzione a schermo intero Moda, per eseguire la riproduzione a schermo intero, creare il controller di riproduzione a schermo intero CLFullViewController e farlo supportare la rotazione in direzione destra e sinistra, creare il controller CLFullViewController, aggiungere CLAVPlayerView al View di CLFullViewController e impostare frame, quando si esce dalla riproduzione a schermo intero, rimuovere CLFullViewController e impostare il frame di CLAVPlayerView al valore originale.
Impostazioni di rotazione e direzione di rotazione in CLFullViewController

- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
 return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
{
 return YES;
}

Evento di click sul pulsante di riproduzione a schermo intero

/** Evento di click sul pulsante a schermo intero */
- (IBAction)fullViewBtnClick:(UIButton *)sender {
 sender.selected = !sender.selected;
 [self videoplayViewSwitchOrientation:sender.selected];
}
/** Apri il riproduttore a schermo intero */
- (void)videoplayViewSwitchOrientation:(BOOL)isFull
{
 if (isFull) {
  [self.contrainerViewController presentViewController:self.fullVc animated:NO completion:^{
   [self.fullVc.view addSubview:self];
   self.center = self.fullVc.view.center;
   [UIView animateWithDuration:0.15 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^{
    self.frame = self.fullVc.view.bounds;
   }] completion:nil];
  }] completion:nil];
 } else {
  [self.fullVc dismissViewControllerAnimated:NO completion:^{
   [self.contrainerViewController.view addSubview:self];
   [UIView animateWithDuration:0.15 delay:0.0 options:UIViewAnimationOptionLayoutSubviews animations:^{
    self.frame = CGRectMake(0, 200, self.contrainerViewController.view.bounds.size.width, self.contrainerViewController.view.bounds.size.width * 9 / 16);
   }] completion:nil];
  }] completion:nil];
 }
}

Attenzione:In questo caso, è necessario ottenere il controller esterno per Moda out il controller di riproduzione a schermo intero, quindi aggiungere l'attributo contrainerViewController a CLAVPlayerView per ottenere il controller.

Imballaggio semplice

Al momento abbiamo già implementato le funzioni di base del riproduttore, ora dobbiamo considerare come impacchettare in modo che sia più facile da usare. Di fatto, abbiamo già completato la maggior parte dell'imballaggio, ciò che dobbiamo fare ora è fornire un'interfaccia semplice ed intuitiva, che permetta all'esterno di chiamare facilmente il riproduttore.

1、Fornire un metodo di classe per creare rapidamente il riproduttore

+ (instancetype)videoPlayView
{
 return [[[NSBundle mainBundle]loadNibNamed:@"CLAVPlayerView" owner:nil options:nil]lastObject];
}

2、La risorsa video da riprodurre dovrebbe essere decisa dall'esterno, quindi forniamo l'attributo urlString per ricevere la risorsa video e poi riprodurre il video tramite la sovrascrittura del metodo set.
/** Set metodo della risorsa video da riprodurre */

-(void)setUrlString:(NSString *)urlString
{
 _urlString = urlString;
 NSURL *url = [NSURL URLWithString:urlString];
 self.playerItem = [AVPlayerItem playerItemWithURL:url];
}

In questo momento, l'uso del riproduttore esterno è molto semplice, non è necessario considerare la logica interna, è sufficiente creare rapidamente CLAVPlayerView, aggiungerlo alla View del controller, impostare il suo frame e poi specificare la risorsa video da riprodurre.

- (void)viewDidLoad {
 [super viewDidLoad];
 [self setUpVideoPlayView]; 
 self.playView.urlString = @"http://120.25.226.186:32812/resources/videos/minion_02.mp4";
}
-(void)setUpVideoPlayView
{
 self.playView = [CLAVPlayerView videoPlayView];
 self.playView.frame = CGRectMake(0, 200, self.view.frame.size.width, self.view.frame.size.width * 9 / 16);
 self.playView.contrainerViewController = self;
 [self.view addSubview:self.playView];
}

Infine, il lettore video è più o meno così

Conclusione

Ci sono ancora molte cose da perfezionare, alcune funzioni non sono state implementate, ad esempio, ci sono due pulsanti di placeholder che possono essere utilizzati in futuro per scaricare video e controllare la funzione di danza a schermo. Dopo la fine della riproduzione, il pulsante di condivisione non è stato implementato. In futuro, continueremo a condividere con tutti, questo è tutto il contenuto dell'articolo, speriamo che il contenuto di questo articolo possa essere utile a tutti, se hai domande, puoi lasciare un messaggio per comunicare.

Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, di proprietà dei rispettivi autori, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene i diritti di proprietà, non è stato editato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a: notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito rimuoverà immediatamente il contenuto sospetto di violazione del copyright.

Ti potrebbe interessare