chore(gitignore): 更新 .gitignore 以忽略本地规划设计笔记
English | 简体中文
MoonPost 是一个用 MoonBit 编写的字幕、时间码与后期交付质检工具包。
它面向文本型媒体交付工作:检查 SRT/WebVTT 字幕文件、转换字幕格式、 计算 SMPTE 风格时间码、重定时字幕 cue,并让同一套核心逻辑可以运行在 native CLI 和浏览器本地 WebAssembly demo 中。
MoonPost 不做视频解码、转码或 FFmpeg 封装。项目关注的是适合用 MoonBit 确定性实现的后期基础设施层:parser、数据模型、QC 规则、报告、CLI 工具 和 Wasm-ready 核心包。
23.976
24
25
29.97
29.97df
30
50
59.94
59.94df
MoonPost 适合放在字幕交付、媒体 QA 和创作者发布流程中,作为轻量、可重复的 字幕检查与时间码工具。
MoonPost 主要面向会直接处理字幕文件和交付检查的用户。
moon
开发过程中测试过的本地 MoonBit 工具链:
moon 0.1.20260512 moonc v0.9.2
克隆仓库后运行测试:
moon test --target native moon test --target wasm-gc
从源码运行 CLI:
moon run cmd/main --target native -- --help
源码运行前缀是:
moon run cmd/main --target native --
下面的示例都会使用这个前缀。如果之后发布独立二进制,可以把该前缀替换为 moonpost。
moonpost
MoonPost - subtitle, timecode and post-production QC toolkit Usage: moonpost <command> [options] Commands: qc Check subtitle delivery quality timecode Convert SMPTE-style timecode and frame counts subtitle Convert subtitle formats retime Shift, speed-convert, or snap subtitle timing merge Merge two subtitle tracks into bilingual cues split-bilingual Split bilingual cues into two subtitle tracks
检查 SRT 或 WebVTT 文件:
moon run cmd/main --target native -- qc examples/bad.srt --fps 25 --profile streaming
输出 JSON report:
moon run cmd/main --target native -- qc examples/good.srt --json
显式开启中英双语文本规范检查:
moon run cmd/main --target native -- qc examples/good.srt --text-style bilingual
--text-style 默认关闭,不会改变普通 qc 结果。可选值包括 bilingual、 zh 和 en。
--text-style
qc
bilingual
zh
en
构建 native CLI 后,可以用 --fail-on-error 在发现 Error 级问题时返回非零退出码:
--fail-on-error
moon build cmd/main --target native _build/native/debug/build/cmd/main/main.exe qc examples/bad.srt --fail-on-error
示例报告:
examples/bad.srt summary: 3 errors, 7 warnings WARN W201 cue#1 | duration 377ms below minimum 800ms WARN W310 cue#1 | 225 cps exceeds max 20 WARN W203 cue#1 | line 1: 85 chars, max 42 WARN W401 cue#1 | cue timing is not aligned to 40ms frame grid WARN W202 cue#2 | duration 7600ms above maximum 7000ms WARN W203 cue#2 | line 1: 49 chars, max 42 ERROR E102 cue#3 | end time must be after start time ERROR E201 cue#3 | empty cue text WARN W401 cue#3 | cue timing is not aligned to 40ms frame grid ERROR E101 cue#1 | overlaps cue#2 by 100ms
Profiles 为不同交付上下文提供实用默认值。
default
streaming
cinema
social-video
CLI 也支持通过 --fps <rate> 覆盖当前 profile 的帧网格。
--fps <rate>
E101
E102
E201
W201
W202
W203
W204
W310
W401
W402
W501
W502
W503
W510
W511
W520
把 SMPTE 风格时间码转换为帧数:
moon run cmd/main --target native -- timecode to-frames 01:00:00:00 --fps 25
输出:
01:00:00:00 @25fps = 90000 frames
把帧数转换回时间码:
moon run cmd/main --target native -- timecode from-frames 90000 --fps 25
90000 frames @25fps = 01:00:00:00
在不同帧率假设之间转换时间码:
moon run cmd/main --target native -- timecode convert 01:00:00:00 --from 23.976 --to 25
01:00:00:00 @23.976fps = 00:00:24:12 @25fps
支持的 CLI 帧率值:
23976
2997
29.97DF
29.97-drop
2997df
5994
59.94DF
59.94-drop
5994df
SRT 转 WebVTT:
moon run cmd/main --target native -- subtitle convert examples/good.srt --to webvtt
写出到文件:
moon run cmd/main --target native -- subtitle convert examples/good.srt --to webvtt -o output.vtt
WebVTT 转 SRT:
moon run cmd/main --target native -- subtitle convert examples/good.vtt --to srt -o output.srt
标点半角/全角规范化转换:
moon run cmd/main --target native -- subtitle normalize examples/good.srt --punctuation bilingual -o fixed.srt
--punctuation 可选值包括 bilingual、zh 和 en。该命令只改 cue 文本中的 常见标点,不会重写词语、重排字幕行或改变时间码。
--punctuation
已实现的 parser 行为:
WEBVTT
NOTE
STYLE
REGION
整体平移所有 cue:
moon run cmd/main --target native -- retime examples/good.srt --offset +1200ms
1 00:00:02,200 --> 00:00:04,400 Hello, welcome to MoonBit. 2 00:00:05,200 --> 00:00:06,700 This subtitle is ready for QC.
把重定时结果写入文件:
moon run cmd/main --target native -- retime examples/good.srt --offset -500ms -o shifted.srt
在不同帧率假设之间转换 cue 时间:
moon run cmd/main --target native -- retime examples/good.srt --from-fps 23.976 --to-fps 25 -o converted.srt
把 cue 时间吸附到帧网格:
moon run cmd/main --target native -- retime examples/good.srt --snap-fps 25 -o snapped.srt
MoonPost 包含一个本地字幕 QC 浏览器 demo。该 demo 加载 MoonBit wasm-gc 构建产物,并在浏览器中运行 QC。字幕文本保留在本地浏览器会话中。
wasm-gc
构建 Wasm 产物:
./wasm-demo/build.sh
启动本地服务:
python3 -m http.server 8765 --directory wasm-demo/public
打开:
http://localhost:8765
该 demo 需要浏览器支持 WebAssembly GC 和 JS string builtins。
MoonPost 由多个小型 MoonBit package 组成。公开 API 可参考生成的 pkg.generated.mbti 文件。
pkg.generated.mbti
phenom8010/moonpost/timecode
phenom8010/moonpost/subtitle
phenom8010/moonpost/qc
phenom8010/moonpost/retime
phenom8010/moonpost/align
phenom8010/moonpost/cli
phenom8010/moonpost/wasm_demo/core
qc_subtitle
Timecode:
parse_timecode(String, FrameRate) -> Timecode? Timecode::to_frames() -> Int Timecode::format() -> String FrameRate::frames_to_timecode(Int) -> Timecode convert_timecode(Timecode, FrameRate) -> Timecode rescale_ms_between_rates(Int, FrameRate, FrameRate) -> Int
Subtitle:
parse_srt(String) -> SubtitleTrack? parse_srt_detailed(String) -> Result[SubtitleTrack, ParseError] parse_webvtt(String) -> SubtitleTrack? parse_webvtt_detailed(String) -> Result[SubtitleTrack, ParseError] write_srt(SubtitleTrack) -> String write_webvtt(SubtitleTrack) -> String parse_timestamp_ms(String) -> Int? format_srt_timestamp(Int) -> String format_vtt_timestamp(Int) -> String
QC:
default_profile() -> QcProfile streaming_profile() -> QcProfile cinema_profile() -> QcProfile social_video_profile() -> QcProfile profile_by_name(String) -> QcProfile? check_cues(Array[Cue], QcProfile) -> Array[QcIssue] format_report(String, Array[QcIssue]) -> Array[String] format_json_report(String, Array[QcIssue]) -> String has_errors(Array[QcIssue]) -> Bool
Retime:
offset_cues(Array[Cue], Int) -> Array[Cue] convert_fps_cues(Array[Cue], FrameRate, FrameRate) -> Array[Cue] snap_cues_to_frames(Array[Cue], FrameRate) -> Array[Cue]
Align:
merge_bilingual(Array[Cue], Array[Cue], tolerance_ms~ : Int) -> Array[Cue] split_bilingual(Array[Cue]) -> BilingualSplit
Wasm demo core:
qc_subtitle(String, String) -> String
更完整的层级说明见 docs/project-structure.md。
docs/project-structure.md
moonpost/ ├── timecode/ SMPTE 风格时间码和帧率 helpers ├── subtitle/ SRT/WebVTT parser、timestamp 和 writer ├── qc/ 字幕 QC、报告、双语文本规范和标点规范化 ├── retime/ 整体偏移、帧率转换和帧吸附 ├── align/ 双语字幕 merge/split helpers ├── delivery/ 单集交付预检模型和 manifest 解析 ├── cli/ CLI 参数模型和命令解析 ├── cmd/main/ Native CLI 入口和文件系统 I/O ├── wasm_demo/core/ MoonBit Wasm 导出包 ├── wasm-demo/ 浏览器 demo shell、构建脚本和静态资源 ├── examples/ 示例字幕文件 ├── docs/ 项目结构、设计文档和实施计划 └── .github/ CI workflow
仓库包含 GitHub Actions 工作流 .github/workflows/ci.yml,会在 push、pull request 和手动触发时运行。
.github/workflows/ci.yml
CI 覆盖:
moon fmt
moon info
moon check --target native
moon check --target wasm-gc
moon build --target native
moon build --target wasm-gc
moon test --target native
moon test --target wasm-gc
wasm-demo/public/moonpost_qc.wasm
运行 native 测试:
运行 Wasm-GC 兼容测试:
检查 native 和 Wasm-GC target:
moon check --target native moon check --target wasm-gc
格式化源码:
重新生成公开接口摘要:
构建 Wasm demo core:
moon build wasm_demo/core --target wasm-gc --release
Apache-2.0。见 LICENSE。
MoonPost 是一个用 MoonBit 编写的字幕、时间码与后期交付质检工具包。 它面向文本型媒体交付工作:检查 SRT/WebVTT 字幕文件、转换字幕格式、 计算 SMPTE 风格时间码、重定时字幕 cue,并让同一套核心逻辑可以运行在 native CLI 和浏览器本地 WebAssembly demo 中。
版权所有:中国计算机学会技术支持:开源发展技术委员会 京ICP备13000930号-9 京公网安备 11010802032778号
MoonPost
English | 简体中文
MoonPost 是一个用 MoonBit 编写的字幕、时间码与后期交付质检工具包。
它面向文本型媒体交付工作:检查 SRT/WebVTT 字幕文件、转换字幕格式、 计算 SMPTE 风格时间码、重定时字幕 cue,并让同一套核心逻辑可以运行在 native CLI 和浏览器本地 WebAssembly demo 中。
MoonPost 不做视频解码、转码或 FFmpeg 封装。项目关注的是适合用 MoonBit 确定性实现的后期基础设施层:parser、数据模型、QC 规则、报告、CLI 工具 和 Wasm-ready 核心包。
功能
23.976、24、25、29.97、29.97df、30、50、59.94、59.94df。使用场景
MoonPost 适合放在字幕交付、媒体 QA 和创作者发布流程中,作为轻量、可重复的 字幕检查与时间码工具。
适用人群
MoonPost 主要面向会直接处理字幕文件和交付检查的用户。
环境要求
moon命令的 shell 环境。开发过程中测试过的本地 MoonBit 工具链:
快速开始
克隆仓库后运行测试:
从源码运行 CLI:
源码运行前缀是:
下面的示例都会使用这个前缀。如果之后发布独立二进制,可以把该前缀替换为
moonpost。CLI 概览
字幕 QC
检查 SRT 或 WebVTT 文件:
输出 JSON report:
显式开启中英双语文本规范检查:
--text-style默认关闭,不会改变普通qc结果。可选值包括bilingual、zh和en。构建 native CLI 后,可以用
--fail-on-error在发现 Error 级问题时返回非零退出码:示例报告:
QC Profiles
Profiles 为不同交付上下文提供实用默认值。
defaultstreamingcinemasocial-videoCLI 也支持通过
--fps <rate>覆盖当前 profile 的帧网格。QC 规则代码
E101E102E201W201W202W203W204W310W401W402W501W502W503W510W511W520时间码
把 SMPTE 风格时间码转换为帧数:
输出:
把帧数转换回时间码:
输出:
在不同帧率假设之间转换时间码:
输出:
支持的 CLI 帧率值:
23.976,23976242529.97,299729.97df,29.97DF,29.97-drop,2997df305059.94,599459.94df,59.94DF,59.94-drop,5994df字幕转换
SRT 转 WebVTT:
写出到文件:
WebVTT 转 SRT:
标点半角/全角规范化转换:
--punctuation可选值包括bilingual、zh和en。该命令只改 cue 文本中的 常见标点,不会重写词语、重排字幕行或改变时间码。已实现的 parser 行为:
WEBVTTheader。NOTE、STYLE、REGIONmetadata block 会被 parser 跳过。Retime
整体平移所有 cue:
输出:
把重定时结果写入文件:
在不同帧率假设之间转换 cue 时间:
把 cue 时间吸附到帧网格:
浏览器本地 Wasm Demo
MoonPost 包含一个本地字幕 QC 浏览器 demo。该 demo 加载 MoonBit
wasm-gc构建产物,并在浏览器中运行 QC。字幕文本保留在本地浏览器会话中。构建 Wasm 产物:
启动本地服务:
打开:
该 demo 需要浏览器支持 WebAssembly GC 和 JS string builtins。
Library Packages
MoonPost 由多个小型 MoonBit package 组成。公开 API 可参考生成的
pkg.generated.mbti文件。phenom8010/moonpost/timecodephenom8010/moonpost/subtitlephenom8010/moonpost/qcphenom8010/moonpost/retimephenom8010/moonpost/alignphenom8010/moonpost/cliphenom8010/moonpost/wasm_demo/coreqc_subtitle。核心公开 API
Timecode:
Subtitle:
QC:
Retime:
Align:
Wasm demo core:
仓库结构
更完整的层级说明见
docs/project-structure.md。CI
仓库包含 GitHub Actions 工作流
.github/workflows/ci.yml,会在 push、pull request 和手动触发时运行。CI 覆盖:
moon fmt后检查是否产生未提交 diff。moon info后检查pkg.generated.mbti等生成接口摘要是否同步。moon check --target native和moon check --target wasm-gc。moon build --target native和moon build --target wasm-gc。moon test --target native和moon test --target wasm-gc。wasm-demo/public/moonpost_qc.wasm产物检查。开发
运行 native 测试:
运行 Wasm-GC 兼容测试:
检查 native 和 Wasm-GC target:
格式化源码:
重新生成公开接口摘要:
构建 Wasm demo core:
许可证
Apache-2.0。见 LICENSE。