Files
cv-cat dc078b248b catbus:一个命令操作小红书、抖音、TikTok、B 站、快手、微博、闲鱼、淘宝、京东、X
10 个平台的 web 端全部用 TypeScript 移植自 cv-cat 的开源项目,请求与上游逐字节对拍。
统一的命令语法与 JSON 输出、按 平台 × 端 × 账号 隔离的登录态、给 AI Agent 用的技能与 llms.txt。
2026-10-06 19:24:55 +08:00

78 lines
3.7 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 监听直播间的弹幕、礼物、进场等事件一段时间,写到 jsonl 文件;结束时按事件类型统计。
#
# 用法:
# docs/examples/live-to-file.sh <platform> <room> [时长,默认 10m] [输出文件,默认 live-<platform>-<时间>.jsonl]
#
# 例子:
# docs/examples/live-to-file.sh bilibili <room_id> 30m
# docs/examples/live-to-file.sh douyin "https://live.douyin.com/<web_rid>" 1h douyin-live.jsonl
# docs/examples/live-to-file.sh tiktok @<host_username> 600
#
# 时长:秒数,或 30s、10m、1h(catbus 的 --duration)。到时间或按 Ctrl-C 都正常结束,已收到的事件都在文件里。
# 哪些平台支持 live listen:catbus platforms 查看(目前是 xhs、douyin、tiktok、bilibili、kuaishou)。
#
# 环境变量:
# APPEND=1 追加到已有文件,不覆盖
# CATBUS catbus 命令,默认 catbus;从源码运行时可设为 "node /path/to/catbus/dist/cli/main.js"
#
# 输出:每行一个 Event(AGENTS.md 6.2),例如
# {"type":"chat","time":"2026-09-29T20:00:01+08:00","user":{"id":"...","name":"...","url":"..."},"text":"...","gift":null}
# type 取值 chat / gift / like / enter / follow / other。
#
# 依赖:bash;jq 只用于结束时的统计,没有 jq 也能录。
set -euo pipefail
usage() {
sed -n '2,/^set -euo/p' "$0" | sed '$d' | sed 's/^# \{0,1\}//' >&2
exit 2
}
[[ $# -ge 2 && -n $1 && -n $2 ]] || usage
platform=$1
room=$2
duration=${3:-10m}
out=${4:-live-$platform-$(date +%Y%m%d-%H%M%S).jsonl}
[[ $duration =~ ^[0-9]+(\.[0-9]+)?[smh]?$ ]] || { echo "时长的格式是秒数,或 30s、10m、1h:$duration" >&2; exit 2; }
read -r -a CATBUS_CMD <<<"${CATBUS:-catbus}"
cb() { "${CATBUS_CMD[@]}" "$@"; }
[[ ${APPEND:-} == 1 ]] || : >"$out"
echo "监听 $platform 直播间 $room,时长 $duration → $out(Ctrl-C 提前结束)" >&2
# live listen 总是输出 jsonl:stdout 每行一个事件;日志和结束时的摘要信封在 stderr,原样显示在终端。
# 显式写上 -o jsonl:这样连「未登录」这类开始前的错误也写到 stderr,不会混进事件文件。
# Ctrl-C 由 catbus 自己处理(写完已收到的事件,退出码 0)。这里给 SIGINT 装一个空的 trap,
# 让脚本等 catbus 收尾后继续做统计,而不是跟着一起退出(用 trap '' 会让子进程也忽略 Ctrl-C,不能用)。
trap ':' INT
rc=0
cb "$platform" live listen "$room" --duration "$duration" -o jsonl >>"$out" || rc=$?
trap - INT
total=$(grep -c . "$out" || true)
if [[ $rc -ne 0 ]]; then
case $rc in
2) echo "参数有误,或 $platform 没有这个命令(错误信息见上面的信封)" >&2 ;;
3) echo "需要登录:catbus $platform auth login" >&2 ;;
4) echo "$platform 的 live listen 还没有实现(catbus platforms $platform 查看支持的命令)" >&2 ;;
5) echo "被平台风控拦下,稍后再试(detail 见上面的信封)" >&2 ;;
6) echo "网络错误;长连接断线会自动重连,这里是重连也失败了。检查网络和代理(catbus config get proxy)" >&2 ;;
*) echo "监听失败,退出码 $rc(错误信息见上面的信封)" >&2 ;;
esac
[[ $total -eq 0 ]] || echo "已收到的 $total 条事件仍在 $out" >&2
exit "$rc"
fi
echo "结束:共 $total 条事件 → $out" >&2
if command -v jq >/dev/null && [[ $total -gt 0 ]]; then
# 按类型计数;礼物再按名称汇总数量
jq -rs 'group_by(.type) | map(" \(.[0].type)\t\(length)") | .[]' "$out" >&2
gifts=$(jq -rs '[.[] | select(.type == "gift" and .gift != null)] | group_by(.gift.name)
| map(" \(.[0].gift.name)\t\(map(.gift.count // 1) | add)") | .[]' "$out")
if [[ -n $gifts ]]; then
echo "礼物:" >&2
echo "$gifts" >&2
fi
fi