【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!

嘉楠开发者 2026-10-30 08:00

CanMV 上推 RTSP 已经比较熟悉:摄像头采集、编码,再由 RtspServer 发出去。很多场景反过来——板子要去看别人的码流:NVR、另一块 K230、电脑上的 mediamtx,或者已经在跑的监控地址。


这次 CanMV 补上了拉流这一端。固件类型 multimedia.RtspClient 从 rtsp:// 地址接收 H.264 或 H.265,在固件里解码,再把画面交给现有的 Display。用 from multimedia import RtspClient 调用。接法和 Sensor 相同:bind_info() 给出绑定参数,由调用方自己 Display.bind_layer。


播放留在媒体链路上,检测需要的 RGB 另取。纯看画面时,不必在脚本里一帧帧搬运像素。

【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图1



【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图2
【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图3

一

这次点亮了什么


能力

说明

拉流

rtsp://host[:port]/path,传输为 TCP 交织

编码

由 SDP 决定,接受 H.264 和 H.265

解码

固件内 VDEC 解码,输出 NV12 给视频层

显示

bind_info() + Display.bind_layer,接法和 Sensor 相同

给 AI 取图

get_frame() 返回 RGB 平面,形状为 (3, out_h, out_w)

路数

同时最多 4 个客户端,与 VDEC 通道数一致

认证

地址里写账号,或传入 username、password;401 时按 Digest 或 Basic 重发


类在 CanMV 固件的 multimedia 模块里。需要烧录包含该模块的固件后,才能 import。


固件自带两份示例:


  • 只显示:

    /sdcard/examples/02-Media/rtsp_client_display.py

  • 拉流加人脸检测:

    /sdcard/examples/21-AI-With-Others/rtsp_client_face_detect.py



【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图4
【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图5

二

播放为什么更顺


RtspClient 实现在固件里,脚本侧只负责建连、绑定显示和取图。几处设计和「脚本里自己收包、自己转图」不一样,播放时 Python 侧更轻:


  1. 解码在固件里完成。 构造函数连上服务器并完成 DESCRIBE,记下码流宽高;start() 之后才开始收流和解码。

  2. 显示走视频层 NV12。 视频层只接受 NV12。检测框画在一块 ARGB 的 OSD 上,用 Display.show_image 叠到视频上面。

  3. 缩小由 VDEC 完成。 构造时的 width、height 是解码器的唯一输出,get_frame() 和送给显示的 NV12 都是这个尺寸。与码流尺寸相同时不做缩放。

  4. RGB 按需转换。 只有有人等待 get_frame() 时才做 RGB 转换。不调用 get_frame() 时,已绑定的显示仍然出画面。

  5. 收流和解码之间有缓存。 默认缓存 60 个压缩访问单元(范围 1 到 120),压缩数据总量超过 4 MB 时也视为已满。队列满时丢掉后续帧,直到下一个关键帧。解码输出默认 6 块 YUV 缓冲(范围 3 到 8)。

  6. 播放过程中连接被拆掉时,客户端保留解码器和显示绑定,由接收线程重连。间隔从 1 秒起每次加倍,最长 5 秒,最多 3 次。一次 PLAY 成功后,次数和间隔都恢复。



【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图6
【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图7

三

先联网,再出画


拉流前必须先连上 LAN、Wi-Fi STA 或 Wi-Fi AP。推荐使用 libs.Network。客户端不负责联网。


只显示、不取帧时,顺序和摄像头显示示例一样:先 bind_layer,再 Display.init,再 start()。循环里周期性调用 check(),重连放弃后退出。


import timefrom media.display import Displayfrom multimedia import RtspClientfrom libs.Network import connect_network
_, ip = connect_network("lan")
client = Nonestarted = Falsedisplay_inited = Falsetry:    client = RtspClient(        "rtsp://192.168.1.108:8554/test",        cache_count=60,        buffer_count=6,        width=800,        height=480)
    info = client.bind_info(x=0, y=0, width=800, height=480)    Display.bind_layer(**info, layer=Display.LAYER_VIDEO1)    Display.init(Display.ST7701, width=800, height=480, to_ide=False, osd_num=1)    display_inited = True
    client.start()    started = True    while True:        time.sleep(1)        client.check()except OSError as exc:    print("rtsp failed:", exc)finally:    if started:        client.stop()    if display_inited:        Display.disable_layer(Display.LAYER_VIDEO1)    if client is not None:        client.deinit()    if display_inited:        Display.deinit()


上面的 800 x 480 是缩小后的解码输出,也是送进视频层的窗口大小。窗口必须和解码输出一样大,尺寸不同时这一帧不会送去显示。width、height 同时为 0 时,按码流原尺寸输出。


需要认证时,两种写法都可以:


client = RtspClient("rtsp://user:password@192.168.1.108:8554/test")client = RtspClient("rtsp://192.168.1.108:8554/test", username="user", password="password")



【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图8
【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图9

四

检测另取一帧,显示继续走视频层


客户端不打开屏幕,也不做人脸检测,也不会把图缩成模型输入。检测需要的 RGB 用 get_frame() 另取,letterbox 由 AI 预处理完成。


frame = client.get_frame(timeout_ms=100)if frame is not None:    data = frame.to_numpy_ref()  # (3, out_h, out_w)    # 在这里读 dataframe = None


get_frame() 超时返回 None。返回的图像借用解码器唯一的一块 RGB 缓冲,下一次会等待的 get_frame(),以及 stop()、deinit(),都会释放这块缓冲。在循环里用完就丢掉,不要留到下一次 get_frame()。


