AR/VR -iOSSceneKit首页投稿(暂停使用,暂停投稿)

SceneKIt+ AVFoundation 打造VR播放器(3

2017-06-23  本文已影响65人  hhjdk

下面是我写的播放器

SceneKIt+ AVFoundation 打造VR播放器(1)
SceneKIt+ AVFoundation 打造VR播放器(2)
支持VR,全景,视频缩放,本地,网络视频播放,实时获取视频帧,获取播放时间,获取缓存时间,播放,暂停

2017-06-22 17_47_06.gif

要想完成一个Vr播放器,需要完成两个功能

1、写一个可以实时获取视频帧的播放器
2、写一个可以渲染每一帧图片为全景图片的view

前面已经写好了两个类,现在调用就可以了

//
//  HelloViewController.m
//  SCN3DPlayer
//
//  Created by 俞涛涛 on 16/11/11.
//  Copyright © 2016年 俞涛涛. All rights reserved.
//

#import "HelloViewController.h"
#import "SCN3DPlayerView.h"
#import "SCN3DVideoAdatper.h"
#import "HelloViewController.h"
#import "Masonry.h"

@interface HelloViewController ()<SCN3DVideoAdatperDelegate>{
    

}
@property (nonatomic,strong)SCN3DPlayerView *scn3DPlayerView;
@property (nonatomic,strong)SCN3DVideoAdatper *scn3dVideo;


@property (strong, nonatomic)  UIButton *playAndStop;
@property (strong, nonatomic)  UILabel *curTimeLabel;
@property (strong, nonatomic)  UILabel *allTimeLabel;
@property (strong, nonatomic)  UIProgressView *progressView;
@property (strong, nonatomic)  UISlider *timeSlider;
@property (strong, nonatomic)  UIView *upView;
@property (strong, nonatomic)  UIView *videoView;

@property (nonatomic, assign) CGSize displaySize;
@property (nonatomic, assign) float aspect;

@end


@implementation HelloViewController

-(void)viewWillDisappear:(BOOL)animated{
    [self.scn3dVideo pause];
    [self.scn3dVideo removeDisplaylink];
    [self.scn3DPlayerView removeFromSuperview];
     self.scn3DPlayerView = nil;

}

-(void)viewWillAppear:(BOOL)animated{
//    self.scn3DPlayerView.frame = self.videoView.bounds;

}
-(void)viewDidAppear:(BOOL)animated{
    self.scn3DPlayerView.frame = self.view.frame;
    

    


}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    // Do any additional setup after loading the view, typically from a nib.

    [self initSCN3DPlayerView];
    [self setSlider];
    [self initBtn];
    [self initVideo];
    
    
    }

