1. 程式人生 > >iOS開發筆記 -- 視訊與圖片的混合輪播

iOS開發筆記 -- 視訊與圖片的混合輪播

專案需求:產品詳情頁的輪播圖做成視訊與圖片的混合輪播,類似於淘寶的介面,第一個圖為產品的視訊介紹,其餘為圖片介紹,本篇 demo

demo預覽圖
這裡寫圖片描述

思路:
1、輪播圖我們可以用UICollectionView或者是UIScrollView來實現,本篇demo使用的是後者。
2、根據資料的型別判斷第一張圖是否是視訊型別。
3、若第一張是視訊型別,則將自定義視訊的view加入到UIScrollView中。
4、自定義視訊的view可以使用系統的AVPlayerViewController,也可以自定義AVPlayer來實現視訊的播放。
5、給自定義的視訊view加上遮罩,遮罩的作用是控制視訊的暫停與播放,顯示進度條的進度等等。

一、UIScrollView 輪播圖的建立

1、新建一個view,建立一個類方法,進行初始化,傳入要顯示的資料

+ (instancetype)scrollViewFrame:(CGRect)frame imageStringGroup:(NSArray *)imgArray {
    XQCarousel *carousel = [[self alloc] initWithFrame:frame];
    carousel.contentArray = imgArray;
    return carousel;
}

2、初始化控制元件,並載入資料,實現UIScrollView的協議,當滑動的時候 控制視訊的暫停與播放

- (void)loadUI {

    self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    self.scrollView = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    self.scrollView.contentSize = CGSizeMake(self.frame.size.width
* self.contentArray.count, self.frame.size.height); self.scrollView.pagingEnabled = YES; self.scrollView.showsHorizontalScrollIndicator = NO; self.scrollView.delegate = self; [self addSubview:self.scrollView]; for (NSInteger index = 0; index < self.contentArray.count; index ++) { UIImageView *img = [[UIImageView alloc]initWithFrame:CGRectMake(self.frame.size.width * index, 0, self.frame.size.width, self.frame.size.height)]; img.image = [UIImage imageNamed:self.contentArray[index]]; /** 測試 **/ if (index == 0) { self.videoView = [XQVideoView videoViewFrame:img.frame videoUrl:self.contentArray[index]]; self.videoView.videoUrl = self.contentArray[index]; [self.scrollView addSubview:self.videoView]; }else { [self.scrollView addSubview:img]; } } self.pageControl = [[UIPageControl alloc]init]; self.pageControl.frame = CGRectMake(0, self.frame.size.height - 30, self.frame.size.width, 30); self.pageControl.numberOfPages = self.contentArray.count; self.pageControl.currentPage = 0; self.pageControl.currentPageIndicatorTintColor = [UIColor redColor]; [self addSubview:self.pageControl]; } - (void)scrollViewDidScroll:(UIScrollView *)scrollView { NSInteger currentPage = round(scrollView.contentOffset.x / self.frame.size.width); self.pageControl.currentPage = currentPage; if (self.videoView.isPlay) { if (currentPage == 0) { [self.videoView start]; }else { [self.videoView stop]; } } }

二、新建VideoView,初始化AVPlayerViewController,具體實現見demo,主要用到AVPlayerViewController中AVPlayer的兩個方法。


// ****** 獲取視訊的播放進度 控制進度條的顯示 ******
- (id)addPeriodicTimeObserverForInterval:(CMTime)interval queue:(nullable dispatch_queue_t)queue usingBlock:(void (^)(CMTime time))block;

// ****** 控制播放器的播放進度,本篇demo用來控制重新播放 ******
- (void)seekToTime:(CMTime)time toleranceBefore:(CMTime)toleranceBefore toleranceAfter:(CMTime)toleranceAfter completionHandler:(void (^)(BOOL finished))completionHandler NS_AVAILABLE(10_7, 5_0);

