← back to AgentAbrams
media/engine.py
139 lines
#!/usr/bin/env python3
"""
engine.py — Unified media engine for AgentAbrams.
One function call generates: blog, podcast, video, transcript, chapters, social posts.
Usage:
python3 media/engine.py <post.md> [developer_name]
"""
import os
import sys
from pathlib import Path
# Add project root and sibling dirs to path
PROJECT_ROOT = Path(__file__).parent.parent
sys.path.insert(0, str(PROJECT_ROOT / "media"))
sys.path.insert(0, str(PROJECT_ROOT / "video"))
sys.path.insert(0, str(PROJECT_ROOT / "podcast"))
from md_to_blog import transform as blog_transform
from md_to_podcast import transform as podcast_transform
from chapters import generate_chapters
from social import generate_social
def build(md_path: str, developer: str = "Agent Abrams"):
out = Path("media/output")
out.mkdir(parents=True, exist_ok=True)
print(f"{'='*60}")
print("AgentAbrams Media Engine")
print(f"Source: {md_path}")
print(f"Developer: {developer}")
print(f"{'='*60}")
print()
# 1. Blog
print("[1/6] Generating blog post...")
blog = blog_transform(md_path, developer)
blog_file = out / "blog_output.md"
blog_file.write_text(blog, encoding="utf-8")
print(f" → {blog_file}")
print()
# 2. Podcast script
print("[2/6] Generating podcast script...")
script = podcast_transform(md_path, developer)
script_file = out / "podcast_script.txt"
script_file.write_text(script, encoding="utf-8")
print(f" → {script_file}")
print()
# 3. TTS Audio (requires ELEVEN_API_KEY)
voice_file = out / "voice.mp3"
episode_file = out / "episode.mp3"
if os.environ.get("ELEVEN_API_KEY"):
print("[3/6] Generating TTS audio...")
try:
from tts_engine import generate_audio
generate_audio(script, str(voice_file))
# Mix with intro/outro
from audio_mixer import mix_audio
mix_audio(str(voice_file), str(episode_file))
except Exception as e:
print(f" WARNING: TTS failed: {e}")
print(" Skipping audio generation.")
else:
print("[3/6] Skipping TTS (ELEVEN_API_KEY not set)")
print(" Set ELEVEN_API_KEY to enable audio generation.")
print()
# 4. Chapters
print("[4/6] Generating chapter markers...")
chapters = generate_chapters(md_path)
print()
# 5. Video (requires ffmpeg + audio)
if episode_file.exists():
print("[5/6] Generating video...")
try:
from video import build_video
build_video(str(episode_file))
except Exception as e:
print(f" WARNING: Video generation failed: {e}")
else:
print("[5/6] Skipping video (no audio file)")
print()
# 6. Social posts
print("[6/6] Generating social posts...")
generate_social(str(blog_file))
print()
# 7. Transcript (bonus, if whisper available)
if episode_file.exists():
print("[bonus] Generating transcript...")
try:
from transcript import generate_transcript
generate_transcript(str(episode_file))
except Exception as e:
print(f" Transcript skipped: {e}")
print()
# Summary
print(f"{'='*60}")
print("BUILD COMPLETE")
print(f"{'='*60}")
print()
print("Outputs:")
for f in sorted(out.iterdir()):
size = f.stat().st_size
print(f" {f.name:30s} {size:>10,} bytes")
print()
print("Next steps:")
print(" 1. Review media/output/blog_output.md")
print(" 2. Run: python3 snippets/redact_lint.py media/output/blog_output.md")
print(" 3. Publish to goodquestion.ai")
print(" 4. Upload video: python3 video/upload_youtube.py media/output/video.mp4")
print()
def main():
if len(sys.argv) < 2:
print("Usage: engine.py <post.md> [developer_name]", file=sys.stderr)
sys.exit(2)
if not Path(sys.argv[1]).is_file():
print(f"File not found: {sys.argv[1]}", file=sys.stderr)
sys.exit(2)
developer = sys.argv[2] if len(sys.argv) > 2 else "Agent Abrams"
build(sys.argv[1], developer)
if __name__ == "__main__":
main()