iOS仿抖音上下滑动播放视频

华易安
2023-12-01

首先看下效果图

前言

上一篇文章仿写了抖音的左右滑动效果-iOS之仿抖音左右滑动效果,有兴趣的可以去GKNavigationBarViewController的demo中查看。 这篇文章主要是对抖音的上下滑动及视频播放功能做介绍。其中上下滑动用的是UIScrollview,包含3个子视图。视频播放用的是TX的独立播放器TXLiteAVSDK_Player,可实现音视频的点播、直播等功能。

demo中的视频是通过抓包获取的百度的伙拍小视频,仅供学习使用。

说明

1、上下滑动切换视图实现

主要是在UIScrollview的代理中做处理,且对滑动到第一个和最后一个时分开处理,看下代码

 
  1. - (void)scrollViewDidScroll:(UIScrollView *)scrollView {

  2. // 小于等于三个,不用处理

  3. if (self.videos.count <= 3) return;

  4. // 上滑到第一个

  5. if (self.index == 0 && scrollView.contentOffset.y <= SCREEN_HEIGHT) {

  6. return;

  7. }

  8. // 下滑到最后一个

  9. if (self.index == self.videos.count - 1 && scrollView.contentOffset.y > SCREEN_HEIGHT) {

  10. return;

  11. }

  12. // 判断是从中间视图上滑还是下滑

  13. if (scrollView.contentOffset.y >= 2 * SCREEN_HEIGHT) { // 上滑

  14. [self.player removeVideo]; // 在这里移除播放,解决闪动的bug

  15. if (self.index == 0) {

  16. self.index += 2;

  17. scrollView.contentOffset = CGPointMake(0, SCREEN_HEIGHT);

  18. self.topView.model = self.ctrView.model;

  19. self.ctrView.model = self.btmView.model;

  20. }else {

  21. self.index += 1;

  22. if (self.index == self.videos.count - 1) {

  23. self.ctrView.model = self.videos[self.index - 1];

  24. }else {

  25. scrollView.contentOffset = CGPointMake(0, SCREEN_HEIGHT);

  26. self.topView.model = self.ctrView.model;

  27. self.ctrView.model = self.btmView.model;

  28. }

  29. }

  30. if (self.index < self.videos.count - 1) {

  31. self.btmView.model = self.videos[self.index + 1];

  32. }

  33. }else if (scrollView.contentOffset.y <= 0) { // 下滑

  34. [self.player removeVideo]; // 在这里移除播放,解决闪动的bug

  35. if (self.index == 1) {

  36. self.topView.model = self.videos[self.index - 1];

  37. self.ctrView.model = self.videos[self.index];

  38. self.btmView.model = self.videos[self.index + 1];

  39. self.index -= 1;

  40. }else {

  41. if (self.index == self.videos.count - 1) {

  42. self.index -= 2;

  43. }else {

  44. self.index -= 1;

  45. }

  46. scrollView.contentOffset = CGPointMake(0, SCREEN_HEIGHT);

  47. self.btmView.model = self.ctrView.model;

  48. self.ctrView.model = self.topView.model;

  49. if (self.index > 0) {

  50. self.topView.model = self.videos[self.index - 1];

  51. }

  52. }

  53. }

  54. }

  55. 复制代码

滑动结束后开始播放

 
  1. // 结束滚动后开始播放

  2. - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {

  3. if (scrollView.contentOffset.y == 0) {

  4. if (self.currentPlayId == self.topView.model.post_id) return;

  5. [self playVideoFrom:self.topView];

  6. }else if (scrollView.contentOffset.y == SCREEN_HEIGHT) {

  7. if (self.currentPlayId == self.ctrView.model.post_id) return;

  8. [self playVideoFrom:self.ctrView];

  9. }else if (scrollView.contentOffset.y == 2 * SCREEN_HEIGHT) {

  10. if (self.currentPlayId == self.btmView.model.post_id) return;

  11. [self playVideoFrom:self.btmView];

  12. }

  13. if (self.isPushed) return;

  14. // 当只剩最后两个的时候,获取新数据

  15. if (self.currentPlayIndex == self.videos.count - 2) {

  16. [self.viewModel refreshNewListWithSuccess:^(NSArray * _Nonnull list) {

  17. [self.videos addObjectsFromArray:list];

  18. } failure:^(NSError * _Nonnull error) {

  19. NSLog(@"%@", error);

  20. }];

  21. }

  22. }

  23. 复制代码

