天天看點

iOS短視訊加直播:仿快手的短視訊(附近頁面)附近頁面

在上一篇文章我介紹了如何不用封閉的SDK,做一個完全開源的抖音短視訊,在這篇文章裡我會向大家介紹如何做一個完全開源的快手短視訊。

附近頁面

快手樣式附近頁面整體實作的Gif效果:

iOS短視訊加直播:仿快手的短視訊(附近頁面)附近頁面

首先我說一下UI的整體架構,我們可以看到,附近頁面一開始是以一個UICollectionView頁面作為開始頁面,與上一篇抖音的熱門頁面幾乎一直,實作原理也類似,就不向大家介紹了,我主要說下快手短視訊播放頁面的架構。

快手短視訊播放頁面的底層是一個UITableView,播放視訊的部分放在tableHeaderView裡,而評論部分就放在tableViewCell裡,并且我們在tableHeaderView裡加入了評論,點贊,分享的帶手勢的UIImageView,還在tableHeaderView的左下角加入了輸入評論框。還添加了用于顯示視訊第一幀的wmPlayerBgImgView,并在上面鋪上了用于播放視訊的WMPlayer(這是一個開源播放器,後面我會對它進行詳細解釋,這裡先主要介紹UI),具體代碼如下:

- (void)createTableView{
    _mainTableView = [[UITableView alloc] init];
    _mainTableView.showsVerticalScrollIndicator = NO;
    _mainTableView.delegate = self;
    _mainTableView.dataSource = self;
    _mainTableView.separatorStyle=UITableViewCellSeparatorStyleNone;
    [self.view addSubview:_mainTableView];
    [_mainTableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.top.equalTo(self.view);
        make.bottom.equalTo(self.view)/*.offset(-44)*/;
//        make.bottom.equalTo(self.view).offset(60);
    }];
    // 為了讓tableView自适應高度設定如下兩個屬性
    _mainTableView.estimatedRowHeight = 30;
    _mainTableView.rowHeight = UITableViewAutomaticDimension;
    UIView* headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight)];
    headerView.backgroundColor = [UIColor blackColor];
    UITapGestureRecognizer*tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(Actiondo:)];
    tapGesture.delegate = self;
    [_mainTableView addGestureRecognizer:tapGesture];
    _mainTableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingTarget:self refreshingAction:@selector(refreshCommentsData)];
    _mainTableView.mj_footer = [MJRefreshBackNormalFooter footerWithRefreshingTarget:self refreshingAction:@selector(addCommentsData)];
    
    UIImageView* wmPlayerBgImgView = [[UIImageView alloc] init];
    wmPlayerBgImgView.contentMode = UIViewContentModeScaleAspectFit;
    [wmPlayerBgImgView setClipsToBounds:YES];
    [headerView addSubview:wmPlayerBgImgView];
    [wmPlayerBgImgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.bottom.equalTo(headerView);
    }];
    [wmPlayerBgImgView sd_setImageWithURL:[NSURL URLWithString:_DataModel.cover_url] placeholderImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"usericon02" ofType:@"png"]]];
    
    _mainTableView.tableHeaderView = headerView;
    _wmPlayer  = [[WMPlayer alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight) videoURLStr:_DataModel.video_url];
    [headerView addSubview:_wmPlayer];
    _wmPlayer.closeBtn.hidden = YES;
    _wmPlayer.bottomView.hidden = YES;
    _wmPlayer.fullScreenBtn.hidden = YES;
    _wmPlayer.backgroundColor = [UIColor clearColor];
    [_wmPlayer play];
   
    UILabel* titleLabel = [[UILabel alloc] init];
//    titleLabel.backgroundColor = [UIColor grayColor];
    titleLabel.numberOfLines = 0;
    titleLabel.textColor = [UIColor whiteColor];
    titleLabel.textAlignment = NSTextAlignmentLeft;
    titleLabel.font = [UIFont systemFontOfSize:13.5];
    [headerView addSubview:titleLabel];
    [titleLabel mas_makeConstraints:^(MASConstraintMaker *make) {

        make.top.equalTo(headerView).offset(70);
        make.left.equalTo(headerView).offset(10);
        make.width.equalTo(@(140));
    }];
