Documentation
¶
Overview ¶
Package media provides a pipeline for downloading videos from social platforms, extracting audio, and transcribing speech.
Index ¶
- Constants
- func DownloadFile(ctx context.Context, client HTTPDoer, url, destPath string, maxSize int64) error
- func ExtractAudioChunk(ctx context.Context, videoPath, outputPath string, offsetSec, durationSec int) error
- func ExtractVideoClip(ctx context.Context, videoPath, outputPath string, startSec, endSec float64) error
- func MergeAudioVideo(ctx context.Context, videoPath, audioPath, outputPath string) error
- func ProbeDuration(ctx context.Context, path string) (int, error)
- type BudgetAwareExtractor
- type Chunk
- type Extractor
- type HTTPDoer
- type Media
- type MediaStats
- type Options
- type Processor
- type ProcessorOption
- type Quality
- type Registry
- func (r *Registry) Extract(ctx context.Context, url string) (*Media, error)
- func (r *Registry) ExtractWithBudget(ctx context.Context, url string, maxSize int64) (*Media, error)
- func (r *Registry) Match(url string) Extractor
- func (r *Registry) Platforms() []string
- func (r *Registry) Register(e Extractor)
- type Result
- type Slide
- type SlideError
- type SlideResult
- type SlideType
- type Transcriber
- type Transcription
- type VideoClip
Constants ¶
const ( // DefaultDownloadTimeout is the maximum time for downloading a video file. DefaultDownloadTimeout = 120 * time.Second // DefaultFFmpegTimeout is the maximum time for an ffmpeg operation. DefaultFFmpegTimeout = 60 * time.Second // DefaultProbeTimeout is the maximum time for ffprobe duration check. DefaultProbeTimeout = 10 * time.Second // DefaultChunkSec is the default audio chunk duration in seconds for transcription. DefaultChunkSec = 20 // DefaultClipPaddingSec is the default padding applied to video clips // before and after transcription chunk boundaries, to avoid cutting mid-word. DefaultClipPaddingSec = 0.5 // DefaultFadeDurationSec is the audio fade duration at clip boundaries // to prevent clicks/pops from non-zero-crossing cuts. DefaultFadeDurationSec = 0.03 )
Default configuration values for the media processing pipeline.
Variables ¶
This section is empty.
Functions ¶
func DownloadFile ¶
DownloadFile downloads a URL to a local file with timeout and size limit.
func ExtractAudioChunk ¶
func ExtractAudioChunk(ctx context.Context, videoPath, outputPath string, offsetSec, durationSec int) error
ExtractAudioChunk extracts a WAV audio chunk from a video file using ffmpeg. Output is 16kHz mono PCM suitable for Whisper.
func ExtractVideoClip ¶ added in v0.3.2
func ExtractVideoClip(ctx context.Context, videoPath, outputPath string, startSec, endSec float64) error
ExtractVideoClip extracts a video segment from startSec to endSec using ffmpeg. Video stream is copied (-c:v copy) for fast, lossless extraction. Audio gets a short fade-in/fade-out to prevent clicks at cut boundaries. The -ss flag is placed before -i for fast keyframe-level seeking.
func MergeAudioVideo ¶
MergeAudioVideo combines a video-only and audio-only file into a single MP4 using ffmpeg. Used for DASH streams where video and audio are separate.
Types ¶
type BudgetAwareExtractor ¶ added in v0.3.5
type BudgetAwareExtractor interface {
ExtractWithBudget(ctx context.Context, url string, maxSize int64) (*Media, error)
}
BudgetAwareExtractor is an optional capability implemented by extractors that can pick a quality representation fitting a byte budget (e.g. choosing a DASH representation, or passing --max-filesize to yt-dlp). The Registry routes to ExtractWithBudget when the extractor implements it; otherwise it falls back to Extract and the budget is enforced later by DownloadFile. maxSize == 0 means no limit.
type Chunk ¶
type Chunk struct {
Start float64 // segment start time in seconds
End float64 // segment end time in seconds
Text string // transcribed text for this segment
}
Chunk represents a single transcribed audio segment.
type Extractor ¶
type Extractor interface {
// Name returns the platform name (e.g. "instagram", "youtube").
Name() string
// Match returns true if the URL belongs to this platform.
Match(url string) bool
// Extract fetches media metadata including the direct video URL.
Extract(ctx context.Context, url string) (*Media, error)
}
Extractor fetches media metadata from a platform-specific URL.
type Media ¶
type Media struct {
Platform string // platform name: "instagram", "youtube", etc.
URL string // original input URL
VideoURL string // direct video CDN URL
AudioURL string // separate audio URL (for DASH merge)
LocalPath string // path to already-downloaded file (skips download)
Title string // post/video title
Description string // post caption or video description
Author string // author display name or @username
Duration time.Duration // video duration (zero if unknown)
Qualities []Quality // available quality options
Stats MediaStats // engagement stats (likes, views, etc.)
Metadata map[string]string // platform-specific key-value pairs
// Slides is the ordered, per-slide view of a carousel (or a single photo
// post). Empty for a single video, which uses VideoURL/AudioURL above so
// the single-video pipeline (transcription, DASH mux, clips) is unchanged.
// Each Slide carries the CDN URL chosen for that slide by the extractor's
// rendition selection (best candidate per slide — the same H.264-only DASH
// rule as a single video for video slides, highest-resolution candidate for
// photo slides). The processor downloads every slide and reports the local
// paths in Result.Slides, in the same order.
Slides []Slide
}
Media represents extracted metadata and download information for a video.
type MediaStats ¶
type MediaStats struct {
Views int64 // view/play count
Likes int64 // like/heart count
Comments int64 // comment/reply count
}
MediaStats holds engagement metrics for a media post.
type Options ¶
type Options struct {
// MaxSize bounds a single downloaded file in bytes (0 = no limit). For a
// single video it caps the video (and the separate DASH audio stream). For
// a carousel / photo post it bounds EACH slide independently — an album of
// N slides is checked N times, once per slide; the whole-album total is
// NOT checked. A per-slide cap matches the existing per-file DownloadFile
// guard and the DASH per-representation budget; a whole-album sum would
// require downloading every slide first, which the streaming download
// cannot do mid-flight.
MaxSize int64
ChunkSec int // audio chunk duration for transcription (default 20)
TempDir string // directory for temporary files (default os.TempDir())
ExtractClips bool // if true, extract video clips for each transcription chunk
ClipPaddingSec float64 // seconds to extend clips before/after chunk boundaries (default 0.5)
}
Options configures a single Process call.
type Processor ¶
type Processor struct {
// contains filtered or unexported fields
}
Processor orchestrates the full media pipeline: extract → download → transcribe.
func NewProcessor ¶
func NewProcessor(opts ...ProcessorOption) *Processor
NewProcessor creates a Processor with the given options.
type ProcessorOption ¶
type ProcessorOption func(*Processor)
ProcessorOption configures a Processor.
func WithExtractor ¶
func WithExtractor(e Extractor) ProcessorOption
WithExtractor registers a platform extractor.
func WithHTTPClient ¶
func WithHTTPClient(doer HTTPDoer) ProcessorOption
WithHTTPClient sets a custom HTTP client for video downloads.
func WithTranscriber ¶
func WithTranscriber(t Transcriber) ProcessorOption
WithTranscriber sets the transcription backend.
type Quality ¶
type Quality struct {
Label string // human label: "1080p", "720p", "360p"
URL string // direct download URL for this quality
Width int // pixels, 0 if unknown
Height int // pixels, 0 if unknown
Size int64 // estimated bytes, 0 if unknown
}
Quality represents a single video quality variant.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry holds registered extractors and dispatches URLs to the matching one.
func (*Registry) ExtractWithBudget ¶ added in v0.3.5
func (r *Registry) ExtractWithBudget(ctx context.Context, url string, maxSize int64) (*Media, error)
ExtractWithBudget is like Extract but threads a byte budget into extractors that implement BudgetAwareExtractor. Plain extractors fall back to Extract (the budget is still enforced later by DownloadFile for URL-based downloads).
func (*Registry) Match ¶
Match finds the first extractor that matches the given URL. Returns nil if no extractor matches.
type Result ¶
type Result struct {
Media *Media // extracted media metadata
VideoPath string // path to downloaded video file (single-video path)
Transcription *Transcription // transcription result (nil if not requested or no speech)
VideoClips []VideoClip // extracted video clips (nil if ExtractClips option not set)
// Slides is the per-slide download outcome for a carousel / photo post,
// in slide order. It always has one entry per expected slide (len ==
// len(Media.Slides)); a failed slide has an empty Path and a non-nil Err.
// Empty for the single-video path, which uses VideoPath above. When any
// slide fails, Process returns this Result together with a *SlideError so
// the caller can detect partial success without ranging the slice.
Slides []SlideResult
}
Result is the output of a full processing pipeline.
type Slide ¶ added in v0.3.8
type Slide struct {
Type SlideType
URL string // chosen CDN URL for this slide
AudioURL string // separate audio URL (DASH video slides only)
Width int
Height int
}
Slide is one ordered item of a carousel (or a single photo post), carrying the CDN URL chosen for it by the extractor. For a video slide that went through DASH, AudioURL carries the separate audio stream URL (the processor muxes it); empty for photo slides and for video slides that fell back to a self-contained video_versions rendition.
type SlideError ¶ added in v0.3.8
SlideError reports that one or more carousel slides failed to download while the post as a whole was extracted. It is returned by Process together with a partial Result (whose Slides slice carries the per-slide detail). Expected is the total slide count; Succeeded is how many downloaded; Failed lists the 0-based indices that did not. A caller can distinguish a total slide failure (Succeeded == 0) from a partial one (Succeeded > 0) without ranging Result.Slides, and can read each failure's cause from Result.Slides[i].Err.
func (*SlideError) Error ¶ added in v0.3.8
func (e *SlideError) Error() string
type SlideResult ¶ added in v0.3.8
type SlideResult struct {
Index int // slide position in the album (0-based, matches Media.Slides order)
Type SlideType
Path string // local file path; empty if this slide failed to download
Err error // non-nil if this slide failed; nil on success
}
SlideResult is the download outcome for one carousel slide.
type SlideType ¶ added in v0.3.8
type SlideType int
SlideType is the per-slide media kind of a carousel slide.
type Transcriber ¶
type Transcriber interface {
// Transcribe processes an audio file and returns the transcription.
// audioPath must be a valid file path to a WAV/MP3/OGG file.
Transcribe(ctx context.Context, audioPath string) (*Transcription, error)
// Available reports whether the transcription backend is reachable.
Available() bool
}
Transcriber converts an audio file to text.
type Transcription ¶
type Transcription struct {
Text string // full concatenated text
Language string // detected language code (e.g. "en", "ru")
Duration float64 // audio duration in seconds
Chunks []Chunk // per-segment results with timestamps
FailedChunks int // number of chunks that failed extraction or transcription
}
Transcription holds the result of speech-to-text processing.
func ChunkAndTranscribe ¶
func ChunkAndTranscribe(ctx context.Context, videoPath, tempDir string, t Transcriber, opts Options) (*Transcription, error)
ChunkAndTranscribe splits audio into chunks and transcribes each one. Returns (nil, nil) if transcriber is nil (opt-out). Returns (nil, error) if the transcriber is unavailable or ffprobe fails. Returns (partial, error) if some chunks failed — the partial result contains the successfully transcribed text and FailedChunks is set.
type VideoClip ¶ added in v0.3.2
type VideoClip struct {
Path string // path to the extracted clip file
Start float64 // clip start time in seconds
End float64 // clip end time in seconds
Text string // transcription text for this clip
}
VideoClip is a short video segment extracted from the downloaded video, corresponding to a transcription chunk. The caller is responsible for cleaning up the clip files (Path) after use.
func ExtractVideoClipsFromChunks ¶ added in v0.3.2
func ExtractVideoClipsFromChunks(ctx context.Context, videoPath, tempDir string, chunks []Chunk, paddingSec, totalDuration float64) ([]VideoClip, int)
ExtractVideoClipsFromChunks extracts video clips for each transcription chunk. Clips are named "<base>_clip_<index>.mp4" in tempDir. Chunks with empty text are skipped. Each clip is extended by paddingSec before and after the chunk boundary (clamped to [0, totalDuration]) to avoid cutting mid-word. Returns the extracted clips and a count of failures.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
extract
|
|
|
dash
Package dash parses MPEG-DASH MPD manifests into video/audio representations and selects a representation pair that fits a byte budget.
|
Package dash parses MPEG-DASH MPD manifests into video/audio representations and selects a representation pair that fits a byte budget. |
|
instagram
Package instagram extracts video metadata from Instagram and Threads URLs using the go-threads client library.
|
Package instagram extracts video metadata from Instagram and Threads URLs using the go-threads client library. |
|
youtube
Package youtube extracts video metadata from YouTube URLs using a tiered backend approach: API → yt-dlp → ox-browser.
|
Package youtube extracts video metadata from YouTube URLs using a tiered backend approach: API → yt-dlp → ox-browser. |
|
transcribe
|
|
|
gostt
Package gostt provides a Transcriber that wraps the go-stt client library.
|
Package gostt provides a Transcriber that wraps the go-stt client library. |