香蕉派 K230D 支持 MIPI-CSI 摄像头、支持视频编码,支持无线网络,可以将摄像头采集到的数据进行 H264 编码后再进行 RTSP 推流,这样就能在局域网下的任意地方打开摄像头查看图像。
这里 Camera 出 1080P 60fps,视频流和编码占用 K230D 性能很高,再加上无线传输,推流过程有一定延迟和发热。
实验准备
1、香蕉派 K230D 开发板
2、无线路由器
3、VLC 视频播放器
实验需要使用支持播放 RTSP 流的播放器,Windows 系统可选择的有
1、VLC 播放器
优点:兼容性好、功能强大
缺点:配置繁多且复杂,如果不会配置的话显示效果会比较差
2、YAHBOOM Rtsp Player(已内置在配套小工具程序中)
优点:无需配置,一键使用,低延迟
缺点:体积较大
这里使用 VLC 播放器
配置网络
输入以下代码,连接无线网络(ssid 和 password 需要换成自己的网络和密码):
import network
wlan = network.WLAN(network.STA_IF)
wlan.connect("ssid","password")
print(wlan.status())
while wlan.ifconfig()[0] == '0.0.0.0':
os.exitpoint()
print(wlan.ifconfig())
配置完成后,启动即可联网,获取到 IP 即可访问网络,如下:
配置 RTSP Server
RTSP 已经封装成一个类,可以直接调用,配置的网络端口为 8554,代码如下:
from media.vencoder import *
from media.sensor import *
from media.media import *
import time, os
import _thread
import multimedia as mm
from time import *
class RtspServer:
def __init__(self,session_name="test",port=8554,video_type = mm.multi_media_type.media_h264,enable_audio=False):
self.session_name = session_name # session name
self.video_type = video_type # 视频类型264/265
self.enable_audio = enable_audio # 是否启用音频
self.port = port #rtsp 端口号
self.rtspserver = mm.rtsp_server() # 实例化rtsp server
self.venc_chn = VENC_CHN_ID_0 #venc通道
self.start_stream = False #是否启动推流线程
self.runthread_over = False #推流线程是否结束
def start(self):
# 初始化推流
self._init_stream()
self.rtspserver.rtspserver_init(self.port)
# 创建session
self.rtspserver.rtspserver_createsession(self.session_name,self.video_type,self.enable_audio)
# 启动rtsp server
self.rtspserver.rtspserver_start()
self._start_stream()
# 启动推流线程
self.start_stream = True
_thread.start_new_thread(self._do_rtsp_stream,())
def stop(self):
if (self.start_stream == False):
return
# 等待推流线程退出
self.start_stream = False
while not self.runthread_over:
sleep(0.1)
self.runthread_over = False
# 停止推流
self._stop_stream()
self.rtspserver.rtspserver_stop()
#self.rtspserver.rtspserver_destroysession(self.session_name)
self.rtspserver.rtspserver_deinit()
def get_rtsp_url(self):
return self.rtspserver.rtspserver_getrtspurl(self.session_name)
def _init_stream(self):
width = 1280
height = 720
width = ALIGN_UP(width, 16)
# 初始化sensor
self.sensor = Sensor()
self.sensor.reset()
self.sensor.set_framesize(width = width, height = height, alignment=12)
self.sensor.set_pixformat(Sensor.YUV420SP)
# 实例化video encoder
self.encoder = Encoder()
self.encoder.SetOutBufs(self.venc_chn, 8, width, height)
# 绑定camera和venc
self.link = MediaManager.link(self.sensor.bind_info()['src'], (VIDEO_ENCODE_MOD_ID, VENC_DEV_ID, self.venc_chn))
# init media manager
MediaManager.init()
# 创建编码器
chnAttr = ChnAttrStr(self.encoder.PAYLOAD_TYPE_H264, self.encoder.H264_PROFILE_MAIN, width, height)
self.encoder.Create(self.venc_chn, chnAttr)
def _start_stream(self):
# 开始编码
self.encoder.Start(self.venc_chn)
# 启动camera
self.sensor.run()
def _stop_stream(self):
# 停止camera
self.sensor.stop()
# 接绑定camera和venc
del self.link
# 停止编码
self.encoder.Stop(self.venc_chn)
self.encoder.Destroy(self.venc_chn)
# 清理buffer
MediaManager.deinit()
def _do_rtsp_stream(self):
try:
streamData = StreamData()
while self.start_stream:
os.exitpoint()
# 获取一帧码流
self.encoder.GetStream(self.venc_chn, streamData)
# 推流
for pack_idx in range(0, streamData.pack_cnt):
stream_data = bytes(uctypes.bytearray_at(streamData.data[pack_idx], streamData.data_size[pack_idx]))
self.rtspserver.rtspserver_sendvideodata(self.session_name,stream_data, streamData.data_size[pack_idx],1000)
#print("stream size: ", streamData.data_size[pack_idx], "stream type: ", streamData.stream_type[pack_idx])
# 释放一帧码流
self.encoder.ReleaseStream(self.venc_chn, streamData)
except BaseException as e:
print(f"Exception {e}")
finally:
self.runthread_over = True
# 停止rtsp server
self.stop()
self.runthread_over = True
主程序
调用网络连接代码连接网络,再调用 RTSP Server,即可打开推流服务器,主程序如下:
if __name__ == "__main__":
wlan = network.WLAN(network.STA_IF)
wlan.connect("ssid","password")
print(wlan.status())
while wlan.ifconfig()[0] == '0.0.0.0':
os.exitpoint()
print(wlan.ifconfig())
os.exitpoint(os.EXITPOINT_ENABLE)
# 创建rtsp server对象
rtspserver = RtspServer()
# 启动rtsp server
rtspserver.start()
# 打印rtsp url
print("rtsp server start:",rtspserver.get_rtsp_url())
# 推流60s
sleep(60)
# 停止rtsp server
rtspserver.stop()
print("done")
RTSP 协议简介
RTSP是一种用于控制流媒体服务器的网络应用层协议,由RFC 2326定义。它建立并控制一个或多个时间同步的连续媒体流。
主要特点
常见应用场景
视频监控系统
安防摄像头
工业监控
交通监控
流媒体直播
视频会议
在线教育
远程医疗
** RTSP vs 其他流媒体协议**
协议 | 延迟 | 可靠性 | 交互性 | 应用场景 |
---|---|---|---|---|
RTSP | 低 | 中 | 高 | 视频监控、点播 |
HLS | 高 | 高 | 低 | 直播、点播 |
RTMP | 低 | 中 | 中 | 直播推流 |
WebRTC | 极低 | 中 | 高 | 实时通讯 |
RTSP工作流程
RTSP传输模式
更多回帖