VR模式视频播放.PNGiOS VR模式视频播放,全景视频播放,同时还支持普通视频播放,并且自定义视频播放器,显示logo啊,隐藏进度条啊,拖动进度条啊,这些都可以自定义,腾讯视频上面有的功能都可以自己实现的。有点小激动...
-
有一个很好用的第三方VR播放器 SGPlayer
-
集成步骤,GitHub上写的很详细了,我就不再重复写了,遇到什么问题的话,可以留言询问。这个播放器唯一不好的就是不支持模拟器,必须得用真机测试。模拟器会报错。
-
导入成功之后,接下来就得开始准备搭建UI了。
-
创建播放器View,并定义好frame。
// 播放器
_VRPlayer = [SGPlayer player];
// 开启 FFmpeg 硬解
_VRPlayer.decoder.hardwareAccelerateEnableForFFmpeg = YES;
[_VRPlayer registerPlayerNotificationTarget:self
stateAction:@selector(stateAction:)
progressAction:@selector(progressAction:)
playableAction:@selector(playableAction:)
errorAction:@selector(errorAction:)];
[_VRPlayer setViewTapAction:^(SGPlayer * _Nonnull player, SGPLFView * _Nonnull view) {
NSLog(@"player display view did click!");
}];
_VRPlayer.view.frame = self.frame;
[self addSubview:_VRPlayer.view];
-
_VRPlayer.view 就是一个View,我们可以在这上面添加任何东西,播放按钮,进度条,VR模式切换,title,还有手势,logo什么的
-
这个方法控制视频全屏还是适应原来的尺寸
_VRPlayer.viewGravityMode = SGGravityModeResize;
-
VR模式和全景模式
_VRPlayer.displayMode = SGDisplayModeBox; // VR模式
_VRPlayer.displayMode = SGDisplayModeNormal; // 全景模式
-
播放的话,直接传入url就行了
NSURL *vrVideo = [NSURL URLWithString:vrDetailModel.videoUrl];
[_VRPlayer replaceVideoWithURL:vrVideo videoType:SGVideoTypeVR];
-
实现代理
-
播放的状态,这里面有视频出现的各种状态,正在缓冲,准备播放,正在播放,播放完成,播放失败,我们可以根据相应的状态做事情。
#pragma 播放的状态
- (void)stateAction:(NSNotification *)notification
{
SGState * state = [SGState stateFromUserInfo:notification.userInfo];
// NSString * text;
switch (state.current) {
case SGPlayerStateNone:
// text = @"None";
break;
case SGPlayerStateBuffering:
// text = @"Buffering...";
if (self.playButton.selected) {
[self Buffering];
}
break;
case SGPlayerStateReadyToPlay:
// text = @"Prepare";
/** 总时长 */
self.allTime.text = [self timeStringFromSeconds:_VRPlayer.duration];
[self Prepare];
[_VRPlayer play];
break;
case SGPlayerStatePlaying:
// text = @"Playing";
[self Prepare];
break;
case SGPlayerStateSuspend:
// text = @"Suspend";
break;
case SGPlayerStateFinished:
// text = @"Finished";
if (_VRPattern.selected == YES) {
[_VRPlayer play];
}
break;
case SGPlayerStateFailed:
// text = @"Error";
break;
}
// self.stateLabel.text = text;
}
-
播放进度,改变播放时间和进度条进度
- (void)progressAction:(NSNotification *)notification
{
SGProgress * progress = [SGProgress progressFromUserInfo:notification.userInfo];
if (!self.progressSilderTouching) {
self.progressSilder.value = progress.percent;
}
self.playTime.text = [self timeStringFromSeconds:progress.current];
}
-
缓冲进度
- (void)playableAction:(NSNotification *)notification
{
SGPlayable * playable = [SGPlayable playableFromUserInfo:notification.userInfo];
[UIView animateWithDuration:0.1 animations:^{
_progressSilder.playableProgress = playable.percent;
}];
NSLog(@"playable time : %f", playable.current);
}
-
这样就算是能播放了,剩下的还有进度条,横竖屏切换,3s之后隐藏控件
-
自定义进度条,我选择的是UISlider,上一篇音乐播放器我用的是UILabel,视频的话因为是要拖动,直接用slider会好一些
-
首先创建一个UISlider类
@interface VideoSlider : UISlider
/** 缓冲条进度 */
@property (assign,nonatomic) CGFloat playableProgress;
-
然后对slider进行重绘,实现缓冲条进度方法
-(void)setPlayableProgress:(CGFloat)playableProgress{
if (_playableProgress != playableProgress){
_playableProgress = playableProgress;
[self setNeedsDisplay];
}
}
-(void)setFrame:(CGRect)frame{
[super setFrame:frame];
[self setNeedsDisplay];
}
-(void)setBounds:(CGRect)bounds{
[super setBounds:bounds];
[self setNeedsDisplay];
}
-
这个可以根据需求改变进度条的高度和宽度还有颜色等等
- (void)drawRect:(CGRect)rect{
[super drawRect:rect];
CGContextRef c = UIGraphicsGetCurrentContext();
[[[UIColor whiteColor] colorWithAlphaComponent:0.7] set];
CGRect r = [self trackRectForBounds:self.bounds];
r = CGRectInset(r, 0, 0);
UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:r cornerRadius:r.size.height/2.0];
CGContextAddPath(c, bezierPath.CGPath);
CGContextSetLineWidth(c, 0);
CGContextStrokePath(c);
CGContextAddPath(c, bezierPath.CGPath);
CGContextClip(c);
CGContextFillRect(c, CGRectMake(r.origin.x, r.origin.y, r.size.width * _playableProgress, r.size.height));
}
-
然后把进度条放上去看看有没有起作用
_progressSilder = [[VideoSlider alloc] init];
[_progressSilder addTarget:self action:@selector(progressTouchDown:) forControlEvents:UIControlEventTouchDown];
[_progressSilder addTarget:self action:@selector(progressTouchUp:) forControlEvents:UIControlEventTouchUpInside];
[_progressSilder addTarget:self action:@selector(progressTouchUp:) forControlEvents:UIControlEventTouchCancel];
[_progressSilder addTarget:self action:@selector(progressTouchUp:) forControlEvents:UIControlEventTouchUpOutside];
/* 修改进度条的样式 */
[_progressSilder setThumbImage:[UIImage imageNamed:@"VR滑块"] forState:UIControlStateNormal];
_progressSilder.layer.masksToBounds = YES;
_progressSilder.layer.cornerRadius = 3*WidthJust;
_progressSilder.minimumTrackTintColor = UIColorFromRGB(0Xff9b24);
_progressSilder.maximumTrackTintColor = [[UIColor whiteColor] colorWithAlphaComponent:0.4];
-
实现拖动方法,改变播放时间和视频播放进度
- (void)progressTouchDown:(id)sender
{
self.progressSilderTouching = YES;
}
- (void)progressTouchUp:(id)sender
{
self.progressSilderTouching = NO;
[_VRPlayer seekToTime:_VRPlayer.duration * self.progressSilder.value];
self.playTime.text = [self timeStringFromSeconds:self.progressSilder.value];
}
-
3s之后隐藏控件,在页面一进来就给一个3s倒计时,或者在播放开始的时候给倒计时,这个根据需求
self.timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(hideProgress) userInfo:nil repeats:YES];
-
然后实现方法
- (void)hideProgress{
self.progressBar.hidden = YES;
}
-
还有就是点击视频背景的时候隐藏进度条,或者显示进度条,先给视频背景定义一个手势,然后改变进度条显示状态,然后再改变定时器,先置空,再重新开始3s倒计时
#pragma 单击隐藏播放条
- (void)hideProessBar:(UIGestureRecognizer *)tap {
[self.timer invalidate];
self.timer = nil;
// 3S之后隐藏进度条
self.timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(hideProgress) userInfo:nil repeats:YES];
_progressBar.hidden = !_progressBar.hidden;
}
-
进度条这样就算是完了,有木有很简单
-
横竖屏切换,首先在APPdelegate里面定义一个全局变量,是否支持横屏,因为只有视频页面需要支持横屏,别的页面不需要
// 是否支持横屏
@property (nonatomic,assign) NSInteger allowRotate;
-
然后根据allowRotate的状态去设置设备的状态
#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_9_0
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
#else
//此方法会在设备横竖屏变化的时候调用
- (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
#endif
{
// NSLog(@"方向 ============= %ld", _allowRotate);
if (_allowRotate == 1) {
return UIInterfaceOrientationMaskAll;
}else{
return (UIInterfaceOrientationMaskPortrait);
}
}
// 返回是否支持设备自动旋转
- (BOOL)shouldAutorotate
{
if (_allowRotate == 1) {
return YES;
}
return NO;
}
-
然后再去视频详情页,刚进入页面的时候,把允许横屏改为1,页面消失的时候改为0
//在视图出现的时候,将allowRotate改为1,
AppDelegate * delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
delegate.allowRotate = 1;
-
根据这个方法判断横竖屏,改变UI
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft || toInterfaceOrientation == UIInterfaceOrientationLandscapeRight) {
//屏幕从竖屏变为横屏时执行
}else{}
}
-
切换横竖屏,定义一个全局变量记录横竖屏的状态
// 变为横屏
if (isPortrait) {
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
[[UIDevice currentDevice] performSelector:@selector(setOrientation:) withObject:[NSNumber numberWithInteger:UIInterfaceOrientationLandscapeLeft]];
isPortrait = false;
}
}else{
if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
SEL selector = NSSelectorFromString(@"setOrientation:");
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[UIDevice instanceMethodSignatureForSelector:selector]];
[invocation setSelector:selector];
[invocation setTarget:[UIDevice currentDevice]];
int val = UIDeviceOrientationPortrait;
//从2开始是因为0 1 两个参数已经被selector和target占用
[invocation setArgument:&val atIndex:2];
[invocation invoke];
isPortrait = true;
}
}
-
我们播放器下面是一个tableview,横屏的时候把tableview隐藏,这样的话,就不会出现bug
-
在视频播放view上横竖屏UI显示不一样,也可以根据上面判断横竖屏的方法改变控件的显示与否
-
OK,就这么多吧,赶紧试试把。还有一个事,我的APP被拒了一个月了,因为2.1狗年大礼包,到现在还没过,一直在等,桑心。过了之后分享被拒心得。希望早点过吧,哈哈哈...
网友评论