上下滑动的处理基本就这些,如果有不懂的可以下载demo查看。

2、播放器封装

这里封装的播放器用的是腾讯的视频点播TXVodPlayer。 创建播放器

 
  1. - (TXVodPlayer *)player {

  2. if (!_player) {

  3. [TXLiveBase setLogLevel:LOGLEVEL_NULL];

  4. [TXLiveBase setConsoleEnabled:NO];

  5. _player = [TXVodPlayer new];

  6. _player.vodDelegate = self;

  7. _player.loop = YES; // 开启循环播放功能

  8. }

  9. return _player;

  10. }

  11. 复制代码

由于是多个视频切换播放,所以最好只用一个播放器,因此在切换视图后,需要播放器切换播放视图和播放地址,所以提供了下面的方法。

 
  1. - (void)playVideoWithView:(UIView *)playView url:(NSString *)url {

  2. // 设置播放视图

  3. [self.player setupVideoWidget:playView insertIndex:0];

  4. // 准备播放

  5. [self playerStatusChanged:GKDYVideoPlayerStatusPrepared];

  6. // 开始播放

  7. if ([self.player startPlay:url] == 0) {

  8. // 这里可加入缓冲视图

  9. }else {

  10. [self playerStatusChanged:GKDYVideoPlayerStatusError];

  11. }

  12. }

  13. 复制代码

播放器状态监听,可获取播放状态及进度等

 
  1. - (void)onPlayEvent:(TXVodPlayer *)player event:(int)EvtID withParam:(NSDictionary *)param {

  2. switch (EvtID) {

  3. case PLAY_EVT_PLAY_LOADING:{ // loading

  4. if (self.status == GKDYVideoPlayerStatusPaused) {

  5. [self playerStatusChanged:GKDYVideoPlayerStatusPaused];

  6. }else {

  7. [self playerStatusChanged:GKDYVideoPlayerStatusLoading];

  8. }

  9. }

  10. break;

  11. case PLAY_EVT_PLAY_BEGIN:{ // 开始播放

  12. [self playerStatusChanged:GKDYVideoPlayerStatusPlaying];

  13. }

  14. break;

  15. case PLAY_EVT_PLAY_END:{ // 播放结束

  16. [self playerStatusChanged:GKDYVideoPlayerStatusEnded];

  17. }

  18. break;

  19. case PLAY_ERR_NET_DISCONNECT:{ // 失败,多次重连无效

  20. [self playerStatusChanged:GKDYVideoPlayerStatusError];

  21. }

  22. break;

  23. case PLAY_EVT_PLAY_PROGRESS:{ // 进度

  24. if (self.status == GKDYVideoPlayerStatusPlaying) {

  25. self.duration = [param[EVT_PLAY_DURATION] floatValue];

  26. float currTime = [param[EVT_PLAY_PROGRESS] floatValue];

  27. float progress = self.duration == 0 ? 0 : currTime / self.duration;

  28. // 处理播放结束时,进度不更新问题

  29. if (progress >= 0.95) progress = 1.0f;

  30. // float buffTime = [param[EVT_PLAYABLE_DURATION] floatValue];

  31. // float burrProgress = self.duration == 0 ? 0 : buffTime / self.duration;

  32. if ([self.delegate respondsToSelector:@selector(player:currentTime:totalTime:progress:)]) {

  33. [self.delegate player:self currentTime:currTime totalTime:self.duration progress:progress];

  34. }

  35. }

  36. }

  37. break;

  38. default:

  39. break;

  40. }

  41. }

  42. 复制代码

内容比较多,如果想要具体了解,还需要下载代码查看。

最后

demo的地址:GKDYVideo,由于github的限制,播放器无法上传,所以需要下载下来后pod install即可。

相关资源:ios-iOS仿抖音上下滑动播放视频.zip-其它代码类资源

 类似资料: