android rtmp推流,使用MediaCodec和RTMP做直播推流
目前开源的项目或市面上的Android直播客户端主要是用ffmpeg来实现推流的。本文将介绍使用Android原生的视频编码类MediaCodec实现直播推流。
数据流及大致原理
这里所说的直播,就是将你的客户端产生的视频数据,实时发送到服务器上。服务器上的数据再实时地发送到播放客户端上。
以视频数据为例:
获取Camera画面
首先是摄像头拍摄得到原始画面数据,这里原始画面数据的格式我们不用管,因为我们使用的是MediaCodec,所以我们会使用
camera.setPreviewTexture(surfaceTexture)
来利用Camera获取到的画面。
此处的原理可忽略,大致说明的话,就是Camera会把获得的画面保存为OpenGL的一个纹理,我们使用这个纹理就能使用Camera的画面。
绘制画面
在获得画面之后,我们要把这个画面(纹理)“画”到MediaCodec上。
如何画?
MediaCodec提供一张’白纸’,也就是一个Surface,供我们把纹理画到上面。此处的API是
MediaCodec.createInputSurface()
怎么画?用Canvas画。当然不是一般的Canvas,我用了这个开源项目android-openGL-canvas。
H264数据
画上去后,MediaCodec就会帮我们把原始画面数据,压缩成相应的视频数据,目前我这里是压缩成H264数据。
所谓的H264数据,其实只是一堆堆的byte[]数组。在项目的例子,我把H264数据写成了文件,可以用某些播放器播放(例如PotPlayer)。
RTMP
我使用了一个开源项目,可以将视频数据封成RTMP包,发送到服务器上。
LibRtmp-Client-for-Android
总结
数据流可以这样看
Camera -> SurfaceTexture -> Surface -> MediaCodec -> encode data(byte[]) -> RTMPMuxer -> Server
音频数据:
相对简单一些,就是从AudioRecord里获取原始音频数据(byte[]),编码成AAC数据(也是byte[]),然后给RTMPMuxer,封装成RTMP包,发到服务器
麦克风MIC -> AudioRecord -> voice data(就是byte[]) -> MediaCodec -> encode data(就是byte[]) -> RTMPMuxer -> Server
Muxer
前面有提到有视频的RTMP包和音频的RTMP包,分别是将单元H264和单元AAC封装成RTMP包,发到服务器。这些包之间有什么规律?
这些包之间是按时间顺序排列的,MediaCodec返回编码数据时,会返回编码数据的时间戳。但注意编码成RTMP包时,取的是相对时间戳,也就是说取到时间戳时,需要计算与上一个包的时间戳的差值,写到RTMP包里。
另外RTMP流本质上是FLV格式的音视频,这里也提供了写成FLV文件的功能。
效果图
Android推流端
视频帧图像处理
前面提到视频帧的图像处理,实际上也是利用了android-openGL-canvas。
关键代码如下:
...
streamPublisher.prepareEncoder(streamPublisherParam, new H264Encoder.OnDrawListener() {
@Override
public void onGLDraw(ICanvasGL canvasGL, SurfaceTexture surfaceTexture, RawTexture rawTexture, @Nullable SurfaceTexture outsideSurfaceTexture, @Nullable BasicTexture outsideTexture) {
drawVideoFrame(canvasGL, outsideSurfaceTexture, outsideTexture);
Loggers.i("DEBUG", "gl draw");
}
});
...
private void drawVideoFrame(ICanvasGL canvasGL, @Nullable SurfaceTexture outsideSurfaceTexture, @Nullable BasicTexture outsideTexture) {
// Here you can do video process
// 此处可以视频处理,例如加水印等等
TextureFilter textureFilterLT = new BasicTextureFilter();
TextureFilter textureFilterRT = new HueFilter(180);
int width = outsideTexture.getWidth();
int height = outsideTexture.getHeight();
canvasGL.drawSurfaceTexture(outsideTexture, outsideSurfaceTexture, 0, 0, width /2, height /2, textureFilterLT);
canvasGL.drawSurfaceTexture(outsideTexture, outsideSurfaceTexture, 0, height/2, width/2, height, textureFilterRT);
}
...
如上所示,可以使用各种Filter实现对视频帧图像的处理。总而言之,可以像Canvas那样在视频帧上绘制各种东西。当然要在图上画文字就只能用bitmap代替了。
码率bit/s
在使用MediaCodec时,需要设置码率。这个码率是根据视频分辨率,色彩格式算出来的。
public H264Encoder(int width, int height, int bitRate, int frameRate, int iframeInterval, final EglContextWrapper eglCtx) throws IOException
其中bitRate就是码率,单位bit/s
一些计算方法可以参考此文:
What bitrate should I use when encoding my video?
Output size Bitrate Filesize
320x240 pixels 400 kbps 3MB / minute
480x270 pixels 700 kbps 5MB / minute
1024 x 576 pixels 1500 kbps 11MB / minute
1280x720 pixels 2500 kbps 19MB / minute
1920x1080 pixels 4000 kbps 30MB / minute
此方法大部分情况下够用,但是对于复杂视频处理还欠缺。
例如
对比下图的无处理效果(一张纹理)
对于下图这样处理效果(2个画面用的是与上图同样大小的纹理,虽然我设置显示的尺寸不一样),码率是上图的2倍左右。
测试服务器
需要测试的话,请自行搭建RTMP服务器。我用的是自己搭建的Nginx服务器,用的Module是nginx-rtmp-module。搭建服务器不需要写代码,根据教程敲几行命令就行。可以用开源直播软件OBS对比播放效果。
播放器用各种都行,VLC,PotPlayer,ffplay都可以。我用的是ffplay,注意,因为只是简单的服务器,所以要先开播放器连接后再开始启动推流。我使用的命令是 .\ffplay.exe “rtmp://localhost:19305/live/room live=1”
作者:chillingvan
android rtmp推流,使用MediaCodec和RTMP做直播推流相关推荐
- 使用ffmpeg做直播推流例子
1.视频加音频直播 ffmpeg -f dshow -i audio="麦克风阵列 (Realtek(R) Audio)" -acodec aac -f dshow -i vide ...
- pc端使用融云做直播推流和拉流(因Chrome 93 版本开始不再支持 plan-b 协议、改为RCRTCAdapter 桥接版本)
详细的可以访问融云文档 地址:https://docs.rongcloud.cn/v4/views/rtc/livevideo/guide/quick/audience/web.html 一.推流 & ...
- 视频直播推流技术(MediaCodec硬编码+libRTMP,编码器),Demo - Android
- aac audio_codec; h264,video_codec;25 framerate 25帧; - Camera-YUV帧序列-YUV帧预处理(镜像 缩放 旋转)-编码器-H264数据 从 ...
- android大疆无人机直播推流VLC
官方给了直播的方法:startStream,最近公司需求是大疆无人机做直播推流给后台服务器,然后在后台可以看到无人机拍摄的内容,实时监控无人机的状态 因为这个最新的大疆官方给出了方法,所以做起来是非常 ...
- uniapp直播推流、拉流实现
https://www.h5w3.com/10106.html作者链接 uniapp直播开发教程 发表于:2020年3月10日标签: 标签:Hbuilderx, Javascript, Js, Vue ...
- 视频教程-C++编程FFMpeg(QT5+OpenCV)实战--实时美颜直播推流-C/C++
C++编程FFMpeg(QT5+OpenCV)实战--实时美颜直播推流 夏曹俊:南京捷帝科技有限公司创始人,南京大学计算机硕士毕业,有15年c++跨平台项目研发的经验,领导开发过大量的c++虚拟仿真, ...
- android硬编码用rtmp,Android RTMP推流之MediaCodec硬编码二(RTMPDump推流)
简介 在前面的两篇文章中:Android RTMP推流之MediaCodec硬编码一(H.264进行flv封装)介绍了如何MediaCodec进行H264硬编码,然后将编码后的数据封装到flv文件中. ...
- 【Android RTMP】RTMP 直播推流服务器搭建 ( Ubuntu 18.04.4 虚拟机 )
文章目录 安卓直播推流专栏博客总结 一. Android RTMP 直播推流简介 二. Nginx.RTMP Module 编译环境源码准备 三. pcre.OpenSSL.zlib 函数库安装 四. ...
- android rtmp推流,Android使用libRtmp直播推流
初始化rtmp //分配空间 RTMP *rtmp = RTMP_Alloc(); //初始化 RTMP_Init(rtmp); //设置推流URL RTMP_SetupURL(rtmp, url); ...
最新文章
- 自建ELK vs 日志服务(SLS)全方位对比
- 轻松搞定c++语言pdf_当年锤子的大爆炸,如今12个语言版本都可轻松搞定!
- mysql装一次后再装_MySQL再安装
- MeeGo 1.2发布
- 《计算机组成原理》课程设计任务书——TEC-2实验系统——微程序设计
- RSA加解密算法的Java实现
- [转]深入理解G1垃圾收集器
- ncut算法matlab实现,ncut_multiscale_1_6 经典的图像分割算法 的Matlab代码。 238万源代码下载- www.pudn.com...
- 计算机专业英语霍洪涛出版社,计算机专业英语(霍洪涛)课件Chapter 4.ppt
- 爬虫python能做游戏吗_一入爬虫深似海,从此游戏是路人!总结我的python爬虫学习笔记!...
- FreeMarker的优点和缺点
- 洛谷1031 均分纸牌 解题报告
- 漏洞扫描器简单教程(天镜、Nessus、Appscan、Awvs)
- 介绍一下115sha1链接使用方法
- Linux CentOS 7网络配置基础
- 小米MIUI手机adb连接教程
- IP数据报、TCP报文段
- 【数据挖掘】数据统计性描述与相似度
- 新媒体研究杂志社新媒体研究编辑部新媒体研究杂志2022年第18期目录
- 关于手机屏幕的一些知识(2)