No description
Find a file
Jirodi Schmidt 1327aef2f6
Some checks failed
Release builds / Build linux-amd64 (release) Failing after 1s
Release builds / Build linux-arm64 (release) Failing after 2s
fix: callback sp streammultipliar inconsistency
2025-09-19 10:06:35 -06:00
.github/workflows fix: workflows runs-on 2025-09-12 11:47:21 -06:00
cmd/gozs fix: album contributors discrepancy 2025-09-14 12:34:19 -06:00
dz feat: playlist range setting 2025-09-19 07:13:53 -06:00
sp fix: callback sp streammultipliar inconsistency 2025-09-19 10:06:35 -06:00
spdz feat: playlist range setting 2025-09-19 07:13:53 -06:00
structs feat: playlist range setting 2025-09-19 07:13:53 -06:00
utils feat: playlist range setting 2025-09-19 07:13:53 -06:00
.gitignore chore: gitignore 2025-09-12 10:50:44 -06:00
go.mod chore: bump librespot 2025-09-14 07:22:10 -06:00
go.sum chore: bump librespot 2025-09-14 07:22:19 -06:00
README.md feat: implement track and disc number padding 2025-09-07 22:35:17 -06:00
README_CLI.md feat: update cli to match new features 2025-09-12 11:29:18 -06:00

gozs - Music Downloader Library

A comprehensive Go library for downloading music from Spotify and Deezer with cross-platform metadata matching, automatic tagging, and format conversion capabilities.

Features

🎵 Multi-Platform Support

  • Spotify Integration: Download from Spotify using librespot
  • Deezer Integration: Download from Deezer with decryption support
  • Cross-Platform Matching: Find equivalents between platforms using ISRC, title/artist matching

📁 Content Types

  • Individual tracks
  • Full albums
  • Playlists
  • Batch operations for multiple items

🎚️ Quality & Formats

Spotify:

  • OGG 96kbps, 160kbps, 320kbps

Deezer:

  • MP3 128kbps, 320kbps (premium)
  • FLAC (premium)

Format Conversion:

  • Convert to MP3, FLAC, AAC, WAV, M4A, OGG
  • Custom bitrate settings
  • FFmpeg integration

🏷️ Metadata & Tagging

  • Automatic metadata tagging using go-taglib
  • Support for all major metadata fields
  • Customizable artist separators
  • Cover art embedding

📝 Lyrics Integration

  • Automatic lyrics fetching from lrclib.net
  • Synced and plain lyrics support
  • Instrumental track detection
  • Cached lyrics for faster subsequent downloads

📂 File Organization

  • Customizable directory patterns: {{album_artist}}/{{album}}
  • Customizable filename patterns: {{tracknum}}. {{track}} - {{artist}}
  • Track number padding
  • Flexible template system

Performance & Control

  • Configurable download delays
  • Stream multiplier for rate control
  • Context-based cancellation
  • Concurrent batch operations

Installation

go get lavaforge.org/bert/gozs

Quick Start

Basic Deezer Download

package main

import (
    "context"
    "gozs/dz"
    "gozs/structs/downloads"
)

func main() {
    ctx := context.Background()
    
    settings := downloads.DownloadSettings{
        ARL:         "your_arl_cookie_here",
        OutputDir:   "./downloads",
        Quality:     downloads.FLACQuality,
        DirPattern:  "{{album_artist}}/{{album}}",
        FilePattern: "{{tracknum}}. {{track}} - {{artist}}",
        FetchLyrics: true,
    }
    
    // Create Deezer client
    client, err := dz.NewClient(ctx, settings)
    if err != nil {
        panic(err)
    }
    
    // Download a track
    err = client.DownloadTrack(ctx, "track_id_or_url", settings)
    if err != nil {
        panic(err)
    }
}

Basic Spotify Download

package main

import (
    "context"
    "gozs/sp"
    "gozs/structs/downloads"
)

func main() {
    ctx := context.Background()
    
    settings := downloads.DownloadSettings{
        Credentials:     "./credentials.json",
        OutputDir:       "./downloads",
        Quality:         downloads.OGG320Quality,
        StreamMultiplier: 2.0, // 2x speed
        FetchLyrics:     true,
    }
    
    // Create Spotify metadata fetcher
    fetcher, err := sp.NewSPMetadataFetcher(settings)
    if err != nil {
        panic(err)
    }
    defer fetcher.Close()
    
    // Create downloader
    downloader, err := fetcher.NewDownloader()
    if err != nil {
        panic(err)
    }
    defer downloader.Close()
    
    // Download a track
    result, err := downloader.DownloadTrack(ctx, "spotify_track_id", settings)
    if err != nil {
        panic(err)
    }
    
    fmt.Printf("Downloaded: %s\n", result.FilePath)
}

Cross-Platform Download (Spotify → Deezer)

package main

import (
    "context"
    "gozs/dz"
    "gozs/sp"
    "gozs/structs/downloads"
)