//    titleLabel.text = _DataModel.title;
    [self toSetUpThree_dimensionalShadows:titleLabel andString:_DataModel.title];
    
    UIView* headerViewBottomBar = [[UIView alloc] init];
    headerViewBottomBar.backgroundColor = [UIColor clearColor];
    [headerView addSubview:headerViewBottomBar];
    [headerViewBottomBar mas_makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.left.right.equalTo(headerView);
        make.height.equalTo(@(44));
    }];
    
    
    UIImageView* commentImgView = [[UIImageView alloc] init];
    commentImgView.image = [UIImage imageNamed:@"comment"];
    commentImgView.userInteractionEnabled = YES;
    [headerViewBottomBar addSubview:commentImgView];
    [commentImgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(headerViewBottomBar);
        make.centerX.equalTo(headerViewBottomBar);
        make.width.height.equalTo(@(24));
    }];
    UITapGestureRecognizer* tapGesturecommentImg = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickcommentImgView)];
    [commentImgView addGestureRecognizer:tapGesturecommentImg];
    _commentLabel = [[UILabel alloc] init];
    _commentLabel.textColor = [UIColor whiteColor];
    _commentLabel.textAlignment = NSTextAlignmentLeft;
    _commentLabel.font = [UIFont systemFontOfSize:11];
    _commentLabel.text = _DataModel.comment_count;
    [headerViewBottomBar addSubview:_commentLabel];
    [_commentLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(commentImgView);
        make.left.equalTo(commentImgView.mas_right).offset(2);
    }];
    
    _shareLabel = [[UILabel alloc] init];
    _shareLabel.textColor = [UIColor whiteColor];
    _shareLabel.textAlignment = NSTextAlignmentRight;
    _shareLabel.font = [UIFont systemFontOfSize:11];
    _shareLabel.text = _DataModel.share_count;
    [headerViewBottomBar addSubview:_shareLabel];
    [_shareLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(headerViewBottomBar).offset(-20);
        make.centerY.equalTo(commentImgView);
    }];
    
    UIImageView* shareImgView = [[UIImageView alloc] init];
    shareImgView.image = [UIImage imageNamed:@"xgshare"];
    shareImgView.userInteractionEnabled = YES;
    [headerViewBottomBar addSubview:shareImgView];
    [shareImgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(commentImgView);
        make.right.equalTo(_shareLabel.mas_left).offset(-2);
        make.width.height.equalTo(@(24));
    }];
    UITapGestureRecognizer* tapGestureShareImg = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickShare3rdBtn)];
    [shareImgView addGestureRecognizer:tapGestureShareImg];
    
    
    _zhanImgView = [[UIImageView alloc] init];
    _zhanImgView.image = [UIImage imageNamed:@"xgzhan"];
    _zhanImgView.userInteractionEnabled = YES;
    [headerViewBottomBar addSubview:_zhanImgView];
    [_zhanImgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(commentImgView);
        make.centerX.equalTo(headerViewBottomBar).offset(ScreenWidth/4-24);
        make.width.height.equalTo(@(24));
    }];
    _isZhan = NO;
    UITapGestureRecognizer* tapGestureZhanImg = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickZhanBtn)];
    [_zhanImgView addGestureRecognizer:tapGestureZhanImg];
    
    _zhanLabel = [[UILabel alloc] init];
    _zhanLabel.textColor = [UIColor whiteColor];
    _zhanLabel.textAlignment = NSTextAlignmentLeft;
    _zhanLabel.font = [UIFont systemFontOfSize:11];
    _zhanLabel.text = _DataModel.digg_count;
    [headerViewBottomBar addSubview:_zhanLabel];
    [_zhanLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(_zhanImgView.mas_right).offset(2);
        make.centerY.equalTo(commentImgView);
    }];
    
    UIView* writeBgView = [[UIView alloc] init];
    writeBgView.backgroundColor = [UIColor whiteColor];
    writeBgView.alpha = .3;
    [headerViewBottomBar addSubview:writeBgView];
    [writeBgView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(headerViewBottomBar);
        make.height.equalTo(@(24));
        make.width.equalTo(@(ScreenWidth/2 - 20 -12));
        make.left.equalTo(headerViewBottomBar).offset(10);
        
    }];
