[iOS]JPVideoPlayer 3.0 使用介绍

作者: e2f2d779c022 | 来源:发表于2018-04-12 00:51 被阅读3924次

    01. 引言

    大家好,我是 NewPan,好久没冒泡了,去年下半年不加班的时间里,我一直在研究如何实现基于 AVPlayer实现视频支持拖拽进度的边下载边播放。这个过程缓慢又辛酸,中途数次看不到希望,差点放弃,但是最后还是坚持了下来,于是就有了现在全新的 3.0 版本。这次会分两篇文章讲解,第一篇是 3.0 的使用介绍,是写给那些只需知道如何使用的同学,接下来按照惯例,我会介绍源码的实现。

    首先,我们来看一下全新 3.0 版本的新特性。对了,GitHub 地址在这里

    02. 新版本新特性

    这些特性基本涵盖了做视频播放的各方面,其中最重要的,也是这个框架价值所在,就是基于 AVPlayer实现了边下边播,同时支持断点续传。

    • 边下边播支持
    • 拖拽进度支持(new)
    • 断点续传支持(new)
    • 假横屏 auto-layout 布局支持(new)
    • 继承协议自定义播放控制界面支持(new)
    • 同一 URL 不重复下载支持
    • 保证不阻塞主线程
    • 本地视频播放播放支持
    • Swift 支持

    03. 新版本使用介绍

    由于这个框架最开始的时候就是为列表播放视频设计的,3.0 版本中这一点也得到了延续。框架对外提供了 3 类 UIView 的分类方法,保证不侵入你的项目。

    03.1 静音播放

    这个情况适合在列表中跟随用户的滑动,对应的播放某个 cell 上的视频,就像微博列表页视频播放一样。这种情况没有任何对视频的控制界面,只有一个缓冲进度条和播放进度条,就像下面这样:

    要实现这个功能,只需要调用下面这个方法就可以了:

    NSURL *url = [NSURL URLWithString:@"http://p11s9kqxf.bkt.clouddn.com/bianche.mp4"];
    [aview jp_playVideoMuteWithURL:url
                bufferingIndicator:nil
                      progressView:nil
           configurationCompletion:nil];
    

    这个方法有四个参数,第一个不用说了,第二个是视频缓冲指示器,第三个是缓冲和播放进度条,第四个是配置完视频以后的一些操作回调。

    但是在这个接口,除了第一个必选参数外,其他三个你都可以传空,因为框架为你实现了默认的视图,同时你也可以继承我提供的模板类进行快速的自定义。关于这点,我在下面会提到。

    配套的,还有下面这个方法。

    NSURL *url = [NSURL URLWithString:@"http://p11s9kqxf.bkt.clouddn.com/bianche.mp4"];
    [aview jp_resumeMutePlayWithURL:url
                 bufferingIndicator:nil
                       progressView:nil
            configurationCompletion:nil];
    

    这个方法是什么意思呢?我们在视频列表页播放,当用户选中了某一个 cell 的时候会跳转到对应的视频详情页,这个时候就轮到这个方法上场了。因为如果你直接使用上面那个方法来播放的话,视频会重头播,这样破坏了用户体验,而你调用这个方法,就可以连贯的开始播放。

    同时这个方法中,你仍然可以定制自己的界面,而不是必须和上个界面的控制界面一样,小棉袄贴心吧?

    03.2 带控制界面的播放

    这个功能在视频详情页是必须的。这个时候除了视频图像一般还配套的有缓冲动画、播放进度以及控制视频界面。就像下面这样。

    这个功能的接口是:

    NSURL *url = [NSURL URLWithString:@"http://p11s9kqxf.bkt.clouddn.com/bianche.mp4"];
    [aview jp_playVideoWithURL:url
            bufferingIndicator:nil
                   controlView:nil
                  progressView:nil
       configurationCompletion:nil];
    

    和上一个类型的方法没有太多不同,就是多了一个参数,多了一个 controlView这个是和用户交互的那个界面。

    配套的,还有一个恢复播放的方法,比方上面说的从视频列表进入到视频详情,在视频列表使用的是静音带缓存和播放进度的方法进行播放,当用户点击某个视频的时候,进入到视频详情页就是开始恢复播放,这个界面带有用户控制 controlView 界面,而且还有横屏按钮。就像下面这样。

    这个 API 是:

    NSURL *url = [NSURL URLWithString:@"http://p11s9kqxf.bkt.clouddn.com/bianche.mp4"];
    [aview jp_resumePlayWithURL:url
             bufferingIndicator:nil
                    controlView:nil
                   progressView:nil
        configurationCompletion:nil];
    

    03.3 只有视频

    这种也是比较常见的,比方说悬停播放,在视频详情页,除了视频,还有评论什么的,这时用户滑动列表页,有些就会使用悬停播放,此时视频不需要任何进度或者控制界面。

    这个功能的接口是:

    NSURL *url = [NSURL URLWithString:@"http://p11s9kqxf.bkt.clouddn.com/bianche.mp4"];
    [aview jp_playVideoWithURL:url
               options:kNilOptions
       configurationCompletion:nil];
    

    配套的恢复播放也有一个接口:

    NSURL *url = [NSURL URLWithString:@"http://p11s9kqxf.bkt.clouddn.com/bianche.mp4"];
    [aview jp_resumePlayWithURL:url
                options:kNilOptions
        configurationCompletion:nil];
    

    有了这些以后,我们就可以实现下面的悬停播放功能。

    04. 基于 JPVideoPlayer 快速搭建流行视频 APP

    下面我用 demo 来示范如何基于 JPVideoPlayer 快速搭建抖音、微博等流行 APP 的视频播放界面。

    04.1 抖音

    博主也中了抖音的毒,且毒入骨髓,已无药可救,“c哩c哩”,“海草舞”来一发。下面的 demo 的结构是这样的,一个 scrollView 上面添加三个 imageView,开始的时候设置 scrollView 滚到中间那个 imageView,以后每次用户滑动完屏幕,将 scrollView 复位到这个状态。

    - (void)viewDidAppear:(BOOL)animated {
        [super viewDidAppear:animated];
        self.scrollViewOffsetYOnStartDrag = -100;
        [self scrollViewDidEndScrolling];
    }
    
    - (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];
        [self.secondImageView jp_stopPlay];
    }
    
    #pragma mark - UIScrollViewDelegate
    
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView
                      willDecelerate:(BOOL)decelerate {
        if (decelerate == NO) {
            [self scrollViewDidEndScrolling];
        }
    }
    
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
        [self scrollViewDidEndScrolling];
    }
    
    - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
        self.scrollViewOffsetYOnStartDrag = scrollView.contentOffset.y;
    }
    
    #pragma mark - JPVideoPlayerDelegate
    
    - (BOOL)shouldShowBlackBackgroundBeforePlaybackStart {
        return YES;
    }
    
    #pragma mark - Private
    
    - (void)scrollViewDidEndScrolling {
        if(self.scrollViewOffsetYOnStartDrag == self.scrollView.contentOffset.y){
            return;
        }
    
        CGSize referenceSize = UIScreen.mainScreen.bounds.size;
        [self.scrollView setContentOffset:CGPointMake(0, referenceSize.height) animated:NO];
        [self.secondImageView jp_stopPlay];
        [self.secondImageView jp_playVideoMuteWithURL:[self fetchDouyinURL]
                                   bufferingIndicator:nil
                                         progressView:[JPDouyinProgressView new]
                              configurationCompletion:^(UIView *view, JPVideoPlayerModel *playerModel) {
                                  view.jp_muted = NO;
                              }];
    }
    
    - (NSURL *)fetchDouyinURL {
        if(self.currentVideoIndex == (self.douyinVideoStrings.count - 1)){
            self.currentVideoIndex = 0;
        }
        NSURL *url = [NSURL URLWithString:self.douyinVideoStrings[self.currentVideoIndex]];
        self.currentVideoIndex++;
        return url;
    }
    

    初始化的代码我没拷过来,这些代码里还有百分之七十是用户滚动的判断操作,其实播放视频就只有一行代码。

    [self.secondImageView jp_playVideoMuteWithURL:[self fetchDouyinURL]
                                   bufferingIndicator:nil
                                         progressView:[JPDouyinProgressView new]
                              configurationCompletion:^(UIView *view, JPVideoPlayerModel *playerModel) {
                                  view.jp_muted = NO;
                              }];
    

    这里使用了静音播放,为什么呢?因为这个接口默认不显示视频控制界面。注意,这里在 configurationCompletion 里设置了视频不要静音播放,为什么呢?因为播放视频的初始化并非是同步操作,内部还需要在子线程查视频数据等一系列操作以后才会切回主线程,所以要等播放视频初始化以后再去操作播放器,这样才有效。

    这里还有一个自定义的 progressView,这个是啥呢,因为默认 JPVideoPlayerProgressView 的缓存和播放进度条是加载 view 的最下方,而抖音是显示在 tabBar 上方,所以我们要继承 JPVideoPlayerProgressView 重新布局。

    @interface JPDouyinProgressView: JPVideoPlayerProgressView
    
    @end
    
    @implementation JPDouyinProgressView
    
    - (void)layoutThatFits:(CGRect)constrainedRect
    nearestViewControllerInViewTree:(UIViewController *_Nullable)nearestViewController
      interfaceOrientation:(JPVideoPlayViewInterfaceOrientation)interfaceOrientation {
        [super layoutThatFits:constrainedRect
    nearestViewControllerInViewTree:nearestViewController
                interfaceOrientation:interfaceOrientation];
    
        self.trackProgressView.frame = CGRectMake(0,
                constrainedRect.size.height - JPVideoPlayerProgressViewElementHeight - nearestViewController.tabBarController.tabBar.bounds.size.height,
                constrainedRect.size.width,
                JPVideoPlayerProgressViewElementHeight);
        self.cachedProgressView.frame = self.trackProgressView.bounds;
        self.elapsedProgressView.frame = self.trackProgressView.frame;
    }
    
    @end
    

    注意,如果使用 frame 布局,那么布局代码一定要写在框架提供的布局方法里,因为如果使用横屏的时候,view 要重新布局,只有写在这个方法里,布局代码才会被执行到。

    注意,这里有三个参数。第一个是布局的约束大小,一般是父控件的 bounds。第二个参数是当前这个 view 所在的控制器,可能为空。第三个参数是当前 view 的屏幕方向,可能会是横屏,也有可能是竖屏,你可能拿到这个状态值进行对应的布局。

    - (void)layoutThatFits:(CGRect)constrainedRect
    nearestViewControllerInViewTree:(UIViewController *_Nullable)nearestViewController
      interfaceOrientation:(JPVideoPlayViewInterfaceOrientation)interfaceOrientation;
    

    如果使用 autoLayout 布局则没有要求一定要将布局写在这个方法里。

    04.2 微博

    上个版本不支持不等高 cell 的滑动播放,其实大多数场景都是不等高 cell。也不支持恢复播放,进度详情界面以后就需要重头开始播,用户体验不是很好。

    这个版本不仅解决了这两个大问题,还同时带来了拖拽进度和两种滑动判断策略。一起来看下。

    要实现上面的功能,大致需要这些代码。

    - (void)viewDidLayoutSubviews {
        [super viewDidLayoutSubviews];
    
        CGRect tableViewFrame = self.tableView.frame;
        tableViewFrame.size.height -= self.tabBarController.tabBar.bounds.size.height;
        self.tableView.jp_tableViewVisibleFrame = tableViewFrame;
    }
    
    - (void)viewDidAppear:(BOOL)animated{
        [super viewDidAppear:animated];
    
        [self.tableView jp_handleCellUnreachableTypeInVisibleCellsAfterReloadData];
        [self.tableView jp_playVideoInVisibleCellsIfNeed];
    
        // 用来防止选中 cell push 到下个控制器时, tableView 再次调用 scrollViewDidScroll 方法, 造成 playingVideoCell 被置空.
        self.tableView.delegate = self;
    }
    
    - (void)viewWillDisappear:(BOOL)animated{
        [super viewWillDisappear:animated];
    
        // 用来防止选中 cell push 到下个控制器时, tableView 再次调用 scrollViewDidScroll 方法, 造成 playingVideoCell 被置空.
        self.tableView.delegate = nil;
    }
    
    #pragma mark - Data Srouce
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        JPVideoPlayerWeiBoEqualHeightCell *cell = ...;
        cell.jp_videoURL = [NSURL URLWithString:self.pathStrings[indexPath.row]];
        cell.jp_videoPlayView = cell.videoPlayView;
        [tableView jp_handleCellUnreachableTypeForCell:cell
                                           atIndexPath:indexPath];
        return cell;
    }
    
    
    #pragma mark - TableView Delegate
    
    /**
     * Called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
     * 松手时已经静止, 只会调用scrollViewDidEndDragging
     */
    - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
        [self.tableView jp_scrollViewDidEndDraggingWillDecelerate:decelerate];
    }
    
    /**
     * Called on tableView is static after finger up if the user dragged and tableView is scrolling.
     * 松手时还在运动, 先调用scrollViewDidEndDragging, 再调用scrollViewDidEndDecelerating
     */
    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
        [self.tableView jp_scrollViewDidEndDecelerating];
    }
    
    - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
        [self.tableView jp_scrollViewDidScroll];
    }
    
    
    #pragma mark - JPTableViewPlayVideoDelegate
    
    - (void)tableView:(UITableView *)tableView willPlayVideoOnCell:(UITableViewCell *)cell {
        [cell.jp_videoPlayView jp_resumeMutePlayWithURL:cell.jp_videoURL
                                     bufferingIndicator:nil
                                           progressView:nil
                                configurationCompletion:nil];
    }
    

    框架给 UITableView 添加了分类方法,用户处理滑动列表滑动播放视频,但凡是这个分类中标注了必须调用的方法,就需要在正确的位置正确的调用,否则滑动播放的逻辑就不能正常工作。

    这个是告诉框架,当前这个 tableView 可见区域的属性,这个属性是决定当用户滑动停止的时候这个 tableView 的中心在哪里,必须要正确的赋值。

     CGRect tableViewFrame = self.tableView.frame;
        tableViewFrame.size.height -= self.tabBarController.tabBar.bounds.size.height;
        self.tableView.jp_tableViewVisibleFrame = tableViewFrame;
    

    每次对 tableView 进行 reloadData 操作以后,都需要调用这个方法。这个方法是对 tableView 的 cell 进行是否是滑动不可及的判断的,如果 [self.tableView jp_playVideoInVisibleCellsIfNeed]; 这样代码没有生效,那肯定是你忘记调用下面这个方法了。

    [self.tableView jp_handleCellUnreachableTypeInVisibleCellsAfterReloadData];
    

    下面这些属性也必须赋值。

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        JPVideoPlayerWeiBoEqualHeightCell *cell = ...;
        cell.jp_videoURL = [NSURL URLWithString:self.pathStrings[indexPath.row]];
        cell.jp_videoPlayView = cell.videoPlayView;
        [tableView jp_handleCellUnreachableTypeForCell:cell
                                           atIndexPath:indexPath];
        return cell;
    }
    

    然后就是在 scrollView 的代理方法中告诉框架对应的代理行为,当确定需要播放视频的时候,框架会通过 - (void)tableView:(UITableView *)tableView willPlayVideoOnCell:(UITableViewCell *)cell; 这个代理方法告诉外界,你可以在这个方法里选择想要的方式进行视频播放。

    05. 自定义进度和控制 view

    定制 view 非常简单。你只需要继承对应的模板类进行一系列界面的自定义就可以快速实现。下面是这些模板类的类名。

    缓冲动画指示器:JPVideoPlayerBufferingIndicator
    播放和缓冲进度指示器:JPVideoPlayerProgressView
    控制界面:JPVideoPlayerControlView

    当然,如果你不想使用这些模板类,想要自己从头搭建,也是很方便的,而且能完全和播放逻辑解耦。你只需要实现对应的协议即可。

    缓冲动画指示器:<JPVideoPlayerBufferingProtocol>
    播放和缓冲进度指示器:<JPVideoPlayerProtocol>
    控制界面:<JPVideoPlayerProtocol>

    需要注意的是,对视频的横屏并没有真正的将窗口横过来,这是对国内 APP 现状的平衡,国内大多数 APP 都只支持竖屏,优酷 APP、腾讯视频 APP、哔哩哔哩 APP 等都是采用这种方式进行横屏。如果你关心这内部的实现,请你去看一下源码,这篇文章不进行讲解。

    06. 缓存管理

    非常感谢有些同学是从 2.0 版本一路支持过来的,由于 3.0 对缓存的管理完全重构,缓存路径改了,之前的缓存用不了了。所以我提供了 -clearVideoCacheOnVersion2OnCompletion: 方法来清理掉旧的缓存。

    缓存内部实现改了,但是对外查询管理的接口没有改变,具体请查看接口文档。对了,GitHub 地址在这里

    下篇文章在这里 [iOS]JPVideoPlayer 3.0 源码解析

    我的文章集合

    下面这个链接是我所有文章的一个集合目录。这些文章凡是涉及实现的,每篇文章中都有 Github 地址,Github 上都有源码。

    我的文章集合索引

    你还可以关注我自己维护的简书专题 iOS开发心得。这个专题的文章都是实打实的干货。如果你有问题,除了在文章最后留言,还可以在微博 @盼盼_HKbuy上给我留言,以及访问我的 Github

    相关文章

      网友评论

      • 90后的晨仔:您好,请问怎么播放本地音频,可以控制播放本地音频的次数吗?
      • 哈哈菇凉:m3u8文件是不是 不支持?无法播放
      • 后知后觉空想家:可以支持手势拖拽进度吗?还有播放按钮和全屏按钮不太好点击。
      • Big_black:cell中播放视频时 执行reloadcell播放器消失 但是视频还在播放 这需要怎么解决 谢谢
      • 陈大帅:大神,暴露的方法里有没有横屏的回调接口?我需要知道他现在是否是横屏状态的
      • 天空晴朗_7c39:这个非常好,我用到了 我的swift项目里了,但是怎么都出现不了,默认JPVideoPlayerControlView,
      • 小菜99:- (void)savePlaybackElapsedSeconds:(double)elapsedSeconds
        forVideoURL:(NSURL *)videoURL {
        NSParameterAssert(videoURL);

        调用view jp_stopPlay
        怎么解决
        小菜99:@NewPan 感谢回复,这个方法已经实现过了,return NO, 目前是播放完视频还停留在view上面,我是想播放完之后,把视频界面移除掉,
        e2f2d779c022:@小菜99 /**
        * Controls which video should automatic replay when the video is play completed.
        *
        * @param videoURL the url of the video to be play.
        *
        * @return Return NO to prevent replay for the video. If not implemented, YES is implied.
        */
        - (BOOL)shouldAutoReplayForURL:(nonnull NSURL *)videoURL;
        小菜99:只播放一遍,播放完成后从view上面移除,大佬怎么弄,没有找到相关的移除方法
        - (void)playerStatusDidChanged:(JPVideoPlayerStatus)playerStatus
        在这个代理方法里面 判断 JPVideoPlayerStatusStop 后调用jp_stopPlay 会崩,只能遍历view,把里面东西移掉
      • Obsession丶执:盼神您好,急需请教一下我将您的播放器集成到RN的项目里,界面已经出来了,就是视频播放不了,求帮忙!在线等
      • 8165eb26cacf:你好,我先在遇到个问题,http://askzhu2.oss-cn-hangzhou.aliyuncs.com/media/HUIAFLORYMLTIYWI4119201818783.mp4,这个连接播放不了,但是在网页上又可以,找了很久问题也没找到,请求帮助,谢谢:joy:
        8165eb26cacf:@NewPan 恩,谢谢,我问题解决了。视频怎么支持iphoneX全屏呢
        e2f2d779c022:@snialwar 这个地址,服务器不支持断点续传。
      • 菜先生:您好,请问我设置了状态栏横屏怎么没效果?
        [UIApplication sharedApplication].statusBarOrientation = UIInterfaceOrientationLandscapeLeft;
      • coderST:您好大神,请问一下,在你的工程中抖音部分,缓冲ProgressView, 可以自定义吗? 我看demo是添加到了scrollView中,我想就固定到当前的view中,不随scrollView滚动,可以吗?
      • 滚来滚去的桔子:感谢博主提供框架,代码风格不太适应,在缓慢学习中。。。想问下支持 flv 格式的播放吗?如果要播 swf 格式的,博主有什么建议吗?
      • 竹我:博主你好,你的库能够添加可以,添加Token的接口?因为有些安全机制下播放的视频是需要Token的
      • 90后的晨仔:您好博主,请问播放音频时,有时候比较慢应该怎么优化?
      • WGGHot:播放完第一个就自动播放下一个,能设置吗
        WGGHot:@NewPan configurationCompletion???完全不知道怎么设置呐
        e2f2d779c022:@wzzer 播放完有一个回调
      • WGGHot:reason: '*** -[NSURL initFileURLWithPath:]: nil string parameter'
      • 倔一:楼主,你的缓冲进度控制有bug,连续几次拉动时间,前进或后退,有时候会一直出现缓冲动画不消失,还有时候在播放中,缓冲动画还在。
      • 倔一:楼主,在吗,出现加载中的时候一直是黑屏,然后始终无法再加载出来内容。
      • 呐小伟:能交互不能滑动 能滑动不能交互:unamused: 什么原因啊 博主?
      • 67faed13548f:使用2.0版本的项目 要升级到3.0有什么好的建议
      • 呐小伟:在这个JPVideoPlayerProgressView下,此viewWillAddToSuperView此协议方法自定义UI,点击事件被拦截,userInteractionContainerView这个类不可以隐藏么
      • 倔一:楼主,你的框架有没有中文文档,要修改成既支持点击播放,又支持滑动播放的。发现代码很多地方不好改。
      • ZhangCc_:全屏下,左右滑动无法调节播放进度,左侧1/2位置上下滑动无法调节屏幕亮度,右侧1/2位置上下滑动无法调节音量?这些功能还没做是吗?
      • ZhangCc_:你的注释能不能加上中文的啊,英文虽然看得懂,但是看得慢啊。。。
      • 倔一:楼主,自定义了JPVideoPlayerControlView,为什么默认按钮都是隐藏的。
      • 倔一:楼主你好,请教下。列表播放视频,没有记住上一次的播放时间,每次都是重新播放。是没有实现还是需要调取别的方法。
      • 倔一:楼主你好。谢谢分享。在tableview列表中使用 [cell.jp_videoPlayView jp_resumePlayWithURL:cell.jp_videoURL
        bufferingIndicator:nil
        controlView:[[JPVideoPlayerControlView alloc] initWithControlBar:nil blurImage:nil]
        progressView:nil
        configurationCompletion:nil]; cell手势和视频控制区域的点击冲突,用网上的方法无法解决,请问该怎么处理。
        低调_哲:@倔一 兄弟 cell 必须用他的cell吗 自己的cell可以实现吗
        倔一:已解决,加上 cell.videoPlayView.userInteractionEnabled = YES;
      • 老骚鹅:如果项目中已经有现有的播放器,只是想使用作者的边下边播功能,大家知道怎么弄吧,我看代码看的脑子都乱了,不知道从何下手
      • 爱说故事的聪啊:来支持大神!
        e2f2d779c022:@刀百辟心不易 谢谢请我喝水:smile:
      • 我想静静_6df0:从2.0升级过来的,首先感谢楼主无私的分享。但是目前我遇到了两个问题,希望得到大佬的解答。1:每次播放一个视频,开始播放前,都要黑大概0.5秒,才能显示图像,我看默认播放视图是透明的,可以自己设置黑色,但是我设置的是透明的。2:cacheType总是JPVideoPlayerCacheTypeFragment,是我哪里使用不对吗?感谢回答
        努力的小小四:播放视频前都会黑闪,最好怎么解决的?
        JackerooChu:大佬,首先收下我膜拜的膝盖,其次我发现悬停播放的时候,我点击了暂停,然后滑动UITableView的时候,小窗口是从头开始播放的,这个时候回到顶部的时候,视频也是从头开始播放的,这个怎么处理呢?
        e2f2d779c022:@我想静静_6df0 去 GitHub 上提交 issue,把你怎么使用的描述一下。
      • 动感超人丶:框架真尼玛吊啊。楼组再讲讲FFmpeg吧
        e2f2d779c022:@动感超人丶 之前研究过一段时间,但是是 ijk,后台考虑平台特性没有选择。
      • PGOne爱吃饺子:支持一波,楼主现在的主流视频框架都是基于AVPlayer这个来实现的么
      • c2fffd2b0090:支持一波~
        e2f2d779c022:@打了鸡血 蟹蟹
      • 颓阿废:我来支持大神!!
        颓阿废:@NewPan JPScrollPlayStrategyType这两个策略是什么意思能说一下吗
        e2f2d779c022:@颓阿废 是,但是 swift 的不是,swift 半年没更新了,估计已经跑不起来了。
        颓阿废:楼主,github上的demo是最新的版本吗
      • 吃蘑菇De大灰狼:感谢分享,请问博主文章末尾目录如何设置?
        WGGHot:@FFur 好啦:heart_eyes:
        吃蘑菇De大灰狼:@wzzer 文章改成专栏就行了,是简书官方的排版
        WGGHot:我也遇到这个问题,加个qq交流下
      • 西西西瓜sama:ui支持iPhone X么
        e2f2d779c022:@西西西瓜sama 必须的。
      • c77f4a115d4f:有考虑补充下提前预下载视频(设置下载大小或者全部下载),然后直接播放有下载的部分,没有下载的地方再边下边播么
        e2f2d779c022:@天才晓波 支持的,断点续传。
        c77f4a115d4f:@NewPan 现在是支持播放未缓存完的视频么,我看有JPVideoPlayerCacheTypeFragment类型
        e2f2d779c022:@天才晓波 暂时没有考虑。

      本文标题:[iOS]JPVideoPlayer 3.0 使用介绍

      本文链接:https://www.haomeiwen.com/subject/glqtkftx.html