Android TRTC实时音视频 推 RTSP视频流方法

2023-11-27 06:10

本文主要是介绍Android TRTC实时音视频 推 RTSP视频流方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

        近期有个Android任务:项目中原本集成了TRTC腾讯云实时音视频SDK,要是有过了解的朋友应该就知道,加入房间后,默认是采用手机的前后摄像头进行视频数据采集,并推流。如今的任务是需要将特定外接摄像头采集的视频也集成到房间中,而外接摄像头采集的是rtsp数据视频流。于是就有了今天的话题blog。

总体思路

        1.既然要在TRTC 中推自己的数据流,那么肯定要按照TRTC中的数据格式去传输视频数据。从TRTC SDK中可以查到,我们可以自定义采集视频数据。并通过sendCustomVideoData()方法进行数据传输。具体可以去查SDK文档,写的挺详细的,这里就不赘述了.附截图。sendCustomVideoData()中有两种数据传输方案,按需设置即可。

         2.数据格式解决了,那就需要看数据来源了。一般外接摄像头采集视频数据后都是rtsp流形式。那么关键问题就是如何获取到rtsp流数据,并转换为TRTC所需要的视频传输格式。

 正文

        既然需要获取rtsp流数据并进行转换。那么如何获取rtsp流中的原数据呢?

        小编这里提供一些可行的方法:1.FFMPEG  2.OPENCV 3.JAVACV

        以上三种方法都是可行的,小编这里使用的是JAVACV,主要是方便集成。

        1.JAVACV集成

                 1.1 build.gradle添加依赖

    //JavaCVdef javacvVersion = '1.4.2'def ffmpegVersion = '4.0.1'def opencvVersion = '3.4.2'implementation(group: 'org.bytedeco', name: 'javacv-platform', version: javacvVersion) {exclude group: 'org.bytedeco.javacpp-presets'}implementation group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: "${ffmpegVersion}-${javacvVersion}"implementation group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: "${ffmpegVersion}-${javacvVersion}", classifier: 'android-arm' // for 'armeabi-v7a'implementation group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: "${ffmpegVersion}-${javacvVersion}", classifier: 'android-arm64' // for 'arm64-v8a'implementation group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: "${opencvVersion}-${javacvVersion}"implementation group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: "${opencvVersion}-${javacvVersion}", classifier: 'android-arm' // for 'armeabi-v7a'implementation group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: "${opencvVersion}-${javacvVersion}", classifier: 'android-arm64' // for 'arm64-v8a'

        2.根据根据rtsp获取帧数据

            FFmpegFrameGrabber grabber = FFmpegFrameGrabber.createDefault(url);grabber.setOption("rtsp_transport", "tcp"); grabber.setImageWidth(hotWidth);grabber.setImageHeight(hotHeight);grabber.setPixelFormat(AV_PIX_FMT_RGBA);System.out.println("grabber start");grabber.start();AndroidFrameConverter converter = new AndroidFrameConverter();while (HotRunning) {Frame frame = grabber.grabImage();final Bitmap bmp = converter.convert(frame);}

        其中url就是rtsp地址.例如:rtsp://192.168.2.199:8554/stream1

        最后frame就是得到的帧数据,我们将其转换为bitmap,就可以直接显示出来了。

      2.数据转换

         根据TRTC SDK数据格式要求,我们需要将bitmap转换成YUV格式数据,小编这里是将bitmap转换成NV21格式的数据。

    public byte[] getNV21(int inputWidth, int inputHeight, Bitmap scaled) {int[] argb = new int[inputWidth * inputHeight];scaled.getPixels(argb, 0, inputWidth, 0, 0, inputWidth, inputHeight);byte[] yuv = new byte[inputWidth * inputHeight * 3 / 2];encodeYUV420SP(yuv, argb, inputWidth, inputHeight);//scaled.recycle();return yuv;}public static void encodeYUV420SP(byte[] yuv420sp, int[] argb, int width, int height) {final int frameSize = width * height;int yIndex = 0;int uvIndex = frameSize;int a, R, G, B, Y, U, V;int index = 0;for (int j = 0; j < height; j++) {for (int i = 0; i < width; i++) {a = (argb[index] & 0xff000000) >> 24; // a is not used obviouslyR = (argb[index] & 0xff0000) >> 16;G = (argb[index] & 0xff00) >> 8;B = (argb[index] & 0xff) >> 0;Y = ( (  66 * R + 129 * G +  25 * B + 128) >> 8) +  16;U = ( ( -38 * R -  74 * G + 112 * B + 128) >> 8) + 128;V = ( ( 112 * R -  94 * G -  18 * B + 128) >> 8) + 128;yuv420sp[yIndex++] = (byte) ((Y < 0) ? 0 : ((Y > 255) ? 255 : Y));if (j % 2 == 0 && index % 2 == 0) {yuv420sp[uvIndex++] = (byte)((V<0) ? 0 : ((V > 255) ? 255 : V));yuv420sp[uvIndex++] = (byte)((U<0) ? 0 : ((U > 255) ? 255 : U));}index ++;}}}

3.数据推流

        通过getNV21()方法将数据转换好之后,最后再填入sendCustomVideoData()方法中即可。

TRTCCloudDef.TRTCVideoFrame videoFrame = new TRTCCloudDef.TRTCVideoFrame();//videoFrame.pixelFormat = TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_I420;videoFrame.pixelFormat = TRTCCloudDef.TRTC_VIDEO_PIXEL_FORMAT_NV21;videoFrame.bufferType = TRTCCloudDef.TRTC_VIDEO_BUFFER_TYPE_BYTE_ARRAY;videoFrame.data = sendData;videoFrame.width = hotWidth;videoFrame.height = hotHeight;videoFrame.timestamp = 0;mTRTCCloud.sendCustomVideoData(TRTCCloudDef.TRTC_VIDEO_STREAM_TYPE_BIG,videoFrame);

其中sebdData就是getNV21()转换之后的数据。

至此功能完成。

注意事项

        1.需要将TRTC采集模式设置为自定义采集。

        2.javacv 的 FFmpegFrameGrabber 是采集到每一帧的数据,所以需要放在循环中不断获取。

        3.由于数据量大,转换数据后要注意及时释放内存。

这篇关于Android TRTC实时音视频 推 RTSP视频流方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/427161

相关文章

使用Python和OpenCV库实现实时颜色识别系统

《使用Python和OpenCV库实现实时颜色识别系统》:本文主要介绍使用Python和OpenCV库实现的实时颜色识别系统,这个系统能够通过摄像头捕捉视频流,并在视频中指定区域内识别主要颜色(红... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间详解

Python常用命令提示符使用方法详解

《Python常用命令提示符使用方法详解》在学习python的过程中,我们需要用到命令提示符(CMD)进行环境的配置,:本文主要介绍Python常用命令提示符使用方法的相关资料,文中通过代码介绍的... 目录一、python环境基础命令【Windows】1、检查Python是否安装2、 查看Python的安

OpenCV实现实时颜色检测的示例

《OpenCV实现实时颜色检测的示例》本文主要介绍了OpenCV实现实时颜色检测的示例,通过HSV色彩空间转换和色调范围判断实现红黄绿蓝颜色检测,包含视频捕捉、区域标记、颜色分析等功能,具有一定的参考... 目录一、引言二、系统概述三、代码解析1. 导入库2. 颜色识别函数3. 主程序循环四、HSV色彩空间

Maven 配置中的 <mirror>绕过 HTTP 阻断机制的方法

《Maven配置中的<mirror>绕过HTTP阻断机制的方法》:本文主要介绍Maven配置中的<mirror>绕过HTTP阻断机制的方法,本文给大家分享问题原因及解决方案,感兴趣的朋友一... 目录一、问题场景:升级 Maven 后构建失败二、解决方案:通过 <mirror> 配置覆盖默认行为1. 配置示

SpringBoot排查和解决JSON解析错误(400 Bad Request)的方法

《SpringBoot排查和解决JSON解析错误(400BadRequest)的方法》在开发SpringBootRESTfulAPI时,客户端与服务端的数据交互通常使用JSON格式,然而,JSON... 目录问题背景1. 问题描述2. 错误分析解决方案1. 手动重新输入jsON2. 使用工具清理JSON3.

使用jenv工具管理多个JDK版本的方法步骤

《使用jenv工具管理多个JDK版本的方法步骤》jenv是一个开源的Java环境管理工具,旨在帮助开发者在同一台机器上轻松管理和切换多个Java版本,:本文主要介绍使用jenv工具管理多个JD... 目录一、jenv到底是干啥的?二、jenv的核心功能(一)管理多个Java版本(二)支持插件扩展(三)环境隔

Java中Map.Entry()含义及方法使用代码

《Java中Map.Entry()含义及方法使用代码》:本文主要介绍Java中Map.Entry()含义及方法使用的相关资料,Map.Entry是Java中Map的静态内部接口,用于表示键值对,其... 目录前言 Map.Entry作用核心方法常见使用场景1. 遍历 Map 的所有键值对2. 直接修改 Ma

Mybatis Plus Join使用方法示例详解

《MybatisPlusJoin使用方法示例详解》:本文主要介绍MybatisPlusJoin使用方法示例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录1、pom文件2、yaml配置文件3、分页插件4、示例代码:5、测试代码6、和PageHelper结合6

Java中实现线程的创建和启动的方法

《Java中实现线程的创建和启动的方法》在Java中,实现线程的创建和启动是两个不同但紧密相关的概念,理解为什么要启动线程(调用start()方法)而非直接调用run()方法,是掌握多线程编程的关键,... 目录1. 线程的生命周期2. start() vs run() 的本质区别3. 为什么必须通过 st

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据