go-ytdlp

repository·master·Indexed 43 days ago

https://github.com/lrstanley/go-ytdlp

A Go wrapper for yt-dlp providing type-safe CLI bindings, automatic binary management for yt-dlp, ffmpeg, ffprobe, and bun, and tools for bidirectional conversion between JSON and yt-dlp flags via FlagConfig.

Tokens
9K
Snippets
35
Records
53
Agent score
54%

What's inside go-ytdlp

  1. Convert between JSON and yt-dlp flags using FlagConfig

    master

    The FlagConfig type allows for bidirectional conversion between JSON and yt-dlp command-line flags. This is ideal for HTTP APIs, web UIs, or persisting configurations in a database.

    Key Features

    • Bidirectional Conversion: Use Command.SetFlagConfig to apply a JSON configuration to a command, and Command.GetFlagConfig to extract the current flags into JSON.
    • Compatible Decoding: When loading older or client-supplied configurations, use FlagConfig.UnmarshalJSONWithWarnings. This allows you to retain valid flags even if some members are unknown or incompatible. Always review the returned warnings.
    • Validation: Use the provided validation functions and the JSON schema (available via optiondata.JSONSchema) to ensure correctness. The JSON body allows duplicate flags unless validated against the schema.
    • Persistence Warning: yt-dlp flags can change or be removed during updates. When loading from storage, use compatibility decoding and handle warnings before validating. If validation fails, clear invalid values using the error types ErrMultipleJSONParsingFlags or ErrJSONParsingFlag (which provide the JSON path to the error).
  2. Basic usage of go-ytdlp

    master

    You can use go-ytdlp by creating a new command instance via ytdlp.New() and using a builder pattern to configure flags. Before running, it is recommended to use ytdlp.MustInstall to ensure the yt-dlp binary is available on your system.

    Key methods used in the example:

    • ytdlp.MustInstall(ctx, nil): Downloads and caches the yt-dlp binary.
    • ytdlp.New(): Initializes a new command builder.
    • .FormatSort(string): Sets the format sorting flag.
    • .RecodeVideo(string): Sets the video recoding format.
    • .Output(string): Sets the output template.
    • .Run(ctx, url): Executes the command for the provided URL.
    package main
    
    import (
    	"context"
    
    	"github.com/lrstanley/go-ytdlp"
    )
    
    func main() {
    	// If yt-dlp isn't installed yet, download and cache it for further use.
    	ytdlp.MustInstall(context.TODO(), nil)
    
    	dl := ytdlp.New().
    		FormatSort("res,ext:mp4:m4a").
    		RecodeVideo("mp4").
    		Output("%(extractor)s - %(title)s.%(ext)s")
    
    	_, err := dl.Run(context.TODO(), "https://www.youtube.com/watch?v=dQw4w9WgXcQ")
    	if err != nil {
    		panic(err)
    	}
    }
  3. Manage binaries with Install functions

    master

    The Install* helper functions allow you to automatically download and cache required binaries (yt-dlp, ffmpeg, ffprobe, and bun) for your platform. This ensures the correct versions are used without manual installation.

    Supported Platforms for Automatic Download:

    • yt-dlp: Supported on darwin_amd64, darwin_arm64, linux_amd64, linux_arm64, linux_armv7l, and windows_amd64.
    • ffmpeg & ffprobe: Supported on darwin_amd64, darwin_arm64, linux_amd64, linux_arm64, windows_amd64, and windows_arm.
    • bun: Supported on darwin_amd64, darwin_arm64, linux_amd64, linux_arm64, and windows_amd64.

    Note on JavaScript Runtimes: When using [Must]InstallAll or [Must]InstallBun, the library automatically enables Bun by default and explicitly disables other runtimes. While yt-dlp supports multiple runtimes (like Deno), Deno is not automatically installed because it does not yet support musl-based Linux distributions (e.g., Alpine).

  4. Understand the ExtractedInfo structure

    master

    The ExtractedInfo struct is the primary container for metadata extracted from a video or playlist. It is a highly nested structure that includes:

    • Core Identity: ID, Title, URL, WebpageURL, Description, Tags, Categories.
    • Media Formats: Formats (all available qualities) and RequestedFormats. Each format is an ExtractedFormat containing URL, Resolution, Bitrate, Codec info, etc.
    • Uploader/Channel Info: Uploader, Channel, ChannelID, ChannelURL.
    • Temporal Data: Timestamp, UploadDate, Duration.
    • Playlist Data: If the type is a playlist, it includes Entries (a slice of *ExtractedInfo), PlaylistTitle, PlaylistCount, etc.
    • Series/Track Data: Fields for Series, Season, Episode, Track, Album, Artist.
    • Live Status: IsLive, WasLive, and LiveStatus (e.g., is_live, is_upcoming).
    • Subtitles/Captions: Subtitles and AutomaticCaptions maps keyed by language code.
  5. Configure yt-dlp installation with InstallOptions

    master

    You can pass an InstallOptions struct to Install to customize the download and resolution behavior.

    opts := &ytdlp.InstallOptions{
    	DisableDownload:      false, // Set to true to prevent any downloading
    	DisableChecksum:      false, // Set to true to skip SHA2-256 verification
    	DisableSystem:        false, // Set to true to ignore yt-dlp found in system PATH
    	AllowVersionMismatch: false, // Set to true to use any found version instead of downloading the specific version
    	DownloadURL:           "",   // Provide a specific URL if you don't want to use GitHub releases
    }
    
    resolved, err := ytdlp.Install(ctx, opts)
  6. Configure InstallBunOptions

    master

    The InstallBunOptions struct allows you to control how the Bun binary is located or acquired:

    FieldTypeDescription
    DisableDownloadboolIf true, the function will not attempt to download Bun if it is not found in the system or cache.
    DisableSystemboolIf true, the function will not look for an existing Bun binary in the system PATH.
    DownloadURLstringAn exact URL to the binary location. If left empty, the library automatically selects the correct GitHub or Evermeet.cx URL based on the detected OS and architecture.
    type InstallBunOptions struct {
    	DisableDownload bool
    	DisableSystem   bool
    	DownloadURL     string
    }
  7. Configure InstallFFmpegOptions

    master

    The InstallFFmpegOptions struct allows you to control how the dependency is resolved:

    • DisableDownload (bool): If true, the function will never attempt to download a binary. It will only return a binary if it is already found in the system PATH.
    • DisableSystem (bool): If true, the function will ignore binaries found in the system PATH and will only attempt to use a downloaded version from the cache.
    • DownloadURL (string): Provides a specific URL to download the binary from. If left empty, the library uses default URLs based on the detected OS and architecture (e.g., GitHub for Linux/Windows, evermeet.cx for macOS).
  8. Resolve validation conflicts with Repair

    master

    The Repair method identifies validation conflicts using Validate() and converts them into warnings. When a conflict is found, Repair unsets the offending field(s) using their id tag.

    Note that Validate reports errors using a JSONPath format of <group>.<id>. To resolve these conflicts, you should use UnsetByID rather than attempting to delete keys from a JSON map.

  9. Install Bun programmatically with InstallBun

    master

    Use InstallBun to ensure the Bun runtime is available on the current platform. The function follows this priority:

    1. Checks if Bun is already resolved in the internal cache.
    2. Attempts to find an existing Bun binary in the system PATH (unless DisableSystem is set to true).
    3. If not found and DisableDownload is false, it downloads the appropriate Bun archive for the current OS/architecture and extracts it to a cache directory.

    Returns a *ResolvedInstall pointer containing the path to the executable and metadata about its origin.

    import (
    	"context"
    	"github.com/lrstanley/lrstanley/go-ytdlp"
    )
    
    func main() {
    	ctx := context.Background()
    	opts := &ytdlp.InstallBunOptions{
    		DisableSystem: false,
    		DisableDownload: false,
    	}
    
    	resolved, err := ytdlp.InstallBun(ctx, opts)
    	if err != nil {
    		// handle error
    	}
    
    	// Use resolved.Executable to run bun commands
    	fmt.Printf("Bun version: %s, Path: %s\n", resolved.Version, resolved.Executable)
    }
  10. Merge two JSON byte slices with OverlayFlagConfig

    master

    OverlayFlagConfig(base, overlay []byte) is a convenience function that automates the full lifecycle of merging two JSON configurations. It performs the following steps:

    1. Decodes and repairs the base JSON.
    2. Decodes and repairs the overlay JSON.
    3. Merges the two resulting FlagConfig objects.
    4. Repairs the final merged configuration to ensure no new conflicts were introduced.

    It returns the merged *FlagConfig, a slice of all FlagWarning encountered during the entire process, and any hard error encountered during parsing.

    ```go
    // Example usage of OverlayFlagConfig
    baseJSON := []byte(`{
  11. Run a command using previously extracted info with RunWithInfo

    master

    To avoid re-extracting metadata from a website (which saves time and bandwidth), use RunWithInfo. This method writes the provided []*ExtractedInfo to yt-dlp via --load-info-json - (stdin). This method operates on a clone of the command and does not modify the original.

    // info was obtained via ExtractInfo
    result, err := cmd.RunWithInfo(ctx, info)