//    [[AppDelegate appDelegate].cmImageSize setViewsRounded:writeBgView cornerRadiusValue:12 borderWidthValue:0 borderColorWidthValue:[UIColor whiteColor]];
    writeBgView.layer.masksToBounds = true;
    writeBgView.layer.cornerRadius = 12;
    
    UITapGestureRecognizer* tapGesture2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showkeyboard)];
    [writeBgView addGestureRecognizer:tapGesture2];

    
    UILabel* writeComment = [[UILabel alloc] init];
    writeComment.textColor = [UIColor whiteColor];
    writeComment.textAlignment = NSTextAlignmentLeft;
    writeComment.font = [UIFont systemFontOfSize:11];
    writeComment.text = @"?寫評論...";
    [headerViewBottomBar addSubview:writeComment];
    [writeComment mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerY.equalTo(commentImgView);
        make.left.equalTo(writeBgView).offset(5);
    }];
}
           

在剛進來的時候我模拟了幾條評論資料,模拟資料的代碼如下:

- (void) initcommentS
{
    CommentDataModel* data1 = [CommentDataModel new];
    data1.selfNickName = @"Lithpie";
    data1.createdTime = @"1天前";
    data1.content = @"30萬聽衆,41評論。這裡的都是些不善言談的人。";
    data1.faceurl = @"http://p3.pstatp.com/live/100x100/1946001175da6c6f38a7.jpg"/*[[NSBundle mainBundle] pathForResource:@"usericon01" ofType:@"png"]*/;
    [_commentsMutableAry insertObject:data1 atIndex:0];
    
    CommentDataModel* data2 = [CommentDataModel new];
    data2.selfNickName = @"匠子烤又";
    data2.createdTime = @"8小時前";
    data2.content = @"時常在想,如果我未曾來到這個城市,會去哪裡。如果我還在記憶中的那個小城,是否會找份清閑的工作,或開個不熱鬧的小店。下雨的時候撐着傘,走過那條上學必經落滿梧桐的街。打開我房間的抽屜,朋友寫的信,卡帶,女同學編的手鍊。人是孤獨的動物,卻孤獨不過百年。";
    data2.faceurl = @"http://p1.pstatp.com/live/100x100/26da000097202289e858.jpg"/*[[NSBundle mainBundle] pathForResource:@"usericon01" ofType:@"png"]*/;
    [_commentsMutableAry insertObject:data2 atIndex:0];
    
    CommentDataModel* data3 = [CommentDataModel new];
    data3.selfNickName = @"想不到昵稱l";
    data3.createdTime = @"4小時前";
    data3.content = @"我願我行我素。不願塗脂抹粉,招搖過市。我也不願意生活在這不安的,忙亂的,神經質的世界中。甯可或立或坐沉思着,任聽這大千世界的風雨?";
    data3.faceurl = @"http://p1.pstatp.com/live/100x100/26d90002772cc1565907.jpg"/*[[NSBundle mainBundle] pathForResource:@"usericon01" ofType:@"png"]*/;
    [_commentsMutableAry insertObject:data3 atIndex:0];
    
    CommentDataModel* data4 = [CommentDataModel new];
    data4.selfNickName = @"unkira";
    data4.createdTime = @"1小時前";
    data4.content = @"其實我有時候覺得,這個世界是不存在的,是我想象出來的。每次想到就會覺得很孤單,還是假裝它存在吧。";
    data4.faceurl = @"http://p3.pstatp.com/live/100x100/123f0004e4375f8f63be.jpg"/*[[NSBundle mainBundle] pathForResource:@"usericon01" ofType:@"png"]*/;
    [_commentsMutableAry insertObject:data4 atIndex:0];
}
           

一開始播放視訊的頁面占據了整個螢幕,我們是看不到的,我們可以通過單擊評論圖檔觸發單擊手勢來讓這些評論彈出。這實作的原理是根據擷取的評論條數來設定tableView的contentOffset,核心代碼如下:

Gif動圖:

