Dependencies
# macOS
brew install ffmpeg poppler
# Ubuntu/Debian
sudo apt install ffmpeg poppler-utils
# Windows
# Install ffmpeg from https://ffmpeg.org/download.html
# Install poppler from https://blog.alivate.com.au/poppler-windows/# Required for Marp CLI (will be installed locally by install.sh)
# Install from: https://nodejs.org/# Install MoonBit from https://www.moonbitlang.com/
curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bashcd mdcourse
moon install # Install dependencies
moon build # Build the binary./install.shmdcourse input.mbt.mdrm -rf ~/.mdcourse
rm ~/.local/bin/mdcoursecd mdcourse
moon run cmd/main -- ../course7/lec7-1.mbt.mdexport TTS_KEY="your-azure-subscription-key"
export TTS_REGION="eastus" # or your preferred region# Generate complete video with audio
moon run cmd/main -- input.mbt.md
# Specify output file
moon run cmd/main -- -o output.mp4 input.mbt.md# Only parse markdown and extract SSML
moon run cmd/main -- --parse-only input.mbt.md
# Only generate slide images
moon run cmd/main -- --slides-only input.mbt.md
# Only generate audio (requires previous parse)
moon run cmd/main -- --audio-only input.mbt.md
# Only compose video (requires slides + audio)
moon run cmd/main -- --compose-only input.mbt.md-o, --output <OUTPUT> Output video file path (default: <input-basename>.mp4)
--parse-only Only parse file
--slides-only Only generate slide images
--audio-only Only generate audio
--compose-only Only compose video
--force-audio Force regenerate all audio
--keep-temp Keep temporary video segments for debugging
--voice <VOICE> Specify TTS voice
--fps <FPS> Video frame rate
--resolution <RESOLUTION> Video resolution (4k, 1440p, 1080p, 720p, 480p)
--default-duration <DEFAULT-DURATION> Default duration for slides without audio (seconds)# Generate 4K video with custom voice
moon run cmd/main -- \
-p 4k \
-v zh-CN-XiaoxiaoNeural \
-o course7-video.mp4 \
../course7/lec7-1.mbt.md---
marp: true
theme: custom
headingDivider: 1
---
# Slide Title
Slide content here.
<!-- ssml
这是第一页的旁白文字。
-->
# Another Slide
More content.
<!-- ssml
这是第二页的旁白文字。
--><!-- ssml
普通文字会被朗读。
<break time="500ms"/>
可以使用 SSML 标签来控制语音。
--># Slide Before Video
Content here.
<!-- video path/to/video.mp4 -->
# Slide After Video
More content.<!-- video path/to/video.mp4 ssml
这是视频的配音。
-->---
marp: true
---
# First Slide
Content.
---
# Second Slide
More content.---
marp: true
headingDivider: 1
---
# First Slide
Content.
# Second Slide
More content.<!-- ssml
这是<emphasis>强调</emphasis>的文字。
<break time="1s"/>
暂停一秒。
<prosody rate="slow">慢速朗读。</prosody>
<prosody pitch="+10%">提高音调。</prosody>
-->mdcoursetarget/
└── course-name/
├── manifest.json # Slide and video metadata
├── audio/
│ ├── slide-001.ssml # Original SSML content
│ ├── slide-001.wav # Generated audio
│ ├── slide-001.meta.json # Audio duration metadata
│ └── ...
├── slides/
│ ├── slide-001.png # Slide images (300 DPI)
│ └── ...
├── segments/ # Temporary video segments (if --keep-temp)
│ ├── segment-001.mp4
│ └── ...
└── output.mp4 # Final videopub struct Options {
input_file : String
output_file : String?
parse_only : Bool
slides_only : Bool
audio_only : Bool
compose_only : Bool
force_audio : Bool
keep_temp : Bool
voice : String
fps : Int
resolution : String
default_duration : Double
theme : String
engine : String
}fn get_course_name_from_path(input_file : String) -> Stringasync fn get_video_duration(video_path : String) -> Doubleasync fn parse_file(input_path : String, output_dir : String) -> Boolfn target_dir(course_name : String) -> StringInstall
Download zipDependencies