使用MediaCodec和RTMP进行实时流传输

电脑杂谈  发布时间:2020-04-06 13:05:34  来源:网络整理

potplayer打不开rtmp_大度16开留出血之后可以打印在a4的纸上吗_开辉机械打棉被机为什么断线

当前,市场上的开源项目或Android实时流客户端主要使用ffmpeg来实现流. 本文将介绍使用Android本机视频编码类MediaCodec实现实时流式传输.

数据流和一般原则

此处提到的实时广播是将客户端生成的视频数据实时发送到服务器. 服务器上的数据被实时发送到回放客户端.

以视频数据为例:

camera.setPreviewTexture(surfaceTexture)

这里的原理可以忽略. 粗略地说potplayer打不开rtmp,相机会将获取的图像保存为OpenGL的纹理. 我们可以使用此图像来使用相机图像.

绘制图片

获取图片后,我们需要将该图片(纹理)“绘制”到MediaCodec.

如何绘制?

MediaCodec提供了一张“白皮书”(即Surface),供我们在其上绘制纹理. 这里的API是

MediaCodec.createInputSurface()

大度16开留出血之后可以打印在a4的纸上吗_potplayer打不开rtmp_开辉机械打棉被机为什么断线

如何绘制?用画布绘制. 当然,它不是通用的Canvas,我使用了这个开源项目android-openGL-canvas.

H264数据

绘制后,MediaCodec将帮助我们将原始屏幕数据压缩为相应的视频数据. 目前,我将其压缩为H264数据.

所谓的H264数据实际上只是一堆字节[]数组. 在该项目的示例中,我将H264数据作为文件编写,可以与某些播放器(例如PotPlayer)一起播放.

RTMP

我使用了一个开放源代码项目,该项目可以将视频数据密封成RTMP数据包并将其发送到服务器.

LibRtmp-Client-for-Android

摘要

数据流可以这样看

相机-> SurfaceTexture->表面-> MediaCodec->编码数据(字节[])-> RTMPMuxer->服务器

音频数据:

开辉机械打棉被机为什么断线_potplayer打不开rtmp_大度16开留出血之后可以打印在a4的纸上吗

相对简单,它是从AudioRecord获取原始音频数据(字节[]),将其编码为AAC数据(也为字节[]),然后将其封装到RTMPMuxer中,然后将其发送到服务器

麦克风MIC-> AudioRecord->语音数据(即字节[])-> MediaCodec->编码数据(即字节[])-> RTMPMuxer->服务器

Muxer

如前所述,存在用于视频的RTMP数据包和用于音频的RTMP数据包. 它们是打包为RTMP数据包并发送到服务器的单元H264和单元AAC. 这些软件包之间的规则是什么?

数据包按时间顺序排列. 当MediaCodec返回编码数据时,它将返回编码数据的时间戳. 但是请注意,在编码为RTMP数据包时,会采用相对时间戳. 也就是说,在获取时间戳时,需要计算与前一个数据包的时间戳之差并将其写入RTMP数据包.

此外,RTMP流本质上是FLV格式的音频和视频,在这里还提供了写入FLV文件的功能.

效果图片

Android推送流结束

视频帧图像处理

开辉机械打棉被机为什么断线_potplayer打不开rtmp_大度16开留出血之后可以打印在a4的纸上吗

如前所述,视频帧的图像处理实际上使用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);
    }
    ...

如上所述,可以使用各种过滤器来处理视频帧图像. 简而言之,您可以在视频帧上绘制各种东西,例如Canvas. 当然,要在地图上绘制文本,您只能使用位图.

比特率/比特

使用MediaCodec时,需要设置编码率. 该比特率是根据视频分辨率和颜色格式计算的.

    public H264Encoder(int width, int height, int bitRate, int frameRate, int iframeInterval, final EglContextWrapper eglCtx) throws IOException

其中bitRate是比特率,单位bit / s

某些计算方法可以参考本文:

编码视频时应该使用什么比特率?

输出大小比特率文件大小

potplayer打不开rtmp_大度16开留出血之后可以打印在a4的纸上吗_开辉机械打棉被机为什么断线

320x240像素400 kbps 3MB /分钟

480x270像素700 kbps 5MB /分钟

1024 x 576像素1500 kbps 11MB /分钟

1280x720像素2500 kbps 19MB /分钟

1920x1080像素4000 kbps 30MB /分钟

在大多数情况下,此方法已足够potplayer打不开rtmp,但对于复杂的视频处理仍然缺乏.

例如

对比下图的无处理效果(一种纹理)

对于下一张图片的处理效果(两个屏幕使用与上一张图片相同的大小纹理,尽管我将显示尺寸设置为不同),其编码率约为上一张图片的两倍.

测试服务器

如果需要测试,请设置自己的RTMP服务器. 我使用了自己构建的Nginx服务器,而我使用的模块是nginx-rtmp-module. 您无需编写代码即可构建服务器. 只需根据教程输入几行即可. 您可以使用开源直播软件OBS比较播放效果.

各种播放器,VLC,PotPlayer和ffplay都可以. 我用ffplay. 请注意,由于它只是一台简单的服务器,因此需要在开始开始流式传输之前打开播放器连接. 我使用的命令是. \ Ffplay.exe“ rtmp: // //本地主机: 19305 / live /室内直播= 1”

作者: chillingvan;原始链接:


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/bofangqi/article-165938-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      • 石袛
        石袛

        任何一个门槛低的行业

      • 尹璞
        尹璞

        我承认我的确也写的一般

      • 周玉秋
        周玉秋

        也说明了小米肯关注此事

      热点图片
      拼命载入中...