-(void)initSCN3DPlayerView{
     self.scn3DPlayerView  = [[SCN3DPlayerView alloc]initWithFrame:self.view.frame];
    [self.view addSubview:self.scn3DPlayerView];
    [self.scn3DPlayerView  setInteractiveMode:SCN3DInteractive_MotionAndTouch];//设置重力触摸模式
//    [self.scn3DPlayerView setVideoAspectRatio:2.0];//设置视频宽高比
    [self.scn3DPlayerView setVideoDisplayMode:SCN3DDisplayMode_Plane_Normal];//初始化设置普通模式
    [self.scn3DPlayerView setHorizontalEnabled:YES verticalEnabled:YES];//设置触摸开关
    [self.scn3DPlayerView setPinchScaleEnabled:YES];//设置允许缩放
    [self.scn3DPlayerView setMinScale:1 maxScale:2.0];//设置缩放比例范围
    [self.scn3DPlayerView setCurrentScale:1.0]; //设置当前缩放比例


}
-(void)setSlider{
    _upView = [[UIView alloc]init];
    [self.view addSubview:_upView];
    _upView.backgroundColor = [UIColor grayColor];
    
    _playAndStop = [[UIButton alloc]init];
    
    [self.upView addSubview:_playAndStop];
    [_playAndStop setImage:[UIImage imageNamed:@"play_nor"] forState:UIControlStateNormal];
    [_playAndStop setImage:[UIImage imageNamed:@"pause_nor"] forState:UIControlStateSelected];
    [_playAndStop addTarget:self action:@selector(playAndstopClick:) forControlEvents:UIControlEventTouchUpInside];
    
    _curTimeLabel =[[UILabel alloc]init];
    [self.upView addSubview:_curTimeLabel];
    _curTimeLabel.text = @"00:00:00";
    _curTimeLabel.font =[UIFont systemFontOfSize:13];
    
    _allTimeLabel = [[UILabel alloc]init];
    [self.upView addSubview:_allTimeLabel];
    _allTimeLabel.text = @"00:00:00";
    _allTimeLabel.font = [UIFont systemFontOfSize:13];
    
    _progressView = [[UIProgressView alloc]init];
    [self.upView addSubview:_progressView];
    _progressView.progress = 0.0 ;
    
    _timeSlider = [[UISlider alloc]init];
    [self.upView addSubview:_timeSlider];
    _timeSlider.value = 0;
    [_timeSlider addTarget:self action:@selector(timeSliderValueChanged:) forControlEvents: UIControlEventValueChanged];
 
    
    
    __weak typeof(self) weakSelf = self;
    
    [self.upView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.and.trailing.equalTo(weakSelf.view).offset(0);
        make.bottom.equalTo(weakSelf.view).offset(0);
        make.height.equalTo(@60);
    }];
    
    [self.playAndStop mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.equalTo(weakSelf.upView);
        make.centerY.equalTo(weakSelf.upView);
        make.height.and.width.equalTo(@40);

    }];
    
    [self.curTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.equalTo(weakSelf.playAndStop.mas_trailing).offset(0);
        make.centerY.equalTo(weakSelf.upView);
        make.width.equalTo (@60);
        
    }];
    [self.allTimeLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.trailing.equalTo(weakSelf.upView.mas_trailing).offset(-5);
        make.centerY.equalTo(weakSelf.upView);
        make.width.equalTo (@60);
        
    }];
    
    [self.timeSlider mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.equalTo(weakSelf.curTimeLabel.mas_trailing).offset(0);
        make.trailing.equalTo(weakSelf.allTimeLabel.mas_leading).offset(-8);
        make.centerY.equalTo(weakSelf.upView);
    }];
    
    [self.progressView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.equalTo(weakSelf.curTimeLabel.mas_trailing).offset(0);
        make.trailing.equalTo(weakSelf.allTimeLabel.mas_leading).offset(-8);
        make.centerY.equalTo(weakSelf.upView);
    }];
    
    
    
    
    
    [self.timeSlider setThumbImage:[UIImage imageNamed:@"ic_circle@2x"] forState:UIControlStateNormal];
    [self.timeSlider setThumbImage:[UIImage imageNamed:@"ic_circle@2x"] forState:UIControlStateHighlighted];
    UIGraphicsBeginImageContextWithOptions((CGSize){ 1, 1 }, NO, 0.0f);
    UIImage *transparentImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [self.timeSlider setMinimumTrackImage:transparentImage forState:UIControlStateNormal];
    [self.timeSlider setMaximumTrackImage:transparentImage forState:UIControlStateNormal];
}

