narrate_this/lib.rs
1//! # narrate-this
2//!
3//! A Rust SDK that turns text, URLs, or search queries into narrated videos —
4//! complete with TTS, captions, and stock visuals.
5//!
6//! ## Quick start
7//!
8//! ```rust,no_run
9//! use narrate_this::{
10//! ContentPipeline, ContentSource, ElevenLabsConfig, ElevenLabsTts,
11//! FfmpegRenderer, FirecrawlScraper, FsAudioStorage, OpenAiConfig,
12//! OpenAiKeywords, PexelsSearch, RenderConfig, StockMediaPlanner,
13//! };
14//!
15//! # async fn example() -> narrate_this::Result<()> {
16//! let pipeline = ContentPipeline::builder()
17//! .content(FirecrawlScraper::new("http://localhost:3002"))
18//! .tts(ElevenLabsTts::new(ElevenLabsConfig {
19//! api_key: "your-key".into(),
20//! ..Default::default()
21//! }))
22//! .media(StockMediaPlanner::new(
23//! OpenAiKeywords::new(OpenAiConfig {
24//! api_key: "your-key".into(),
25//! ..Default::default()
26//! }),
27//! PexelsSearch::new("your-key"),
28//! ))
29//! .renderer(FfmpegRenderer::new(), RenderConfig::default())
30//! .audio_storage(FsAudioStorage::new("./output"))
31//! .build()?;
32//!
33//! let output = pipeline
34//! .process(ContentSource::ArticleUrl {
35//! url: "https://example.com/article".into(),
36//! title: Some("My Article".into()),
37//! })
38//! .await?;
39//! # Ok(())
40//! # }
41//! ```
42//!
43//! ## Pipeline stages
44//!
45//! ```text
46//! Content Source → Narration → Text Transforms → TTS → Media → Audio Storage → Video Render
47//! ```
48//!
49//! Only TTS is required. Everything else is optional — skip content sourcing if
50//! you pass raw text, skip media if you just want audio, skip rendering
51//! if you don't need video.
52//!
53//! ## Local / self-hosted AI
54//!
55//! All OpenAI-backed providers accept a `base_url` for any OpenAI-compatible
56//! server (Ollama, LM Studio, vLLM, LocalAI, llama.cpp, etc.):
57//!
58//! ```rust,no_run
59//! use narrate_this::{
60//! ContentPipeline, ContentSource, OpenAiConfig, OpenAiKeywords,
61//! OpenAiTts, OpenAiTtsConfig, PexelsSearch, StockMediaPlanner,
62//! };
63//!
64//! # async fn example() -> narrate_this::Result<()> {
65//! let pipeline = ContentPipeline::builder()
66//! .tts(OpenAiTts::new(OpenAiTtsConfig {
67//! base_url: "http://localhost:8880".into(), // e.g. Kokoro
68//! caption_model: Some("whisper-1".into()),
69//! ..Default::default()
70//! }))
71//! .media(StockMediaPlanner::new(
72//! OpenAiKeywords::new(OpenAiConfig {
73//! base_url: "http://localhost:11434".into(), // e.g. Ollama
74//! model: "llama3".into(),
75//! ..Default::default()
76//! }),
77//! PexelsSearch::new("your-key"),
78//! ))
79//! .build()?;
80//!
81//! let output = pipeline
82//! .process(ContentSource::Text("Hello world".into()))
83//! .await?;
84//! # Ok(())
85//! # }
86//! ```
87//!
88//! ## Custom providers
89//!
90//! Swap any stage by implementing the matching trait: [`TtsProvider`],
91//! [`ContentProvider`], [`KeywordExtractor`], [`MediaSearchProvider`],
92//! [`MediaPlanner`], [`TextTransformer`], [`AudioStorage`], [`CacheProvider`],
93//! or [`VideoRenderer`].
94
95mod error;
96mod types;
97pub(crate) mod util;
98
99pub mod traits;
100pub mod providers;
101
102mod config;
103mod pipeline;
104
105// ── Re-exports: core ──
106
107pub use error::{Result, SdkError};
108pub use types::{
109 AudioTrack, CaptionSegment, ContentOutput, ContentSource, KeywordResult, MediaAsset,
110 MediaFallback, MediaKind, MediaSegment, MediaSource, NarrationStyle, PipelineProgress,
111 TimedChunk, TtsResult,
112};
113
114// ── Re-exports: traits ──
115
116pub use traits::{
117 AudioStorage, CacheCategory, CacheProvider, ContentProvider, KeywordExtractor, MediaPlanner,
118 MediaSearchProvider, MediaSearchResult, PlannedMedia, RenderConfig, TextTransformer,
119 TtsProvider, VideoRenderer,
120};
121
122// ── Re-exports: providers ──
123
124pub use providers::elevenlabs::{ElevenLabsConfig, ElevenLabsTts};
125pub use providers::firecrawl::{FirecrawlConfig, FirecrawlScraper};
126pub use providers::ffmpeg_renderer::FfmpegRenderer;
127pub use providers::fs_storage::FsAudioStorage;
128pub use providers::openai::{LlmMediaPlanner, OpenAiConfig, OpenAiKeywords, OpenAiTransform};
129pub use providers::openai_tts::{OpenAiTts, OpenAiTtsConfig};
130pub use providers::pexels::PexelsSearch;
131pub use providers::stock_planner::StockMediaPlanner;
132
133#[cfg(feature = "pg-cache")]
134pub use providers::pg_cache::PgCache;
135
136// ── Re-exports: builder + pipeline ──
137
138pub use config::PipelineBuilder;
139pub use pipeline::ContentPipeline;