Android流媒体开发之路二:NDK C++开发Android端RTMP直播推流程序

简介: Android流媒体开发之路二:NDK C++开发Android端RTMP直播推流程序

NDK C++开发Android端RTMP直播推流程序

经过一番折腾,成功把RTMP直播推流代码,通过NDK交叉编译的方式,移植到了Android下,从而实现了Android端采集摄像头和麦克缝数据,然后进行h264视频编码和aac音频编码,并发送到RTMP服务器,从而实现Android摄像头直播。程序名为NdkRtmpEncoder,在这里把整个过程,和大体框架介绍一下,算是给需要的人引路。

开发思路

首先,为什么要用NDK来做,因为自己之前就已经实现过RTMP推流、RTMP播放、RTSP转码等等各种c++实现的流媒体项目,有很成熟的代码模块。既然Android有NDK,可以JNI的方式复用之前的成熟代码,大大拓展和加快项目实现,那为什么不这样去做呢。和其他平台一样,要实现采集摄像头推送直播流,需要实现以下几点

  • 获取Android摄像头数据
  • 对摄像头数据进行h264编码
  • 编码后数据以RTMP协议封装数据并推送

下面分开来讲开发思路:

  1. Android端采集摄像头原始数据,可以在Java层通过Camera2获取数据,也可以用NativeCamera通过NDK来获取,不过后者需要的版本高一些,我考虑了一下,还是决定通过Java层获取数据,然后再交给下层处理。
  2. h264编码,可以通过AndroidMediaCodec进行硬件编码,也可以通过x264进行软件编码,这里因为要复用以前的代码,决定使用软件编码来验证
  3. RTMP协议封装,这部分代码,直接使用之前的C++代码即可,本身就是平台无关的,NDK也是linux环境开发,socket网络通信都是相通的。具体可以参考我之前的文章“C++实现RTMP协议发送H.264编码及AAC编码的音视频

程序框架

根据我的开发思路,程序框架就显而易见了:

这里省略了部分内容,比如在so动态库之上,有一层封装模块,供Activity调用

  1. Java层的主要做数据采集。对摄像头,通过Camera2接口,获取到更新的Surface,并转交给Opengl.EGL进行绘制,数据被绘制到TextureView的SurfaceTexture上,同时将RGB原始数据回调给Activity,由Activity把数据转交给动态库。 关于Camera2接口获取摄像头数据,可以参考之前的文章“Android流媒体开发之路一:Camera2采集摄像头原始数据并手动预览”,不同的是,那篇文章里直接使用ImageReader的Surface,这里使用的是自定义的Surface。
  2. C++层实现对原始数据进行编码,并按照RTMP数据包进行封装,然后推送到RTMP服务器。这部分可以参考以前的文章“C++实现RTMP协议发送H.264编码及AAC编码的音视频”。

交叉编译

这部分也是主要工作之一,c++代码要想在Android上使用,必须编译成动态库,然后让APP通过JNI来调用。本质上,Android也是linux嘛,所以跟其他嵌入式arm-linux的交叉编译方式,本质上是差不多的,当然,前提是系统内布置好交叉编译环境。熟悉NDK的应该都知道,Google提供了完整的编译工具链,也包括SDK,下载地址在这里:“NDK Downloads”。我是在Ubuntu Linux上来做的,所以选择“Linux 64-bit(x86)”版本,记得Linux环境必须是64位,不然你什么都编译不了。

解压后其实就可以开始了。不过这里还是有两种编译方式:第一种就是类似其他arm-linux环境,配置好交叉编译工具链环境,然后直接按照普通的linux编译方式进行编译;第二种是编写Android.mk文件,然后用NDK里提供的ndk-build脚本进行编译。

1. 工具链方式

对第一种方式来说其实比较简单,安装好交叉编译工具链之后,配置一下环境,就可以编译了。比如如下配置

这样基本就可以了,当然不同项目可能还需要进一步的修改配置,make之前需要执行configure等,但大致如此。

2. ndk-build方式

对Android.mk来说,跟Makefile差别是很大的,有它自己的语法,它在整个编译过程中的位置,可能更接近于automake工具里Makefile.am。关于它的语法,参见我下面的mk文件,做了一些注释,可以帮助理解,具体的语法可以参考官方网站Android Developer。我在这里把我rtmp_enc_sdk.so动态库的Android.mk的主要内容贴出来,大家可作参考。

模式基本是一样的,按照这个模板,修改成你自己项目里使用并不困难。

关键代码