iOS短視訊加直播:仿快手的短視訊(附近頁面)附近頁面
-(void)clickcommentImgView
{
    
    if (_commentsMutableAry.count == 0) {
        [_mainTableView setContentOffset:CGPointMake(0,  44) animated:YES];
    }else if (_commentsMutableAry.count == 1)
    {
        if (_mainTableView.contentOffset.y<44) {
            [_mainTableView setContentOffset:CGPointMake(0,  44) animated:NO];
            NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
            [_mainTableView scrollToRowAtIndexPath:scrollIndexPath
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }else
        {
            NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:0 inSection:0];
            [_mainTableView scrollToRowAtIndexPath:scrollIndexPath
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }
        
    }else if (_commentsMutableAry.count == 2)
    {
        if (_mainTableView.contentOffset.y<44) {
            [_mainTableView setContentOffset:CGPointMake(0,  44) animated:NO];
            NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:1 inSection:0];
            [_mainTableView scrollToRowAtIndexPath:scrollIndexPath
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }else
        {
            NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:1 inSection:0];
            [_mainTableView scrollToRowAtIndexPath:scrollIndexPath
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }
    }else if (_commentsMutableAry.count == 3)
    {
        if (_mainTableView.contentOffset.y<44) {
            [_mainTableView setContentOffset:CGPointMake(0,  44) animated:NO];
            NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:2 inSection:0];
            [_mainTableView scrollToRowAtIndexPath:scrollIndexPath
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }else
        {
            NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:2 inSection:0];
            [_mainTableView scrollToRowAtIndexPath:scrollIndexPath
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }
    }else if (_commentsMutableAry.count == 4)
    {
        if (_mainTableView.contentOffset.y<44) {
            [_mainTableView setContentOffset:CGPointMake(0,  44) animated:NO];
            NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:3 inSection:0];
            [_mainTableView scrollToRowAtIndexPath:scrollIndexPath
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];
        }else
        {
            NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:3 inSection:0];
            [_mainTableView scrollToRowAtIndexPath:scrollIndexPath
                                  atScrollPosition:UITableViewScrollPositionBottom animated:YES];

        }
    }else
    {
        [_mainTableView setContentOffset:CGPointMake(0, ScreenHeight - 64) animated:YES];
    }
//    [_mainTableView setContentOffset:CGPointMake(0, ScreenHeight - 64) animated:YES];
}
           

還可以通過滾動tableView來看到評論,這種方式就不說了,但是此時我們可以注意到在最下方出現了一個可以輸入評論的框,

這是因為一開始可輸入的評論框設定對于self.view的offset為44,即在目前螢幕下方。代碼如下:

[_commentsTextFieldBar mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.view);
        make.height.equalTo(@(44));
        make.bottom.equalTo(self.view).offset(44);
    }];
           

在滾動的時候,我們通過滾動的tableView的contentOffset改變了評論框的offset,并且同時改變了最上方的navigationBar的透明度 ,核心代碼如下:

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
        float y = scrollView.contentOffset.y;
   
    if (y>=0 && y<=44) {
         NSLog(@"scrollViewDidScroll andcontentOfyValue:%f",y);
        [_commentsTextFieldBar mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(self.view).offset(44-y);
        }];
        [_mainTableView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(self.view).offset(-y);
        }];
        [self.view layoutIfNeeded];
        
    }
    if (y < 0) {
        [_commentsTextFieldBar mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(self.view).offset(44);
        }];
        [_mainTableView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(self.view).offset(0);
        }];
        [self.view layoutIfNeeded];

    }
    if (y> 44) {
        [_commentsTextFieldBar mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(self.view).offset(0);
        }];
        [_mainTableView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(self.view).offset(-44);
        }];
        [self.view layoutIfNeeded];
    }
        float alphaValue = (y/ScreenHeight);
        _visualEffectView.alpha = alphaValue;
}
           

當我們輸入文字的時候,文字會高亮,并會提示,核心代碼如下:

Gif動圖:

iOS短視訊加直播:仿快手的短視訊(附近頁面)附近頁面
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(textFieldEditChanged:)                                              name:@"UITextFieldTextDidChangeNotification" object:_commentsTextField];
           
-(void)textFieldEditChanged:(NSNotification *)obj{
    UITextField *textField = (UITextField *)obj.object;
    NSString *toBeString = textField.text;
    
    //擷取高亮部分
    UITextRange *selectedRange = [textField markedTextRange];
    UITextPosition *position = [textField positionFromPosition:selectedRange.start offset:0];
    
    // 沒有高亮選擇的字,則對已輸入的文字進行字數統計和限制
    if (!position)
    {
        if (toBeString.length > MAX_STARWORDS_LENGTH)
        {
            NSRange rangeIndex = [toBeString rangeOfComposedCharacterSequenceAtIndex:MAX_STARWORDS_LENGTH];
            if (rangeIndex.length == 1)
            {
                textField.text = [toBeString substringToIndex:MAX_STARWORDS_LENGTH];
            }
            else
            {
                NSRange rangeRange = [toBeString rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, MAX_STARWORDS_LENGTH)];
                textField.text = [toBeString substringWithRange:rangeRange];
            }
        }
    }
}
           

