开始
快速上手
用一个带示例视频的容器先试一试,或者在你的服务器上生成令牌,然后用命令行、TypeScript 或 Python 搜索、上传文件,并给它加上元数据。
先在自己电脑上试
还没有服务器和账号?一个容器就能跑起全部服务,里面还有一个放好示例视频的空间可以随便试:
git clone https://github.com/blendduck/sidespace && cd sidespace
docker build -f deploy/trial/Dockerfile -t sidespace-trial .
docker run --rm -p 8080:8080 -p 8090:8090 -p 8070:8070 -v sidespace-trial:/data sidespace-trial第一次启动会建好一个开发者账号、一个空间 "Film A" 和一个全权令牌(同时是 S3 密钥),打印在日志里,之后每次启动打印同一个。
export SIDESPACE_URL=http://localhost:8080 SIDESPACE_TOKEN=ssp_… # 日志里打印的那一行
curl -H "Authorization: Bearer $SIDESPACE_TOKEN" "$SIDESPACE_URL/v1/search?q=storm"
curl -H "Authorization: Bearer $SIDESPACE_TOKEN" "$SIDESPACE_URL/v1/search?q=the+ocean+at+dusk&mode=meaning"- "Film A" 里一开始就有四段示例视频(
/Ep01、/Ep02),已经带着转写和 AI 标签,是side.transcribe和side.tags真正跑出来的。背后的模型换成了容器里的替身,回答是固定的,不需要任何 API key。搜索(带说到那个词的时间点)、按意思搜索、动作、流水线和 MCP(http://localhost:8080/mcp)都能直接试。 - 想换成真模型,启动时给
SIDESPACE_TRANSCRIBE_URL和_KEY、SIDESPACE_ANTHROPIC_API_KEY或SIDESPACE_EMBED_URL和_KEY,配了哪个就用哪个,其余仍用替身。-e SIDESPACE_DEMO=0不放示例视频,也不用替身。 - 别人可以用任意邮箱加验证码
000000登录。它不发邮件、不备份,只用来试,不要放真实素材。删掉sidespace-trial卷就从头再来。
用试用容器的话,跳过第 1 步,直接用日志里的令牌;本页其余步骤照做,把 https://side.example.com 换成 http://localhost:8080。
1. 生成令牌
先用 CLI 登录一次,再生成个人访问令牌。令牌只显示这一次,记得马上复制。
export SIDESPACE_SERVER=https://side.example.com # CLI 连接的服务器
sidespace login [email protected]
sidespace token create "quickstart" --scope files:write --scope sidecars:write --space "Film A"
# ssp_6Jw… (只显示一次)
export SIDESPACE_URL=$SIDESPACE_SERVER # Python SDK 读这个
export SIDESPACE_TOKEN=ssp_6Jw… # CLI 和 Python SDK 都读这个--space 把令牌限定在一个空间;不加就能访问你加入的所有空间。权限、AI 成员和 OAuth 见认证。
2. 装 SDK(可选)
两个 SDK 都没有依赖,Apache-2.0 许可。它们还没有发布到 npm 和 PyPI:从仓库的检出目录安装,或者把文件夹拷进你的项目。
npm install ./sdks/typescript # import { SideSpace } from "@sidespace/sdk"pip install ./sdks/python # from sidespace import SideSpace# 什么都不用装。每次调用带上:-H "Authorization: Bearer $SIDESPACE_TOKEN"3. 搜索
搜索覆盖文件名、标签、AI 提示词、转写和审阅评论。命中转写时,结果会带上这句话出现的时间点。
curl -H "Authorization: Bearer $SIDESPACE_TOKEN" "$SIDESPACE_URL/v1/search?q=harbor+night"import { SideSpace } from "@sidespace/sdk";
const side = new SideSpace({ baseUrl: process.env.SIDESPACE_URL!, token: process.env.SIDESPACE_TOKEN! });
for (const hit of await side.search("harbor night")) {
console.log(hit.space_name, hit.folder, hit.node.name, hit.moments?.[0]?.at_ms);
}from sidespace import SideSpace
side = SideSpace() # 读取 SIDESPACE_URL 和 SIDESPACE_TOKEN
for hit in side.search("harbor night"):
print(hit["space_name"], hit["folder"], hit["node"]["name"])4. 上传文件
保存到已有的路径会多一个版本,不会覆盖任何东西。缺少的文件夹会自动建好。
await side.upload("Film A", "/Ep01/notes.md", "# Notes\n\nPick-ups on Tuesday.\n");side.upload("Film A", "/Ep01/notes.md", "# Notes\n\nPick-ups on Tuesday.\n")
with open("A001_C003.mov", "rb") as f:
side.upload("Film A", "/Ep01/Shots/A001_C003.mov", f) # 流式上传,不会整个读进内存sidespace put "Film A" ./notes.md Ep01/notes.md
# 直接用 HTTP 上传分三步,见“文件与版本”。5. 加上你自己的元数据
结果写进附加信息,而不是在原文件旁边再放一个文件。自定义命名空间以 x- 开头。
await side.putSidecar("Film A", "/Ep01/Shots/A001_C003.mov", "x-shotcheck", { focus: "soft", score: 0.42 });
const media = await side.getSidecar("Film A", "/Ep01/Shots/A001_C003.mov", "media");
console.log(media?.duration_s, media?.width, media?.height);side.put_sidecar("Film A", "/Ep01/Shots/A001_C003.mov", "x-shotcheck", {"focus": "soft", "score": 0.42})
media = side.get_sidecar("Film A", "/Ep01/Shots/A001_C003.mov", "media")curl -X PUT "$SIDESPACE_URL/v1/spaces/$SPACE/versions/$VERSION/sidecars/x-shotcheck" \
-H "Authorization: Bearer $SIDESPACE_TOKEN" -H "Content-Type: application/json" \
-d '{"doc": {"focus": "soft", "score": 0.42}}'现在在应用里打开这个文件,“信息”里能看到你写的字段,搜索也能搜到它们。
接下来
- 用 Webhook 跟踪变化,不用轮询。
- 运行 AI 处理:转写或给视频打标签,然后读取结果。
- 在 Claude 里用,或者通过 MCP 接入你自己的 agent。
- 看过去、整体回滚一个文件夹,或者只改文件的一部分。