不管是Java层还是C++层的代码其实都不少,不过之前几篇文章里已经有关于他们的逻辑结构和实现方法的介绍,有兴趣的可以参考,按照文章里写的架构去理解,相信都可以实现。我这里把Java层对摄像头捕获到数据以后的处理逻辑的代码贴一下。

1 当TextureView有效之后,开始创建工作。首先要生成一个OES SurfaceTexture,后面要把它传递给Camera2接口,用于接收摄像头画面,之后开始创建RTMP推流模块调用线程,并创建摄像头捕获模块,和渲染模块

2 当OESTexture画面有效之后,获取摄像头画面的实际分辨率,以及旋转矩阵,画面旋转信息等,封装在一起,交给EGLRender,通知渲染模块进行画面渲染

3 渲染模块绘制完数据后,读取RGB原始数据并回调,在这里交给Rtmp发送线程,调用动态库,完成最后h264编码,并推送到RTMP服务器,这下面就是c++层so动态库做的事情了

运行效果

在手机端RTMP推流画面:

在PC上用flash播放RTMP直播画面:

目录
相关文章
|
5天前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台策略
在移动应用开发的战场上,安卓和iOS两大阵营各据一方。随着技术的演进,跨平台开发框架成为开发者的新宠,旨在实现一次编码、多平台部署的梦想。本文将探讨跨平台开发的优势与挑战,并分享实用的开发技巧,帮助开发者在安卓和iOS的世界中游刃有余。
|
10天前
|
搜索推荐 Android开发 开发者
探索安卓开发中的自定义视图:打造个性化UI组件
【10月更文挑战第39天】在安卓开发的世界中,自定义视图是实现独特界面设计的关键。本文将引导你理解自定义视图的概念、创建流程,以及如何通过它们增强应用的用户体验。我们将从基础出发,逐步深入,最终让你能够自信地设计和实现专属的UI组件。
|
12天前
|
Android开发 Swift iOS开发
探索安卓与iOS开发的差异和挑战
【10月更文挑战第37天】在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统扮演着主角。它们各自拥有独特的特性、优势以及面临的开发挑战。本文将深入探讨这两个平台在开发过程中的主要差异,从编程语言到用户界面设计,再到市场分布的不同影响,旨在为开发者提供一个全面的视角,帮助他们更好地理解并应对在不同平台上进行应用开发时可能遇到的难题和机遇。
|
14天前
|
XML 存储 Java
探索安卓开发之旅:从新手到专家
【10月更文挑战第35天】在数字化时代,安卓应用的开发成为了一个热门话题。本文旨在通过浅显易懂的语言,带领初学者了解安卓开发的基础知识,同时为有一定经验的开发者提供进阶技巧。我们将一起探讨如何从零开始构建第一个安卓应用,并逐步深入到性能优化和高级功能的实现。无论你是编程新手还是希望提升技能的开发者,这篇文章都将为你提供有价值的指导和灵感。
|
12天前
|
存储 API 开发工具
探索安卓开发:从基础到进阶
【10月更文挑战第37天】在这篇文章中,我们将一起探索安卓开发的奥秘。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的信息和建议。我们将从安卓开发的基础开始,逐步深入到更复杂的主题,如自定义组件、性能优化等。最后,我们将通过一个代码示例来展示如何实现一个简单的安卓应用。让我们一起开始吧!
|
13天前
|
存储 XML JSON
探索安卓开发:从新手到专家的旅程
【10月更文挑战第36天】在这篇文章中,我们将一起踏上一段激动人心的旅程,从零基础开始,逐步深入安卓开发的奥秘。无论你是编程新手,还是希望扩展技能的老手,这里都有适合你的知识宝藏等待发掘。通过实际的代码示例和深入浅出的解释,我们将解锁安卓开发的关键技能,让你能够构建自己的应用程序,甚至贡献于开源社区。准备好了吗?让我们开始吧!
24 2
|
14天前
|
Android开发
布谷语音软件开发:android端语音软件搭建开发教程
语音软件搭建android端语音软件开发教程!
|
22天前
|
编解码 Java Android开发
通义灵码:在安卓开发中提升工作效率的真实应用案例
本文介绍了通义灵码在安卓开发中的应用。作为一名97年的聋人开发者,我在2024年Google Gemma竞赛中获得了冠军,拿下了很多项目竞赛奖励,通义灵码成为我的得力助手。文章详细展示了如何安装通义灵码插件,并通过多个实例说明其在适配国际语言、多种分辨率、业务逻辑开发和编程语言转换等方面的应用,显著提高了开发效率和准确性。
|
20天前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
30 5
|
19天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!