Skip to content

phayes/tidalrs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Tidalrs

A comprehensive Rust client library for the Tidal music streaming service API. This library provides async/await support, automatic token refresh, and a clean, type-safe interface for interacting with Tidal's music catalog and user data.

Features

  • Complete Music API: Access tracks, albums, artists, and playlists
  • Audio Streaming: Stream tracks in various quality levels via DASH-MPEG
  • Advanced Search: Search across all content types with filtering
  • User Management: Manage favorites, playlists, and user data
  • OAuth2 Authentication: Device flow authentication with automatic token refresh
  • Async/Await: Built on Tokio for high-performance async operations
  • Type Safety: Comprehensive type definitions for all Tidal API responses
  • Cross-Platform: Works on all platforms supported by Rust

Quick Start

Add this to your Cargo.toml:

[dependencies]
tidalrs = "0.4.1"
tokio = { version = "1.0", features = ["full"] }

Basic Usage

use tidalrs::{TidalClient, Authz};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a client with your Tidal client ID
    let mut client = TidalClient::new("your_client_id".to_string());
    
    // Authenticate using device flow
    let device_auth = client.device_authorization().await?;
    println!("Visit: {}", device_auth.url);
    println!("Enter code: {}", device_auth.user_code);
    
    // After user authorizes, complete the flow
    let authz_token = client.authorize(&device_auth.device_code, "your_client_secret").await?;
    
    // Now you can use the authenticated client
    let track = client.track(123456789).await?;
    println!("Track: {} by {}", track.title, track.artists[0].name);

    // Play the track
    let track_stream = client.track_stream(123456789, AudioQuality::Lossless).await?;
    let music_bytes_stream = track_stream.stream().await?;
    
    Ok(())
}

Using Existing Authentication

If you already have authentication tokens:

use tidalrs::{TidalClient, Authz};

let authz = Authz::new(
    "access_token".to_string(),
    "refresh_token".to_string(),
    user_id,
    Some("US".to_string()),
);

let client = TidalClient::new("your_client_id".to_string())
    .with_authz(authz);

API Overview

Authentication

The library supports Tidal's OAuth2 device flow authentication:

// Start device authorization
let device_auth = client.device_authorization().await?;

// User visits the URL and enters the code
println!("Visit: {}", device_auth.url);
println!("Code: {}", device_auth.user_code);

// Complete authorization
let authz_token = client.authorize(&device_auth.device_code, client_secret).await?;

Searching

Search across all content types:

use tidalrs::{SearchQuery, ResourceType};

let mut query = SearchQuery::new("Radiohead");
query.limit = Some(10);
query.search_types = Some(vec![ResourceType::Artist, ResourceType::Album]);

let results = client.search(query).await?;

for artist in results.artists.items {
    println!("Artist: {}", artist.name);
}

for album in results.albums.items {
    println!("Album: {}", album.title);
}

Tracks

Get track information and stream audio:

// Get track details
let track = client.track(123456789).await?;
println!("{} - {}", track.title, track.artists[0].name);

// Get streaming URL
let stream = client.track_stream(123456789, AudioQuality::Lossless).await?;
let audio_stream = stream.stream().await?;

// Add to favorites
client.add_favorite_track(123456789).await?;

Albums

Work with albums and their tracks:

// Get album information
let album = client.album(987654321).await?;
println!("Album: {}", album.title);

// Get album tracks
let tracks = client.album_tracks(987654321, Some(0), Some(50)).await?;
for track in tracks.items {
    println!("Track {}: {}", track.track_number, track.title);
}

// Add album to favorites
client.add_favorite_album(987654321).await?;

Artists

Explore artist information and their albums:

// Get artist details
let artist = client.artist(456789123).await?;
println!("Artist: {}", artist.name);

// Get artist's albums
let albums = client.artist_albums(456789123, Some(0), Some(20), None).await?;
for album in albums.items {
    println!("Album: {}", album.title);
}

Playlists

Manage playlists and their contents:

// Create a new playlist
let playlist = client.create_playlist("My Playlist", "A great playlist").await?;
println!("Created playlist: {}", playlist.title);

// Add tracks to playlist
let track_ids = vec![123456789, 987654321];
client.add_tracks_to_playlist(&playlist.uuid, &playlist.etag.unwrap(), track_ids, false).await?;

// Get playlist tracks
let tracks = client.playlist_tracks(&playlist.uuid, Some(0), Some(100)).await?;
for track in tracks.items {
    println!("Track: {}", track.title);
}

// Remove a track from playlist
client.remove_track_from_playlist(&playlist.uuid, &playlist.etag.unwrap(), 123456789).await?;

User Favorites

Manage user's favorite content:

// Get favorite tracks
let favorite_tracks = client.favorite_tracks(Some(0), Some(50), None, None).await?;
for fav_track in favorite_tracks.items {
    println!("Favorite: {}", fav_track.item.title);
}

// Get favorite albums
let favorite_albums = client.favorite_albums(Some(0), Some(20), None, None).await?;
for fav_album in favorite_albums.items {
    println!("Favorite album: {}", fav_album.item.title);
}

// Get favorite artists
let favorite_artists = client.favorite_artists(Some(0), Some(20), None, None).await?;
for fav_artist in favorite_artists.items {
    println!("Favorite artist: {}", fav_artist.name);
}

Audio Quality

The library supports all Tidal audio quality levels:

use tidalrs::AudioQuality;

// Available quality levels:
// - AudioQuality::Low
// - AudioQuality::High  
// - AudioQuality::Lossless
// - AudioQuality::HiResLossless

let stream = client.track_stream(track_id, AudioQuality::Lossless).await?;

Configuration

Configure the client for different regions and locales:

let client = TidalClient::new("client_id".to_string())
    .with_country_code("GB".to_string())  // United Kingdom
    .with_locale("en_GB".to_string())     // British English
    .with_device_type(DeviceType::Browser);

Token Refresh

The client automatically handles token refresh, but you can also set up callbacks:

use std::sync::Arc;

let client = TidalClient::new("client_id".to_string())
    .with_authz_refresh_callback(Arc::new(|new_authz| {
        println!("Tokens refreshed for user: {}", new_authz.user_id);
        // Save the new tokens to persistent storage
    }));

Examples

Check the examples/ directory for complete working examples:

  • basic_search.rs - Simple search functionality
  • playlist_management.rs - Creating and managing playlists
  • audio_streaming.rs - Streaming and playing audio
  • favorites_management.rs - Managing user favorites

Requirements

  • Rust 1.70+
  • Tokio runtime
  • Valid Tidal API client credentials

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Disclaimer

This library is not officially affiliated with Tidal. Use at your own risk and ensure compliance with Tidal's Terms of Service.

About

Rust Tidal Client Libary

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages