cardstream
指南

分析你的 Whatnot 或 Fanatics Live 直播

cardstream 从不登录 Whatnot、Fanatics Live 或任何其他交易平台。它在你自己的机器上,看着你已经在推给它们的同一路视频,叫出每张放到桌上的卡的名字。下面是完整的路径,从零到实时叠加层:大约十五分钟,只需做一次。

一台离摄像头不远的电脑

macOS、Linux 或 Windows 都行。如果你已经在某台机器上跑 OBS,那台就是最合适的:分析在本地进行,什么都不用传出去。

你已经在推的视频

OBS 场景、网络摄像头、采集卡或编码器。cardstream 接入你现有的东西,不要求你重新布置直播。

一个 Ximilar API 密钥

整个系统唯一的凭据,而且它只留在你的机器上。不需要平台账号,不需要密码,聊天室里也不会多出机器人。

第一步

先让它独立跑起来

在它碰到你的直播之前,先用笔记本的网络摄像头证明它能用。三条命令。

01

安装

脚本会在 ~/.cardstream 里建一个虚拟环境,用校验和验证发行版 wheel,下载模型权重,并把命令加到 PATH。wheel、Docker 和源码安装见下载页。

$ curl -fsSL https://raw.githubusercontent.com/Ximilar-com/cardstream/main/scripts/install.sh | sh
02

加上你的密钥

识别默认走 Ximilar collectibles/v2,也可以换成你自己的系统。XIMILAR_API_KEY 是唯一会被读取的环境变量:把它写进 shell 配置文件,这样直播当晚重启也不会丢。

$ export XIMILAR_API_KEY=your-key
03

把一张卡举到笔记本前

这会用内置网络摄像头打开浏览器界面。把卡拿稳一小会儿:叠加层先显示状态机在判断,然后出现名称、系列和置信度,匹配结果旁边还标着这次识别调用的实际耗时。产品的全部就是这样,本页剩下的内容只关乎画面从哪里来。

$ cardstream-web
# → http://127.0.0.1:8001
然后

把它对准你的直播

选一行。选哪一行只取决于一个问题:你是用电脑直播,还是用手机直播?

做不到的事

把 cardstream 对准你在 Whatnot 或 Fanatics 上的公开播放页。你自己的直播并没有一个对外的流地址,抓取播放器不仅违反平台条款,还会多出好几秒延迟。下面每条路线都是在视频到达交易平台之前接入的,这正是 cardstream 不需要它们的账号、密码或 API 密钥的原因。

A
你在电脑上用 OBS 直播

OBS 虚拟摄像头

从这里开始

OBS 可以把你合成好的场景作为一个普通网络摄像头呈现给操作系统。cardstream 打开它的方式和打开任何其他摄像头完全一样:不用二次编码,编码器没有额外负担,也不用安装 ffmpeg。

  1. 在 OBS 的控件面板里点击启动虚拟摄像机。
  2. 把它当作网络摄像头编号交给 cardstream。编号 0 通常是内置摄像头,所以虚拟摄像头一般是 1:依次试 0、1、2,直到看见你的场景。
$ cardstream-web --source 1

开播前先试一次,别等直播中再试:macOS 上终端需要摄像头权限;如果 OpenCV 在你的机器上打不开虚拟设备,路线 B 在任何环境都能用。

B
你用 OBS 直播,并且想要和播出完全一致的画面

OBS 的第二路输出

cardstream 在你自己的机器上监听,OBS 把一份拷贝推给它。Whatnot 或 Fanatics 收到的和以前分毫不差:这是多加一个目标,绝不是改道。

  1. 先启动监听端;它会等待推流,断了也会自己重连。
  2. OBS 只有一路推流输出,所以拷贝要从第二路发:要么用 obs-multi-rtmp 插件,要么在 设置 → 输出 → 录像 → 自定义输出 (FFmpeg) 里,类型选输出到 URL,URL 填 rtmp://127.0.0.1:1935/live,容器选 flv,然后点开始录制。
  3. 这条路线会调用系统里的 ffmpeg:先执行 brew install ffmpeg。
$ cardstream-web --listen \
    --source rtmp://0.0.0.0:1935/live
C
你用手机开播,大多数卖家都是这样

桌上一台专用摄像头

手机直接推给 App,没有任何东西可以分流。所以别再追那路出去的流了,给 cardstream 一个属于它自己的、对着同一张桌子的视角:一台俯拍的第二网络摄像头,或者把相机的 HDMI 输出接进采集卡。

  1. 把网络摄像头或采集卡对准你开包展示的位置。
  2. 在那台摄像头旁边的机器上运行。
$ cardstream-web --source 0

不必和买家看到的角度一样。一个近距离、光线充足的俯拍画面,识别效果永远好过经过压缩的平台画面。

D
你用的是编码器、切换台或 IP 摄像头

