美文网首页OC开发
iOS视频渲染(大小屏切换,小屏拖拽,后台唤醒)

iOS视频渲染(大小屏切换,小屏拖拽,后台唤醒)

作者: 远方的枸杞 | 来源:发表于2017-09-11 11:39 被阅读265次

    前言

    上一篇 视频采集
    demo地址

    正文

    ios中视频流渲染有三种方法:

    AVCaptureVideoPreviewLayer:视频采集时回显使用的图层, 调用简单,功能较少。

    AVSampleBufferDisplayLayer:CPU渲染yuv数据也可直接渲染压缩的视频数据,小巧方便,功能比较丰富,可操作性强。

    openGl:GPU渲染,功能强大,性能卓越,使用复杂。

    本文主要介绍AVSampleBufferDisplayLayer,demo分为两个类,大屏和小屏,小屏继承自大屏类.

    openGl推荐参考:落影loyinglin

    创建渲染图层

    - (void)createLayer
    {
        if (!self.buffer_layer)
        {
            self.buffer_layer = [[AVSampleBufferDisplayLayer alloc]init];
            self.buffer_layer.frame = self.bounds;
            self.buffer_layer.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
            /*!
             @constant      AVLayerVideoGravityResizeAspect  根据图像像素比例 绘制图像 图像会填充不满图层size
             @abstract      Preserve aspect ratio; fit within layer bounds.
             
             @constant      AVLayerVideoGravityResizeAspectFill  根据像素比例 填充图层 画面会超出图层size
             @abstract      Preserve aspect ratio; fill layer bounds.
             
             @constant      AVLayerVideoGravityResize   拉伸 用这个自适应不同size图层最好
             @abstract      Stretch to fill layer bounds.
             */
            self.buffer_layer.videoGravity = AVLayerVideoGravityResizeAspect;
            //不透明
            self.buffer_layer.opaque = YES;
            [self.layer addSublayer:self.buffer_layer];
        }
        else
        {
            [CATransaction begin];
            [CATransaction setDisableActions:YES];
            self.buffer_layer.bounds = self.qlframe;
            self.buffer_layer.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
            [CATransaction commit];
        }
    }
    

    播放

    #pragma mark - play
    // 每来一帧数据进行缓存, 从后台模式返回后, 重启layer
    - (void)play:(CMSampleBufferRef)buffer
    {
        if (buffer)
        {
            [_buffer_layer enqueueSampleBuffer:buffer];
            if (_buffer_layer.status == AVQueuedSampleBufferRenderingStatusFailed)
            {
                //后台唤醒重启渲染层
                if (-11847 == _buffer_layer.error.code)
                {
                    NSLog(@"11111");
                    [self rebuildSampleBufferDisplayLayer];
                }
                else
                {
                    [self rebuildSampleBufferDisplayLayer];
                    NSLog(@"%s 第%d行 %@",__func__,__LINE__,_buffer_layer.error.description);
                }
            }
        }
    }
    
    #pragma mark - 重启渲染layer
    - (void)rebuildSampleBufferDisplayLayer
    {
        [self remove_layer];
        [self createLayer];
    }
    
    - (void)remove_layer
    {
        if (self.buffer_layer)
        {
            [self.buffer_layer stopRequestingMediaData];
            [self.buffer_layer removeFromSuperlayer];
            self.buffer_layer = nil;
        }
    }
    

    小屏

    小屏的切换和拖拽功能只是添加了两个手势

    - (instancetype)initWithFrame:(CGRect)frame and_touchBlock:(touchBlock)touch_block and_panBlcok:(panblock)pan_block
    {
        if (self = [super initWithFrame:frame and_touchBlock:touch_block and_panBlcok:pan_block])
        {
            UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tap:)];
            [self addGestureRecognizer:tap];
            UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pan:)];
            [self addGestureRecognizer:pan];
        }
        return self;
    }
    
    - (void)tap:(UITapGestureRecognizer*)tap
    {
         // 切换大小屏时,在此block内 调用flushAndRemoveImage 清除缓存
        self.touch_block();
    }
    
    - (void)pan:(UIPanGestureRecognizer*)pan
    {
        self.pan_block(pan);
    }
    

    最后

    demo地址
    下一篇:音频采集播放与编解码
    欢迎交流指正

    相关文章

      网友评论

      • feng55:ios11上面使用AVSampleBufferDisplayLayer会导致手机死机,你给的demo也有同样的问题。
        feng55:@远方的枸杞 几乎百分之百出现手机卡死现象,你写的还好。我写的AVSampleBufferDisplayLayer渲染画面非常不流畅。你这个不动的话还能用
        feng55:@远方的枸杞 你可以向上拉出控制栏试试
        远方的枸杞:你好,我的手机已升级为ios11,刚才测试了一下demo ,并没出现死机问题.请教下你指的死机在什么情况下出现的

      本文标题:iOS视频渲染(大小屏切换,小屏拖拽,后台唤醒)

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