美文网首页
AVFoundation框架

AVFoundation框架

作者: 宙斯YY | 来源:发表于2018-07-24 16:41 被阅读21次

    一.AVAudioRecorder(录音)

    1.info.plist配置
    1.png
    2.代码部分
    //录音配置
    -(NSDictionary *)getAudioSettingWithPCM {
        
        NSMutableDictionary * setting=[NSMutableDictionary dictionary];
        //录音数据格式-PCM
        setting[AVFormatIDKey]=[NSNumber numberWithInt:kAudioFormatLinearPCM];
        //采样率
        setting[AVSampleRateKey]=[NSNumber numberWithFloat:11025.0];
        //声道数 1为单声道, 2为双声道(立体声)
        setting[AVNumberOfChannelsKey]=[NSNumber numberWithInt:2];
        //录音质量
        setting[AVEncoderAudioQualityKey]=[NSNumber numberWithInt:AVAudioQualityMin];
        return setting;
    }
    
    //录音准备
    -(void)recordPrepare
    {
        //存放录音文件路径
        fullPath = NSTemporaryDirectory();
        fullPath = [fullPath stringByAppendingString:[NSString stringWithFormat:@"%f.caf", [[NSDate date] timeIntervalSince1970]]];
        //NSLog(@"fullPath:%@",fullPath);
        NSError * error;
        recorder=[[AVAudioRecorder alloc]initWithURL:[NSURL fileURLWithPath:fullPath] settings:[self getAudioSettingWithPCM] error:&error];
        [recorder prepareToRecord];
    }
    
    //开始录音
    -(void)recordStart
    {
        [recorder record];
    }
    //停止录音
    -(void)recordStop
    {
        [recorder stop];
    }
    
    /*
    具体代理方法,属性可查看AVAudioRecorder头文件
    */
    
    3.转码mp3(压缩大小)

    使用Lame库
    A.下载源文件 http://lame.sourceforge.net/download.php
    B.下载运行脚本 https://github.com/kewlbear/lame-ios-build

    2.png
    C.把两个文件放到一个文件夹下,修改文件名Lame,根据github指令
    ./build-lame.sh运行脚本,会生成三个文件
    3.png
    其中fat-lame中包含头文件和.a静态库文件。
    D.创建工具类LameTool,转码之前的录音文件caf为mp3文件
    + (NSString *)audioToMP3: (NSString *)sourcePath isDeleteSourchFile:(BOOL)isDelete{
        NSString *inPath = sourcePath;
        NSFileManager *fm = [NSFileManager defaultManager];
        if (![fm fileExistsAtPath:sourcePath]){
            NSLog(@"file path error!");
            return @"";
        }
        NSString *outPath = [[sourcePath stringByDeletingPathExtension] stringByAppendingString:@".mp3"];
        @try {
            int read, write;
            FILE *pcm = fopen([inPath cStringUsingEncoding:1], "rb");
            fseek(pcm, 4*1024, SEEK_CUR);
            FILE *mp3 = fopen([outPath cStringUsingEncoding:1], "wb");
            const int PCM_SIZE = 8192;
            const int MP3_SIZE = 8192;
            short int pcm_buffer[PCM_SIZE*2];
            unsigned char mp3_buffer[MP3_SIZE];
            lame_t lame = lame_init();
            lame_set_in_samplerate(lame, 11025.0);
            lame_set_VBR(lame, vbr_default);
            lame_init_params(lame);
            do {
                size_t size = (size_t)(2 * sizeof(short int));
                read = fread(pcm_buffer, size, PCM_SIZE, pcm);
                if (read == 0)
                    write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
                else
                    write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
                fwrite(mp3_buffer, write, 1, mp3);
            } while (read != 0);
            lame_close(lame);
            fclose(mp3);
            fclose(pcm);
        }
        @catch (NSException *exception) {
            NSLog(@"%@",[exception description]);
        }
        @finally {
            NSLog(@"mp3 build success!");
            if (isDelete) {
                NSError *error;
                [fm removeItemAtPath:sourcePath error:&error];
                if (error == nil){
                    NSLog(@"source file is deleted!");
                }
            }
            return outPath;
        }
    }
    

    二.AudioServicesSystemSoundID(音效播放)

    1.要求

    音频文件必须打包成.caf、.aif、.wav中的一种(注意这是官方文档的说法,实际测试发现一些.mp3也可以播放)
    这个段音效播放不能大于30s,这个30s不是我说的,是苹果的API说的

    2.代码
    -(void)playaudio:(NSString*)resourceName andCompletion:(void(^)(void))completion
    {
        NSString *pathStr = [[NSBundle mainBundle] pathForResource:resourceName ofType:nil];
        if(!pathStr)
        {
            NSLog(@"文件不存在");
            return;
        }
        NSURL *path = [NSURL fileURLWithPath:pathStr];
        SystemSoundID systemsoundid=0;
        AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(path), &systemsoundid);
        //播放音效+震动
    //    AudioServicesPlayAlertSoundWithCompletion(systemsoundid, ^{
    //        completion();
    //        //销毁资源
    //        AudioServicesDisposeSystemSoundID(systemsoundid);
    //    });
        //直接播放音效
        AudioServicesPlaySystemSoundWithCompletion(systemsoundid, ^{
            completion();
            //销毁资源
            //AudioServicesDisposeSystemSoundID(systemsoundid);
        });
    }
    

    三.AVAudioPlayer(音乐播放)

    //播放
    -(void)playmusic
    {
        if(!player)
        {
            //后台播放
            //[[AVAudioSession sharedInstance] setCategory: AVAudioSessionCategoryPlayback error:nil];
            //[[AVAudioSession sharedInstance] setActive: YES error: nil];
            
            NSError * error;
            NSURL *path = [NSURL fileURLWithPath:fullPath];
            player=[[AVAudioPlayer alloc]initWithContentsOfURL:path error:&error];
            [player prepareToPlay];
            NSLog(@"播放错误:%@",error.description);
        }else
        {
            [player play];
            NSLog(@"播放录音:%@",fullPath);
        }
    }
    //停止播放
    -(void)stop
    {
        player.currentTime=0;
        [player stop];
    }
    

    三.AVPlayer(视频播放)

    使用环境 优点 缺点
    MPMoviePlayerController MediaPlayer 简单易用 不可定制
    AVPlayerViewController AVKit 简单易用 不可定制
    AVPlayer AVFoundation 可定制度高,功能强大 不支持流媒体
    IJKPlayer IJKMediaFramework 定制度高,支持流媒体播放 使用稍复杂

    AVPlayer相关类

    • AVPlayer:控制播放器的播放,暂停,播放速度
    • AVURLAsset : AVAsset 的一个子类,使用 URL 进行实例化,实例化对象包换 URL 对应视频资源的所有信息。
    • AVPlayerItem:管理资源对象,提供播放数据源
    • AVPlayerLayer:负责显示视频,如果没有添加该类,只有声音没有画面

    看到有小伙伴写的更详细的参数含义:https://www.jianshu.com/p/29bfc7dc401a

    我的项目中要实现类似抖音的效果,所以这里直接上核心代码。

    1.jpeg
    1.UI核心:

    UITableView为主体,每个UITableViewCell铺一张视频第一帧图片,且铺一张透明的功能页面。

    2.功能核心:

    AVPlayer实例有且只有一个,每次滑动到新页面的时候,加载视频资源,切换AVPlayer播放源,当播放的时候,移除第一帧占位图,保证平滑过渡。
    相关联的AVPlayerLayer也保证只有一个,使用一个ControlView进行管理AVPlayer的相关状态和播放相关,每次滑动到最新页面,移除之前的ControlView,添加到最新页面上。

    获取最新滑动Cell位置

    -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        //获取当前播放位置indexPath
        if(scrollView==self.tableview)
        {
            NSArray<NSIndexPath*> * arr=[self.tableview indexPathsForVisibleRows];
            for (int i=0; i<arr.count; i++) {
                NSIndexPath * indexpath=arr[i];
                if(indexpath.row==self.currentIndex)
                {
                    return;
                }
                [self playVideoAtIndex:indexpath];
            }
        }
    }
    

    播放当前位置的视频资源

    -(void)playVideoAtIndex:(NSIndexPath*)indexpath
    {
        //移除AVPlayer控制层和显示层
        if(self.controlview)
        {
            [self.controlview removeFromSuperview];
            self.controlview=nil;
        }
        if(self.playerlayer)
        {
            [self.playerlayer removeFromSuperlayer];
            self.playerlayer=nil;
        }
        
            
        //如果还是原来的页面,则不做加载
        if(indexpath.row>=self.dataList.count)
        {
            return;
        }
        
        VideoMainCell * currentCell=(VideoMainCell*)[self.tableview cellForRowAtIndexPath:indexpath];
        self.currentCell=currentCell;
        self.currentIndex=indexpath.row;
        VideoRelateDYData * data= self.dataList[self.currentIndex];
        [self getCommentData:data.id];
        
        //创建新的AVPlayerItem,AVPlayerLayer,切换AVPlayer当前AVPlayerItem,并监听AVPlayerItem的状态
        AVPlayerItem * item=[AVPlayerItem playerItemWithURL:[NSURL URLWithString:data.video_url]];
        self.playeritem=item;
        [self.playeritem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
        [self.playeritem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
        [self.playeritem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
        [self.player replaceCurrentItemWithPlayerItem:self.playeritem];
        
        //创建控制层管理当前AVPlayer的播放进度状态
        self.controlview.player=self.player;
        self.controlview.videodata=self.dataList[self.currentIndex];
        self.controlview.videotype=VideoControlType_Comment;
        
        //使用控制层管理功能函数
        @weakify(self);
        self.controlview.block = ^(ControlBtn controlBtn) {
            @strongify(self);
            if(controlBtn==ControlBtn_Goods)
            {
                SDLog(@"商品列表");
                [self.controlview setVideotype:VideoControlType_Nothing];
                VideoRelateDYData * goodsData=self.dataList[self.currentIndex];
                if(goodsData.lists.count==1)
                {
                    VideoRelateDYDetailData * data=goodsData.lists[0];
                    SearchType searchType=SearchType_tb;
                    if ([data.user_type isEqualToString:@"0"] || [data.user_type isEqualToString:@"1"]) {
                            searchType=SearchType_tb;
                    }else if ([data.user_type isEqualToString:@"2"]){
                            searchType=SearchType_pdd;
                    }else if ([data.user_type isEqualToString:@"3"]){
                            searchType=SearchType_jd;
                    }
                    if(self.isScreenRight)
                    {
                            [self rotateScreen];
                    }
                    [self pushToStoreDetailViewControler:data.num_iid andSearchType:searchType];
                    }else
                    {
                        self.storeview=[VideoStoresView shareView];
                        self.storeview.goodsData=goodsData;
                        [self.storeview show:^{
                            [self.controlview setVideotype:VideoControlType_Comment];
                            [self.storeview removeFromSuperview];
                            self.storeview=nil;
                    } andGoods:^(VideoRelateDYDetailData *data) {
                            [self.controlview setVideotype:VideoControlType_Comment];
                            [self.storeview removeFromSuperview];
                            self.storeview=nil;
                            SearchType searchType=SearchType_tb;
                            if ([data.user_type isEqualToString:@"0"] || [data.user_type isEqualToString:@"1"]) {
                                searchType=SearchType_tb;
                            }else if ([data.user_type isEqualToString:@"2"]){
                                searchType=SearchType_pdd;
                            }else if ([data.user_type isEqualToString:@"3"]){
                                searchType=SearchType_jd;
                            }
                            if(self.isScreenRight)
                            {
                                [self rotateScreen];
                            }
                            [self pushToStoreDetailViewControler:data.num_iid andSearchType:searchType];
                        }];
                    }
                }else if(controlBtn==ControlBtn_Rotate)
                {
        
                }else if(controlBtn==ControlBtn_Input)
                {
                    SDLog(@"输入");
                    [self presentToLoginController:^(BOOL success) {
                        if(success)
                        {
                            [self.controlview setVideotype:VideoControlType_Nothing];
                            self.inputview=[VideoCommentInputView shareView];
                            [self.inputview show:CGRectMake(0, 0, SDScreenWidth,300) andClose:^{
                                [self.inputview removeFromSuperview];
                                self.inputview=nil;
                            } andText:^(NSString *text) {
                                VideoRelateDYData * videoData=self.dataList[self.currentIndex];
                                [self sendCommentData:videoData.id andContent:text andTime:[NSString stringWithFormat:@"%lld",self.player.currentItem.currentTime.value/self.player.currentItem.currentTime.timescale] andview:self.commentListview];
                            }];
                            [self.inputview.textview becomeFirstResponder];
                        }
                    }];
                }
            };
            self.playerlayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
            self.playerlayer.backgroundColor = [UIColor blackColor].CGColor;
            self.playerlayer.frame = [UIScreen mainScreen].bounds;
            [self.currentCell.coverImg.layer addSublayer:self.playerlayer];
        
            //添加第一帧占位图覆盖到当前Cell上
            if(!self.coverImgview)
            {
                self.coverImgview=[[UIImageView alloc]initWithImage:data.firstvideoImg];
                self.coverImgview.frame=[UIScreen mainScreen].bounds;
                self.coverImgview.contentMode=UIViewContentModeScaleAspectFit;
                [self.currentCell.coverImg addSubview:self.coverImgview];
            }
    }
    

    监听AVPlayer的状态

    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
    {
        if(object==self.playeritem)
        {
            AVPlayerItem *playerItem = (AVPlayerItem *)object;
            if ([keyPath isEqualToString:@"status"]) {
                if ([playerItem status] == AVPlayerStatusReadyToPlay) {
                    //播放器准备完成后,移除占位图,添加控制层
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        [self.coverImgview removeFromSuperview];
                        self.coverImgview=nil;
                        [self.currentCell.coverImg addSubview:self.controlview];
                    });
                }else if ([playerItem status] == AVPlayerStatusFailed || [playerItem status] == AVPlayerStatusUnknown) {
                    [JSXHUD showMessage:@"播放失败"];
                    [self.player pause];
                }
            }else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) { //监听播放器在缓冲数据的状态
                SDLog(@"缓冲不足暂停了");
                [self.player pause];
            }else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
                SDLog(@"缓冲达到可播放程度了");
                //由于 AVPlayer 缓存不足就会自动暂停,所以缓存充足了需要手动播放,才能继续播放
                [self.player play];
                
            }
        }
    }
    
    

    控制层VideoMainControlView.m

    @interface VideoMainControlView()
    @end
    @implementation VideoMainControlView
    
    -(void)awakeFromNib
    {
        [super awakeFromNib];
        [self.playBtn addTarget:self action:@selector(clickPlay:) forControlEvents:UIControlEventTouchUpInside];
        [self.bottomview addSubview:self.bottom1];
        [self.bottomview addSubview:self.bottom2];
        [self setUserInteractionEnabled:YES];
        UITapGestureRecognizer * tap=[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(clickBG)];
        [self addGestureRecognizer:tap];
    }
    
    -(void)layoutSubviews
    {
        [super layoutSubviews];
        [self.bottom1 mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.top.right.bottom.offset(0);
        }];
        
        [self.bottom2 mas_makeConstraints:^(MASConstraintMaker *make) {
            make.left.top.right.bottom.offset(0);
        }];
    }
    
    -(void)clickBG
    {
        if(self.videotype==VideoControlType_Play)
        {
            self.videotype=VideoControlType_Comment;
        }else if(self.videotype==VideoControlType_Comment)
        {
            self.videotype=VideoControlType_Play;
        }else
        {
            self.videotype=VideoControlType_Comment;
        }
    }
    
    -(void)clickPlay:(UIButton*)btn
    {
        if(btn.selected)
        {
            [self.player play];
        }else
        {
            [self.player pause];
        }
        btn.selected=!btn.selected;
    }
    
    /** 拖动视频进度 */
    - (void)seekPlayerTimeTo:(NSTimeInterval)time
    {
        [self.player pause];
        [self.player seekToTime:CMTimeMake(time,10) completionHandler:^(BOOL finished) {
            [self.player play];
        }];
        
    }
    
    -(void)sliderValueChanged:(UISlider*)slider
    {
        if(self.player)
        {
            CGFloat duration = self.player.currentItem.duration.value / self.player.currentItem.duration.timescale; //视频总时间
            [self seekPlayerTimeTo:slider.value*duration];
        }
    }
    
    -(void)refreshProgress
    {
        if(self.bottom2&&self.player)
        {
            CGFloat duration = CMTimeGetSeconds(self.player.currentItem.duration); //视频总时间
            CGFloat currentTime = CMTimeGetSeconds(self.player.currentItem.currentTime); //视频当前时间
            self.bottom2.currentTime.text=[self convert:currentTime];
            self.bottom2.totalTime.text=[self convert:duration];
            self.bottom2.progressview.value=currentTime/duration;
            [self.bottom2.progressview addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
        }
        
        if(self.bottom1&&self.player)
        {
            CGFloat duration = CMTimeGetSeconds(self.player.currentItem.duration); //视频总时间
            CGFloat currentTime = CMTimeGetSeconds(self.player.currentItem.currentTime); //视频当前时间
            self.bottom1.progressview.progress=currentTime/duration;
        }
    }
    
    - (NSString *)convert:(CGFloat)time{
        int minute = time / 60;
        int second = time - minute * 60;
        NSString *minuteString;
        NSString *secondString;
        if(minute < 10){
            minuteString = [NSString stringWithFormat:@"0%d", minute];
        }else{
            minuteString = [NSString stringWithFormat:@"%d", minute];
        }
        if(second < 10){
            secondString = [NSString stringWithFormat:@"0%d", second];
        }else{
            secondString = [NSString stringWithFormat:@"%d", second];
        }
        return [NSString stringWithFormat:@"%@:%@", minuteString, secondString];
    }
    
    #pragma mark - Setter
    
    -(void)setPlayer:(AVPlayer *)player
    {
        _player=player;
        [player addPeriodicTimeObserverForInterval:CMTimeMake(1,10) queue:NULL usingBlock:^(CMTime time) {
            [self refreshProgress];
        }];
    }
    
    -(void)setVideodata:(VideoRelateDYData *)videodata
    {
        _videodata=videodata;
        //[self.coverImageView setImageWithURLString:videodata.coverImg placeholder:[UIImage imageNamed:PlaceHolderImg_TTG]];
        self.bottom1.goodsTitleLab.text=videodata.title;
        if(videodata.lists.count>0)
        {
            self.bottom1.goodPicUrl.hidden=NO;
            self.bottom1.goodsDescLab.hidden=NO;
            VideoRelateDYDetailData * detailData=videodata.lists[0];
            [self.bottom1.goodPicUrl sd_setImageWithURL:[NSURL URLWithString:detailData.pict_url] placeholderImage:[UIImage imageNamed:PlaceHolderImg_TTG]];
            self.bottom1.goodsDescLab.text=[NSString stringWithFormat:@"%ld件商品",videodata.lists.count];
        }else
        {
            self.bottom1.goodPicUrl.hidden=YES;
            self.bottom1.goodsDescLab.hidden=YES;
        }
    }
    
    -(void)setVideotype:(VideoControlType)videotype
    {
        _videotype=videotype;
        if(videotype==VideoControlType_Comment)
        {
            self.playBtn.hidden=YES;
            self.bottom1.hidden=NO;
            self.bottom2.hidden=YES;
        }else if(videotype==VideoControlType_Play)
        {
            self.playBtn.hidden=NO;
            self.bottom1.hidden=YES;
            self.bottom2.hidden=NO;
        }else if(videotype==VideoControlType_Nothing)
        {
            self.playBtn.hidden=YES;
            self.bottom1.hidden=YES;
            self.bottom2.hidden=YES;
        }
    }
    
    #pragma mark - Getter
    
    -(VideoMainBottomView *)bottom1
    {
        if(!_bottom1)
        {
            _bottom1=[VideoMainBottomView shareView];
            @weakify(self);
            _bottom1.block = ^(int type) {
                @strongify(self);
                if(type==0)
                {
                    //点击输入框
                    if(self.block)
                    {
                        self.block(ControlBtn_Input);
                    }
                }
                else if(type==1)
                {
                    //点击商品
                    if(self.block)
                    {
                        self.block(ControlBtn_Goods);
                    }
                }
            };
        }
        return _bottom1;
    }
    
    -(VideoMainBottomView2 *)bottom2
    {
        if(!_bottom2)
        {
            _bottom2=[VideoMainBottomView2 shareView];
            @weakify(self);
            _bottom2.block = ^{
                @strongify(self);
                if(self.block)
                {
                    self.block(ControlBtn_Rotate);
                }
            };
        }
        return _bottom2;
    }
    
    -(void)dealloc
    {
        
    }
    

    显示层VideoMainCell.m

    @interface VideoMainCell()<FDanmakuViewProtocol>
    {
        NSTimeInterval clickLikeTime;
    }
    @end
    
    @implementation VideoMainCell
    
    - (void)awakeFromNib {
        [super awakeFromNib];
        
        self.commentBtn.titleLabel.textAlignment=NSTextAlignmentCenter;
        [self.commentBtn addTarget:self action:@selector(clickComment) forControlEvents:UIControlEventTouchUpInside];
        self.likeBtn.titleLabel.textAlignment=NSTextAlignmentCenter;
        [self.likeBtn addTarget:self action:@selector(clickLike:) forControlEvents:UIControlEventTouchUpInside];
        self.shareBtn.titleLabel.textAlignment=NSTextAlignmentCenter;
        [self.shareBtn addTarget:self action:@selector(clickShare) forControlEvents:UIControlEventTouchUpInside];
        self.dmview.delegate=self;
    }
    
    -(void)clickComment
    {
        if(self.block)
        {
            self.block(FuncButtton_Comment);
        }
    }
    
    -(void)clickLike:(UIButton*)btn
    {
        btn.selected=!btn.selected;
        if(!btn.selected)
        {
            self.commentdata.zanNum=[NSString stringWithFormat:@"%d",[self.commentdata.zanNum intValue]-1];
            self.commentdata.isLaud=@"0";
        }else
        {
            self.commentdata.zanNum=[NSString stringWithFormat:@"%d",[self.commentdata.zanNum intValue]+1];
            self.commentdata.isLaud=@"1";
        }
        [self.likeBtn setTitle:self.commentdata.zanNum forState:UIControlStateNormal];
        [self.likeBtn setTitle:self.commentdata.zanNum forState:UIControlStateSelected];
        btn.transform=CGAffineTransformMakeScale(0.6, 0.6);
        [UIView animateWithDuration:0.3 animations:^{
            btn.transform=CGAffineTransformMakeScale(1.4,1.4);
        } completion:^(BOOL finished) {
            btn.transform=CGAffineTransformIdentity;
        }];
        
        if([[NSDate date]timeIntervalSince1970]-clickLikeTime>2)
        {
            if(self.block)
            {
                self.block(FuncButtton_Like);
            }
        }
        clickLikeTime=[[NSDate date]timeIntervalSince1970];
    }
    
    -(void)clickShare
    {
        if(self.block)
        {
            self.block(FuncButtton_Share);
        }
    }
    
    
    #pragma mark - Setter
    
    -(void)setCommentdata:(VideoRelateCommentDYData *)commentdata
    {
        _commentdata=commentdata;
        if([commentdata.isLaud intValue]==0)
        {
            self.likeBtn.selected=NO;
        }else
        {
            self.likeBtn.selected=YES;
        }
        
        [self.commentBtn setTitle:commentdata.commentNum forState:UIControlStateNormal];
        [self.likeBtn setTitle:commentdata.zanNum forState:UIControlStateNormal];
        [self.likeBtn setTitle:commentdata.zanNum forState:UIControlStateSelected];
        [self.shareBtn setTitle:commentdata.zfNum forState:UIControlStateNormal];
        
        if(commentdata.commentNum.length==0)
        {
            [self.commentBtn setTitle:@"0" forState:UIControlStateNormal];
        }
        
        if(commentdata.zanNum.length==0)
        {
            [self.likeBtn setTitle:@"0" forState:UIControlStateNormal];
            [self.likeBtn setTitle:@"0" forState:UIControlStateSelected];
        }
        if(commentdata.zfNum.length==0)
        {
            [self.shareBtn setTitle:@"0" forState:UIControlStateNormal];
        }
        
        if(self.dmview.modelsArr.count==0)
        {
            for (int i=0; i<commentdata.comment_list.count; i++) {
                VideoRelateCommentDYData_detail * detailData=commentdata.comment_list[i];
                FDanmakuModel *model = [[FDanmakuModel alloc]init];
                model.beginTime = [detailData.playTime doubleValue];
                model.liveTime = 5;
                model.content = detailData.content;
                [self.dmview.modelsArr addObject:model];
            }
        }
    }
    
    #pragma mark - FDanmakuView相关
    
    -(NSTimeInterval)currentTime {
        static double time = 0;
        time += 0.3 ;
        return time;
    }
    
    - (UIView *)danmakuViewWithModel:(FDanmakuModel*)model {
        UILabel *label = [UILabel new];
        label.text = model.content;
        label.textColor=[UIColor whiteColor];
        [label sizeToFit];
        return label;
        
    }
    - (void)danmuViewDidClick:(UIView *)danmuView at:(CGPoint)point {
        NSLog(@"%@ %@",danmuView,NSStringFromCGPoint(point));
    }
    

    视频控制器VideoMainViewController.m

    @interface VideoMainViewController ()<UITableViewDelegate,UITableViewDataSource>
    
    @property(nonatomic,strong)NSMutableArray * dataList;
    @property(nonatomic,strong)VideoMainControlView * controlview;
    @property(nonatomic,assign)NSInteger currentIndex;
    @property(nonatomic,strong)AVPlayer *player;
    @property(nonatomic,strong)AVPlayerItem *playeritem;
    @property(nonatomic,strong)AVPlayerLayer * playerlayer;
    @property(nonatomic,strong)UIImageView * coverImgview;
    
    //数据相关
    @property(nonatomic,strong) VideoRelateCommentDYData *commentData;
    
    //UI相关
    @property(nonatomic,weak)VideoMainCell *currentCell;
    @property(nonatomic,strong) VideoCommentListView *commentListview;
    @property(nonatomic,strong) VideoCommentInputView *inputview;
    @property(nonatomic,strong) VideoStoresView *storeview;
    
    @property(nonatomic,assign) BOOL isScreenRight;
    @property(nonatomic, assign) int currentPage;
    
    @end
    
    @implementation VideoMainViewController
    
    
    #pragma mark - 生命周期
    
    -(void)addSubViews
    {
        self.tableview.pagingEnabled=YES;
        self.tableview.scrollsToTop=NO;
        self.tableview.separatorStyle=UITableViewCellSeparatorStyleNone;
        [self.tableview registerNib:[UINib nibWithNibName:@"VideoMainCell" bundle:nil] forCellReuseIdentifier:@"videoMainCell"];
        @weakify(self);
        [[self.backBtn rac_signalForControlEvents:UIControlEventTouchUpInside]subscribeNext:^(__kindof UIControl * _Nullable x) {
            @strongify(self);
            if(self.isScreenRight)
            {
                [[UIDevice currentDevice]setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
                self.isScreenRight=!self.isScreenRight;
            }else
            {
                if(self.playerlayer)
                {
                    [self.playerlayer removeFromSuperlayer];
                }
                if(self.playeritem)
                {
                    self.playeritem=nil;
                }
                if(self.player)
                {
                    [self.player pause];
                    self.player=nil;
                }
                [self.navigationController popViewControllerAnimated:YES];
            }
        }];
        self.currentPage=1;
    }
    
    -(void)registerNotification
    {
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];
        
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWasHidden:) name:UIKeyboardDidHideNotification object:nil];
        
        [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(change:) name:UIDeviceOrientationDidChangeNotification object:nil];
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemDidPlayToEnd:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
    }
    
    -(void)dealloc
    {
        [self.playeritem removeObserver:self forKeyPath:@"status"];
        [self.playeritem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
        [self.playeritem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
        [[NSNotificationCenter defaultCenter]removeObserver:self];
    }
    
    
    -(void)keyboardWasShown:(NSNotification*)notification
    {
        NSDictionary *info = [notification userInfo];
        NSValue *value = [info objectForKey:UIKeyboardFrameBeginUserInfoKey];
        CGSize keyboardSize = [value CGRectValue].size;
        if(self.inputview!=nil)
        {
            self.inputview.frame=CGRectMake(0, 0, SDScreenWidth,self.view.height-keyboardSize.height);
        }
    }
    
    -(void)keyboardWasHidden:(NSNotification*)notification
    {
        if(self.inputview!=nil)
        {
            [self.inputview removeFromSuperview];
            self.inputview=nil;
        }
    }
    
    -(void)change:(NSNotification*)notification
    {
        CGFloat width=[UIScreen mainScreen].bounds.size.width;
        CGFloat height=[UIScreen mainScreen].bounds.size.height;
        if(width/height<1.0)
        {
            //SDLog(@"竖屏:%ld",self.player.currentPlayIndex);
            //[self playTheIndex:self.player.currentPlayIndex];
            //[self playTheVideoAtIndexPath:[NSIndexPath indexPathForRow:self.player.currentPlayIndex inSection:0] scrollToTop:YES];
        }else
        {
            //SDLog(@"横屏:%ld",self.player.currentPlayIndex);
            //[self playTheIndex:self.player.currentPlayIndex];
            //[self playTheVideoAtIndexPath:[NSIndexPath indexPathForRow:self.player.currentPlayIndex inSection:0] scrollToTop:YES];
        }
    }
    
    -(void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        self.fd_interactivePopDisabled = YES;
        self.navigationController.fd_fullscreenPopGestureRecognizer.enabled = NO;
        [self.navigationController setNavigationBarHidden:YES animated:animated];
    }
    
    -(void)viewDidAppear:(BOOL)animated
    {
        [super viewDidAppear:animated];
        if(self.player)
        {
            [self.player play];
        }
    }
    
    -(void)viewDidDisappear:(BOOL)animated
    {
        [super viewDidDisappear:animated];
        if(self.player)
        {
            [self.player pause];
        }
    }
    
    #pragma mark - ScrollView代理
    
    -(void)rotateScreen
    {
        if(self.isScreenRight)
        {
            [[UIDevice currentDevice]setValue:@(UIInterfaceOrientationPortrait) forKey:@"orientation"];
        }else
        {
            [[UIDevice currentDevice]setValue:@(UIInterfaceOrientationLandscapeRight) forKey:@"orientation"];
        }
        //点击旋转
        self.isScreenRight=!self.isScreenRight;
    }
    
    -(void)scrollViewDidScroll:(UIScrollView *)scrollView{
        
    }
    
    -(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
    {
        if(scrollView==self.tableview)
        {
            CGPoint point =  [scrollView.panGestureRecognizer translationInView:self.view];
            if (point.y>0) {
                SDLog(@"------往上滚动");
            }else{
                SDLog(@"------往下滚动");
            }
        }
    }
    
    -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
    {
        if(scrollView==self.tableview)
        {
            NSArray<NSIndexPath*> * arr=[self.tableview indexPathsForVisibleRows];
            for (int i=0; i<arr.count; i++) {
                NSIndexPath * indexpath=arr[i];
                if(indexpath.row==self.currentIndex)
                {
                    return;
                }
                [self playVideoAtIndex:indexpath];
            }
        }
        
    //    if(self.dataList.count-1==self.currentIndex)
    //    {
    //        self.currentPage++;
    //        [self getVideoData];
    //    }
    }
    
    #pragma mark - TableView代理和数据源
    
    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return self.dataList.count;
    }
    
    -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return SDScreenHeight;
    }
    
    -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        VideoMainCell * cell= [tableView dequeueReusableCellWithIdentifier:@"videoMainCell"];
        cell.selectionStyle=UITableViewCellSelectionStyleNone;
        VideoRelateDYData * data=self.dataList[indexPath.row];
        [cell.coverImg setImage:data.firstvideoImg];
        cell.commentdata=self.commentData;
        @weakify(self);
        cell.block = ^(FuncButtton funcBtn) {
            @strongify(self);
            if(funcBtn==FuncButtton_Comment)
            {
                SDLog(@"评论列表");
                self.commentListview=[VideoCommentListView shareView];
                VideoRelateDYData * videoData=self.dataList[indexPath.row];
                self.commentListview.vid=videoData.id;
                [self.commentListview show:^{
                    [self.commentListview removeFromSuperview];
                    self.commentListview=nil;
                } andtextBlock:^{
                    [self presentToLoginController:^(BOOL success) {
                        if(success)
                        {
                            self.inputview=[VideoCommentInputView shareView];
                            [self.inputview show:CGRectMake(0, 0, SDScreenWidth,300) andClose:^{
                                [self.inputview removeFromSuperview];
                                self.inputview=nil;
                            } andText:^(NSString *text) {
                                VideoRelateDYData * videoData=self.dataList[indexPath.row];
                                [self sendCommentData:videoData.id andContent:text andTime:[NSString stringWithFormat:@"%lld",self.player.currentItem.currentTime.value/self.player.currentItem.currentTime.timescale] andview:self.commentListview];
                            }];
                            [self.inputview.textview becomeFirstResponder];
                        }
                    }];
                }];
            }else if(funcBtn==FuncButtton_Like)
            {
                SDLog(@"点赞");
                [self presentToLoginController:^(BOOL success) {
                    if(success)
                    {
                        VideoRelateDYData * videoData=self.dataList[indexPath.row];
                        [self sendLikeData:videoData.id];
                    }
                }];
                
            }else if(funcBtn==FuncButtton_Share)
            {
                SDLog(@"分享");
                [self presentToLoginController:^(BOOL success) {
                    if(success)
                    {
                        VideoRelateDYData * videoData=self.dataList[indexPath.row];
                        [self sendShareData:videoData.id];
                        NSString * url=[NSString stringWithFormat:@"https://gl.koalamom.net/h5/video.html?videoid=%@",videoData.id];
                        [self shareWebOfThirdparty:InvateFriendsTitle andDesc:InvateFriendsDesc andIcon:[UIImage imageNamed:@"logo3"] andwebUrl:url];
                    }
                }];
                
            }
        };
        return cell;
    }
    
    
    #pragma mark - 数据源
    
    -(void)getInitData
    {
        [self getVideoData];
    }
    
    
    -(void)dealLastData
    {
        [SVProgressHUD showWithStatus:@"加载中..."];
        for (int i=0; i<self.videoArr.count; i++) {
            videoModel * originData=self.videoArr[i];
            VideoRelateDYData * resData=[[VideoRelateDYData alloc]init];
            resData.id=[NSString stringWithFormat:@"%ld",(long)originData.ID] ;
            resData.vid=originData.vid;
            resData.title=originData.title;
            resData.desc=originData.desc;
            resData.coverImg=originData.coverImg;
            resData.addtime=originData.addtime;
            resData.video_url=originData.video_url;
            NSMutableArray * tempList=[NSMutableArray array];
            for (int i=0; i<originData.lists.count; i++) {
                VideoRelateDYDetailData * data=originData.lists[i];
                [tempList addObject:data];
            }
            resData.lists=tempList;
            resData.firstvideoImg=[self getVideoPreViewImage:[NSURL URLWithString:originData.video_url]];
            [self.dataList addObject:resData];
        }
        [SVProgressHUD dismiss];
        [self.tableview reloadData];
        if(self.dataList.count>0)
        {
            [self.tableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.index inSection:0] atScrollPosition:UITableViewScrollPositionNone animated:NO];
            [self playVideoAtIndex:[NSIndexPath indexPathForRow:self.index inSection:0]];
        }
    }
    
    -(void)getVideoData
    {
        [SVProgressHUD showWithStatus:@"加载中..."];
        NSMutableDictionary * params = [NSMutableDictionary dictionary];
        params[@"pageno"]=@(self.currentPage);
        params[@"pagesize"]=@10;
        [JSXHttpTool Post:Interface_VideoList params:params success:^(id json) {
            [SVProgressHUD dismiss];
            NSString * returnCode = json[@"status"];
            NSMutableArray * data = json[@"data"];
            if([returnCode intValue]==40001)
            {
                for (int i=0; i<data.count; i++) {
                    NSDictionary * dict=data[i];
                    VideoRelateDYData * data=[VideoRelateDYData mj_objectWithKeyValues:dict];
                    [self.dataList addObject:data];
                    //self.playeritem=[AVPlayerItem playerItemWithURL:[NSURL URLWithString:data.video_url]];
                    data.firstvideoImg=[self getVideoPreViewImage:[NSURL URLWithString:data.video_url]];
                }
                [self.tableview reloadData];
            }
            
            if(data.count>0)
            {
                [self.tableview scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:self.index inSection:0] atScrollPosition:UITableViewScrollPositionNone animated:NO];
                [self playVideoAtIndex:[NSIndexPath indexPathForRow:self.index inSection:0]];
            }
        } failure:^(NSError *error) {
            [SVProgressHUD dismiss];
        }];
    }
    -(void)getCommentData:(NSString*)vid
    {
        NSMutableDictionary * params = [NSMutableDictionary dictionary];
        params[@"vid"]=vid;
        params[@"uid"]=[loginUserDataTools getUserInfo].uid;
        params[@"pageno"]=@1;
        params[@"pagesize"]=@30;
        [JSXHttpTool Post:Interface_VideoCommentList params:params success:^(id json) {
            NSString * returnCode = json[@"status"];
            NSDictionary * data = json[@"data"];
            if([returnCode intValue]==40001)
            {
                self.commentData=[VideoRelateCommentDYData mj_objectWithKeyValues:data];
            }else
            {
                self.commentData=[[VideoRelateCommentDYData alloc]init];
            }
            [self.tableview reloadData];
        } failure:^(NSError *error) {
        }];
    }
    
    -(void)sendCommentData:(NSString*)vid andContent:(NSString*)content andTime:(NSString*)time andview:(VideoCommentListView*)commentListview
    {
        NSMutableDictionary * params = [NSMutableDictionary dictionary];
        params[@"vid"]=vid;
        params[@"uid"]=[loginUserDataTools getUserInfo].uid;
        params[@"content"]=content;
        params[@"ptime"]=time;
        [JSXHttpTool Post:Interface_VideoAddComment params:params success:^(id json) {
            NSString * returnCode = json[@"status"];
            if([returnCode intValue]==40001)
            {
                if(commentListview)
                {
                    commentListview.vid=vid;
                }
                [self getCommentData:vid];
            }
        } failure:^(NSError *error) {
        }];
    }
    
    -(void)sendLikeData:(NSString*)vid
    {
        NSMutableDictionary * params = [NSMutableDictionary dictionary];
        params[@"vid"]=vid;
        params[@"uid"]=[loginUserDataTools getUserInfo].uid;
        [JSXHttpTool Post:Interface_VideoAddLike params:params success:^(id json) {
            NSString * returnCode = json[@"status"];
            if([returnCode intValue]==40001)
            {
            }
        } failure:^(NSError *error) {
        }];
    }
    
    -(void)sendShareData:(NSString*)vid
    {
        NSMutableDictionary * params = [NSMutableDictionary dictionary];
        params[@"vid"]=vid;
        [JSXHttpTool Post:Interface_VideoAddShare params:params success:^(id json) {
            NSString * returnCode = json[@"status"];
            if([returnCode intValue]==40001)
            {
            }
        } failure:^(NSError *error) {
        }];
    }
    
    // 获取视频第一帧
    - (UIImage*)getVideoPreViewImage:(NSURL *)path
    {
        AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:path options:nil];
        AVAssetImageGenerator *assetGen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
        assetGen.appliesPreferredTrackTransform = YES;
        CMTime time = CMTimeMakeWithSeconds(0.0, 600);
        NSError *error = nil;
        CMTime actualTime;
        CGImageRef image = [assetGen copyCGImageAtTime:time actualTime:&actualTime error:&error];
        UIImage *videoImage = [[UIImage alloc] initWithCGImage:image];
        CGImageRelease(image);
        return videoImage;
    }
    
    #pragma mark - 播放器相关
    
    -(void)playVideoAtIndex:(NSIndexPath*)indexpath
    {
        //移除AVPlayer控制层和显示层
        if(self.controlview)
        {
            [self.controlview removeFromSuperview];
            self.controlview=nil;
        }
        if(self.playerlayer)
        {
            [self.playerlayer removeFromSuperlayer];
            self.playerlayer=nil;
        }
        
            
        //如果还是原来的页面,则不做加载
        if(indexpath.row>=self.dataList.count)
        {
            return;
        }
        
        VideoMainCell * currentCell=(VideoMainCell*)[self.tableview cellForRowAtIndexPath:indexpath];
        self.currentCell=currentCell;
        self.currentIndex=indexpath.row;
        VideoRelateDYData * data= self.dataList[self.currentIndex];
        [self getCommentData:data.id];
        
        //创建新的AVPlayerItem,AVPlayerLayer,切换AVPlayer当前AVPlayerItem,并监听AVPlayerItem的状态
        AVPlayerItem * item=[AVPlayerItem playerItemWithURL:[NSURL URLWithString:data.video_url]];
        self.playeritem=item;
        [self.playeritem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
        [self.playeritem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
        [self.playeritem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
        [self.player replaceCurrentItemWithPlayerItem:self.playeritem];
        
        //创建控制层管理当前AVPlayer的播放进度状态
        self.controlview.player=self.player;
        self.controlview.videodata=self.dataList[self.currentIndex];
        self.controlview.videotype=VideoControlType_Comment;
        
        //使用控制层管理功能函数
        @weakify(self);
        self.controlview.block = ^(ControlBtn controlBtn) {
            @strongify(self);
            if(controlBtn==ControlBtn_Goods)
            {
                SDLog(@"商品列表");
                [self.controlview setVideotype:VideoControlType_Nothing];
                VideoRelateDYData * goodsData=self.dataList[self.currentIndex];
                if(goodsData.lists.count==1)
                {
                    VideoRelateDYDetailData * data=goodsData.lists[0];
                    SearchType searchType=SearchType_tb;
                    if ([data.user_type isEqualToString:@"0"] || [data.user_type isEqualToString:@"1"]) {
                            searchType=SearchType_tb;
                    }else if ([data.user_type isEqualToString:@"2"]){
                            searchType=SearchType_pdd;
                    }else if ([data.user_type isEqualToString:@"3"]){
                            searchType=SearchType_jd;
                    }
                    if(self.isScreenRight)
                    {
                            [self rotateScreen];
                    }
                    [self pushToStoreDetailViewControler:data.num_iid andSearchType:searchType];
                    }else
                    {
                        self.storeview=[VideoStoresView shareView];
                        self.storeview.goodsData=goodsData;
                        [self.storeview show:^{
                            [self.controlview setVideotype:VideoControlType_Comment];
                            [self.storeview removeFromSuperview];
                            self.storeview=nil;
                    } andGoods:^(VideoRelateDYDetailData *data) {
                            [self.controlview setVideotype:VideoControlType_Comment];
                            [self.storeview removeFromSuperview];
                            self.storeview=nil;
                            SearchType searchType=SearchType_tb;
                            if ([data.user_type isEqualToString:@"0"] || [data.user_type isEqualToString:@"1"]) {
                                searchType=SearchType_tb;
                            }else if ([data.user_type isEqualToString:@"2"]){
                                searchType=SearchType_pdd;
                            }else if ([data.user_type isEqualToString:@"3"]){
                                searchType=SearchType_jd;
                            }
                            if(self.isScreenRight)
                            {
                                [self rotateScreen];
                            }
                            [self pushToStoreDetailViewControler:data.num_iid andSearchType:searchType];
                        }];
                    }
                }else if(controlBtn==ControlBtn_Rotate)
                {
        
                }else if(controlBtn==ControlBtn_Input)
                {
                    SDLog(@"输入");
                    [self presentToLoginController:^(BOOL success) {
                        if(success)
                        {
                            [self.controlview setVideotype:VideoControlType_Nothing];
                            self.inputview=[VideoCommentInputView shareView];
                            [self.inputview show:CGRectMake(0, 0, SDScreenWidth,300) andClose:^{
                                [self.inputview removeFromSuperview];
                                self.inputview=nil;
                            } andText:^(NSString *text) {
                                VideoRelateDYData * videoData=self.dataList[self.currentIndex];
                                [self sendCommentData:videoData.id andContent:text andTime:[NSString stringWithFormat:@"%lld",self.player.currentItem.currentTime.value/self.player.currentItem.currentTime.timescale] andview:self.commentListview];
                            }];
                            [self.inputview.textview becomeFirstResponder];
                        }
                    }];
                }
            };
            self.playerlayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
            self.playerlayer.backgroundColor = [UIColor blackColor].CGColor;
            self.playerlayer.frame = [UIScreen mainScreen].bounds;
            [self.currentCell.coverImg.layer addSublayer:self.playerlayer];
        
            //添加第一帧占位图覆盖到当前Cell上
            if(!self.coverImgview)
            {
                self.coverImgview=[[UIImageView alloc]initWithImage:data.firstvideoImg];
                self.coverImgview.frame=[UIScreen mainScreen].bounds;
                self.coverImgview.contentMode=UIViewContentModeScaleAspectFit;
                [self.currentCell.coverImg addSubview:self.coverImgview];
            }
    }
    
    - (void)playerItemDidPlayToEnd:(NSNotification *)notification{
        [self rerunPlayVideo];
    }
    -(void)rerunPlayVideo{
        if (!self.player) {
            return;
        }
        CGFloat a=0;
        NSInteger dragedSeconds = floorf(a);
        CMTime dragedCMTime = CMTimeMake(dragedSeconds, 1);
        [self.player seekToTime:dragedCMTime];
        [self.player play];
    }
    
    
    
    //监听获得消息
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
    {
        if(object==self.playeritem)
        {
            AVPlayerItem *playerItem = (AVPlayerItem *)object;
            if ([keyPath isEqualToString:@"status"]) {
                if ([playerItem status] == AVPlayerStatusReadyToPlay) {
                    //播放器准备完成后,移除占位图,添加控制层
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        [self.coverImgview removeFromSuperview];
                        self.coverImgview=nil;
                        [self.currentCell.coverImg addSubview:self.controlview];
                    });
                }else if ([playerItem status] == AVPlayerStatusFailed || [playerItem status] == AVPlayerStatusUnknown) {
                    [JSXHUD showMessage:@"播放失败"];
                    [self.player pause];
                }
            }else if ([keyPath isEqualToString:@"playbackBufferEmpty"]) { //监听播放器在缓冲数据的状态
                SDLog(@"缓冲不足暂停了");
                [self.player pause];
            }else if ([keyPath isEqualToString:@"playbackLikelyToKeepUp"]) {
                SDLog(@"缓冲达到可播放程度了");
                //由于 AVPlayer 缓存不足就会自动暂停,所以缓存充足了需要手动播放,才能继续播放
                [self.player play];
                
            }
        }
    }
    
    
    #pragma mark - Getter
    
    -(VideoMainControlView *)controlview
    {
        if(!_controlview)
        {
            _controlview=[VideoMainControlView shareView];
            [_controlview setUserInteractionEnabled:YES];
            _controlview.frame=[UIScreen mainScreen].bounds;
        }
        return _controlview;
    }
    
    -(NSMutableArray *)dataList
    {
        if(!_dataList)
        {
            _dataList=[NSMutableArray array];
        }
        return _dataList;
    }
    
    -(AVPlayer *)player
    {
        if(!_player&&self.playeritem)
        {
            _player=[AVPlayer playerWithPlayerItem:self.playeritem];
        }
        return _player;
    }
    

    相关文章

      网友评论

          本文标题:AVFoundation框架

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