-(void)initBtn{
    UIButton * btn0 = [[UIButton alloc]initWithFrame:CGRectMake(100, 50, 70, 40)];
    [btn0 setTitle:@"正常" forState:UIControlStateNormal];
    [btn0 setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview: btn0];
     btn0.alpha = 0.5;
     btn0.tag = SCN3DDisplayMode_Plane_Normal;
    [btn0 addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    
    
    UIButton * btn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 70, 40)];
    [btn setTitle:@"平面180" forState:UIControlStateNormal];
    [btn setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview: btn];
     btn.alpha = 0.5;
     btn.tag = SCN3DDisplayMode_Plane_Slide;
    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    
    
    UIButton * btn2 = [[UIButton alloc]initWithFrame:CGRectMake(100, 150, 70, 40)];
    [btn2 setTitle:@"圆柱" forState:UIControlStateNormal];
    [btn2 setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview: btn2];
     btn2.alpha = 0.5;
     btn2.tag = SCN3DDisplayMode_Tube;
    [btn2 addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    
    
    UIButton * btn3 = [[UIButton alloc]initWithFrame:CGRectMake(100, 200, 70, 40)];
    [btn3 setTitle:@"圆" forState:UIControlStateNormal];
    [btn3 setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview: btn3];
    btn3.alpha = 0.5;
    btn3.tag = SCN3DDisplayMode_Sphere;
    [btn3 addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    
    UIButton * btn4 = [[UIButton alloc]initWithFrame:CGRectMake(100, 250, 70, 40)];
    [btn4 setTitle:@"全景" forState:UIControlStateNormal];
    [btn4 setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview: btn4];
    btn4.alpha = 0.5;
    btn4.tag = SCN3DDisplayMode_VR360;
    [btn4 addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    
    UIButton * btn5 = [[UIButton alloc]initWithFrame:CGRectMake(100, 300, 70, 40)];
    [btn5 setTitle:@"VR" forState:UIControlStateNormal];
    [btn5 setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview: btn5];
    btn5.alpha = 0.5;
    btn5.tag = SCN3DDisplayMode_VRGlass;
    [btn5 addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    
    
    
    UIButton * btn6 = [[UIButton alloc]initWithFrame:CGRectMake(10, 10, 50, 50)];
    [btn6 setTitle:@"返回" forState:UIControlStateNormal];
    [btn6 setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview: btn6];
    btn6.alpha = 0.5;
    [btn6 addTarget:self action:@selector(backClick:) forControlEvents:UIControlEventTouchUpInside];
    
    UIButton * btn7 = [[UIButton alloc]initWithFrame:CGRectMake(80, 10, 50, 50)];
    [btn7 setTitle:@"+" forState:UIControlStateNormal];
    [btn7 setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview: btn7];
    btn7.alpha = 0.5;
    [btn7 addTarget:self action:@selector(addvoluem:) forControlEvents:UIControlEventTouchUpInside];
    UIButton * btn8 = [[UIButton alloc]initWithFrame:CGRectMake(150, 10, 50, 50)];
    [btn8 setTitle:@"-" forState:UIControlStateNormal];
    [btn8 setBackgroundColor:[UIColor blueColor]];
    [self.view addSubview: btn8];
    btn8.alpha = 0.5;
    
    [btn8 addTarget:self action:@selector(subvoluem:) forControlEvents:UIControlEventTouchUpInside];
    
    UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapClick)];
    [self.view addGestureRecognizer:tap];
   

}

-(void)btnClick:(UIButton*)btn{
    
    if (btn.tag == SCN3DDisplayMode_Plane_Normal) {
        [self.scn3DPlayerView setVideoDisplayMode:SCN3DDisplayMode_Plane_Normal];
        
    }else if (btn.tag == SCN3DDisplayMode_Plane_Slide) {
        [self.scn3DPlayerView setVideoDisplayMode:SCN3DDisplayMode_Plane_Slide];
        [self.scn3DPlayerView setHorizontalEnabled:YES verticalEnabled:NO];//设置水平垂直是否启用
        [self.scn3DPlayerView setPinchScaleEnabled:YES];



    }else if (btn.tag == SCN3DDisplayMode_Tube){
        [self.scn3DPlayerView setVideoDisplayMode:SCN3DDisplayMode_Tube];
        [self.scn3DPlayerView setHorizontalEnabled:YES verticalEnabled:YES];
        [self.scn3DPlayerView setVerticalMinRotate:-60 maxRotate:60];


    }else if (btn.tag == SCN3DDisplayMode_Sphere){
        [self.scn3DPlayerView setVideoDisplayMode:SCN3DDisplayMode_Sphere];
        [self.scn3DPlayerView setHorizontalEnabled:YES verticalEnabled:YES];//设置水平垂直是否启用

    }else if (btn.tag == SCN3DDisplayMode_VR360){
        
        [self.scn3DPlayerView setVideoDisplayMode:SCN3DDisplayMode_VR360];
        [self.scn3DPlayerView setVerticalMinRotate:30 maxRotate:90];
        [self.scn3DPlayerView setCurrentRotateX:30 rotateY:0];
         self.scn3DPlayerView.cameraNode.position = SCNVector3Make(0, 0.1, 1.0);
        [self.scn3DPlayerView setHorizontalEnabled:YES verticalEnabled:YES];
        [self.scn3DPlayerView setGSensorMotionEnabled:YES];
        [self.scn3DPlayerView setPinchScaleEnabled:YES];

        
    }else if (btn.tag == SCN3DDisplayMode_VRGlass){
        
        [self.scn3DPlayerView setVideoDisplayMode:SCN3DDisplayMode_VRGlass];
        [self.scn3DPlayerView setHorizontalEnabled:YES verticalEnabled:YES];
        [self.scn3DPlayerView setGSensorMotionEnabled:YES];
        [self.scn3DPlayerView setPinchScaleEnabled:YES];

    }


}

-(void)tapClick{
    dispatch_async(dispatch_get_main_queue(), ^{
        [UIView animateWithDuration:0.3 animations:^{
            self.upView.alpha = 1.0;
            self.upView.alpha = 1.0;
        }];
        
    });
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [UIView animateWithDuration:1.0 animations:^{
            self.upView.alpha = 0.0;
            self.upView.alpha = 0.0;
        }];
        
    });



}
-(void)initVideo{
    self.scn3dVideo = [[SCN3DVideoAdatper alloc]init];
        
    NSString * urlString = [[NSBundle mainBundle]pathForResource:@"abc" ofType:@"mp4"];
//    NSString * urlString = @"http://cache.utovr.com/aa38e1ffef5d4b9baaf393777dbc9342/L2_gx91akbix0qkiacw.mp4";
    
    
    NSURL *videoURL;
    
    if ([self checkPathIsHTTPURL:urlString]) {
        videoURL = [NSURL URLWithString:urlString]; //网络视频

    }
    else {
        videoURL = [NSURL fileURLWithPath:urlString];//本地视频

    }
    //播放方法一
    [self.scn3dVideo setURL:videoURL];
    
    //播放方法二
//    AVPlayerItem *playerItem = [[AVPlayerItem alloc] initWithURL:url];
//    [self.scn3dVideo setPlayerItem:playerItem];
    
    //方法三
//    AVAsset * asset = [AVAsset assetWithURL:url];
//    [self.scn3dVideo setAsset:asset];
    
    
     self.scn3dVideo.delegate = self;
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
}
    
    
    
    
    
