09e9f3545f
Test / Code Quality (push) Has been cancelled
Test / Test (macos-latest, Python 3.10) (push) Has been cancelled
Test / Test (macos-latest, Python 3.11) (push) Has been cancelled
Test / Test (macos-latest, Python 3.12) (push) Has been cancelled
Test / Test (macos-latest, Python 3.13) (push) Has been cancelled
Test / Test (macos-latest, Python 3.14) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.10) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.11) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.12) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.13) (push) Has been cancelled
Test / Test (ubuntu-latest, Python 3.14) (push) Has been cancelled
Test / Test (windows-latest, Python 3.10) (push) Has been cancelled
Test / Test (windows-latest, Python 3.11) (push) Has been cancelled
Test / Test (windows-latest, Python 3.12) (push) Has been cancelled
Test / Test (windows-latest, Python 3.13) (push) Has been cancelled
Test / Test (windows-latest, Python 3.14) (push) Has been cancelled
CodeQL / Analyze (push) Has been cancelled
dependency-audit / pip-audit (push) Has been cancelled
164 lines
5.9 KiB
Python
164 lines
5.9 KiB
Python
"""Example: Generate a Video Overview from notebook sources.
|
|
|
|
This example demonstrates:
|
|
1. Setting up a notebook with sources
|
|
2. Generating a video overview with style options
|
|
3. Checking artifact status
|
|
4. Downloading the completed video
|
|
|
|
Video Overviews are animated explainer videos that summarize your
|
|
notebook content with AI-generated narration and visuals.
|
|
|
|
Prerequisites:
|
|
- Authentication configured via `notebooklm auth` CLI command
|
|
- Valid Google account with NotebookLM access
|
|
"""
|
|
|
|
import asyncio
|
|
|
|
from notebooklm import NotebookLMClient, VideoFormat, VideoStyle
|
|
|
|
|
|
async def main():
|
|
"""Generate a video overview from notebook sources."""
|
|
|
|
async with NotebookLMClient.from_storage() as client:
|
|
# Step 1: Create a notebook with content
|
|
print("Creating notebook...")
|
|
notebook = await client.notebooks.create("Video Demo Notebook")
|
|
print(f"Created notebook: {notebook.id}")
|
|
|
|
# Add sources for video content
|
|
print("\nAdding sources...")
|
|
urls = [
|
|
"https://en.wikipedia.org/wiki/Quantum_computing",
|
|
]
|
|
|
|
for url in urls:
|
|
source = await client.sources.add_url(notebook.id, url)
|
|
print(f" Added: {source.title or url}")
|
|
|
|
# Wait for source processing
|
|
print("\nWaiting for source processing...")
|
|
await asyncio.sleep(5)
|
|
|
|
# Step 2: Generate the video overview
|
|
# Video generation options:
|
|
#
|
|
# video_format:
|
|
# - EXPLAINER: Full explanatory video (default)
|
|
# - BRIEF: Shorter summary video
|
|
# - CINEMATIC: AI-generated documentary footage (Veo 3)
|
|
# - SHORT: Vertical short-form video (fixed style; no video_style)
|
|
#
|
|
# video_style:
|
|
# - AUTO_SELECT: Let AI choose the best style (default)
|
|
# - CUSTOM: Caller-provided style
|
|
# - CLASSIC: Traditional presentation style
|
|
# - WHITEBOARD: Whiteboard animation style
|
|
# - KAWAII: Cute, kawaii-inspired style
|
|
# - ANIME: Anime visual style
|
|
# - WATERCOLOR: Watercolor painting style
|
|
# - RETRO_PRINT: Retro print style
|
|
# - HERITAGE: Heritage/vintage style
|
|
# - PAPER_CRAFT: Paper-craft style
|
|
|
|
print("\nStarting video generation...")
|
|
print("Video generation typically takes 3-8 minutes")
|
|
|
|
generation = await client.artifacts.generate_video(
|
|
notebook.id,
|
|
video_format=VideoFormat.EXPLAINER,
|
|
video_style=VideoStyle.AUTO_SELECT,
|
|
language="en",
|
|
instructions="Create an engaging overview suitable for general audiences",
|
|
)
|
|
|
|
print(f"Generation started: {generation.task_id}")
|
|
print(f"Initial status: {generation.status}")
|
|
|
|
# Step 3: Wait for completion with status updates
|
|
print("\nWaiting for video generation...")
|
|
|
|
try:
|
|
final_status = await client.artifacts.wait_for_completion(
|
|
notebook.id,
|
|
generation.task_id,
|
|
initial_interval=10.0, # Check every 10 seconds initially
|
|
max_interval=30.0, # Max 30 seconds between checks
|
|
timeout=900.0, # 15 minute timeout for videos
|
|
)
|
|
|
|
if final_status.is_complete:
|
|
print("\nVideo generation complete!")
|
|
|
|
# Step 4: Download the video
|
|
output_path = "quantum_video.mp4"
|
|
print(f"Downloading video to {output_path}...")
|
|
|
|
await client.artifacts.download_video(
|
|
notebook.id,
|
|
output_path,
|
|
artifact_id=generation.task_id,
|
|
)
|
|
print(f"Video downloaded: {output_path}")
|
|
|
|
elif final_status.is_failed:
|
|
print(f"\nGeneration failed: {final_status.error}")
|
|
|
|
except TimeoutError:
|
|
print("\nVideo generation timed out")
|
|
print("Check NotebookLM web UI for completion")
|
|
|
|
# =====================================================================
|
|
# Alternative: Check existing artifacts
|
|
# =====================================================================
|
|
|
|
print("\n--- Listing All Video Artifacts ---")
|
|
|
|
# List all video artifacts in the notebook
|
|
videos = await client.artifacts.list_video(notebook.id)
|
|
|
|
for video in videos:
|
|
status = "Ready" if video.is_completed else "Processing"
|
|
print(f"\n Title: {video.title}")
|
|
print(f" ID: {video.id}")
|
|
print(f" Status: {status}")
|
|
if video.created_at:
|
|
print(f" Created: {video.created_at}")
|
|
|
|
# =====================================================================
|
|
# Manual status polling example
|
|
# =====================================================================
|
|
|
|
print("\n--- Manual Status Polling ---")
|
|
|
|
if generation.task_id:
|
|
# You can manually poll status without wait_for_completion
|
|
status = await client.artifacts.poll_status(
|
|
notebook.id,
|
|
generation.task_id,
|
|
)
|
|
print(f"Current status: {status.status}")
|
|
print(f"Is complete: {status.is_complete}")
|
|
print(f"Is in progress: {status.is_in_progress}")
|
|
|
|
# =====================================================================
|
|
# Download existing video
|
|
# =====================================================================
|
|
|
|
# If you have an existing completed video, download it directly
|
|
if videos and videos[0].is_completed:
|
|
print("\n--- Downloading Existing Video ---")
|
|
existing_path = "existing_video.mp4"
|
|
await client.artifacts.download_video(
|
|
notebook.id,
|
|
existing_path,
|
|
artifact_id=videos[0].id,
|
|
)
|
|
print(f"Downloaded: {existing_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|