Android直播,音视频播放那些事儿

前言

随着音视频领域的火热,在很多领域(教育,游戏,娱乐,体育,跑步,餐饮,音乐等)尝试做音视频直播/点播功能,那么作为开发一个小白,如何快速学习音视频基础知识,了解音视频编解码的传输协议,编解码方式,以及如何技术选型,如何解决遇到的坑,本文抛砖引玉,欢迎大咖交流。

一. 音视频的基础知识

1.1 基本概念

视频是什么

静止的画面叫图像(picture)。连续的图像变化每秒超过24帧(frame)画面以上时,根椐视觉暂留原理,
人眼无法辨别每付单独的静态画面,看上去是平滑连续的视觉效果。这样的连续画面叫视频。
当连续图像变化每秒低于24帧画面时,人眼有不连续的感觉叫动画(cartoon)

流媒体

指采用流式传输的方式在Internet / Intranet播放的媒体格式.流媒体的数据流随时传送随 时播放,只是在开始时有些延迟
边下载边播入的流式传输方式不仅使启动延时大幅度地缩短,而且对系统缓存容量的需求也大大降低,极大地减少用户用在等待的时间

分辨率

分辨率是一个表示平面图像精细程度的概念,通常它是以横向和纵向点的数量来衡量的,表示成水平点数垂直点数的形式,
在计算机显示领域我们也表示成“每英寸像素”(ppi).在一个固定的平面内,分辨率越高,意味着可使用的点数越多,图像越细致

码流

 数据传输时单位时间传送的数据位数,可以理解其为取样率,单位时间内取样率越大,精度就越高,处理出来的文件就越接近原始文件,但是文件体积与取样率是成正比的
 如何用最低的码率达到最少的失真,一般我们用的单位是kbps即千位每秒

帧率

帧/秒(frames per second)的缩写,也称为帧速率,测量用于保存、显示动态视频的信息数量。每一帧都是静止的图象,快速连续地显示帧便形成了运动的假象。
每秒钟帧数 (fps) 愈多,所显示的动作就会愈流畅,可理解为1秒钟时间里刷新的图片的帧数,也可以理解为图形处理器每秒钟能够刷新几次,也就是指每秒钟能够播放(或者录制)多少格画面。

1.2 多媒体的格式分类

封装格式(专业上讲叫容器,通俗的叫文件格式),视频编解码,音频编解码
####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 压缩编码
等等

1.3 流媒体协议(RTP RTCP RTSP RTMP HLS)

  1. RTP RTCP RTSP
RTP :(Real-time Transport Protocol)是用于Internet上针对多媒体数据流的一种传输层协议.RTP协议和RTP控制协议RTCP一起使用,而且它是建立在UDP协议上的
RTCP:Real-time Transport Control Protocol或RTP Control Protocol或简写RTCP)实时传输控制协议,是实时传输协议(RTP)的一个姐妹协议
RTP协议和RTP控制协议RTCP一起使用,而且它是建立在UDP协议上的
RTSP:(Real Time Streaming Protocol)是用来控制声音或影像的多媒体串流协议,RTSP提供了一个可扩展框架,使实时数据,如音频与视频的受控、点播成为可能。
数据源包括现场数据与存储在剪辑中的数据。该协议目的在于控制多个数据发送连接,为选择发送通道,如UDP、多播UDP与TCP提供途径,并为选择基于RTP上发送机制提供方法
传输时所用的网络通讯协定并不在其定义的范围内,服务器端可以自行选择使用TCP或UDP来传送串流内容,比较能容忍网络延迟

