Shorts Auto Creator
RSS記事から生成された縦型ショート動画
YouTube Data APIを使って自動投稿
プロジェクト概要
Shorts Auto Creatorは、指定したRSSサイトの記事を取得し、その内容をもとにYouTube Shorts向けの動画を自動生成・自動投稿するツールです。 記事の選定、ナレーション台本の生成、音声合成、背景画像の生成、字幕付き縦型動画の作成、BGM合成、YouTubeへのアップロードまでをPythonで一括処理します。GitHub Actionsのスケジュール実行に対応しており、手動操作なしで継続的にショート動画を投稿できる構成にしています。
開発目的
- 記事コンテンツを短尺動画として再利用し、発信作業を効率化するため
- 動画生成、音声合成、API連携、CI/CD実行を組み合わせた自動化を実践するため
- YouTube投稿に必要な認証、メタデータ生成、投稿ログ管理まで含めた運用可能な仕組みを作るため
- 無料枠やAPI利用量に配慮しながら、定期実行できる自動投稿パイプラインを構築するため
使用技術
プログラミング言語
Python
バックエンド / 外部サービス
GitHub Actions
YouTube Data API
Google Gemini API
Google OAuth
gTTS
RSS / Atom feed
FFmpeg
主な機能
- RSSフィードから最新記事を取得
- 投稿済み記事を記録し、同じ記事の重複投稿を防止
- 複数ソースURLから投稿対象をランダム選択
- Gemini APIを使った英語ナレーション台本生成
- gTTSによるナレーション音声生成
- ローカル背景生成または画像生成APIによる縦型背景作成
- 字幕、BGM、背景画像を合成した9:16動画生成
- YouTube投稿用タイトル・説明文・ハッシュタグ生成
- YouTube Data APIによる動画アップロード
- GitHub Actionsによる定期実行
- OAuthトークンをGitHub Secretsで安全に復元
システム構成
GitHub Actionsを実行基盤とし、PythonスクリプトがRSS記事の取得から動画生成、YouTubeアップロードまでを順番に処理します。APIキーやOAuthトークンはGitHub Secretsに保存し、実行時に必要なファイルとして復元します。投稿後は記事URLと動画IDをログに残し、次回以降の重複投稿を防ぎます。
データフロー
GitHub Actionsのスケジュールまたは手動実行でワークフロー開始
↓ 実行環境をセットアップ
GitHub Secretsから`.env`、`client_secrets.json`、`token.pickle`を復元
↓ Python依存関係をインストール
RSSフィードから記事一覧を取得
↓ 投稿済みログと照合
未投稿の記事を選択
↓ Gemini APIでナレーション台本を生成
gTTSで音声ファイルを作成
↓ 背景、字幕、BGMを合成
MoviePyでYouTube Shorts用の縦型動画を生成
↓ YouTube Data APIでアップロード
投稿済み記事ログを更新
↓ GitHubにログをコミット
工夫した点
- 投稿済み記事を`posted_articles.json`に保存し、同じ記事を繰り返し投稿しないようにした
- API利用量を抑えるため、背景生成はローカル生成も選べるようにした
- GitHub Actions上でOAuth認証ファイルを直接置かず、Base64化したSecretから復元する構成にした
- YouTube OAuthトークン失効時の復旧手順をドキュメント化し、運用時に迷わないようにした
- 動画生成後に一時ファイルを削除し、リポジトリや実行環境に不要な生成物が残らないようにした
- 実行時刻をUTCとJSTでログ出力し、スケジュール実行の確認をしやすくした
- BGMカテゴリ、字幕位置、字幕色、動画長、音声言語などを環境変数で調整できるようにした
技術的ハイライト
1. RSS記事から未投稿コンテンツを選ぶ仕組み
def choose_article_from_source(
source_url: str,
log_entries: list[dict],
recent_limit: int,
) -> Article | None:
articles = fetch_recent_articles(source_url, limit=recent_limit)
for article in articles:
if article.link and not is_article_already_posted(log_entries, article.link):
return article
return None
2. 環境変数で調整できる動画生成パイプライン
video_result = generate_video(
article,
client=client,
target_seconds=int(os.getenv("TARGET_SECONDS", "45")),
text_model=os.getenv("GEMINI_TEXT_MODEL", "gemini-2.5-flash-lite"),
background_mode=os.getenv("BACKGROUND_MODE", "local"),
bgm_mode=os.getenv("BGM_MODE", "auto"),
subtitle_style=os.getenv("SUBTITLE_STYLE", "karaoke"),
output=os.getenv("VIDEO_OUTPUT", "output.mp4"),
)
3. YouTube OAuth認証とアップロード処理
if credentials and credentials.expired and credentials.refresh_token:
credentials.refresh(Request())
elif not credentials or not credentials.valid:
flow = InstalledAppFlow.from_client_secrets_file(str(secrets_path), SCOPES)
credentials = flow.run_local_server(port=0)
with token_file.open("wb") as handle:
pickle.dump(credentials, handle)
return build("youtube", "v3", credentials=credentials)
開発情報
開発形態
個人開発
役割
企画、設計、実装、GitHub Actions設定、YouTube API連携、OAuth設定、運用手順整備
制作期間
約1週間
開発時の注意事項
本プロジェクトは、学習・ポートフォリオ・発信作業の自動化を目的として開発しました。外部APIやYouTube投稿機能を扱うため、認証情報の管理、API利用量、投稿内容の重複防止に配慮しています。
認証情報の管理
- `.env`、`client_secrets.json`、`token.pickle`はGit管理対象外にした
- GitHub ActionsではGitHub Secretsから必要ファイルを復元する構成にした
- YouTube OAuthトークンが失効した場合の再発行手順をドキュメント化した
- OAuth同意画面を本番環境に設定し、テスト中トークンの短期失効リスクを下げた
API利用量と無料枠への配慮
- Gemini APIの利用回数を抑えるため、必要な場面に絞って生成処理を行うようにした
- 背景画像はローカル生成を選択できるようにし、画像生成APIの利用を抑えた
- 定期実行のスケジュールを固定し、想定外の高頻度実行を避ける構成にした
投稿品質と運用面
- 投稿済みログを使い、同じ記事を繰り返し投稿しないようにした
- 動画生成後に一時ファイルを削除し、不要なファイルが蓄積しないようにした
- YouTubeアップロード後に動画IDとタイトルをログに残し、後から確認できるようにした
デモ動画
実際に自動生成されたYouTube Shorts動画を掲載できます。RSS記事からナレーション、字幕、BGM付きの縦型動画が生成され、YouTubeへアップロードされる流れを紹介するデモとして利用できます。
謝辞
- Google Gemini API: ナレーション台本および投稿メタデータ生成
- YouTube Data API: 動画アップロード機能
- GitHub Actions: 定期実行と自動化基盤
- MoviePy: 動画編集・音声合成処理
- Pillow: 画像生成・字幕描画処理
- gTTS: ナレーション音声生成
- feedparser: RSSフィード取得
- FFmpeg: 動画・音声処理基盤