Android 音视频开发入门指南

 在具体的业务领域,你可以慢慢沉淀下来,用自己的努力和时间换来对领域知识的深入理解和积累,逐渐从一个开发小白走向最懂这个行业的专家。
 -- 无论什么平台,他们的学习曲线其实是类似的,都要经历差不多如下的环节:
 1.学习对应平台的编程语言,如:C/C++,Java,Object C,Javascript 等
 2.熟悉对应平台提供的 API,如:UI 库,网络,文件,数据库, 图片处理,多媒体处理 等等
 3.掌握平台相关的特性、框架和原理,如:Windows 的 WINSOCK,ODBC,WPF 等,Unix 的设计哲学,Android 的四大组件,iOS 的 MVC 模式等等

 4.通过具体的项目,熟悉和练手,达到可完成任意功能的开发.

视频组成:音频 视频 字幕。

封装格式:MKV/WebM, AVI, MP4/MOV, MPEG-TS/PS (including basic EVO support), FLV, OGG, 以及其他ffmpeg支持的格式!
视频编码:H264, VC-1, MPEG-2, MPEG4-ASP (Divx/Xvid), VP8, MJPEG 等。
音频编码:AAC, AC3, DTS(-HD), TrueHD, MP3/MP2, Vorbis, LPCM 等。
字幕:VOB, DVB Subs, PGS, SRT, SSA/ASS, Text

--对于多媒体开发入门及提升:(MPEG阵营和Google开源阵营)
  1.首先,务必明确自己的目标和定位。用互联网式的语言说,就是场景在哪里、有什么样的痛点,最终学习/开发出的技术方案/软件产品需要满足哪些可量化的指标。我个人建议在入门阶段不要过早聚焦在一个技术点上,而应该更多建立一个偏全局、偏框架性的概念理解。早早地手捧一份类似ISO/IEC 14496-10的大部头生掰硬啃,收获的可能只有心理上的高大上。不如先以外行心态、以给产品经理或者商务销售讲技术的心态,仅仅从通用性的逻辑层面来入门学习。把大象放进冰箱需要3步,那么一个实时视频聊天系统有哪几个逻辑模块呢?从一方好友开始呼叫、到双方建立连接、开始数据通信直至最终会话终止,其间的协议交互和流程是怎样的呢?不考虑具体的Codec实现及复杂的应用场景技术指标要求,就当是加强版的CS通信,比起某年初学socket API调用时的DEMO代码如何?……由此一层层、一步步用自己熟悉的技术类比、反推和延伸,并逐步理解主要环节的实现原理及技术难点,最终能给自己明确一两个点进行后续的深究挖掘,例如:彻底排查和理清实时通话中时延的原因并优化、寻找系统中能够影响图像质量的因素并进行优化等。
  2.其次,针对一个具体的、“局部性”问题不妨以“庖丁解牛”“掘地三尺”的态度来对待。因为音视频技术有一定的数学基础和较清晰的年代演进历程,所以我个人非常主张追根溯源式的学习。例如我在公司内开设视频压缩原理的课程时,一定会先讲一次图像压缩的课程。看似古老的JPEG压缩框架,能够非常直接地理解Spatial domain到Transform domain的意义、DCT频带数据特征之于人类视觉的影响、量化及量化表的由来、变长字编码的设计理念等等。这些技术环节构成了视频压缩的半壁江山,而且虽然历经二十余年的发展,很多环节不断演进更迭,但其数学理论根基和工程设计理念得以传承和延续。再略微进一步,体会下WebP和JPEG流程上的差异与改进,Intra prediction的设计理念与作用已然清晰。至此,视频编码框架下I frame的主干流程跃然眼前;剩下的细节,比如Intra prediction如何从H.264/AVC的9种模式演变到HEVC的35种,虽是匠心不改、历经雕琢、但可作为锦上添花之物了。
  3.再次,当一个个小的局部性问题逐个攻克后,就需要回归全局性视角,对之前已有的结论和观点再次推敲。多媒体项目产品中往往会遇到技术指标之间的冲突和矛盾,例如:开启复杂的算法工具可以获得更高的压缩效率,即同等码率下可以有更高的图像清晰度,但在中低端设备上复杂度过高会导致编码帧率上不来,严重时用户甚至会觉得画面有明显的顿挫感、通话质量不好。如何在一对对矛盾中取得权衡,既需要对每个指标背后的技术原理有深刻的理解,同时更要求对整体业务需求和应用场景有所把控。懂得取舍、合理平衡,也是多媒体开发进阶的必由之路。

  4.最后,身处互联网行业,自然要重视信息的交流。但我个人不建议白纸一张时就盲目交流,也对很多自媒体鼓吹的碎片化干货学习保留怀疑。我建议初学者在具备一定基础后,带着自己的理解、感悟和困惑去交流,切勿人云亦云、东施效颦,对所谓大公司的“成功案例”、“领先指标”最好在充分对比业务场景、成本投入、平台差异、目标用户群等等因素后进行消化,并为我所用。

