OSS livechannel 推流过程
案例:录制 M3u8 缺失
默认录制成品的 m3u8 所以只有最后 3 片,遵循的是 hls 协议的默认规则,是正常想象,可以通过调用 PostVodPlaylist
接口将指定时间范围内的 ts 文件汇聚到一个 m3u8 索引内来解决;
tips
-
EndTime
必须大于StartTime
,且时间跨度不能大于1
天。 - OSS会查询指定时间范围内的所有该
LiveChannel
推流生成的ts
文件,并将其拼装为一个播放列表。
案例:录制 m3u8 文件 失败
- 先看下是否已经成功推流到来 OSS 才算成功,客户端抓包必须能看到有 publish succees 的标志后,和 OSS 有正常的音频包交互才算成功,所以发现客户端推流有记录,但是就是没有录制视频的情况,就需要自己抓包分析下;
案例:客户端无法推流到 OSS
ffmpeg -re -i 0_20180525105430445.aac -acodec aac -strict -2 -f flv rtmp://xxx.oss-cn-beijing.aliyuncs.com/live/test_1000?Expires=1540458859&OSSAccessKeyId=LTAlujianb6C9z&Signature=qwh31xQsanmao6ygCFJgovNIg%3D&playlistName=playlist.m3u8
- 使用 ffmpeg 推不上去的时候建议用最原始的命令推流,不要加一些复杂的参数,而且推流 URL 在有 & 符号时请用 "" 囊括起来;
- 尝试更换成 obs 推流测试下,看是否是 ffmpeg 问题导致的推流失败;
案例:录制 M3u8 文件卡顿
- 转储类型为 HLS 时,写入当前 ts 文件的音视频数据时长达到
FragDuration
指定的时长后,OSS 会在收到下一个关键帧的时候切换到下一个 ts 文件;如果max(2*FragDuration, 60s)
后仍未收到下一个关键帧,OSS 强制切换文件,此时可能引起播放时卡顿;
案例:录制 M3u8 文件没有音频或视频
在此之前没有 hls 协议基础,或者对音视频不懂的同学很难理解,我们先恶补一些关键名词和包结构
RTMP 的音视频流的封装形式和 FLV 格式相似, 流媒体服务器向客户端发送包含 H264 和 AAC 的 RTMP 直播流,需要首先发送这两个 header,没有这些信息播放端是无法解码音视频流的,其中音频 tag 格式如下
-
AVC
sequence header -
AAC
sequence header
从上面推论出 AAC sequence header 内容的前 2 个字节是 0xAF 0x00,我们来看一个示例:
ADIF
:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。
ADTS
:Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于 mp3 数据流格式。
解码流程
经过知识补充后我们说下以下几种情况会出现音频或者视频没有录制的情况:
-
AVC header
或者AAC header
没有发送,抓包也能看出来。 -
RTMP message
长度小于2,或者是sequence header
非常小 - 音频
Message
超过缓冲区大小。 -
codec_ ctx
解码上下文的关键信息,如果携带的音视频数据异常,也会导致录制失败。
案例:ffmpeg 推流到 OSS 录制没有音频
背景:
想问下,我们使用类似于这样的命令录制直播转推到阿里云OSS,录制下来的视频没有声音
ffmpeg -re -v -1 -loglevel debug -timeout 60000 -reconnect_at_eof 1 -reconnect_streamed 1 -reconnect_delay_max 60 -i http://laochouzhibo.com/live/10456_33832518963510801728548610115630440343599.flv -acodec copy -vcodec copy -f flv rtmp://laochou.oss-cn-beijing-internal.aliyuncs.com/live/6db24fe6307e4cbcbf4f1764f5a1fb86?OSSAccessKeyId=LTAHSFdouboolevJG&Expires=1541002834&Signature=yRPuvIsIe90ipETg%3D
分析:
- 出现这种问题,可以直接看下 ffmpeg 记录的 log ,可以发现客户端是没有发送 aac_header 。
- 或者客户端抓个 RTMP 的包也可以看到是否发送了 aac_header