三、給VideoView加一個遮罩,在其view上新增開始與重新播放的按鈕、進度條和單擊手勢。

#import "VideoMaskView.h"

@interface VideoMaskView ()

// ******* 底部進度條 *******
@property (nonatomic, strong) UIProgressView *progressView;
// ******* 開始播放按鈕 *******
@property (nonatomic, strong) UIButton *stratButton;
// ******* 單擊手勢 *******
@property (nonatomic, strong) UITapGestureRecognizer *singleTap;
// ******* 重新播放按鈕 *******
@property (nonatomic, strong) UIButton *replayButton;

@end

@implementation VideoMaskView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self loadUI];
    }
    return self;
}

- (void)loadUI {

    [self addSubview:self.stratButton];
    [self addSubview:self.replayButton];
    [self addSubview:self.progressView];

    [self createGesture];

}

/*
 *  建立手勢
 */
- (void)createGesture {
    // 單擊
    self.singleTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(singleTapAction:)];
    self.singleTap.numberOfTouchesRequired = 1; //手指數
    self.singleTap.numberOfTapsRequired = 1;
    [self addGestureRecognizer:self.singleTap];
}

- (void)singleTapAction:(UITapGestureRecognizer *)tap {
    if (self.buttonValue) {
        self.buttonValue(XQPlayerStateStart);
    }
}

- (void)setIsStartButton:(BOOL)isStartButton {
    _isStartButton = isStartButton;
    isStartButton ? [self.stratButton setHidden:YES] : [self.stratButton setHidden:NO];
}

- (void)setProgressValue:(CGFloat)progressValue {
    _progressValue = progressValue;
    self.progressView.progress = progressValue;
    progressValue == 1 ? [self.replayButton setHidden:NO] : [self.replayButton setHidden:YES];
}

- (void)playerCurrentTime:(NSInteger)currentTime totalTime:(NSInteger)totalTime sliderValue:(CGFloat)sliderValue {
    self.progressValue = sliderValue;
}

- (UIProgressView *)progressView {
    if (!_progressView) {
        _progressView = [[UIProgressView alloc]initWithFrame:CGRectMake(0, self.frame.size.height - 2, self.frame.size.width, 5)];
        _progressView.progressViewStyle = UIProgressViewStyleDefault;
        _progressView.progressTintColor = [UIColor orangeColor];
        _progressView.progress = 0;
    }
    return _progressView;
}

- (UIButton *)stratButton {
    if (!_stratButton) {
        _stratButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _stratButton.bounds = CGRectMake(0, 0, 40, 40);
        _stratButton.center = self.center;
        [_stratButton setImage:[UIImage imageNamed:@"play"] forState:UIControlStateNormal];
        [_stratButton addTarget:self action:@selector(startButtonTaped) forControlEvents:UIControlEventTouchUpInside];
    }
    return _stratButton;
}

- (UIButton *)replayButton {
    if (!_replayButton) {
        _replayButton = [UIButton buttonWithType:UIButtonTypeCustom];
        _replayButton.bounds = CGRectMake(0, 0, 50, 70);
        _replayButton.center = self.center;
        [_replayButton setImage:[UIImage imageNamed:@"ZFPlayer_repeat_video"] forState:UIControlStateNormal];
        _replayButton.hidden = YES;
        [_replayButton addTarget:self action:@selector(replayButtonTaped) forControlEvents:UIControlEventTouchUpInside];
    }
    return _replayButton;
}

- (void)startButtonTaped {
    if (self.buttonValue) {
        self.buttonValue(XQPlayerStateStart);
    }
}

- (void)replayButtonTaped {
    if (self.buttonValue) {
        self.buttonValue(XQPlayerStateReplay);
    }
}

@end

1、本篇demo只是粗略實現了圖片和視訊輪播,可在實際的專案中根據需要進行修改,本人只是提供了一個思路。
2、推薦 視訊播放的第三方 ZFPlayer