DAYS

只要写下来,人的念想就能超越死亡与时间,永远存在下去。

0%

“直播”

2020年的一场疫情将直播行业及音视频技术带到了大家的视野中,原本只在娱乐行业被人熟知的直播,在数月中就充斥了人们的整个日常生活。直播卖货远程会议系统直播教育原本小众的场景被强行拉上舞台,接受本不该承受的QPS。

部分数据可参考下图:

如果你是一名开发者,你有没有想过,从主播开始推流到用户看到画面,这里面都发生了些什么?一次次的卡顿缓冲时怎么引起的?观众看到的画面和主播实时画面差了几秒,最短能缩减到多少?不同观众看到的画面是否一致?

为了大家可以直观理解本文剩余部分,这里笔者先把直播整体的流程图放出来。

直播整体流程

上图只是将主要的流程列出来,真正的流程比这个当然要更复杂。

本文的主题是直播移动端播放体验优化,结合上图,笔者会从推流端cdn拉流端给大家介绍如何在这三个环节进行播放体验优化。

本文会尽量写的通俗易懂,不会涉及到具体代码实现,即使你不是直播行业的开发者,读完这篇文章,也能对直播优化有个比较全面的了解。

阅读全文 »

在前面几篇文章中我们已经初始化了GLSurfaceView 和 EGL,并且使用 OpenGLES(下文简称GLES)渲染出了红色画面。

这一节中我们将在红色上继续画上三角形。

在着手画三角形之前,我们先要学习一点点关于 GLES 的预备知识,非常简单。

  1. GLES 底层是由 c 语言实现,所以没有面向对象特性,它的接口及工作原理更接近面向过程,且其内部就是一个巨大的状态机。例如前面画的红色我们做了两步操作,第一步GLES32.glClearColor,设置清屏颜色,第二步GLES32.glClear进行清屏。
    总结一下就是 GLES 的渲染一般经历两步:1. 状态设置,2. 状态使用。 牢记这一点,对后面的学习会有很大的帮助。

  2. GLES 的渲染工作是在 GPU 中完成,所以我们的模型数据都需要由 CPU 转交给 GPU。

  3. GLES 中的坐标是标准化设备坐标(Normalized Device Coordinates, NDC),标准化设备坐标是一个x、y和z值在-1.0到1.0的一小段空间。任何落在范围外的坐标都会被丢弃/裁剪,不会显示在你的屏幕上。如下图:

    所以如果我们在手机上直接画(0,0.5)、(0.5,0.5)和(-0.5,0.5)这三个点的时候,得到的就未必是上图中的等边三角形了,因为我们屏幕并不是一个正方形,某个方向是会被拉伸的。具体怎么解决这个问题,在以后的章节中会讲到。

差不多就是以上三点,把他们都牢记在心,对入门 GLES 很重要。

阅读全文 »

什么是 EGL?

EGL 官网是这么介绍 EGL 的:

EGL™ is an interface between Khronos rendering APIs such as OpenGL ES or OpenVG and the underlying native platform window system. It handles graphics context management, surface/buffer binding, and rendering synchronization and enables high-performance, accelerated, mixed-mode 2D and 3D rendering using other Khronos APIs. EGL also provides interop capability between Khronos to enable efficient transfer of data between APIs – for example between a video subsystem running OpenMAX AL and a GPU running OpenGL ES.

这段介绍很长,但意思可以总结为 EGL 是设备显示与渲染引擎之间的。展开讲就是说设备上的渲染引擎比如 OpenGL ES,它只负责如何将用户输入的模型数据渲染成图形数据,但它却不知道怎么将图像显示在设备显示器上。而 EGL 专门就是做这个的,OpenGL ES 把数据给 EGL,EGL 负责将图形数据显示在设备屏幕上。

那么如果我们想要使用 OpenGL ES 进行渲染,前提就是要有 EGL 环境。那 EGL 环境该如何初始化呢?

阅读全文 »

在 Android 应用层我们如果要使用 OpenGL 进行绘制,可以选择 Android 平台给我提供的 GLSurfaceView 和 GLSurfaceView.Renderer。
其中 GLSurfaceView 是 SurfaceView 的子类,GLSurfaceView.Renderer 为我们在 GLSurfaceView 上渲染提供了回调。

简单写一个例子,首先是定义 Renderer:

1
2
3
4
5
6
7
8
9
10
11
12
13
class MyRenderer : GLSurfaceView.Renderer {
override fun onDrawFrame(gl: GL10?) {
GLES32.glClear(GLES32.GL_COLOR_BUFFER_BIT)
}

override fun onSurfaceChanged(gl: GL10?, width: Int, height: Int) {
GLES32.glViewport(0, 0, width, height)
}

override fun onSurfaceCreated(gl: GL10?, config: EGLConfig?) {
GLES32.glClearColor(1.0F, 0F, 0F, 1F)
}
}
阅读全文 »

最近老婆一直在听这首歌,感觉我已经被洗脑了。

阅读全文 »