RTP不像http和ftp可完整的下载整个影视文件,它是以固定的数据率在网络上发送数据,客户端也是按照这种速度观看影视文件,当影视画面播放过后,就不可以再重复播放,除非重新向服务器端要求数据。
RTSP与RTP最大的区别在于:RTSP是一种双向实时数据传输协议,它允许客户端向服务器端发送请求,如回放、快进、倒退等操作。当然,RTSP可基于RTP来传送数据,还可以选择TCP、UDP、组播UDP等通道来发送数据,具有很好的扩展性。它时一种类似与http协议的网络应用层协议

  1. RTMP

    RTMP(Real Time Messaging Protocol)实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输 开发的开放协议
  2. HLS
    HTTP Live Streaming(HLS)是苹果公司(Apple Inc.)实现的基于HTTP的流媒体传输协议,可实现流媒体的直播和点播,主要应用在iOS系统,
    为iOS设备(如iPhone、iPad)提供音视频直播和点播方案。HLS点播,基本上就是常见的分段HTTP点播,不同在于,它的分段非常小。
    相对于常见的流媒体直播协议,例如RTMP协议、RTSP协议、MMS协议等,HLS直播最大的不同在于,直播客户端获取到的,并不是一个完整的数据流。
    HLS协议在服务器端将直播数据流存储为连续的、很短时长的媒体文件(MPEG-TS格式),而客户端则不断的下载并播放这些小文件,
    因为服务器端总是会将最新的直播数据生成新的小文件,这样客户端只要不停的按顺序播放从服务器获取到的文件,就实现了直播。
    由此可见,基本上可以认为,HLS是以点播的技术方式来实现直播。由于数据通过HTTP协议传输,所以完全不用考虑防火墙或者代理的问题,
    而且分段文件的时长很短,客户端可以很快的选择和切换码率,以适应不同带宽条件下的播放。不过HLS的这种技术特点,决定了它的延迟一般总是会高于普通的流媒体直播协议。

二. android音视频的开发

播放流程: 获取流-->解码-->播放

录制播放路程: 录制音频视频-->剪辑-->编码-->上传服务器 别人播放.

直播过程 : 录制音视频-->编码-->流媒体传输-->服务器--->流媒体传输到其他app-->解码-->播放

几个重要的环节

  1. 录制音视频 AudioRecord/MediaRecord
  2. 视频剪辑 mp4parser 或ffmpeg
  3. 音视频编码 aac&h264
  4. 上传大文件 网络框架,进度监听,断点续传
  5. 流媒体传输 流媒体传输协议rtmp rtsp hls
  6. 音视频解码 aac&h264
  7. 渲染播放 MediaPlayer

问题

android本身有提供MediaPlayer,那么mediaplayer支持哪些格式的流媒体协议呐?又支持哪些解码器呐?兼容性如何,性功能如何?

Supported Media Formats

Media Playback

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.

三. ijkplayer的引入&介绍&使用

正如上文所说,android本事对音视频流媒体传输协议,以及音视频编解码支持有限.所以对于直播类应用,要自己解码

3.1 调研过程

vitamio

webRTC

ffmpeg

vlc

ijkplayer

先说下 vitamio这个是功能很强大,但是企业收费版的,个人用户可以玩玩.

目前WebRtc只适合小范围(8人以内)音视频会议,不适合做直播可以用WebRTC来做视频直播吗?

接下来介绍下 ffmpeg vlc ijkplayer以及选择方案

ffmpeg是一个非常强大的音视频编解码开源库,目前市场上流行的播放器,大部分都是基于此开发的,包括暴风,腾讯,等等以及上面提到的vitamio,vlc,ijkplayer

关于ffmpeg源码分析,有兴趣的请看雷霄骅(leixiaohua1020)的专栏

vlc 支持android开发 ,ijkplayer也支持. 通过反编译网易云音乐,以及YY等音视频app.发现网易云音乐,斗鱼用的ijkplayer,YY用的VLC.

那么vlc&ijkplayer相比较各有什么优缺点呐,该如何选择呐?[待深入使用,或者用过的可以交流下]

其实这个没有深入分析,ijkplayer是bilibili开源的音视频编解码库,对android,ios进行和很好的抽取封装,易于编译使用.vlc尝试过,稍微复杂些.

3.2 ijkplayer的导入&编译&使用

如果不需要对源码进行修改,在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=<your sdk path>

    export ANDROID_NDK=<your ndk path>

    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="$COMMON_FF_CFG_FLAGS --enable-demuxer=hls"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-parser=aac"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-parser=h264"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --disable-protocol=rtp"
