【流媒体开发】树莓派开发基于RTMP的网络摄像头

(一) 预备知识

关于RTMP推流

1、消息

消息格式

RTMP消息头和载荷两部分。
消息头

长度含义
message type1byte表示消息类型
payload length3byte表示载荷的字节数,big-endian格式
timestamp4byte表示消息的时间戳,big-endian格式
stream id3byte表示消息流ID,big-endian格式
消息类型:

1-7的消息ID用于协议控制消息

8、9的消息分别用于传输音频和视频数据

15-20的消息用于发送AMF编码的命令,负责用户与服务器之间的交互,比如播放,暂停

载荷

载荷中消息中包含的真实数据。例如,它可以是音频样本或压缩的视频数据。

2、块

消息是rtmp协议的基本数据单元,在网络传输时,消息会被重新封装成块进行传输,每个块都有固定的大小,如果消息大小大于块的大小,消息就会被拆分成几个块发送。
块格式

块由头和载荷组成
块头结构

长度含义
basic header1byte或2byte或3byte块基本头
chunk msg header11byte或2byte或3byte块消息头
extended timestamp4byte扩展时间戳
a、块基本头(basic header)
基本头第一个字节的结构:
长度含义
fmt2bit块格式
cs id6bit块流ID
b、块消息头(chunk msg header)
类型0

总共11byte,格式如下:

长度含义
timestamp3byte时间戳
message length3byte载荷的长度
message type id1byte消息类型id
message stream id4byte消息流id
类型1

类型1总共7byte,格式如下:

长度含义
timestamp3byte时间戳
message length3byte载荷的长度
message type id1byte消息类型id
类型2

类型2总共3byte,格式如下:

长度含义
timestamp3byte时间戳
类型3

类型3的块没有头。流ID,消息长度,时间戳都不出现。这种类型的块使用与先前块相同的数据。当一个消息被分成多个块,除了第一块以外,所有的块都应使用这种类型。

3、rtmp的消息类型

rtmp的消息类型可分为三大类:协议控制消息、用户控制消息、RTMP命令消息

协议控制消息
  • 设置块大小消息(Message Type=1)
  • 终止消息(Message Type=2)
  • 确认消息(Message Type=3)
  • 确认窗口大小消息(Message Type=5)
  • 设置对端带宽消息(Message Type=6)
用户控制消息

(Message Type=4)

RTMP使用消息类型ID 4表示用户控制消息。这些消息包含RTMP流传输层所使用的信息。协议控制消息使用的ID为 1、2、3、5 和 6 (前面已经介绍过了)。
用户控制消息应该使用消息流ID 0 (以被认为是控制流),并且以RTMP块流发送时以块流ID为2。协议控制消息接收立即生效;解析时,时间戳字段被忽略。

RTMP命令消息
数据消息(Message Type=18或15)

客户端或服务端通过本消息向对方发送元数据和用户数据。元数据包括数据的创建时间、时长、主题等细节。消息类型为18的用AMF0编码,消息类型为15的用AMF3编码。

共享对象消息 (Message Type=19或16)

共享对象是跨多个客户端,实例同步的FLASH对象(名值对的集合)。消息类型kMsgContainer=19用AMF0编码,kMsgContainerEx=16用AMF3编码,这两个消息用于共享对象事件。每个消息可包含多个事件。

4、实例分析rtmp传输过程
  • 握手
  • 建立网络连接
  • 建立流
  • 播放
(1)握手

在这里插入图片描述
(1)握手开始于客户端发送C0,C1块。

(2)服务端在接收到C0后发送S0,S1块。

(3)客户端接收到S0,S1块后,发送C2块,服务端接收到C0,C1块后发送S2块。

(4)当客户端接收到S2,服务端接受到C2,分别校验后握手成功

(2)建立连接

在这里插入图片描述

(1)客户端发送"connect消息"请求连接。

(2)服务收到"connect"请求后,发送一个"确认窗口大小消息"。

(3)服务端发送"设置带宽消息"到客户端。

(4)客户端处理"设置带宽消息"后,发送"确认窗口大小消息"到服务端(设置带宽消息的值与窗口大小不相同才会发送此消息)。

(5)服务器发送用户控制消息中的“流开始(Stream Begin)消息“到客户端。

(6)服务器发送“命令消息”中的”结果“(_result),通知客户端连接的状态。

(3)建立流

在这里插入图片描述(1)客户端发送"命令消息"中的"创建流命令(createStream)"到服务端。

(2)服务端接受到消息之后,发送"命令消息"中的"结果(_result)"。

(4)发布音视频

在这里插入图片描述
(1)客户端发送"命令消息"中的"publish命令"。

(2)服务端接受到消息之后发送用户控制消息中的“streambegin”。

(3)客户端开始发送音视频数据

(二)构建思路

需要实现RTMP网络推流一般需要三个部分。
分为RTMP服务器进行数据分发,拉流部分与推流部分。