func main() {
    ctx := context.Background()
    
    settings := downloads.DownloadSettings{
        ARL:             "your_arl_cookie",
        Credentials:     "./credentials.json",
        OutputDir:       "./downloads",
        Quality:         downloads.FLACQuality,
        SpotifyMetadata: true, // Use Spotify metadata when downloading from Deezer
        FetchLyrics:     true,
    }
    
    // Initialize both clients
    dzClient, _ := dz.NewClient(ctx, settings)
    spFetcher, _ := sp.NewSPMetadataFetcher(settings)
    defer spFetcher.Close()
    
    // Create cross-platform downloader
    dzFetcher := dz.NewDZMetadataFetcher()
    matcher := dz.NewSpotifyToDeezerMatcher(dzFetcher)
    downloader := dz.NewSpotifyToDeezerDownloader(matcher, dzClient)
    
    // Download Spotify content via Deezer
    spTrack, _ := spFetcher.FetchTrackMetadata(ctx, "spotify_track_id", nil)
    err := downloader.DownloadSpotifyTrack(ctx, spTrack, settings)
}

Configuration

DownloadSettings

type DownloadSettings struct {
    // Authentication
    ARL         string // Deezer ARL cookie
    Credentials string // Path to Spotify credentials.json
    
    // Output
    OutputDir string // Base download directory
    TempDir   string // Temporary files directory
    
    // Quality & Format
    Quality           Quality         // Source quality
    ConvertToQuality  ConvertToQuality // Target format
    ConvertToBitrate  int             // Target bitrate
    
    // Organization
    DirPattern  string // Directory template
    FilePattern string // Filename template
    
    // Features
    FetchLyrics      bool    // Enable lyrics fetching
    SpotifyMetadata  bool    // Use Spotify metadata for Deezer downloads
    ArtistSeparator  string  // Artist separator (default: " feat. ")
    StreamMultiplier float64 // Download speed multiplier
    
    // Control
    DelayMultiplier int // Delay between downloads
    PadTrackNumber  bool // Zero-pad track numbers
    TrackNumberPadding int // Track number padding width
}

Template Variables

Directory Patterns:

  • {{album_artist}} - Primary album artist
  • {{album}} - Album title
  • {{artist}} - Primary artist

Filename Patterns:

  • {{tracknum}} - Track number
  • {{track}} - Track title
  • {{artist}} - Primary artist
  • {{album}} - Album title
  • {{album_artist}} - Primary album artist

Quality Options

Spotify:

downloads.OGG96Quality   // 96kbps OGG
downloads.OGG160Quality  // 160kbps OGG  
downloads.OGG320Quality  // 320kbps OGG

Deezer:

downloads.MP3128Quality  // 128kbps MP3
downloads.MP3320Quality  // 320kbps MP3 (premium)
downloads.FLACQuality    // FLAC (premium)

Advanced Usage

Batch Operations

// Download multiple tracks
trackIDs := []string{"id1", "id2", "id3"}
results, err := downloader.DownloadTracks(ctx, trackIDs, settings)

// Download entire album
err = client.DownloadAlbum(ctx, "album_id", settings)

// Download playlist
err = client.DownloadPlaylist(ctx, "playlist_id", settings)

Metadata Management

// Create custom metadata
metadata := &metadata.AudioMetadata{
    Title:    "Track Title",
    Artist:   "Artist Name",
    Album:    "Album Title",
    Year:     2024,
    Genre:    []string{"Rock", "Pop"},
    Lyrics:   "Lyrics content...",
}

// Tag existing file
tagger := utils.NewTagger()
result := tagger.TagFile("path/to/file.mp3", metadata, settings)

Lyrics Service

// Create lyrics service
lyricsService := utils.NewLyricsService()

// Fetch lyrics
result := lyricsService.GetLyrics("Track Name", "Artist", "Album", 180)
if result.Success {
    fmt.Println("Lyrics:", result.Lyrics)
}

// Fetch synced lyrics
if result.HasSyncedLyrics() {
    fmt.Println("Synced:", result.Synced)
}

Custom File Organization

settings := downloads.DownloadSettings{
    DirPattern:      "{{album_artist:1}}/{{album}} [{{year}}]",
    FilePattern:     "{{tracknum:3}}. {{track}}",
    ArtistSeparator: " & ",
    PadTrackNumber:  true,
    TrackNumberPadding: 2,
}

Authentication

Deezer

Requires ARL cookie from a logged-in Deezer session:

settings := downloads.DownloadSettings{
    ARL: "your_arl_cookie_here",
}

Spotify

Requires credentials.json file with credentials. See bert-auth for that.

Dependencies

  • go-taglib: Metadata tagging
  • librespot: Spotify integration
  • FFmpeg: Audio format conversion
  • lrclib.net: Lyrics service

License

This project is for educational purposes only. Please respect the terms of service of the platforms you download from.

Contributing

Contributions welcome! Please ensure code follows Go best practices and includes appropriate tests.