--《视音频基础知识》包括下面内容:
视频播放器原理
封装格式(MP4,RMVB,TS,FLV,AVI)
视频编码数据(H.264,MPEG2,VC-1)
音频编码数据(AAC,MP3,AC-3)
视频像素数据(YUV420P,RGB)
音频采样数据(PCM)

-- 2012,2013年总结:在视音频技术道路上摸索- https://blog.csdn.net/leixiaohua1020/article/details/17851977
  研究视频质量评价的。做一个网络视音频方面的项目,需要研究网络协议。究RTSP+RTP/RTCP这样的流媒体协议。这样的协议组合很适合IPTV系统。实际互联网视频分析。对一个未知领域的摸索 。找到开源的优秀的视音频项目,花费了大量的时间。有实际应用价值的很多视音频项目都是不开源的商业项目。FLV是互联网上相当通用的封装格式,H.264也是相当通用的视频编码标准。文章《100行代码实现最简单的基于FFMPEG+SDL的视频播放器》。
  为了寻找互联网视频使用较多的协议,我做了很多的分析工作。比如说,用WireShark抓取正在播放的互联网视频的数据报。然后把数据报的内容取出来进行分析。在多次的尝试之后,我发现:直播使用最多的是RTMP,主要因为它可以实现无插件直播;点播使用最多的是HTTP,主要因为它不丢包,而且节约服务器资源。基于HTTP的点播其实不用多学,因为实际上它和下载文件差不多。直播的RTMP协议则是需要学习的。
  RTMP大部分文章都是协议破解之类的文章。后来找到了协议规范。把libRTMP看一看。libRTMP差不多是我看的第一个视音频工程内部的代码了,通过查看libRTMP的源代码,我渐渐的掌握了RTMP。
  教室直播,学习的JavaEE,再结合新学的流媒体技术,自己设计前台,后台,各种界面;前台用div + css + jQuery,后台用Struts2 + Spring + Hibernate,流媒体技术采用RTMP相关技术,搞出了一个Demo。
  用Eclipse + MinGW搭建了一个环境后就开始看起了FFMPEG的源代码。FFMPEG不仅仅局限于视频解码。事实上,它可以做和视音频相关的方方面面的工作。掌握了它,基本上就掌握了视音频处理技术了。互联网视音频的播放,码流分析,图像分析的系统。
  视频质量评价技术其实很重要,是衡量视频好坏的关键技术。互联网视频技术,重点应该是质量评价。网络,视频,音频,编解码,质量评价。

-- Android 音视频开发入门指南- http://blog.51cto.com/ticktick/1956269

Android 音视频从入门到提高 —— 任务列表》,如果你认真把所有任务都完成了,你一定会成为音视频人才招聘市场的香饽饽
1. 在 Android 平台绘制一张图片,使用至少 3 种不同的 API,ImageView,SurfaceView,自定义 View
2. 在 Android 平台使用 AudioRecord 和 AudioTrack API 完成音频 PCM 数据的采集和播放,并实现读写音频 wav 文件
3. 在 Android 平台使用 Camera API 进行视频的采集,分别使用 SurfaceView、TextureView 来预览 Camera 数据,取到 NV21 的数据回调
4. 学习 Android 平台的 MediaExtractor 和 MediaMuxer API,知道如何解析和封装 mp4 文件
5. 学习 Android 平台 OpenGL ES API,了解 OpenGL 开发的基本流程,使用 OpenGL 绘制一个三角形
6. 学习 Android 平台 OpenGL ES API,学习纹理绘制,能够使用 OpenGL 显示一张图片
7. 学习 MediaCodec API,完成音频 AAC 硬编、硬解
8. 学习 MediaCodec API,完成视频 H.264 的硬编、硬解
9. 串联整个音视频录制流程,完成音视频的采集、编码、封包成 mp4 输出
10. 串联整个音视频播放流程,完成 mp4 的解析、音视频的解码、播放和渲染
11. 进一步学习 OpenGL,了解如何实现视频的剪裁、旋转、水印、滤镜,并学习 OpenGL 高级特性,如:VBO,VAO,FBO 等等
12. 学习 Android 图形图像架构,能够使用 GLSurfaceviw 绘制 Camera 预览画面
13. 深入研究音视频相关的网络协议,如 rtmp,hls,以及封包格式,如:flv,mp4
14. 深入学习一些音视频领域的开源项目,如 webrtc,ffmpeg,ijkplayer,librtmp 等等
15. 将 ffmpeg 库移植到 Android 平台,结合上面积累的经验,编写一款简易的音视频播放器
16. 将 x264 库移植到 Android 平台,结合上面积累的经验,完成视频数据 H264 软编功能
17. 将 librtmp 库移植到 Android 平台,结合上面积累的经验,完成 Android RTMP 推流功能
18. 上面积累的经验,做一款短视频 APP,完成如:断点拍摄、添加水印、本地转码、视频剪辑、视频拼接、MV 特效等功能