點選發送時會将輸入的評論發送出去,并在tableView上顯示,實作的核心代碼如下:

-(void)ClicksendCommentsBtn
{
    
    NSLog(@"發送%@",_commentsTextField.text);
    if ([self isEmpty:_commentsTextField.text]) {
        return;
    }
    NSString* newContentStr;
    if (_placeholderStr.length>0) {
        newContentStr = [_placeholderStr stringByAppendingString:_commentsTextField.text];
    }else
    {
        newContentStr = _commentsTextField.text;
    }
    
    CommentDataModel* data = [CommentDataModel new];
    data.selfNickName = @"Alan Zhang";
    data.createdTime = @"剛剛";
    data.content = newContentStr;
    data.faceurl = @"http://p3.pstatp.com/live/100x100/21690003e9cf762985e3.jpg"/*  [[NSBundle mainBundle] pathForResource:@"usericon01" ofType:@"png"]*/;
    [_commentsMutableAry insertObject:data atIndex:0];
    NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [indexPaths addObject: indexPath];
    [_mainTableView beginUpdates];
    [_mainTableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationLeft];
    [_mainTableView endUpdates];
    
    [_commentsTextField setText:@""];
    [_commentsTextField resignFirstResponder];
    _sendCommentsBtn.enabled = NO;
    _sendCommentsBtn.backgroundColor = [UIColor grayColor];
    
    int commentCount = [_commentLabel.text intValue];
    _commentLabel.text = [NSString stringWithFormat:@"%d",++commentCount];
}
           

這裡要注意到重新整理tableView使用的是beginUpdates和endUpdates,使用這個的原因在于

1)使用beginUpdates和endUpdates可以在改變一些行(row)的高度時自帶動畫,并且不需要Reload row(不用調用cellForRow,僅僅需要調用heightForRow,這樣效率最高)

2)在beginUpdates和endUpdates中執行insert,delete,select,reload row時,動畫效果更加同步和順滑,否則動畫卡頓且tableView的屬性(如row count)可能會失效 

我們其實還可以通過單擊tableHeaderView左下角的顯示"?寫評論..."的Label,來觸發彈出輸入評論框的手勢,核心代碼如下:

UITapGestureRecognizer* tapGesture2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showkeyboard)];
    [writeBgView addGestureRecognizer:tapGesture2];
           
-(void)showkeyboard
{
    
    [_commentsTextField becomeFirstResponder];
}
           

接下來我要詳細的介紹下這裡使用播放短視訊的開源三方架構WMPlayer,我沒有使用和上一篇抖音一樣的播放器,那是因為我感覺既然是嘗試去做,就要把所有可以用的開源播放器都要嘗試用一遍,首先我們要對它進行初始化,并開始播放短視訊,

核心代碼如下:

_wmPlayer  = [[WMPlayer alloc]initWithFrame:CGRectMake(0, 0, ScreenWidth, ScreenHeight) videoURLStr:_DataModel.video_url];
    [headerView addSubview:_wmPlayer];
    _wmPlayer.closeBtn.hidden = YES;
    _wmPlayer.bottomView.hidden = YES;
    _wmPlayer.fullScreenBtn.hidden = YES;
    _wmPlayer.backgroundColor = [UIColor clearColor];
    [_wmPlayer play];//開始播放
           

可以看到我們可以通過輕按兩下來實作視訊的暫停和播放,也可以通過點選暫停後顯示出來的按鈕繼續播放,這就要涉及到修改WMPlayer内部的代碼了,修改如下:

Gif動圖:

iOS短視訊加直播:仿快手的短視訊(附近頁面)附近頁面
- (void)PlayOrPause:(UIButton *)sender{
    if (self.durationTimer==nil) {
        self.durationTimer = [NSTimer timerWithTimeInterval:0.2 target:self selector:@selector(finishedPlay:) userInfo:nil repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:self.durationTimer forMode:NSDefaultRunLoopMode];
    }
    
    if (self.player.rate != 1.f) {
        if ([self currentTime] == [self duration])
            [self setCurrentTime:0.f];
        sender.selected = NO;
        [self.player play];
        //Alan add start
        self.playOrPauseBtn.hidden = YES;
        //Alan add end
    } else {
        sender.selected = YES;
        [self.player pause];
    }
    
    //    CMTime time = [self.player currentTime];
}
           
