有Android开发的小伙伴问有没有系统学习音视频的路线或者资料,今天抽空写一篇文章,整理一条从难到易从浅入深的路线,并配套对应的主流代码库.
音视频从采集到播放都经历了哪些流程呢::
通过上面的图,我们简单的把音视频方向分为主要的两块:
1.媒体部分
我们这篇文章不再从音视频专业知识开始,而Android系统API的角度,逐层深入.
1.1 原始版本
我们最开始接触的摄像拍照是通过Intent调用系统摄像头:
Intent intent=new Intent();
// 指定开启系统相机的Action
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
// 根据文件地址创建文件
File file=new File(FILE_PATH);
// 把文件地址转换成Uri格式
Uri uri=Uri.fromFile(file);
// 设置系统相机拍摄照片完成后图片文件的存放地址
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
我们要播放视频最原始的是基于VideoView系统控件.
但是系统相机和系统控件VideoView的局限性都是可定制型太差,系统相机的图像分辨率,视频码率以及VideoView的进度条等.
1.2 初级版本
接下来,Android开发中我们
接触到最上层的两个API(Android官方提供了的么:
github.com/android/med…
包含了MediaRecorder VideoPlayer等)是:
-
MediaRecorder 音频/视频采集 对应上图蓝色部分, 参考
github.com/werbhelius/…
实现
-
MediaPlayer 音频/视频播放, (VideoView封装了MediaPlayer),对应上图绿色部分 参考:
github.com/crossle/Med…
实现
MediaRecorder示例:
mediaRecorder = new MediaRecorder(); // 创建
mediaRecorder.reset(); // 设置为空闲模式 可以赋属性了
mediaRecorder.setCamera(mCamera);// 设置一个摄像头用于录制。
// 使用SurfaceView预览
mediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
// 1.设置采集声音
// mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 设置采集图像
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// 2.设置视频,音频的输出格式 mp4
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
// 开始录制
mediaRecorder.prepare();
mediaRecorder.start();
MediaRecorder示例:
MediaPlayer mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.prepareAsync();
示例代码简单介绍了一下MediaRecorder和MediaRecorder的API,参考上面提供的demo已经可以实现简单的播放器和音视频录制功能了.上面我们又引出两个接口来:Camera, Surface. 拍照等功能我们都可以使用Camera的接口实现,关于Camera的API可以参考goog
le的demo:
github.com/googlearchi…
Surface我们接下来介绍.
1.3 进阶版本
上面的的MediaRecorder,MediaPlayer直接封装了图中的蓝色部分与绿色部分.它们将输入编码复用以及解码解复用输出封装到了一起,可定制性差: 1.MediaPlayer只支持固定的编码和封装,不支持rtmp等 2.MediaRecorder无法支持mp3,opus, ogg等编码,无法对采集到音视频做预处理(比如变声,美颜等)
基于上述几个原因,我们再认识几个API:
-
视频采集 Camera
-
音频采集 AudioRecorder
-
视频预处理:SurfaceTexture, Surface, EGL ,GLES10
-
音视频编码 MediaCodec MediaFormat
-
音视频封装(复用) MediaMuxer
-
音视频(解复用) MediaExtractor
-
音视频解码 MediaCodec
-
视频预览 SurfaceView, GLSurfaceView, TextureView
-
音频播放 AudioTrack
上述API Android也为我们提供了示
例
https://github.com/google/grafika,
里面包含的示例相当全面:
-
Play video (TextureView)
. 基于MediaCodec ,MediaExtractor, TextureView封装的播放器,可以帮助理解这几个api.
-
Continuous capture
. 基于Camera,GLES20,SurfaceTexture,SurfaceView,MediaCodec实现的建议的视频录制器.
-
Double decode
. 类似于Play video示例,只是解码两路视频渲染到TextureView.
-
Hardware scaler exerciser
. 演示OpenGL进行画面缩放
-
Live camera (TextureView)
. 演示Camera,SurfaceTexture以及TextureView使用
-
Multi-surface test
. 演示三路视频渲染
-
Play video (SurfaceView)
. 类似于Play video (TextureView),只是输出从TextureView变成了SurfaceView.
-
Record GL app
. 基于FBO同时将摄像头采集数据输出到编码器和屏幕,FBO是实时美颜的关键技术.
-
Record Screen using MediaProjectionManager
.基于MediaProjectionManager将屏幕内容录制成文件.之前我们的输入都是摄像头,Android5.0开始提供了MediaProjectionManager,可以对屏幕内容进行采集.
-
Scheduled swap
. 了解一个新伙伴Choreographer
-
Show + capture camera
. 摄像头同时输出到文件和屏幕(与"RecordFBOActivity"输出对象变成了GLSurfaceView)
-
Simple Canvas in TextureView
. 一般的我们把基于OpenGL的渲染称为"硬"渲染,基于Canvas的称为"软"渲染,这个示例展示了如何通过Canvas绘制到TextureView
-
Simple GL in TextureView
. 可以理解为实现了GLThread的TextureView.
-
Texture from Camera
. Camera->SurfaceTexture->SurfaceView
-
Color bars
. Canvas绘制示例
-
OpenGL ES Info
. 获取OpenGL 版本等相关信息
-
glTexImage2D speed test
. 纹理上传示例,从图片装换为OpenGL纹理,又要认识一个新伙伴:
glTexImage2D()
.
-
glReadPixels speed test
. OpenGL纹转换为图片(RGBA/YUV),再认识一个新伙伴
glReadPixels()
上面的demo主要是图形相关的,编解码器观光一下官方文档:
developer.android.google.cn/reference/a…
已经不能再明白了.
此外,想弄明白Med
iaCodec,还需要了解一个数据结构ByteBuffer(移步官方文档了解一下?
developer.android.google.cn/reference/j…
)
如果学习完这些,那么恭喜你,你已经对音视频相关知识有了一些了解了.接下来你可以试着去接触一下著名的
android-gpuimage
,以及了解OpenGL相关的FBO,PBO,Texture等,可以处理视频编辑,简单实现美颜等滤镜了. 推荐一些OpenGL相关文章:
-
第一个OpenGL程序:
blog.csdn.net/fuyajun01/a…
-
计算机图形学网络课程:
netclass.csu.edu.cn/NCourse/hep…
-
LearnOpenGl-CN:
learnopengl-cn.readthedocs.io/zh/latest/0…
-
opengl-tutorial:
learnopengl-cn.readthedocs.io/zh/latest/0…
-
OpenGl Pixel Buffer Object(PBO):
www.songho.ca/opengl/gl_p…
-
OpenGL深入探索——缓冲区对象(*BO):
blog.csdn.net/panda1234le…
-
OpenGL深入探索——像素缓冲区对象 (PBO):
blog.csdn.net/panda1234le…
-
Android 关于美颜/滤镜 利用PBO从OpenGL录制视频:
www.jianshu.com/p/3bc4db687…
-
EGL API Notes
-
Learn OpenGL ES:
www.learnopengles.com/android-les…
-
OpenGL Transformation:
www.songho.ca/opengl/gl_t…
-
glsl_tutorial:
zach.in.tu-clausthal.de/teaching/cg…
-
GLSL ES(OpenGL ES着色器语言)_WebGL笔记9:
www.ayqy.net/blog/glsl-e…
-
OpenGL 纹理坐标 和 顶点坐标映射关系 详解:
blog.csdn.net/xipiaoyouzi…
-
www.khronos.org/registry/EG…
OpenGL中FrameBuffer使用:
blog.csdn.net/wl_soft50/a…
1.4 高级版本
进阶版本中处理的都是Java层数据,有时候我们要编码mp3,opus等,手机硬件编码器(就是MediaCodec)不支持,我们需要引入编解码器库(lame,opus),这些库都是c/cpp实现,我们要经过jni封装,但是jni是有消耗的,那么我们可以不可以直接在c/cpp层实现采集,编码,播放呢? 当然是YES,下面我们再来了解一下jni层的API:
-
图像采集: 图像采集可以使用Java Camera,通过给Camera Surface,Surface再给jni的MediaCodec,也可以试试<camera/NdkCameraManager.h>
-
声音采集: 了解一下<SLES/OpenSLES_Android.h> , <SLES/OpenSLES.h>, opensl的文档太粗陋,给你一份Android官方demo:
github.com/android/ndk…
-
编解码: 了解一下<media/NdkMediaCodec.h>
-
封装(复用)器: <media/NdkMediaMuxer.h>
-
解封装(解复用)器: <media/NdkMediaExtractor.h>
-
图像渲染:
ndk-bundle/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include
下的EGL, GLES, GLES2, GLES3等
如果了解到这,那么恭喜你,可以继续学习一些其他库了:
-
lamemp3:Android只支持mp3解码,不支持mp3编码,幸好有lame:
官网
,
使用示例
文章介绍:
带你写一个Mp文件解析器-Mp3文件结构全解析(一)
,
带你写一个Mp文件解析器-Mp3文件结构全解析(二)
-
opus: 实时语音场景的首选是opus,但是Android还是只能解码不能编码,索性移步:
官网
,文章介绍
Opus从入门到精通(一):简介
,
Opus从入门到精通(二):编解码器使用
,
Opus从入门到精通(三)手撸一个Opus编码程序
,
Opus从入门到精通(四)Opus解码程序实现
,
Opus从入门到精通(五)OggOpus封装器全解析
,学习到这应该不再需要demo了,自己动手来一个吧
-
aac: Android支持了aac硬件编解码,但是出于编码效率以及低端手机考虑,了解一下
FAAC
-
x264: Android默认支持了h264的编解码,但也是出于编码效率及低端手机考虑,了解一下
x264
-
ffmpeg: 现在终于可以了解下传说中的ffmpeg了,音视频界的万能神器.
1.5 终极阶段
现在你可以更深入的了解声音的本质,特性,图像的压缩原理等等,去理解时域与频域,去学习
charlesliuyx.github.io/2018/02/18/…
,这个时候可以把高等数学和线性代数翻出来了.
2.媒体部分
传输部分我们音视频领域主要用到的应用层协议:
2.1基于http的音视频传输
Android上面的系统播放器MediaPlayer默认支持http的,可以传入一个远程的mp4地址给MediaPlayer播放.但是这种只能实现点播,如果要在http上实现直播的话,了解一下HLS以及HttpFLV:
www.jianshu.com/p/32417d8ee…
2.2 rtmp
rtmp是adobe的产物,主要用于直播场景,主播一路上行,观众多路下行
具体资源,文章里都有介绍了
2.3 rtc
rtmp实现了直播,但要互动直播就需要rtc了.现在好多都是基于webrtc的二次开发.
3.资源整理
3.1 摄像头及录制相关
3.2 webrtc
-
Pion WebRtc(
github.com/pion/webrtc
):Pure Go implementation of the WebRTC API
-
WebRtc 学而思镜像(
gitlab.com/webrtc-mirr…
):
-
WebRtc声网镜像(
webrtc.agora.io/mirror/
)
-
Flutter-p2p-engine(
gitee.com/cdnbye/flut…
):Flutter视频/直播APP省流量&加速,基于webrtc
-
Android-p2p-engine(
gitee.com/cdnbye/andr…
):传输能力基于WebRTC Datachannel,可以与CDNBye的Web端插件互联互通
-
UnityRenderStreaming(
github.com/Unity-Techn…
):Streaming Server for unity
-
WebRTC的拥塞控制和带看策略(
mp.weixin.qq.com/s/Ej63-FTe5…
):
-
WebRTC拥塞控制策略(
www.freehacker.cn/media/webrt…
)
-
Google's BBR拥塞控制算法如何对抗diu丢包(
blog.csdn.net/dog250/arti…
)
-
RTP Media Congestion Avoidance Techniques:
datatracker.ietf.org/wg/rmcat/ch…
-
medooze/media-server(
github.com/medooze/med…
):WebRTC Media Server
-
涂鸦开源voip:
gitee.com/tucodec/rel…
-
Jackarain/avplayer(
github.com/Jackarain/a…
):一个基于FFmpeg、libtorrent的P2P播放器实现
-
EricssonResearch/openwebrtc:A cross-platform WebRTC client framework based on GStreamer
www.openwebrtc.org
-
webrtc/apprtc: The video chat demo app based on WebRTC. This project is currently on HOLD with minimal maintenance.
appr.tc
-
AirenSoft/OvenMediaEngine: OvenMediaEngine (OME) is a streaming engine for real-time live broadcasting with ultra-low latency.
OvenMediaEngine.com/ome
-
runner365/read_book:一点点从基础做起 从音视频协议原文精读翻译做起,欢迎交流指导!
-
WebRTC in the real world: STUN, TURN and signaling:
www.html5rocks.com/en/tutorial…
-
WebRTC 的 Android 2 Android 实现:
blog.csdn.net/youmingyu/a…
-
webrtc进阶-信令篇-之四: 如何为WebRTC项目选择信令协议
-
pristineio/webrtc-build-scripts: A set of build scripts useful for building WebRTC libraries for Android and iOS.
-
weizhenwei
www.jianshu.com/u/102fafe8c…
Webrtc源码分析相关博客
-
WebRTC代码走读(八):代码目录结构:
blog.csdn.net/wanghorse/a…
-
WEBRtc相关:
www.wolfcstech.com/archives/
3.3 音视频标准/历史相关
-
编解码和视频处理技术介绍:
wenku.baidu.com/view/0ce015…
-
多媒体技术基础第三方03章_数字声音编码:
wenku.baidu.com/view/f098cf…
-
音视频系统培训资料(内部):
wenku.baidu.com/view/3fa2be…
-
音视频编解码技术:
wenku.baidu.com/view/419f83…
-
音视频专业知识:
wenku.baidu.com/view/6ea5db…
-
音视频通信基础知识:
wenku.baidu.com/view/7d3c24…
-
第二章音频的数字化:
wenku.baidu.com/view/715444…
-
音视频技术及发展:
wenku.baidu.com/view/4d4f13…
3.4 其他
-
rainfly123/flvmuxer(
github.com/rainfly123/…
):This tool is used to encapsulate H264 and AAC to RTMP
-
ant-media/LibRtmp-Client-for-Android(
github.com/ant-media/L…
):It is probably the smallest(~60KB, fat version ~300KB) rtmp client for android. It calls librtmp functions over JNI interface
antmedia.io
-
video-dev/hls.js(
github.com/video-dev/h…
):JavaScript HLS client using Media Source Extension
hls-js.netlify.com/demo
-
rao1219/VideoAnalysisTool(
github.com/rao1219/Vid…
):这是一款视频分析处理工具,目前嵌入了Visual Tracking功能,手动勾选视频中第一帧的某个物体,程序自动跟踪该物体在整个视频序列中的位置
-
github.com/guoguo11/JS…
JNI 调用C实现.speex转换为.wav;使用场景:微信高清语音.speex解码为.wav
-
github.com/kaldi-asr/k…
is the official location of the Kaldi project.
kaldi-asr.org
-
latelee/H264BSAnalyzer:H264(AVC) and H265(HEVC) bit stream Analyzer, VS2010 MFC project(Windows 7 x64).
-
ZhengfengRao/rtp2mp4:recv rtp(h264+aac), save as mp4 file
-
hmgle/h264_to_rtp:Send H264 file by RTP over UDP
-
kn007/silk-v3-decoder:[Skype Silk Codec SDK]Decode silk v3 audio files (like wechat amr, aud files, qq slk files) and convert to other format (like mp3). Batch conversion support.
kn007.net/topics/deco…
-
SimpleLivePublisher.Lite
github.com/gezhaoyou/S…
: 简介的Android平台直播推流
其他资源持续整理输出中...