随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播、点播功能,那么,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及如何技术选型,如何解决遇到的难题呢,下面来看看,欢迎大咖交流。
- 视频是什么
- <code class="hljs mel has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
- 静止的画面叫图像(
- <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">
- picture
- </span>
- )。连续的图像变化每秒超过
- <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">
- 24
- </span>
- 帧(frame)画面以上时,根椐视觉暂留原理, 人眼无法辨别每付单独的静态画面,看上去是平滑连续的视觉效果。这样的连续画面叫视频。 当连续图像变化每秒低于
- <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">
- 24
- </span>
- 帧画面时,人眼有不连续的感觉叫动画(cartoon)
- </code>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 3
- </li>
- </ul>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 3
- </li>
- </ul>
- 流媒体
- <code class="hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
- 指采用流式传输的方式在Internet / Intranet播放的媒体格式.流媒体的数据流随时传送随 时播放,只是在开始时有些延迟 边下载边播入的流式传输方式不仅使启动延时大幅度地缩短,而且对系统缓存容量的需求也大大降低,极大地减少用户用在等待的时间
- </code>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- </ul>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- </ul>
- 分辨率
- <code class="hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
- 分辨率是一个表示平面图像精细程度的概念,通常它是以横向和纵向点的数量来衡量的,表示成水平点数垂直点数的形式, 在计算机显示领域我们也表示成"每英寸像素"(ppi).在一个固定的平面内,分辨率越高,意味着可使用的点数越多,图像越细致
- </code>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- </ul>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- </ul>
- 码流
- <code class="hljs has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
- 数据传输时单位时间传送的数据位数,可以理解其为取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件,但是文件体积与取样率是成正比的
- 如何用最低的码率达到最少的失真,一般我们用的单位是kbps即千位每秒
- </code>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- </ul>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- </ul>
- 帧率
- <code class="hljs livecodeserver has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">
- 帧/秒(frames per
- <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">
- second
- </span>
- )的缩写,也称为帧速率,测量用于保存、显示动态视频的信息数量。每一帧都是静止的图象,快速连续地显示帧便形成了运动的假象。 每秒钟帧数 (fps)
- 愈多,所显示的动作就会愈流畅,可理解为
- <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">
- 1
- </span>
- 秒钟时间里刷新的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次,也就是指每秒钟能够播放(或者录制)多少格画面。
- </code>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- </ul>
- <ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);">
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 1
- </li>
- <li style="box-sizing: border-box; padding: 0px 5px;">
- 2
- </li>
- </ul>
- 封装格式 (专业上讲叫容器, 通俗的叫文件格式),
- 视频编解码,
- 音频编解码####1.1常见的封装格式 * MPEG: 编码采用的容器,具有流的特性。里面又分为PS,TS等,PS主要用于DVD存储,TS主要用于HDTV. * MPEG Audio Layer 3 : 大名鼎鼎的MP3,已经成为网络音频的主流格式,能在128kbps的码率接近CD音质 * MPEG - 4(Mp4) : 编码采用的容器,基于QuickTime MOV开发,具有许多先进特性;实际上是对Apple公司开发的MOV格式 (也称Quicktime格式)的一种改进. * MKV: 它能把Windows Media Video,RealVideo,MPEG - 4等视频音频融为一个文件,而且支持多音轨,支持章节字幕等;开源的容器格式 * 3GP: 3GPP视频采用的格式,主要用于流媒体传送;
- 3GP其实是MP4格式的一种简化版本,
- 是手机视频格式的绝对主流. * MOV: QuickTime的容器,恐怕也是现今最强大的容器,甚至支持虚拟现实技术,Java等,它的变种MP4,
- 3GP都没有这么厉害;广泛应用于Mac OS操作系统,在Windows操作系统上也可兼容,但是远比不上AVI格式流行 * AVI: 最常见的音频视频容器,
- 音频视频交错(Audio Video Interleaved)允许视频和音频交错在一起同步播放. * WAV: 一种音频容器,大家常说的WAV就是没有压缩的PCM编码,其实WAV里面还可以包括MP3等其他ACM压缩编码等等
播放流程: 获取流–> 解码–> 播放
录制播放路程: 录制音频视频–> 剪辑–> 编码–> 上传服务器 别人播放.
直播过程 : 录制音视频–> 编码–> 流媒体传输–> 服务器—> 流媒体传输到其他 app–> 解码–> 播放
几个重要的环节
问题
本身有提供 MediaPlayer, 那么 mediaplayer 支持哪些格式的流媒体协议呐? 又支持哪些解码器呐? 兼容性如何, 性功能如何?
MPEG-2:制定于 1994 年,设计目标为高级工业标准的图像质量以及更高的传输率。这种格式主要应用在 DVD/SVCD 的制作 (压缩) 方面,同时在一些 HDTV(高清晰电视广播)和一些高要求视频编辑、处理上面也有相当的应用。使用 MPEG-2 的压缩算法,可以把一部 120 分钟长的电影压缩到 4 到 8GB 的大小。这种视频格式的文件扩展名包括. mpg、.mpe、.mpeg、.m2v 及 DVD 光盘上的. vob 文件等。MPEG-4:制定于 1998 年,MPEG-4 是为了播放流式媒体的高质量视频而专门设计的,它可利用很窄的带宽,通过帧重建技术,压缩和传输数据,以求使用最少的数据获得最佳的图像质量。目前 MPEG-4 最有吸引力的地方在于它能够保存接近于 DVD 画质的小体积视频文件。另外,这种文件格式还包含了以前 MPEG 压缩标准所不具备的比特率的可伸缩性、动画精灵、交互性甚至版权保护等一些特殊功能。这种视频格式的文件扩展名包括. asf、.mov 和 DivX
AVI 等。
从上图我们也看到, android 平台自身支持的音视频解码是有限的 一般的 mp3 mp4….3gp 等等 其他的只能自己解码了。。。
那么如何解码呐?
经过一番调研对比, 选择乐 ijkplayer.
正如上文所说, android 本事对音视频流媒体传输协议, 以及音视频编解码支持有限. 所以对于直播类应用, 要自己解码
先说下 vitamio 这个是功能很强大, 但是企业收费版的, 个人用户可以玩玩.
目前 WebRtc 只适合小范围(8 人以内)音视频会议,不适合做直播
接下来介绍下 ffmpeg vlc ijkplayer 以及选择方案
ffmpeg 是一个非常强大的音视频编解码开源库, 目前市场上流行的播放器, 大部分都是基于此开发的, 包括暴风, 腾讯, 等等以及上面提到的 vitamio,vlc,ijkplayer
关于 ffmpeg 源码分析, 有兴趣的请看
vlc 支持 android 开发 ,ijkplayer 也支持. 通过反编译网易云音乐, 以及 YY 等音视频 app. 发现网易云音乐, 斗鱼用的 ijkplayer,YY 用的 VLC.
那么 vlc&ijkplayer 相比较各有什么优缺点呐, 该如何选择呐?[待深入使用, 或者用过的可以交流下]
其实这个没有深入分析, ijkplayer 是 bilibili 开源的音视频编解码库, 对 android, 进行和很好的抽取封装, 易于编译使用. vlc 尝试过, 稍微复杂些.
如果不需要对源码进行修改, 在 app 的 build.gradle 中加入如下依赖即可
- dependencies {#required,
- enough
- for most devices.compile 'tv.danmaku.ijk.media:ijkplayer-java:0.4.5.1'compile 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.4.5.1'#Other ABIs: optional compile 'tv.danmaku.ijk.media:ijkplayer-armv5:0.4.5.1'compile 'tv.danmaku.ijk.media:ijkplayer-arm64:0.4.5.1'compile 'tv.danmaku.ijk.media:ijkplayer-x86:0.4.5.1'#ExoPlayer as IMediaPlayer: optional,
- experimental compile 'tv.danmaku.ijk.media:ijkplayer-exo:0.4.5.1'
- }
当然如何你想对其源码进行修改, 采用如下方式
1. 需要
下载配置 NDK r10e
配置 androidsdk
# add these lines to your ~/.bash_profile or ~/.profile
# export ANDROID_SDK=
# export ANDROID_NDK=
2.
- Build Android git clone https: //github.com/Bilibili/ijkplayer.git ijkplayer-android
- cd ijkplayer - android git checkout - B latest k0.4.5.1. / init - android.sh //此步用于下载ffmpeg,初始化配置
- cd android / contrib. / compile - ffmpeg.sh clean. / compile - ffmpeg.sh all cd... / compile - ijk.sh all然后通过androidstudio把生成的project导入工程#Android Studio: #Open an existing Android Studio project#Select android / ijkplayer / and import
可以根据需要对音视频编解码库进行裁剪. 编译出最小的满足需要的库
bilibili 提供三种裁剪方式
If you prefer more codec/format
- cd config rm module.sh ln - s module -
- default.sh module.sh cd android / contrib sh compile - ffmpeg clean
If you prefer less codec/format for smaller binary size (include hevc function)
- cd config rm module.sh ln - s module - lite - hevc.sh module.sh cd android / contrib sh compile - ffmpeg clean
If you prefer less codec/format for smaller binary size (by default)
- cd config rm module.sh ln - s module - lite.sh module.sh cd android / contrib sh compile - ffmpeg clean
当然也可以根据需要自己裁剪.
我们来看下 ijkplayer/config/module-lite.sh 即 default 裁剪模式支持哪些编解码方式
我们可以看到
export COMMON_FF_CFG_FLAGS="
export COMMON_FF_CFG_FLAGS="
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS –enable-protocol=rtmp"
【先占坑,接下来详解】
【先占坑,接下来详解】
【先占坑,接下来重点学习】
【接下来仿网易云音乐,写一个开源项目,欢迎多多关注】
- ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "http-detect-range-support", 0);
- ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
- ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "analyzeduration", "2000000");
- ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "probsize", "4096");
- ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 0);
来源: http://lib.csdn.net/article/liveplay/47360