
【2026年8月版】
AstroのMarkdownコードブロックにVHSのターミナル動画を埋め込む
公開日: 2026/08/17
読了時間: 約 10分
ターミナルの操作をブログで説明するとき、コマンドをコードブロックに貼るだけでは、どこに入力して、どんな結果が出たのかが分かりにくいです。
そこで、あそぴテックでは、コマンドの入力と結果を見せられるVHSを導入してみました。VHSで作ったデモを、AstroのMarkdown記事に埋め込みました。この記事では、その取り組みを紹介します。
VHSとは
VHSは、.tapeファイルに書いた台本を仮想ターミナル上で実行し、コマンドの入力と結果を再現したGIF、MP4、WebM、PNGを作るオープンソースのターミナルツールです。入力速度、待ち時間、画面サイズも台本で指定できます。
画面録画と違い、入力速度や待ち時間などを台本で揃えられるため、全く同じ手順を何度でも再現できます。ブログ用のMP4、X用のGIF、結果を示すPNGも同じ台本から作れます。
このページのデモも、同じ方法で生成しました。
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
VHSは.txtまたは.asciiをOutputに指定すると、最終的なターミナルの内容をテキストファイルにも出力できます。このブログでは、動画エリア右上のボタンから、その実行結果をコピーできるようにしました。
AstroにVHSを埋め込むには?
このブログでは、コードブロックの宣言にvideoを指定し、ブロック内に動画のURLやタイトルなどを書くことで、記事内にターミナルデモを表示できるようにしました。
AstroのMarkdownファイルでは、次のように書きます。
```video
src: /videos/astro-vhs-blog/demo.mp4
```srcには動画のURLを指定します。詳しい属性の指定方法は、後の「動画表示の属性」で説明します。
Astroの設定には、既存のRemarkプラグインと並べて登録しました。
// astro.config.mjs
import { remarkTerminalVideo } from './src/lib/remark-terminal-video';
export default defineConfig({
markdown: {
remarkPlugins: [
remarkCodeTitles,
remarkReadingTime,
remarkTerminalVideo,
],
},
});記事ごとにAstroコンポーネントをimportしなくて済むようにしました。Markdownでvideoブロックを書くだけで、サイト全体で同じ動画表示を使えます。AstroのMarkdown処理とMarkdownプラグインの考え方は、Astro公式ドキュメントにも整理されています。
本サイトで使用したVHS台本の例
本サイトでは、コマンドの入力、処理中、結果の流れを見せるため、echoを使った台本からターミナルデモを作成しました。
Output public/videos/analyze-project/demo.mp4
Output public/videos/analyze-project/demo.gif
Output public/videos/analyze-project/demo.txt
Require echo
Set Shell "bash"
Set Width 960
Set Height 540
Set FontSize 22
Set Padding 8
Set CursorBlink false
Set Framerate 10
Set TypingSpeed 65ms
Hide
Type "clear"
Enter
Type "echo 'analyzing sample-project...'"
Enter
Sleep 1s
Type "echo 'files: 42 dependencies: 8 status: ready'"
Enter
Sleep 2s
Screenshot public/videos/analyze-project/demo.png
Showこの台本では、Set WidthとSet Heightでターミナルのサイズを指定し、Type、Enter、Sleepで入力と処理中の時間を表現しています。MP4、GIF、PNGはこのサイズで生成し、記事では縦横比を保って表示します。スマートフォンでは画面幅に合わせて縮小されます。
本サイトでは、何度実行しても同じデモになるよう、入力データを固定し、本番環境で繰り返し実行できないコマンドは--demoモードで再現しています。
Outputで動画、GIF、テキストを、Screenshotでポスター画像を生成しています。
動画ブロックの表示方法と属性
このブログでは、Markdownの言語名にvideoと書いたコードブロックを、ターミナルデモとして表示します。ブロック内のkey: value形式の設定を読み取り、formatに応じて動画プレーヤー、GIF、PNGを表示します。titleとcaptionを添え、textを指定した場合は実行結果をコピーできるボタンを表示します。通常のコードブロックや他のMarkdownは、そのまま表示します。
メディアのURLはサイト内のパスまたはHTTPSに限定しています。javascript:やdata:、制御文字、HTML属性を壊す引用符は受け付けず、記事の値は表示時にエスケープします。これにより、記事に書いた設定が意図しないHTMLとして解釈されることを防ぎます。
次のように属性をまとめて指定できます。
```video
format: video
src: /videos/astro-vhs-blog/demo.mp4
webm: /videos/astro-vhs-blog/demo.webm
poster: /videos/astro-vhs-blog/demo.png
text: /videos/astro-vhs-blog/demo.txt
title: プロジェクト解析のターミナルデモ
caption: コマンドを実行して解析結果を表示する
autoplay: true
controls: true
loop: true
muted: true
playsinline: true
preload: metadata
fallback: /videos/astro-vhs-blog/demo.mp4
```src: 表示する動画や画像を指定します。必須ですwebm: WebM形式の動画を指定しますposter: 動画の再生前に表示する画像を指定しますtext: 実行結果をコピーするためのテキストファイルを指定しますtitle: デモのタイトルを指定しますcaption: 動画や画像の説明を指定しますautoplay: ページを開いたときに再生しますcontrols: 再生、一時停止、音量などの操作を表示しますloop: 再生を繰り返しますmuted: 音声を消して再生しますplaysinline: スマートフォンでもページ内で再生しますpreload: 動画の読み込み方法を指定します。metadataなら、ページを開いた時点では動画全体を読み込みませんfallback: 動画を再生できない場合に表示する代替コンテンツを指定します
controls、loop、muted、playsinlineは既定で有効にし、autoplayは指定した場合だけ有効にしています。
formatで表示形式を切り替えます。
| format | 表示 | 向いている用途 |
|---|---|---|
video | 動画プレーヤー | 操作UI、ポスター、MP4/WebM、長めのデモ |
gif | 繰り返し再生する画像 | X向けと同じ短い無音ループ、軽い確認用 |
png | 静止画 | 結果の保存、動画のポスター |
GIFとPNGでは、altで画像の内容を説明できます。たとえば、次のように指定します。
```video
format: gif
src: /videos/astro-vhs-blog/demo.gif
text: /videos/astro-vhs-blog/demo.txt
alt: VHSで生成したターミナルアニメーション
caption: GIFは画像として自動的にループします
```実際の表示例です。

>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
```video
format: png
src: /videos/astro-vhs-blog/demo.png
text: /videos/astro-vhs-blog/demo.txt
alt: VHSで生成したターミナルの静止画
caption: PNGはポスターや静止画として表示します
```PNGの表示例です。

>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
> echo 'Astro + VHS'
Astro + VHS
> echo 'demo generated by VHS'
demo generated by VHS
>
────────────────────────────────────────────────────────────────────────────────
CSSは、動画や画像が記事の幅に合わせて表示され、スマートフォンでも横幅に収まるように調整しています。
VHS生成物の管理例
本サイトでの保存単位の一例は次の通りです。
tapes/
└── <デモ名>.tape
public/videos/<記事スラッグ>/
├── demo.mp4
├── demo.gif
└── demo.png動画ファイルだけを更新すると、どの手順や設定から作った動画なのか分からなくなります。そこで、本サイトでは台本を残し、同じデモから作ったファイルと一緒に管理しています。
まとめ
VHSの台本からMP4・GIF・PNGを生成し、Astroのvideoコードブロックで記事に表示できるようにしました。formatで表示形式を切り替え、動画エリアのボタンから実行結果をコピーできるようにしました。
今後ともあそぴテックサイトをよろしくお願いします。