在这里我用树莓派作为一个网络摄像头,当然最简单的方法是运用x264 ffmpeg直接拉流usb摄像头,同时进行编码与推流。
当然为了方便,必须对WIFI的连接与程序的启动进行一些配置,使树莓派可以在没有接屏幕的情况下自动接到WIFI中,然后启动推流。

当然为了实现在不同的局域网内,都可以进行拉流,你当然要有一个具有公网IP的服务器,这里我买了一个云服务器进行部署。这里需要移植一个SRS的RTMP服务器。这里需要考虑到SRS的编译移植问题。

至于拉流部分,有很多方法,包括PC端,网页,IOS,
Android等情况,这里只采用最简单的使用VLC直接拉流。

(三)编译部署SRS

准备工作

1. 创建文件夹 mkdir srs,将我们的项目存放在该目录下

2. 下载SRS源码,这里是去github上下载,使用

git clone https://github.com/ossrs/srs

3. 编译与安装

cd srs/trunk
./configure --full --without-utest --use-sys-ssl && make

4. 运行

cd srs-master/trunk // 先进入trunk目录。
./objs/srs -c conf/srs.conf

检查SRS是否启动成功:
ps -ef | grep srs

(四)树莓派编译FFmpeg

进入需要放置文件的目录git安装ffmpeg:git clone git://source.ffmpeg.org/ffmpeg.git

安装 libx264-dev
sudo apt-get install libx264-dev
另外ffmpeg中的播放器程序ffplay依赖sdl来显示视频,sdl是一个图形显示库,安装命令:
sudo apt-get install libsdl2-dev

ffmpeg 配置脚本 ffmpeg_rpi.sh ,放进 ffmpeg 目录

#!/bin/sh
PREFIX=/usr/local
./configure \
--enable-gpl --enable-version3 --enable-nonfree \
--enable-static --disable-shared \
\
--prefix=$PREFIX \
\
--disable-opencl \
--disable-thumb \
--disable-pic \
--disable-stripping \
\
--enable-small \
\
--enable-ffmpeg \
--enable-ffplay \
--enable-ffprobe \
\
--disable-doc \
--disable-htmlpages \
--disable-podpages \
--disable-txtpages \
--disable-manpages \
\
--disable-everything \
\
--enable-libx264 \
--enable-encoder=libx264 \
--enable-decoder=h264 \
--enable-encoder=aac \
--enable-decoder=aac \
--enable-encoder=ac3 \
--enable-decoder=ac3 \
--enable-encoder=rawvideo \
--enable-decoder=rawvideo \
--enable-encoder=mjpeg \
--enable-decoder=mjpeg \
\
--enable-demuxer=concat \
--enable-muxer=flv \
--enable-demuxer=flv \
--enable-demuxer=live_flv \
--enable-muxer=hls \
--enable-muxer=segment \
--enable-muxer=stream_segment \
--enable-muxer=mov \
--enable-demuxer=mov \
--enable-muxer=mp4 \
--enable-muxer=mpegts \
--enable-demuxer=mpegts \
--enable-demuxer=mpegvideo \
--enable-muxer=matroska \
--enable-demuxer=matroska \
--enable-muxer=wav \
--enable-demuxer=wav \
--enable-muxer=pcm* \
--enable-demuxer=pcm* \
--enable-muxer=rawvideo \
--enable-demuxer=rawvideo \
--enable-muxer=rtsp \
--enable-demuxer=rtsp \
--enable-muxer=rtsp \
--enable-demuxer=sdp \
--enable-muxer=fifo \
--enable-muxer=tee \
\
--enable-parser=h264 \
--enable-parser=aac \
\
--enable-protocol=file \
--enable-protocol=tcp \
--enable-protocol=rtmp \
--enable-protocol=cache \
--enable-protocol=pipe \
--enable-protocol=srtp \
\
--enable-filter=aresample \
--enable-filter=allyuv \
--enable-filter=scale \
--enable-libfreetype \
\
--enable-indev=v4l2 \
--enable-indev=alsa \
\
--enable-omx \
--enable-omx-rpi \
--enable-encoder=h264_omx \
\
--enable-mmal \
--enable-hwaccel=h264_mmal \
--enable-decoder=h264_mmal \
\

测试ffmpeg

采集mjpeg格式视频

ffplay -f video4linux2 -input_format mjpeg -framerate 25 -video_size 640x480 -i /dev/video0

采集yuyv422格式视频

ffplay -f video4linux2 -input_format yuyv422  -framerate 25 -video_size 640x480 -i /dev/video0

推送mjpeg视频流

ffmpeg -f video4linux2 -input_format mjpeg -framerate 25 -video_size 1280x720 -i /dev/video0 -vcodec copy -rtsp_transport tcp -f rtsp rtsp://172.17.6.213/test

然后配置开机运行 (/etc/rc.local)

添加

sleep 10
#这里需要延时,因为WIFI连接可能需要较长的时间
ffmpeg -framerate 15 -video_size 640x480 -i /dev/video0 -vcodec h264_omx -f flv rtmp://123.57.93.3/live/livestream

在这里插入图片描述

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

与光同程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值