推荐的参考资料:
1. 《雷霄骅的专栏》:http://blog.csdn.net/leixiaohua1020
2. 《Android音频开发》:http://ticktick.blog.51cto.com/823160/d-15
3. 《FFMPEG Tips》:http://ticktick.blog.51cto.com/823160/d-17
4. 《Learn OpenGL 中文》:https://learnopengl-cn.readthedocs.io/zh/latest/

5. 《Android Graphic 架构》:https://source.android.com/devices/graphics/

-- 实时音视频技术入门提纲- https://blog.csdn.net/GV7lZB0y87u7C/article/details/80523625

-音视频开发,就是要掌握图像、音频、视频的基础知识,并且学会采集、渲染、处理、传输等:
采集:它解决的是,数据从哪里来的问题
渲染:它解决的是,数据怎么展现的问题
处理:它解决的是,数据怎么加工的问题
传输:它解决的是,数据怎么共享的问题

-音视频第三方库:
1)图像处理:OpenGL,OpenCV,libyuv,ffmpeg 等;
2)视频编解码:x264,OpenH264,ffmpeg 等;
3)音频处理:speexdsp,ffmpeg 等;
4)音频编解码:libfaac,opus,speex,ffmpeg 等。


-研究音视频传输,其实就是在研究协议,具体有哪些协议呢 ?
1)音视频在传输前,怎么打包的,如:FLV,ts,mpeg4 等;
2)直播推流,有哪些常见的协议,如:RTMP,RSTP 等;
3)直播拉流,有哪些常见的协议,如:RTMP,HLS,HDL,RTSP 等;
4)基于 UDP 的协议有哪些?如:RTP/RTCP,QUIC 等。

----------------------------------------

Android 视频分离和合成(MediaMuxer和MediaExtractor)-
https://github.com/RrtoyewxXu/AndroidLiveRecord/tree/master/mediaexactorandmediamuxerdemo

GraphicsTestBed 滤镜处理和OpenGLES进阶- https://github.com/lb377463323/GraphicsTestBed
AndroidLiveRecord视频分离和合成,MediaExtractor和MediaMuxer的Demo- https://github.com/RrtoyewxXu/AndroidLiveRecord/tree/master/mediaexactorandmediamuxerdemo
   在Android的多媒体类中,MediaMuxer和MediaCodec算是比较年轻的,它们是JB 4.1和JB 4.3才引入的。前者用于将音频和视频进行混合生成多媒体文件。缺点是目前只能支持一个audio track和一个video track,而且仅支持mp4输出。不过既然是新生事物,相信之后的版本应该会有大的改进。MediaCodec用于将音视频进行压缩编码,它有个比较牛X的地方是可以对Surface内容进行编码,如KK 4.4中屏幕录像功能就是用它实现的。
  MediaExtractor用于音视频分路,和MediaMuxer正好是反过程。MediaFormat用于描述多媒体数据的格式。MediaRecorder用于录像+压缩编码,生成编码好的文件如mp4, 3gpp,视频主要是用于录制Camera preview。MediaPlayer用于播放压缩编码后的音视频文件。AudioRecord用于录制PCM数据。AudioTrack用于播放PCM数据。PCM即原始音频采样数据,可以用如vlc播放器播放。
  MediaExtractor类,可以用来分离容器中的视频track和音频track.

  opengl渲染的整个过程。openGL采用cs模型:c是cpu,s是GPU,c给s的输入是vertex信息和Texture信息,s的输出是显示器上显示的图像。
  几何顶点数据包括模型的顶点集、线集、多边形集,这些数据经过流程图的上部,包括运算器、逐个顶点操作等;图像数据包括象素集、影像集、位图集等,图像象素数据的处理方式与几何顶点数据的处理方式是不同的,但它们都经过光栅化、逐个片元(Fragment)处理直至把最后的光栅数据写入帧缓冲器。在OpenGL中的所有数据包括几何顶点数据和象素数据都可以被存储在显示列表中或者立即可以得到处理。OpenGL中,显示列表技术是一项重要的技术。
  OpenGL要求把所有的几何图形单元都用顶点来描述,这样运算器和逐个顶点计算操作都可以针对每个顶点进行计算和操作,然后进行光栅化形成图形碎片;对于象素数据,象素操作结果被存储在纹理组装用的内存中,再象几何顶点操作一样光栅化形成图形片元。
  整个流程操作的最后,图形片元都要进行一系列的逐个片元操作,这样最后的象素值BZ送入帧缓冲器实现图形的显示。 
  
  OpenGL中的坐标是带有深度信息的三维坐标,把这些三维坐标转换成可以在LCD上显示的二维坐标,这个过程叫做pipeline。pipeline分为以下两个步骤: 