- (void)handleDoubleTap{
    [[NSNotificationCenter defaultCenter] postNotificationName:WMPlayerDoubleTapNotification object:nil];
    if (self.player.rate != 1.f) {
        if ([self currentTime] == self.duration)
            [self setCurrentTime:0.f];
        [self.player play];
        self.playOrPauseBtn.selected = NO;
        //Alan add start
        self.playOrPauseBtn.hidden = YES;
        //Alan add end
    } else {
        [self.player pause];
        self.playOrPauseBtn.selected = YES;
        //Alan add start
        self.playOrPauseBtn.hidden = NO;
        //Alan add end
    }
}
           
self.playOrPauseBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        self.playOrPauseBtn.showsTouchWhenHighlighted = YES;
        [self.playOrPauseBtn addTarget:self action:@selector(PlayOrPause:) forControlEvents:UIControlEventTouchUpInside];
        [self.playOrPauseBtn setImage:[UIImage imageNamed:WMVideoSrcName(@"pause")] ?: [UIImage imageNamed:WMVideoFrameworkSrcName(@"pause")] forState:UIControlStateNormal];
        [self.playOrPauseBtn setImage:[UIImage imageNamed:WMVideoSrcName(@"play")] ?: [UIImage imageNamed:WMVideoFrameworkSrcName(@"play")] forState:UIControlStateSelected];
        //Alan add start
//        [self.bottomView addSubview:self.playOrPauseBtn];
        [self addSubview:self.playOrPauseBtn];
        //Alan add end
        //autoLayout _playOrPauseBtn
        [self.playOrPauseBtn mas_makeConstraints:^(MASConstraintMaker *make) {
//            make.left.equalTo(self.bottomView).with.offset(0);//Alan change
            //Alan add start
            make.centerX.equalTo(self);
            make.centerY.equalTo(self);
            //Alan add end
            make.height.mas_equalTo(40);
//            make.bottom.equalTo(self.bottomView).with.offset(0);//Alan change
            make.width.mas_equalTo(40);
            
        }];
        
        //Alan add start
        self.playOrPauseBtn.hidden = YES;
        //Alan add end
           

以上代碼的修改就可以實作視訊的暫停和繼續播放了。那我們是如何來實作循環播放的呢?主要是通過WMPlayerFinishedPlayNotification這個表示視訊播放完成的key去通知視訊再播放一遍。核心代碼如下:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(finishPlayer) name:WMPlayerFinishedPlayNotification object:nil];
           
-(void) finishPlayer
{
    [_wmPlayer play];
}
           

并且當點選正在播放的視訊時,假如輸入評論框已經彈起了會落下,核心代碼如下:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clickOneWMPlayer) name:WMPlayerSingleTapNotification object:nil];
           
-(void)clickOneWMPlayer
{
    [self Actiondo:nil];
}
           
-(void)Actiondo:(id)sender{
    [_commentsTextField resignFirstResponder];
}
           

當點選退出播放短視訊頁面時,一定要注意釋放WMPlayer對象并移除相關的觀察者,切記。核心代碼如下:

[_wmPlayer.player.currentItem cancelPendingSeeks];
    [_wmPlayer.player.currentItem.asset cancelLoading];
    [_wmPlayer pause];
    
    //移除觀察者
    [_wmPlayer.currentItem removeObserver:_wmPlayer forKeyPath:@"status"];
    
    [_wmPlayer removeFromSuperview];
    [_wmPlayer.playerLayer removeFromSuperlayer];
    [_wmPlayer.player replaceCurrentItemWithPlayerItem:nil];
    _wmPlayer.player = nil;
    _wmPlayer.currentItem = nil;
    //釋放定時器,否側不會調用WMPlayer中的dealloc方法
    [_wmPlayer.autoDismissTimer invalidate];
    _wmPlayer.autoDismissTimer = nil;
    [_wmPlayer.durationTimer invalidate];
    _wmPlayer.durationTimer = nil;
    
    _wmPlayer.playOrPauseBtn = nil;
    _wmPlayer.playerLayer = nil;
    _wmPlayer = nil;
           

綜上,一個完整的快手短視訊就實作完畢了,下一篇我就會向大家介紹如何做一個完全開源的直播。