- (void)videoPlayerIsReadyToPlayVideo:(SCN3DVideoAdatper *)videoAdatper{
    NSLog(@"准备播放====================");
    [self.scn3dVideo addDisplaylink];
    [self.scn3dVideo play];
     self.playAndStop.selected = YES;
    int totalTime = CMTimeGetSeconds(videoAdatper.playerItem.duration);
    self.timeSlider.maximumValue = totalTime;
    self.allTimeLabel.text = [self getVideoTimeString:totalTime];
    NSLog(@"time =========%d",totalTime);

}

- (void)videoPlayerDidReachEnd:(SCN3DVideoAdatper *)videoAdatper{
    NSLog(@"播放结束 ==============");
    [self.scn3dVideo pause];
   
        
}

- (void)videoPlayer:(SCN3DVideoAdatper *)videoAdatper timeDidChange:(CMTime)cmTime{
   
    int curTime = CMTimeGetSeconds(cmTime);
    self.timeSlider.value = curTime;
    self.curTimeLabel.text = [self getVideoTimeString:curTime];
}

- (void)videoPlayer:(SCN3DVideoAdatper *)videoAdatper loadedTimeRangeDidChange:(float)duration{
    
    // 视频缓冲长度
    int totalTime = CMTimeGetSeconds(videoAdatper.playerItem.duration);
    if (totalTime != 0) {
        self.progressView.progress = duration / totalTime;

    
    }
}
- (void)videoPlayer:(SCN3DVideoAdatper *)videoAdatper didFailWithError:(NSError *)error{
    NSLog(@"error====================%@",error);
}
    
- (void)videoPlayer:(SCN3DVideoAdatper *)videoAdatper displaylinkCallbackImage:(UIImage *)videoImage{
    //获取视频的每一帧
    [self.scn3DPlayerView setFramesPerVideoImage:videoImage];
    _aspect = videoImage.size.width/videoImage.size.height;
    
        
}

- (NSString *)getVideoTimeString:(int)time {
    int hou = time / 3600;
    int min = (time - hou * 60) / 60;
    int sec = time - hou * 3600 - min * 60;
    return [NSString stringWithFormat:@"%02d:%02d:%02d", hou, min, sec];
}

//支持的方向
-(UIInterfaceOrientationMask)supportedInterfaceOrientations{
        
    return UIInterfaceOrientationMaskAll;
        
}
    
//是否可以旋转
-(BOOL)shouldAutorotate{
    
    return YES;
}
// 横竖屏适配.
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
    
    [self relayout];
}
    
- (void)relayout
{
    if(self.view.frame.size.width>self.view.frame.size.height) {
        self.scn3DPlayerView .frame = self.view.frame;
            
    } else {
        self.scn3DPlayerView.frame = self.view.frame;
    }
}

- (BOOL)checkPathIsHTTPURL:(NSString *)path {
    NSString *head = [path substringWithRange:NSMakeRange(0, 4)];
    NSStringCompareOptions options = NSCaseInsensitiveSearch | NSNumericSearch;
    if ([head compare:@"http" options:options] == NSOrderedSame) {
        return YES;
    }
    return NO;
}
- (void)playAndstopClick:(UIButton *)sender {
    if (self.scn3dVideo.isPlaying) {
        [self.scn3dVideo pause];
        self.playAndStop.selected = NO;
    }else{
        [self.scn3dVideo play];
        self.playAndStop.selected = YES;
    }
}

- (void)timeSliderValueChanged:(UISlider*)sender {  // 滑动播放进度
    float seekTime = sender.value;
    if (self.scn3dVideo.isPlaying) {
        [self.scn3dVideo pause];
    }
    if (self.playAndStop.selected == YES) {
        [self.scn3dVideo play];
    }

    [self.scn3dVideo seekToTime:seekTime completion:nil];
}
- (void)backClick:(UIButton *)sender {
    
    [self dismissViewControllerAnimated:YES completion:nil];
}

-(void)subvoluem:(UIButton *)sender{
    
    [self.scn3dVideo fadeOutVolume];
}
-(void)addvoluem:(UIButton *)sender{
    
    [self.scn3dVideo  fadeInVolume];
}

@end

源代码下载
如果喜欢的话,就点个赞,star一下,本文里面有误的地方,请大家指教

上一篇下一篇

猜你喜欢

热点阅读