音视频首页推荐iOS Developer

iOS_VR视频播放(自定义视频播放器)

2018-03-15  本文已影响55人  小二同學

iOS VR模式视频播放,全景视频播放,同时还支持普通视频播放,并且自定义视频播放器,显示logo啊,隐藏进度条啊,拖动进度条啊,这些都可以自定义,腾讯视频上面有的功能都可以自己实现的。有点小激动...

VR模式视频播放.PNG
// 播放器
_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.viewGravityMode = SGGravityModeResize;
_VRPlayer.displayMode = SGDisplayModeBox; // VR模式
_VRPlayer.displayMode = SGDisplayModeNormal; // 全景模式
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);
}
@interface VideoSlider : UISlider
/** 缓冲条进度 */
@property (assign,nonatomic) CGFloat playableProgress;
-(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];
}
self.timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(hideProgress) userInfo:nil repeats:YES];
- (void)hideProgress{
    self.progressBar.hidden = YES;
}
#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;
}
// 是否支持横屏
@property (nonatomic,assign) NSInteger 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;
}
//在视图出现的时候,将allowRotate改为1,
AppDelegate * delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
delegate.allowRotate = 1;
- (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;
        }
    }
横竖屏切换.gif
上一篇 下一篇

猜你喜欢

热点阅读