目前开源的项目或市面上的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() {@Overridepublic 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;原文链接:https://www.jianshu.com/p/3c479c0f4876

欢迎关注我的微信公众号「码农突围」,分享Python、Java、大数据、机器学习、人工智能等技术,关注码农技术提升•职场突围•思维跃迁,20万+码农成长充电第一站,陪有梦想的你一起成长。

使用MediaCodec和RTMP做直播推流相关推荐

  1. android rtmp推流,使用MediaCodec和RTMP做直播推流

    目前开源的项目或市面上的Android直播客户端主要是用ffmpeg来实现推流的.本文将介绍使用Android原生的视频编码类MediaCodec实现直播推流. 数据流及大致原理 这里所说的直播,就是 ...

  2. iOS直播:LFLiveKit + RTMP实现直播推流

    相关库 LFLiveKit LFLiveKit + RTMP实现直播推流 RTMP协议:RTMP(the Real-time Messaging Protocol)协议作为客户端和服务器端的传输协议, ...

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

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

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

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

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

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

  6. 基于GPUImage的多滤镜rtmp直播推流

    之前做过开源videocore的推流改进:1)加入了美颜滤镜; 2) 加入了librtmp替换原来过于简单的rtmpclient: 后来听朋友说,在videocore上面进行opengl修改,加入新的 ...

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

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

  8. Windows平台RTMP/RTSP直播推送模块设计和使用说明

    开发背景 好多开发者一直反馈,Windows平台,做个推屏或者推摄像头,推RTMP或者RTSP出去,不知道哪些功能是必须的,哪些设计是可有可无的,还有就是,不知道如何选技术方案,以下是基于我们设计的W ...

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

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

  10. 直播推流实现RTMP协议的一些注意事项

    018年8月4日第三次更新,详细介绍了RTMP协议与遇到的坑,另外纯Java重写了RTMP协议,做了个Android 推流项目,包含安卓相机采集,编码和RTMP推流,上传到github了. 项目地址: ...

最新文章

  1. Gartner 认定 Microsoft 为具有远见卓识的云基础结构即服务提供商
  2. 1091 Acute Stroke (30)(30 分)
  3. arcgis Manager 登陆时提示Incorrect login Information
  4. spirngmvc如何实现直接输入网页重定向到登录_Python 模拟新浪微博登录
  5. mysql一对多代码_MySQL实现一对多查询的代码示例
  6. jclouds的命令行界面
  7. 制作 小 linux 教程,【NanoPi NEO Plus2开发板试用体验】编译uboot和linux制作最小根文件系统制作刷机包---详细教程...
  8. 分解因数(信息学奥赛一本通-T1200)
  9. mysql练习题练习
  10. Jmeter中的几个重要测试指标释义
  11. log4j的org.apache.log4j.PatternLayout
  12. Call for Presentations!Flink Forward Global 2021 议题征集ing
  13. WebForm中 页面传参的总结
  14. 华硕物联网机器人今年推出 开发进入最后阶段
  15. spring切点表达式提取jdk版本与aspectjweaver版本不匹配
  16. 计算机二级真题期刊论文模板,最新一般期刊论文格式
  17. C++笔试题目大全(笔试宝典)
  18. A load persistent id instruction was encountered, but no persistent_load function was specified.
  19. Linux配置自动获取ip方式和静态ip方
  20. Ubuntu16.04下fctix无法切换中英文输入法

热门文章

  1. linux 命令行字符缩放,用Linux命令行修图——缩放、编辑、转换格式
  2. jq移除一条html语句,jquery html()删除脚本标签
  3. Java怎么按照字母对单词排序_将一段字符串文本中的每个单词提取出来后按照字母顺序排序...
  4. python_统计数组中指定范围的数据占的比例
  5. OpenCV_(Fit Line with points)用直线拟合一组点
  6. android apk 反编译,android编译错误解决方法
  7. 斯坦福大学深度学习公开课cs231n学习笔记(8)神经网络学习过程中的检查事项和参数调优
  8. DeepMind成为AI界创业加速营:3年17名资深员工与高管离职
  9. springcloud---how2java--记录零碎的信息
  10. PAT 7-14 公路村村通