首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从dji无人机到本地服务器的实况转播的最佳设置是什么?

从dji无人机到本地服务器的实况转播的最佳设置是什么?
EN

Stack Overflow用户
提问于 2019-08-06 14:47:58
回答 1查看 964关注 0票数 0

我需要使用Android 将DJI无人机的实时视频数据传输到本地服务器。来自服务器的视频数据将由其他软件(人工识别)处理。什么是证明最佳流媒体质量的推荐方法?我们使用Mavic 2进行开发,Matrice 210 v2 RTK用于生产目的。因此,答案应该主要集中在马特里斯210 v2 RTK的可能性上。

目前,我们使用这样的DJIs Livestreammanager

代码语言:javascript
运行
复制
DJISDKManager.getInstance().getLiveStreamManager().setLiveUrl( rtmpURL );
DJISDKManager.getInstance().getLiveStreamManager().startStream(); 

我们使用带有rtmp模块的nginx Webserver作为流端点,将流推送到网络,同时将流记录到磁盘。这是可行的,但我们看到这种流的质量很差。这股气流经常会滞后,它会加速无人机的移动。

由于我不熟悉视频处理,我需要建议如何解决这一需求。我的问题是:-Do,我需要使用ffmpeg库对流进行某种方式的预处理?对于后端服务器,-Is有比nginx+rtmp模块更好的解决方案吗?-Would是否有可能利用matrice遥控器的输出来提供更高的质量?

EN

回答 1

Stack Overflow用户

发布于 2019-11-11 14:03:21

-Do我需要使用ffmpeg库以某种方式对流进行预处理?

如果您想自己处理流,则需要使用ffmpeg将原始的livestream解码为实际的帧。见我对问题3的答复。

-Is有比nginx+rtmp模块更好的后端服务器解决方案吗?

这在很大程度上取决于用例。如果你对视频质量不满意,用ffmpeg解码流会更可靠。实际上,我不知道nginx+rtmp自动完成了多少任务,因为我从未使用过它。

-Would是否可以利用矩阵遥控器的输出来提供更高的质量?

可以使用SDK访问的原始livestream是一个原始的h264或h265流(NAL ),这取决于所使用的无人机模型。

在我的应用程序中,我将VideoDataCallback在onComponentChange方法中注册到相机componentKey中,并通过LocalBroadcastManager发送出去。然后,只要订阅广播,就可以在应用程序中的任何地方访问livestream。

代码语言:javascript
运行
复制
private VideoFeeder.VideoDataListener videoDataCallback = (videoBuffer, size) -> {
        Intent intent = new Intent("videoStream");
        intent.putExtra("content", videoBuffer);
        intent.putExtra("size", size);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    };

通过网络发送livestream的一个简单方法是使用TCP-套接字:启动线程并使用IP和端口打开套接字:

代码语言:javascript
运行
复制
this.s = new Socket(this.ipAddress, this.port);
this.s.setKeepAlive(true);
this.s.setTcpNoDelay(true);
this.dos = new DataOutputStream(this.s.getOutputStream());

如果连接/发送失败,设置一个循环来重新连接它。在BroadcastReceiver中,通过分析大小来累积字节(bos是一个简单的ByteArrayOutputStream):

代码语言:javascript
运行
复制
private BroadcastReceiver frameReceiverNAL = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
        try {
            int frameSize = intent.getIntExtra("size", 0);

            if(frameSize == 2032) {
                bos.write(intent.getByteArrayExtra("content"), 0, frameSize);
            } else {
                bos.write(intent.getByteArrayExtra("content"), 0, frameSize);
                final byte[] sendUnit = bos.toByteArray();
                bos.reset();
                if(numAsyncTasks < MAX_NUMBER_ASYNCTASKS) {
                    numAsyncTasks++;
                    AsyncTask.execute(() -> sendNAL(sendUnit));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        }
    };

private void sendNAL(byte[] sendUnit){
        try {
            if(dos != null) {
                dos.write(sendUnit);
                dos.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        numAsyncTasks--;
    }

如果MAX_NUMBER_ASYNCTASKS不能足够快地发送NAL(导致500+在崩溃前未完成AsyncTasks ),则它被用作上限,以防止应用程序崩溃。在我的例子中,我将数字设置为128。

在服务器端,您需要创建一个ServerSocket来接收byteStream。根据编程语言的不同,您可以直接使用ffmpeg,也可以使用本机接口,例如bytedeco从流创建框架。

另一种方法是将智能手机上的流解码为YUV图像(每个图像为2.8MB),并可选择地将它们转换为jpeg,以缩小单个帧的大小(每个帧约100 of )。然后,可以使用TCP套接字将YUV或jpeg映像发送到服务器。SDK提供了在类DJICodecManager中创建YUV图像的方法,教程中包含将它们转换为JPEG的示例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57378706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档