iOS开发第三方控件SJVideoPlayer所遇到的问题及解决
蕾姆
github 地址
一、在 UITableView 中的使用
这种可以在UITableView上可以实现播放,就是把SJVideoPlayer加到 cell上,不是在 cell 点击跳转到另一个页面播放,一般是在 cell 展示一张视频封面的图片,然后点击图片上的播放按钮再开始播放,可以全屏。如图
实现原理:点击cell 的播放按钮的时候,可以在点击回调里面在视频封面上面加上SJVideoPlayer即可,这样SJVideoPlayer在播放视频的时候就可以把封面遮住,点击下一个视频的时候,上一个SJVideoPlayer移除的时候,封面又会展示上来,视频封面作为SJVideoPlayer的视图的父视图要加上 tag,要不 tableView 在滑动的时候会混乱
cell.videoPlayBlock = ^{
self.videoPlayerView = [SJVideoPlayer player];
[cell.coverImageView addSubview:self.videoPlayerView.view]; // coverImageView就是封面
[self.videoPlayerView.view mas_remakeConstraints:^(MASConstraintMaker *make) {
make.edges.offset(0);
}];
UIView *playerSuperview = cell.coverImageView;
// 一定要把这个SJPlayModel写上,要不然会混乱,tag 不能0,随便一个数
SJPlayModel *playModel = [SJPlayModel UITableViewCellPlayModelWithPlayerSuperviewTag:playerSuperview.tag atIndexPath:indexPath tableView:self.myTableView];
self.videoPlayerView.URLAsset = [[SJVideoPlayerURLAsset alloc] initWithURL:[NSURL URLWithString:StringEncoding(imageArray.firstObject)] playModel:playModel];
}
二、视频没播放完,退出页面或是进入下一个页面,还能发出声音,视频还在播放
开始的时候不知道,我是在viewWillDisappear里面手动调用 stop 这个方法,行是行,不过最好调用SJVideoPlayer的生命周期,可以把这个控件看作一个视图控制器,那他肯定也有生命周期,而在他的生命周期里面都写好了,只需调用下,页面消失的时候就会停止播放了
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.videoPlayerView vc_viewDidAppear];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.videoPlayerView vc_viewWillDisappear];
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.videoPlayerView vc_viewDidDisappear];
}
三、视频资源路径问题
如果其他都没问题,但还是有些视频可以播放有些不可以播放,可以考虑一下是资源路径的,我就是因为这个 App是分安卓和 iOS 端的,安卓端在上传视频的时候,视频名字不是根据时间戳命名的,是跟随系统命名的,如果视频名字含有中文,上传的成功也会有中文出现在资源的 url 上,他把这个路径传给后台,后台也没做处理,所以我们拿到的时候也是有中文的,这个控件是不支持含有中文的url的,这时我们可以自己转化一下
urlString = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]
四、旋转问题
首先这个控件如果视频是竖屏的视频,点击全屏的时候,他会全屏但他是不会旋转的,所以这个可以不考虑,主要考虑,如果播放的视频是横屏的时候,点击全屏的时候,要手机旋转,但其他页面你不想它旋转。
- 情况一
如果你的App的根控制器是固定由一个 UITabBarController组成,那么简单,继承UITabBarController那个控制器里面重写支不支持旋转的方法,
//不支持旋转
-(BOOL)shouldAutorotate{
return NO;
}
重写了这个方法后,那么在UITabBarController子类控制器所有的子控制器,都不会旋转了,但App旋不旋转那肯定还要另外设置,App如果不支持旋转,那你再怎么设置也没用,
(1)可以直接在工程里面设置
设置
(2)可以在 AppDelegate里面设置,直接添加以下方法
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
这样就可以做到其他页面不旋转,只要全屏的时候旋转,如果这样点全屏还是无法全屏,并且页面还会卡住,如果使用Masonry约束该控件的还会在Masonry里面崩溃,NSAssert(closestCommonSuperview, @"couldn't find a common superview for %@ and %@", self.firstViewAttribute.view, self.secondViewAttribute.view);,找不到父视图什么的,像我这个,视频控件是在首页里面的子控制器里面的,如果点了快聊和我的,再进去首页子控制器点击视频全屏又是可以的,应该和和导航栏有关的,或者是导航栏的这个第三方EasyNavigation的问题,具体原因不清楚,猜测是没点击快聊和我的页面之前,它们的导航栏是还没有加载出来的,而在点击视频全屏的时候,有用到其他页面的导航栏还是什么的,具体原因不知道,或者只是我的问题,解决方法是在 Tabbar 的控制器里面,在初始化导航栏控制器,把他添加到 Tabbar 的时候,把导航栏控制器视图的透明度设置为1
UIViewController *viewController = [[NSClassFromString(arrVC[i]) alloc]init];
UINavigationController *navi = [[UINavigationController alloc]initWithRootViewController:viewController];
viewController.view.alpha = 1.f;
- 情况二
如果你的根控制器是会改变的,比如有强制登录功能,登录前根控制器是登录的控制器,登陆后才是 Tabbar,所以想要想要其他页面不旋转,之前是在 Tabbar 控制器重写了shouldAutorotate方法,但登录的控制器并不在 Taabar 里面,登录的控制器还是会旋转,在登录的控制器里面重写那个方法也是不行的,具体要在他的UINavigationController控制器里面重写里面重新,可以写个导航栏控制器继承UINavigationController,再在里面重写这个方法,设根控制器再把登录的控制器套到这个导航栏控制器上就行了,其他跟情况一一样就行。
五、iOS13点击返回按钮,移除监听崩溃
直接更新下 pod