export COMMON_FF_CFG_FLAGS="$COMMON_FF_CFG_FLAGS --enable-protocol=rtmp"

### 四. ijkplayer的java层源码分析
【先占坑,接下来详解】
### 五. 项目中ijkplayer的封装以及mediaview的封装以及使用
【先占坑,接下来详解】
### 六. ijkplayer底层学习
【先占坑,接下来重点学习】
### 七. 开源项目
【接下来仿网易云音乐,写一个开源项目,欢迎多多关注】
### 七. 常见问题以及解决方案
1. [ijkplayer播放rtmp直播流,延迟明显 ](https://github.com/Bilibili/ijkplayer/issues/210)
2. 全屏播放
3. 有时候会开始直播时出现黑屏
4. 有时候会出现花屏
5. 解码方式设置
6. 如何区分点播直播
7. 是否需要开启硬件加速
8. [How to set up only listen to the sound does not show video?](https://github.com/Bilibili/ijkplayer/issues/1074)
9. 如何设置后台播放
10. 视频加载速度慢
The traffic speed is mostly depending on the quality of video CDN, not player itself.
11. 怎么静音 和非静音
mute/unmute system volume.There is no mute/unmute API in ijkplayer.
12. 视频黑屏,但是有声音
确定下视频源的编码方式,ijk默认只带了h264解码code
13. 适配问题,对于不同的cpu架构,需要编译不同的so库
14. 播放视频有的设备声画不同步
15. 如何查看m3u8时长
   cat game05.m3u8 | grep EXTINF | wc -l 32
16. how to change the video quality?
Video quality is determined when being encoded.I don‘t think it can be changed by player.
17. 倍速播放
Not until Android 6.0
18. 为什么往前拖动进度条后,还会往后退几秒
seek只支持关键帧,出现这个情况就是原始的视频文件中i 帧比较少,播放器会在拖动的位置找最近的关键帧。
19. how to change URL when ijkplayer is playing RTMP video
Create new player.
20. 怎样添加字幕呢?
如果希望字幕时间精确,可以在native层做解析和时间同步,到了时间后回调给java层,一般字幕文件加载都是在java层做的,解析文件格式,然后按照时间区间来显示。
21. 如何设置硬解?
ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "mediacodec", 1);

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);