任何有 URL 的东西

rtsp://、rtmp:// 和 srt:// 直接拉流,自制设备还能用 ws:// JPEG 流。重连采用有上限的退避,所以拆盒中途演播室链路断了,也会自动恢复,不用你动手。

  1. 把编码器已经在发布的 URL 交给它。
  2. 浏览器页面变成一个被动的查看器:即使没有打开任何浏览器,分析也照常运行。
$ cardstream-web \
    --source rtsp://studio/stream1
开播之前

按今天的直播调一调

默认值很实在,但拆盒不是一路普通的摄像头画面:你通常在拆开之前就知道自己要拆什么。

04

告诉它你在拆什么

预设游戏或系列可以缩小搜索范围:调用更快,匹配更准。只有一条规则:传 --game 时务必同时传 --alphabet,因为预设游戏会关闭端点自己的字母表检测,转而默认拉丁字母,一张日文卡就会匹配到它的英文版。

$ cardstream-web --source 1 \
    --game "Pokémon" --alphabet japanese --set-code M4
05

直播中改主意

下一批货换了游戏,什么都不用重启:类别、游戏、系列代码、字母表、结果阈值和清晰度阈值都可以在直播进行时于浏览器的设置对话框里修改。其他的(检测器、闸门、分辨率)只在启动时读取一次,所以现在就把它们定好。

06

留下日志,关好端口

--split-results 让每次出现各占一行,而不是把重复合并:一份按展示顺序排列的清单,事后核对订单正好用。--host 保持默认的 127.0.0.1:那个进程持有你的密钥,而本地界面没有身份验证,所以绝不应该能从局域网访问到。

$ cardstream-web --source 1 --split-results
07

保存直播,第二天早上再看

加上 --ximilar-stream NEW,那份历史记录的每一行(卡、价格、在直播中停留了多久,以及据以识别它的裁切图)都会在你直播时保存到你 Ximilar 账号里的一个会话中。之后,Ximilar 应用的 Cardstream 板块会展示整场直播:它的总价值、最有价值的卡,以及每张卡和它的图片;你也在那里标记已售出的卡、更正认错的匹配。如果客户端在直播中途重启,用打印出来的会话 id 代替 NEW 再启动一次,同一场直播就会接着进行。要保存到团队工作区,用 --ximilar-workspace。

$ cardstream-web --source 1 --price-stats --ximilar-stream NEW
# 重启之后:
$ cardstream-web --source 1 --price-stats --ximilar-stream <session-id>

然后开播吧。检测、运动判断和身份闸门全部在你的机器上本地运行;识别调用对你放到桌上的每张卡只发一次:一小时大约一百次,而那一小时有 54,000 帧。账在这里算给你看。

哪里不对时

真正会出问题的六件事

列表里没有虚拟摄像头

依次试 --source 0、1、2:编号是操作系统随机分配的。在 macOS 上,到 系统设置 → 隐私与安全性 里给终端授予摄像头权限。如果 OpenCV 还是打不开,就换到路线 B。

提示 "ffmpeg not found"

只有 --listen 和 --ffmpeg 会调用系统里的 ffmpeg。安装它(brew install ffmpeg)后重新运行;虚拟摄像头、网络摄像头和普通拉流的路线不需要任何额外东西。

OBS 不让我添加第二路推流

这是 OBS 的限制,不是 cardstream 的:它只有一路推流输出。obs-multi-rtmp 插件可以真正增加推流目标;路线 B 里用自定义输出 (FFmpeg) 录像的办法,原版 OBS 就能用。

能找到卡,但从来匹配不上

几乎总是分辨率或运动的问题。你发出去的那一帧里必须能看清卡号:让 OBS 保持 1080p,开包展示时把卡拿稳一小会儿,然后才考虑放宽 --result-threshold(默认 0.9;越高保留的弱匹配越多,1.0 全部保留)。

同一张卡被识别了两次

身份闸门把两个画面的相似度打在了 --similarity-threshold(默认 0.85)以下,于是当成了新卡。稍微调低一点。如果你把卡放下又拿起来,那就改为调高 --forget-after:离开画面 2 秒后,卡会被当成新卡,这是设计如此。

什么都检测不到

加上 --show-detection 运行,把检测框画出来:检测一直在跑,只是默认不画。没有框,说明卡在画面里太小或者动得太快;有框却没匹配,请看上一条。

还是卡住了?README 记录了所有参数,文档中心则按你想做的事把它们分了组。

开源。自托管。你的直播,你的技术栈。

没有中间平台,没有按席位收费的许可:接入 Ximilar API 或你自己的识别系统,cardstream 对每张不同的卡只调用一次,而不是每帧一次。无论你是在 Whatnot 上拆盒、做 Fanatics Live 式的直播秀,还是在自己的直播电商环境里开播,今晚就能用手头现有的硬件跑起 cardstream。