框画到与窗口同样大小的 ARGB 图像上,用 Display.show_image(..., layer=Display.LAYER_OSD0) 叠上去。完整流程见 rtsp_client_face_detect.py。


只绑定显示、循环里不调用 get_frame() 的程序,应周期性调用 check()。重连还在进行时它直接返回;重连已放弃时抛出 OSError("rtsp connection closed")。



【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图10
【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图11

五

最多四路,屏幕上能绑三层


同时最多 4 个还没有 deinit() 的客户端,第 5 个构造抛出 OSError。某个客户端 deinit() 之后,名额空出来,可以再创建一个。不绑定显示同样占一个名额,这时只解码,用 get_frame() 取图。


要上屏时,可用的视频层是 Display.LAYER_VIDEO1、LAYER_VIDEO2、LAYER_VIDEO3。层不够的那几路继续 get_frame()。每个窗口的 x + width、y + height 必须落在屏幕内。


多路 1080p 占用很大。显示时把 width、height 设成窗口大小,由 VDEC 缩小。例如 800×480 屏上左右各半,第三路只取图做检测:


left = RtspClient("rtsp://192.168.1.108:8554/cam0", width=400, height=480)right = RtspClient("rtsp://192.168.1.108:8554/cam1", width=400, height=480)detect = RtspClient("rtsp://192.168.1.108:8554/cam2", width=320, height=320)left_info = left.bind_info(x=0, y=0, width=400, height=480)right_info = right.bind_info(x=400, y=0, width=400, height=480)Display.bind_layer(**left_info, layer=Display.LAYER_VIDEO1)Display.bind_layer(**right_info, layer=Display.LAYER_VIDEO2)


每路单独分配输入和输出缓冲。stop()、deinit() 按对象分别调用,绑定过的层再 Display.disable_layer。



【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图12
【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图13

六

上板前先对一下这几条


  1. 先确认固件里有这个模块。 from multimedia import RtspClient 失败时,换一份已包含该模块的 CanMV 固件。

  2. 输出尺寸只能缩小或保持原尺寸。 width 和 height 必须同时为 0,或同时为大于 0 的偶数。任一方向大于码流可见尺寸时,构造函数抛出 OSError。

  3. 显示窗口和解码输出保持一致。 x、y 为非负偶数。播放开始后要改位置或大小,先 stop(),再 Display.disable_layer,然后重新 bind_info。

  4. 账号不要写两遍。 地址里已经有 user:password@ 时,不要再传 username。只给 password、不给 username 会抛出 ValueError。

  5. 重连有次数。 3 次都失败后停止重连,之后 get_frame() 和 check() 抛出 OSError。初次 DESCRIBE 失败不会重连,构造函数直接抛出 OSError。PLAY 之前会话被关掉时,由接下来的 start() 重新 DESCRIBE。

  6. 当前处理视频。 音频数据会被丢掉。传输固定为 TCP 交织。

  7. 退出按这个顺序。 先 client.stop(),再 Display.disable_layer,然后 client.deinit(),最后 Display.deinit()。要换地址,在 stop() 之后调用 init(url, ...),不要先 deinit()。init()、start()、stop() 失败时抛出 OSError,成功时返回 0。正在播放时调用 init() 也会抛出 OSError。



【K230/K230D 新技能点亮】CanMV 新增 RtspClient,RTSP 码流硬解上屏更流畅!图14

写在最后


推流用 RtspServer,拉流用 RtspClient。一块 K230 / K230D 既可以把自己的画面发出去,也可以把网络上的 H.264 / H.265 码流解出来:直接上屏,或再交一帧给检测。


监控预览、多路拼接、拉流做人脸或目标检测,都可以从固件里的 rtsp_client_display.py 和 rtsp_client_face_detect.py 改起。


现在就烧录带 RtspClient 的固件,把一条 rtsp:// 地址点亮到屏幕上。


说明:实际观感仍取决于码流分辨率、码率、关键帧间隔、网络质量和同时打开的路数。多路 1080p 请把解码输出设成窗口大小。建议在目标板卡上确认延时和稳定性。


📚 参考 

官方API文档:

https://www.kendryte.com/k230_canmv/zh/main/api/mpp/k230_canmv_rtsp_module_api_manual.html


关于科技区角:国内科技展会垂直内容策划服务商,提供从论坛内容全案策划、会展市场化IP打造到精准专业观众一站式邀约服务,以产业内容吸引高质量B端人群,打通展会从议题设计、演讲嘉宾邀约、宣传预热、精准邀观到供需对接全链路。
声明:内容取材于网络,仅代表作者观点,如有内容违规问题,请联系处理。
more
从“一江一河”IP看上海城市发展三部曲
苹果折叠屏iPhone Duo遭遇“开盖即裂”危机,售后排队引发用户不满
苹果iPhone Air 2开案测试:补齐短板但保留eSIM争议
芯粒互联,智驱未来 ——HIPI CHIPLET FORUM 2026报名通道正式开启
苹果确认部分 iPhone Duo 内屏存在问题!受影响用户可免费换机
iPhone Duo黄牛加价缩水,前苹果工程师谈内屏开裂疑因
曝苹果iPhone Air 2已开屏!最大短板补上了,但没完全补
iPhone Duo首发遇冷:溢价迅速消退,硬件故障与软件适配成主要槽点
iPhone Duo裂屏,是苹果新CEO接班后第一次“大考”
NeurIPS 2026 Oral|让大模型精准「看图」:NV-CoT用连续坐标重构视觉思维链
Copyright © 2025-成都区角科技有限公司
蜀ICP备2025143415号-1
  
川公网安备51015602001305号