```

八. 参考

视频基础知识

多媒体编解码基础知识

流媒体中用到的几个协议简介

流媒体协议介绍(rtp/rtcp/rtsp/rtmp/mms/hls)

android-developer

No RTSP keep-alive packets in 2.3 causing streaming server to close the connection

H264解码器源码(Android 1.6 版)

Android VLC播放器二次开发1——程序结构分析

可以用WebRTC来做视频直播吗?

WebRTC音视频开发总结

雷霄骅(leixiaohua1020)的专栏

MediaPlayer

时间: 2024-10-25 18:30:51

Android直播,音视频播放那些事儿的相关文章

Android视频播放方案选择——深刻分析android平台的视频播放优缺点

https://zhuanlan.zhihu.com/p/27029577?utm_source=qq&utm_medium=social Android我还可以相信你多少系列文章二之音视频播放 音频视频播放在现在的应用里面很常见,传统应用发展到一定阶段多少会引入音视频资源,特别是现在短视频被看作下一个增长爆发点,和之相关的创业层出不穷,作为开发者如何进行音视频技术选型非常关键 MediaPlayer和VideoView给我们提供了非常方便的播放音视频的能力,几乎不需要要写几行代码就可以完成.

Android直播推流学习

Android直播推流学习 Android直播推流学习 第一部 第二部 第三部 第四部 第一部 本文也主要是一步步分析spydroid源码. 首先spydroid的采用的协议是RTSP,目前我知道支持RTSP协议的服务器是Darwin,但是Darwin比较复杂,所以大家可以选择EasyDarwin,大家可以去搜搜看看.还是继续说spydroid吧,spydroid这个项目大家可以在github上搜到的,不过作者也是很久没有更新了,如果大家只做推流的话可以看看原作者的另外一个项目Spydroid.

iOS - AVPlayer 音视频播放

iOS - AVPlayer 音视频播放 本文目录 前言 1.本地/网络音视频播放 2.本地/网络音视频播放设置 3.AVPlayerViewControllerDelegate 画中画协议方法 回到顶部 前言 NS_CLASS_AVAILABLE(10_7, 4_0) @interface AVPlayer : NSObject @available(iOS 4.0, *) public class AVPlayer : NSObject NS_CLASS_AVAILABLE_IOS(8_0)

Android直播实现 Android端推流、播放

最近想实现一个Android直播,但是对于这方面的资料都比较零碎,一开始是打算用ffmpeg来实现编码推流,在搜集资料期间,找到了几个强大的开源库,直接避免了jni的代码,集成后只用少量的java代码就可实现编码.推流和取流播放,整理了一下做了一个demo,在这里记录一下 效果图:  编码和推流,有两个方案选择: 一: 使用javacv来实现,最终也是用过ffmpeg来进行编码和推流,javacv实现到可以直接接收摄像头的帧数据 需要自己实现的代码只是打开摄像头,写一个SurfaceView进行

Android WebRTC 音视频开发总结(五)

这几天用WebRTC做了个视频监控的功能,分享出来,供想了解这方面内容的朋友参考. 一.基本模块: 1.视频采集端:相当于是客户端,用来采集视频,只需要发送视频,不需要接收. 2.视频监控端:接收采集端传入的视频数据,相当于监控客户端,不需要发送视频数据给客户端. 3.服务端:负责客户端注册.信令控制.数据包转发.UDP打洞等,支持TCP,UDP连接. 二.环境要求: 1.两台Andorid4.0 以上的手机,分别做采集端和监控端. 2.一台PC 做服务端. 3.PC.手机在同一个局域网内.理论

Android 即时音视频解决方案2——腾讯云

上一篇文章介绍了环信的解决方案,见Android 即时音视频解决方案1--环信,这篇文章,介绍一下更加靠谱,也就是腾讯云的解决方案,毕竟腾讯是是这方面的头头,比较靠谱.当然,集成腾讯云比集成环信稍微复杂那么一点,需要有一点点的耐心. 官方地址音视频云通信 AVC SDK下载AV Andriod1.3 文档地址音视频云通讯 先讲讲腾讯云的原理,使用腾讯云的时候,要有一个账号体系,这个账号体系比较灵活,可以使用独立模式也可以只用第三方账号体系,这里使用独立模式. 使用独立模式,要使用腾讯云的服务的时

iOS AVKit音视频播放全面详解

公司项目中经常要用到音视频处理,也需要去定制一些东西,然后整理这些音视频处理就显得尤为重要!方便自己和广大朋友学习收藏! 以下参考连接特别重要: 苹果官方:AVKit API 苹果官方:AVFoundation API 苹果官方:AVFoundation 专题(开发指引.视频.文章.代码) 苹果官方:AVFoundation Programming Guide iOS 教你使用MP.AVPlayer.AVPlayerVC构建一个完整的视频播放器 iOS - AVPlayer 音视频播放 基于 A

Pyqt 音视频播放器

在寻找如何使用Pyqt做一个播放器时首先找到的是openCV2 openCV2 貌似太强大了,各种关于图像处理的事情它都能完成,如 读取摄像头.图像识别.人脸识别.  图像灰度处理 . 播放视频等,强大的让你想不到! openCV2 播放视频也很简单: 1 #coding=utf-8 2 3 import cv2.cv as cv 4 filename = "cn.avi" 5 win_name = "video player" 6 capture = cv.Cap

android 自己定义视频播放器之2/1

非常久没更新博客,相信大家年后都比較忙. 今天给大家带来了一款视频播放器,首先确认的得有几点. 1.首先得有个播放视频的view. 2.加点额外功能进去左边上下滑动调节亮度,右边上下滑动调节声量: 3.视频当然得有快进和快退,左右滑动快进和快退: 4.可全屏播放: 5.临时仅仅做了离线播放.下篇博客再去研究在线播放.视频路径 这是视频本地路径,视频资源的话你们自己去找.目录会自己主动创建.放在该目录以下就能够了 private String Path = Environment.getExter