天天看点

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;
           

综上,一个完整的快手短视频就实现完毕了,下一篇我就会向大家介绍如何做一个完全开源的直播。