目前开源的项目或市面上的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做直播推流相关推荐

  1. 使用ffmpeg做直播推流例子

    1.视频加音频直播 ffmpeg -f dshow -i audio="麦克风阵列 (Realtek(R) Audio)" -acodec aac -f dshow -i vide ...

  2. pc端使用融云做直播推流和拉流(因Chrome 93 版本开始不再支持 plan-b 协议、改为RCRTCAdapter 桥接版本)

    详细的可以访问融云文档 地址:https://docs.rongcloud.cn/v4/views/rtc/livevideo/guide/quick/audience/web.html 一.推流 & ...

  3. 视频直播推流技术(MediaCodec硬编码+libRTMP,编码器),Demo - Android

    - aac audio_codec; h264,video_codec;25 framerate 25帧; - Camera-YUV帧序列-YUV帧预处理(镜像 缩放 旋转)-编码器-H264数据 从 ...

  4. android大疆无人机直播推流VLC

    官方给了直播的方法:startStream,最近公司需求是大疆无人机做直播推流给后台服务器,然后在后台可以看到无人机拍摄的内容,实时监控无人机的状态 因为这个最新的大疆官方给出了方法,所以做起来是非常 ...

  5. uniapp直播推流、拉流实现

    https://www.h5w3.com/10106.html作者链接 uniapp直播开发教程 发表于:2020年3月10日标签: 标签:Hbuilderx, Javascript, Js, Vue ...

  6. 视频教程-C++编程FFMpeg(QT5+OpenCV)实战--实时美颜直播推流-C/C++

    C++编程FFMpeg(QT5+OpenCV)实战--实时美颜直播推流 夏曹俊:南京捷帝科技有限公司创始人,南京大学计算机硕士毕业,有15年c++跨平台项目研发的经验,领导开发过大量的c++虚拟仿真, ...

  7. android硬编码用rtmp,Android RTMP推流之MediaCodec硬编码二(RTMPDump推流)

    简介 在前面的两篇文章中:Android RTMP推流之MediaCodec硬编码一(H.264进行flv封装)介绍了如何MediaCodec进行H264硬编码,然后将编码后的数据封装到flv文件中. ...

  8. 【Android RTMP】RTMP 直播推流服务器搭建 ( Ubuntu 18.04.4 虚拟机 )

    文章目录 安卓直播推流专栏博客总结 一. Android RTMP 直播推流简介 二. Nginx.RTMP Module 编译环境源码准备 三. pcre.OpenSSL.zlib 函数库安装 四. ...

  9. android rtmp推流,Android使用libRtmp直播推流

    初始化rtmp //分配空间 RTMP *rtmp = RTMP_Alloc(); //初始化 RTMP_Init(rtmp); //设置推流URL RTMP_SetupURL(rtmp, url); ...

最新文章

  1. 自建ELK vs 日志服务(SLS)全方位对比
  2. 轻松搞定c++语言pdf_当年锤子的大爆炸,如今12个语言版本都可轻松搞定!
  3. mysql装一次后再装_MySQL再安装
  4. MeeGo 1.2发布
  5. 《计算机组成原理》课程设计任务书——TEC-2实验系统——微程序设计
  6. RSA加解密算法的Java实现
  7. [转]深入理解G1垃圾收集器
  8. ncut算法matlab实现,ncut_multiscale_1_6 经典的图像分割算法 的Matlab代码。 238万源代码下载- www.pudn.com...
  9. 计算机专业英语霍洪涛出版社,计算机专业英语(霍洪涛)课件Chapter 4.ppt
  10. 爬虫python能做游戏吗_一入爬虫深似海,从此游戏是路人!总结我的python爬虫学习笔记!...
  11. FreeMarker的优点和缺点
  12. 洛谷1031 均分纸牌 解题报告
  13. 漏洞扫描器简单教程(天镜、Nessus、Appscan、Awvs)
  14. 介绍一下115sha1链接使用方法
  15. Linux CentOS 7网络配置基础
  16. 小米MIUI手机adb连接教程
  17. IP数据报、TCP报文段
  18. 【数据挖掘】数据统计性描述与相似度
  19. 新媒体研究杂志社新媒体研究编辑部新媒体研究杂志2022年第18期目录
  20. 关于手机屏幕的一些知识(2)

热门文章

  1. 分享一个项目平台原型图
  2. Linux Ubuntu NFS 调试,Arm 挂载命令
  3. oracle ebs mrp提前期,EBS-MRP提前期.doc
  4. 仓库管理系统-新名词(经济订货批量 、订货周期、订货提前期)
  5. VUE购物车小案例—vue指令的综合应用
  6. Pointnet语义分割任务S3DIS数据集上的注意点
  7. BP神经网络原理简单介绍以及公式推导(矩阵形式和分量形式)
  8. Pytorch使用autograd.Function自定义拓展神经网络
  9. vim 录制宏,自动循环执行组合操作
  10. 微星GE62 2QC-264XCN刷黑苹果详细教程亲测有效,完美双系统,双屏!