第一步:将坐标值由3D的转换成2D。 
第二步:对第一步中的2D坐标赋予颜色值(RGBA)。

AndroidOpenGLDemo- https://github.com/doggycoder/AndroidOpenGLDemo

android-openGL-canvas- https://github.com/ChillingVan/android-openGL-canvas

> 学习 MediaCodec API,完成音频 AAC 硬编、硬解;学习 MediaCodec API,完成视频 H.264 的硬编、硬解
mp3文件转码为aac音频文件
转码实现原理:mp3->pcm->aac,首先将mp3解码成PCM,再将PCM编码成aac格式的音频文件。

码率控制模式有三种:
1.CQ  表示完全不控制码率,尽最大可能保证图像质量;
2.CBR 表示编码器会尽量把输出码率控制为设定值,即我们前面提到的“不为所动”;
3.VBR 表示编码器会根据图像内容的复杂度(实际上是帧间变化量的大小)来动态调整输出码率,图像复杂则码率高,图像简单则码率低;

Android 流控策略选择:
1.质量要求高、不在乎带宽、解码器支持码率剧烈波动的情况下,可以选择 CQ 码率控制策略。
2.VBR 输出码率会在一定范围内波动,对于小幅晃动,方块效应会有所改善,但对剧烈晃动仍无能为力;连续调低码率则会导致码率急剧下降,如果无法接受这个问题,那 VBR 就不是好的选择。
3.CBR 的优点是稳定可控,这样对实时性的保证有帮助。所以 WebRTC 开发中一般使用的是CBR。

音视频的编码方式分为两种:
  硬编码:用设备GPU去实现编解码,这样可以减轻CPU的压力。
  软编码:让CPU来进行编解码,在c层代码来进行编解码,因为c/c++有很多好的编解码库。

通过Camera采集NV21数据编码为H.264视频文件并保存;
通过Camera2采集YV12数据编码为H.264视频文件并保存;
通过SurfaceView解码显示Camera编码保存的H.264视频文件;

通过TextureView解码显示Camera编码保存的H.264视频文件;


> MediaCodec编码解码音频AAC
 H264,AAC解码Demo下载地址:http://download.csdn.net/detail/a512337862/9882200 。附带aac以及H264文件以及源码
 AudioTrack主要是用来进行主要是用来播放声音的,但是只能播放PCM格式的音频流。
 mp3转码成aac为例,转码实现原理:mp3->pcm->aac,首先将mp3解码成PCM,再将PCM编码成aac格式的音频文件。
 mime:用来表示媒体文件的格式 mp3为audio/mpeg;aac为audio/mp4a-latm;mp4为video/mp4v-es;音频前缀为audio,视频前缀为video 我们可用此区别区分媒体文件内的音频轨道和视频轨道

  Android MediaCodec 音频转码——硬编硬解- https://blog.csdn.net/qq_28251907/article/details/78565227
 Android多媒体之 wav和amr的互转- https://blog.csdn.net/honeybaby201314/article/details/50379040
使用的aac的采样率一般是44100Hz,但是amr的采样率一般设置为8000Hz,所以将aac转为amr时需要downSample,将采样率从44100 变为8000,upsampling/downsampling- https://github.com/hutm/JSSRC
 wav2amr-  https://github.com/kevinho/opencore-amr-android

  音频(一) - 音频基础知识- https://blog.csdn.net/kevindgk/article/details/52924779
 MediaCodec可以处理的数据有以下三种类型:压缩数据、原始音频数据、原始视频数据。
 Android端的音频技术,包括音频的录制、播放、降噪、压缩,以及在局域网中的实时传输等。

 音频的使用场景:
音频播放器,录音机,语音电话,音视频监控应用,音视频直播应用,音频编辑/处理软件,蓝牙耳机/音箱等。

 音频开发的具体内容:
(1)音频采集/播放
(2)音频算法处理(去噪、静音检测、回声消除、音效处理、功放/增强、混音/分离等)
(3)音频的编解码和格式转换
(4)音频传输协议的开发(SIP,A2DP、AVRCP等)

 延时敏感、卡顿敏感、噪声抑制(Denoise)、回声消除(AEC)、静音检测(VAD)、混音算法等.
 根据编码方式的不同,音频编码技术分为三种:波形编码、参数编码和混合编码。一般来说,波形编码的话音质量高,但编码速率也很高;参数编码的编码速率很低,产生的合成语音的音质不高;混合编码使用参数编码技术和波形编码技术,编码速率和音质介于它们之间。
 脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。
 在计算机应用中,能够达到最高保真水平的就是PCM编码,被广泛用于素材保存及音乐欣赏,CD、DVD以及我们常见的WAV文件中均有应用。常用的音频采样频率有8kHz、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz、48kHz、96kHz、192kHz等。

  码率 = 采样频率 * 量化位数 * 声道个数
 音频数据是流式的,本身没有明确的一帧帧的概念,在实际的应用中,为了音频算法处理/传输的方便,一般约定俗成取2.5ms~60ms为单位的数据量为一帧音频。这个时间被称之为“采样时间”,其长度没有特别的标准,它是根据编解码器和具体应用的需求来决定的,我们可以计算一下一帧音频帧的大小。

假设某通道的音频信号是采样率为8kHz,位宽为16bit,20ms一帧,单通道,则一帧音频数据的大小为:
int size = 8000 x 16bit x 0.02s x 1 = 2560 bit = 320 byte = 160 short

 常见的编码方式有:PCM 和 ADPCM,这些数据代表着无损的原始数字音频信号,添加一些文件头信息,就可以存储为WAV文件了,它是一种由微软和IBM联合开发的用于音频数字存储的标准,可以很容易地被解析和播放。

  音频开发的Android API:
音频采集:  MediaRecoder,AudioRecord
音频播放:  SoundPool,MediaPlayer,AudioTrack
音频编解码: MediaCodec
NDK API:     OpenSL ES

音频处理的开源库:Speex、WebRTC、Opus等

> MediaCodec编码解码视频H.264,
  MediaCodec硬解码实现RTSP+H264实时视频播放完整功能可以参考:
https://github.com/ldm520/ANDROID_MEDIACODEC_RTSP_H264
 在Android里,最常用的视频编码解码用的API就是mediacodec了,可以进行多种格式的硬解码,也能和mediamuxer一起使用实现音视频文件的编辑(结合MediaExtractor),用OpenGL绘制Surface并生成mp4文件,屏幕录像以及类似Camera app里的录像功能(虽然这个用MediaRecorder更合适)等
  MediaExtractor用于音视频分路,和MediaMuxer正好是反过程。MediaFormat用于描述多媒体数据的格式。MediaRecorder用于录像+压缩编码,生成编码好的文件如mp4, 3gpp,视频主要是用于录制Camera preview。MediaPlayer用于播放压缩编码后的音视频文件。AudioRecord用于录制PCM数据。AudioTrack用于播放PCM数据。PCM即原始音频采样数据,可以用如vlc播放器播放。

 【Android 多媒体应用】使用MediaCodec将摄像头采集的视频编码为h264- https://www.cnblogs.com/CoderTian/p/6224605.html
android编码h264(二):MediaCodec 硬编码 h264(硬编码)- https://blog.csdn.net/ss182172633/article/details/50256733  https://github.com/sszhangpengfei/MediaCodecEncodeH264

  IDR帧:IDR帧属于I 帧。解码器收到IDR frame时,将所有的参考帧队列丢弃 ,这点是所有I 帧共有的特性,但是收到IDR帧时,解码器另外需要做的工作就是:把所有的PPS和SPS参数进行更新。由此可见,在编码器端,每发一个 IDR,就相应地发一个 PPS&SPS_nal_unit
  I帧:帧内编码帧是一种自带全部信息的独立帧,无需参考其它图像便可独立进行解码,视频序列中的第一个帧始终都是I帧。
  P帧:前向预测编码帧
  B帧:双向预测内插编码帧

阅读更多
个人分类: 音视频方案
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