关于大疆无人机的Webrtc

文章讲述了在没有本地摄像头的情况下,如何通过实现WebRTC的VideoCapturer接口来捕获大疆无人机的视频流。具体流程包括创建自定义捕获器,处理YUV数据,以及初始化解码器并添加数据监听器,以便将无人机的视频流作为本地流使用。
摘要由CSDN通过智能技术生成

关于大疆无人机的Webrtc

阐述问题

在做webrtc期间,都是获取本地的摄像头,那么问题来了,如果没有本地摄像头怎么办?就像大疆无人机,摄像头在飞机上,遥控器根本没有摄像头,你总不能在遥控上插一个摄像头吧?那还叫无人机吗?

流程说明

自创建一个捕获器来捕获飞机的视频流设置为自己的本地流(项目是基于大疆V5.20,获取YUV数据)

实现VideoCapturer接口

在这里插入图片描述

  1. 初始化捕捉器
            dji_yuv_data_callback_ = new YuvDataListener() {
                @Override
                public void onReceive(MediaFormat mediaFormat, byte[] data, int width, int height) {
                    if (is_rate_time) {
                        JavaI420Buffer buffer = JavaI420Buffer.allocate(width, height);
                        ByteBuffer dataY = buffer.getDataY();
                        ByteBuffer dataU = buffer.getDataU();
                        ByteBuffer dataV = buffer.getDataV();
                        final byte[] bytes = data;

                        int yLen = width * height;
                        int uLen = (width + 1) / 2 * ((height + 1) / 2);
                        int vLen = uLen;

                        int color_format = mediaFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT);
                        switch (color_format) {
                            case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar:
                                byte[] ubytes = new byte[uLen];
                                byte[] vbytes = new byte[vLen];
                                for (int i = 0; i < uLen; i++) {
                                    ubytes[i] = bytes[yLen + 2 * i];
                                    vbytes[i] = bytes[yLen + 2 * i + 1];
                                }
                                dataY.put(bytes, 0, yLen);
                                dataU.put(ubytes, 0, uLen);
                                dataV.put(vbytes, 0, vLen);
                                break;
                            case MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420Planar:
                                int yPos = 0;
                                int uPos = yPos + yLen;
                                int vPos = uPos + uLen;
                                dataY.put(bytes, yPos, yLen);
                                dataU.put(bytes, uPos, uLen);
                                dataV.put(bytes, vPos, vLen);

                                break;
                            default:
                                break;
                        }
                        long captureTimeNs = TimeUnit.MILLISECONDS.toNanos(SystemClock.elapsedRealtime());
                        VideoFrame videoFrame = new VideoFrame(buffer, 0, captureTimeNs);
                        capturer_observer_.onFrameCaptured(videoFrame);
                        videoFrame.release();
                    }
                }
            };
            capturer_observer_ = capturerObserver;
  1. 开始捕捉
            frame_width_ = width;
            frame_height_ = height;
            frame_rate_ = framerate;
            timer.schedule(tickTask, 0L, (long) (1000 / frame_rate_));
            //获取可用的渲染页
            surfaceViewRenderer = new SurfaceViewRenderer(_context);
            surfaceViewRenderer.init(_rootEglBase.getEglBaseContext(), null);
            surfaceViewRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
            surfaceViewRenderer.setMirror(true);
            //创建解码器
            iVideoDecoder = new CapturerDefault.Decodec(_context, videoChannel.getVideoChannelType(), DecoderOutputMode.YUV_MODE,
                    surfaceViewRenderer.getHandler(), frame_width_, frame_height_, true);
            iVideoDecoder.addDecoderStateChangeListener(new DecoderStateChangeListener() {
                @Override
                public void onUpdate(DecoderState from, DecoderState to) {
                    System.out.println("解码器状态" + from + "----------" + to);
                }
            });
            //设置数据监听
            iVideoDecoder.addYuvDataListener(dji_yuv_data_callback_);
  1. 继承大疆解码器
//因为获取YUV数据需要在解码器上绑定监听器,在初始化的时候做了这一步
       private static class Decodec extends VideoDecoder {
            public Decodec(Context context, VideoChannelType channelType, DecoderOutputMode outputMode, Object outputSurface, int width, int height, boolean isForLiveStream) {
                super(context, channelType, outputMode, outputSurface, width, height, isForLiveStream);
            }
        }
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猿小路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值