All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.adamratzman.spotify.models.Track.kt Maven / Gradle / Ivy

/* Spotify Web API, Kotlin Wrapper; MIT License, 2017-2022; Original author: Adam Ratzman */
package com.adamratzman.spotify.models

import com.adamratzman.spotify.SpotifyRestAction
import com.adamratzman.spotify.utils.Market
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

/**
 * Simplified Playlist object that can be used to retrieve a full [Playlist]
 *
 * @param artists The artists who performed the track. Each artist object includes a link in href to
 * more detailed information about the artist.
 * identified by their ISO 3166-1 alpha-2 code.
 * @param discNumber The disc number (usually 1 unless the album consists of more than one disc).
 * @param durationMs The track length in milliseconds.
 * @property length The track length in milliseconds. Alias of [durationMs]
 * @param explicit Whether or not the track has explicit lyrics ( true = yes it does; false = no it does not OR unknown).
 * @param href A link to the Web API endpoint providing full details of the track.
 * @param id The Spotify ID for the track.
 * @param isPlayable Part of the response when Track Relinking is applied. If true ,
 * the track is playable in the given market. Otherwise false.
 * @param name The name of the track.
 * @param previewUrl A URL to a 30 second preview (MP3 format) of the track.
 * @param trackNumber The number of the track. If an album has several discs, the track number
 * is the number on the specified disc.
 * @param type The object type: “track”.
 * @param isLocal Whether or not the track is from a local file.
 * @param popularity the popularity of this track. possibly null
 * @param restrictions Part of the response when Track Relinking is applied, the original track is not available in
 * the given market, and Spotify did not have any tracks to relink it with. The track response will still contain
 * metadata for the original track, and a restrictions object containing the reason why the track is not available:
 * "restrictions" : {"reason" : "market"}
 *
 * @property availableMarkets A list of the countries in which the track can be played.
 * @property externalIds External IDs for this track.
 */
@Serializable
public data class SimpleTrack(
    @SerialName("external_urls") override val externalUrlsString: Map,
    @SerialName("available_markets") private val availableMarketsString: List = listOf(),
    @SerialName("external_ids") private val externalIdsString: Map = hashMapOf(),
    override val href: String,
    override val id: String,
    override val uri: SpotifyUri,

    val artists: List,
    @SerialName("disc_number") val discNumber: Int,
    @SerialName("duration_ms") val durationMs: Int,
    val explicit: Boolean,
    @SerialName("is_playable") val isPlayable: Boolean = true,
    @SerialName("linked_from") override val linkedTrack: LinkedTrack? = null,
    val name: String,
    @SerialName("preview_url") val previewUrl: String? = null,
    @SerialName("track_number") val trackNumber: Int,
    val type: String,
    @SerialName("is_local") val isLocal: Boolean? = null,
    val popularity: Double? = null,
    val restrictions: Restrictions? = null
) : RelinkingAvailableResponse() {
    val availableMarkets: List get() = availableMarketsString.map { Market.valueOf(it) }

    val externalIds: List get() = externalIdsString.map { ExternalId(it.key, it.value) }

    val length: Int get() = durationMs

    /**
     * Converts this [SimpleTrack] into a full [Track] object with the given
     * market
     *
     * @param market Provide this parameter if you want the list of returned items to be relevant to a particular country.
     */
    public suspend fun toFullTrack(market: Market? = null): Track? = api.tracks.getTrack(id, market)

    /**
     * Converts this [SimpleTrack] into a full [Track] object with the given
     * market
     *
     * @param market Provide this parameter if you want the list of returned items to be relevant to a particular country.
     */
    public fun toFullTrackRestAction(market: Market? = null): SpotifyRestAction =
        SpotifyRestAction { toFullTrack(market) }

    override fun getMembersThatNeedApiInstantiation(): List = artists + linkedTrack + this
}

/**
 * Represents a music track on Spotify
 *
 * @param album The album on which the track appears. The album object includes a link in
 * href to full information about the album.
 * @param artists The artists who performed the track. Each artist object includes a link in href
 * to more detailed information about the artist.
 * @param isPlayable Part of the response when Track Relinking is applied. If true , the track is playable in the
 * given market. Otherwise false.
 * @param discNumber The disc number (usually 1 unless the album consists of more than one disc).
 * @param durationMs The track length in milliseconds.
 * @property length The track length in milliseconds. Alias of [durationMs]
 * @param explicit Whether or not the track has explicit lyrics ( true = yes it does; false = no it does not OR unknown).
 * @param href A link to the Web API endpoint providing full details of the track.
 * @param id The Spotify ID for the track.
 * @param linkedTrack Part of the response when Track Relinking is applied and is only part of the response
 * if the track linking, in fact, exists. The requested track has been replaced with a different track. The track in
 * the [linkedTrack] object contains information about the originally requested track.
 * @param name The name of the track.
 * @param popularity The popularity of the track. The value will be between 0 and 100, with 100 being the most
 * popular. The popularity of a track is a value between 0 and 100, with 100 being the most popular. The popularity
 * is calculated by algorithm and is based, in the most part, on the total number of plays the track has had and how
 * recent those plays are. Generally speaking, songs that are being played a lot now will have a higher popularity
 * than songs that were played a lot in the past. Duplicate tracks (e.g. the same track from a single and an album)
 * are rated independently. Artist and album popularity is derived mathematically from track popularity. Note that
 * the popularity value may lag actual popularity by a few days: the value is not updated in real time.
 * @param previewUrl A link to a 30 second preview (MP3 format) of the track. Can be null
 * @param trackNumber The number of the track. If an album has several discs, the track number is the number on the specified disc.
 * @param type The object type: “track”.
 * @param isLocal Whether or not the track is from a local file.
 * @param restrictions Part of the response when Track Relinking is applied, the original track is not available in
 * the given market, and Spotify did not have any tracks to relink it with. The track response will still contain
 * metadata for the original track, and a restrictions object containing the reason why the track is not available:
 * "restrictions" : {"reason" : "market"}
 *
 * @property availableMarkets A list of the countries in which the track can be played, identified by their ISO 3166-1 alpha-2 code.
 * @property externalIds External IDs for this track.
 */
@Serializable
public data class Track(
    @SerialName("external_urls") override val externalUrlsString: Map,
    @SerialName("external_ids") private val externalIdsString: Map = hashMapOf(),
    @SerialName("available_markets") private val availableMarketsString: List = listOf(),
    override val href: String,
    override val id: String,
    override val uri: PlayableUri,

    val album: SimpleAlbum,
    val artists: List,
    @SerialName("is_playable") val isPlayable: Boolean = true,
    @SerialName("disc_number") val discNumber: Int,
    @SerialName("duration_ms") val durationMs: Int,
    val explicit: Boolean,
    @SerialName("linked_from") override val linkedTrack: LinkedTrack? = null,
    val name: String,
    val popularity: Double,
    @SerialName("preview_url") val previewUrl: String? = null,
    @SerialName("track_number") val trackNumber: Int,
    override val type: String,
    @SerialName("is_local") val isLocal: Boolean? = null,
    val restrictions: Restrictions? = null,

    val episode: Boolean? = null,
    val track: Boolean? = null
) : RelinkingAvailableResponse(), Playable {
    val availableMarkets: List get() = availableMarketsString.map { Market.valueOf(it) }

    val externalIds: List get() = externalIdsString.map { ExternalId(it.key, it.value) }

    val length: Int get() = durationMs

    override fun getMembersThatNeedApiInstantiation(): List = artists + album + linkedTrack + this
}

/**
 * Represents a [relinked track](https://github.com/adamint/spotify-web-api-kotlin#track-relinking). This is playable in the
 * searched market. If null, the API result is playable in the market.
 *
 * @param href A link to the Web API endpoint providing full details of the track.
 * @param id The Spotify ID for the track.
 * @param type The object type: “track”.
 */
@Serializable
public data class LinkedTrack(
    @SerialName("external_urls") override val externalUrlsString: Map,
    override val href: String,
    override val id: String,
    override val uri: PlayableUri,

    val type: String
) : CoreObject() {

    /**
     * Retrieves the full [Track] object associated with this [LinkedTrack] with the given market
     *
     * @param market Provide this parameter if you want the list of returned items to be relevant to a particular country.
     */
    public suspend fun toFullTrack(market: Market? = null): Track? = api.tracks.getTrack(id, market)

    /**
     * Converts this [SimpleTrack] into a full [Track] object with the given
     * market
     *
     * @param market Provide this parameter if you want the list of returned items to be relevant to a particular country.
     */
    public fun toFullTrackRestAction(market: Market? = null): SpotifyRestAction =
        SpotifyRestAction { toFullTrack(market) }

    override fun getMembersThatNeedApiInstantiation(): List = listOf(this)
}

@Serializable
internal data class AudioFeaturesResponse(
    @SerialName("audio_features") val audioFeatures: List
)

/**
 * The Audio Analysis endpoint provides low-level audio analysis for all of the tracks
 * in the Spotify catalog. The Audio Analysis describes the track’s structure
 * and musical content, including rhythm, pitch, and timbre. All information is
 * precise to the audio sample. Many elements of analysis include confidence values,
 * a floating-point number ranging from 0.0 to 1.0. Confidence indicates the reliability
 * of its corresponding attribute. Elements carrying a small confidence value should
 * be considered speculative. There may not be sufficient data in the audio to
 * compute the attribute with high certainty.
 *
 *
 * @param bars The time intervals of the bars throughout the track. A bar (or measure) is a segment of time defined as
 * a given number of beats. Bar offsets also indicate downbeats, the first beat of the measure.
 * @param beats The time intervals of beats throughout the track. A beat is the basic time unit of a piece of music;
 * for example, each tick of a metronome. Beats are typically multiples of tatums.
 * @param meta Analysis meta information (limited use)
 * @param sections Sections are defined by large variations in rhythm or timbre, e.g. chorus, verse, bridge, guitar
 * solo, etc. Each section contains its own descriptions of tempo, key, mode, time_signature, and loudness.
 * @param segments Audio segments attempts to subdivide a song into many segments, with each segment containing
 * a roughly consitent sound throughout its duration.
 * @param tatums A tatum represents the lowest regular pulse train that a listener intuitively infers from the timing
 * of perceived musical events (segments).
 * @param track An analysis of the track as a whole. Undocumented on Spotify's side.
 */
@Serializable
public data class AudioAnalysis(
    val bars: List,
    val beats: List,
    val meta: AudioAnalysisMeta,
    val sections: List,
    val segments: List,
    val tatums: List,
    val track: TrackAnalysis
)

/**
 * Information about the analysis run
 *
 * @param analyzerVersion Which version of the Spotify analyzer the analysis was run on
 * @param platform The OS the analysis was run on
 * @param detailedStatus Whether there was an error in the analysis or "OK"
 * @param statusCode 0 on success, any other integer on error
 * @param timestamp When this analysis was completed
 * @param analysisTime How long, in milliseconds, this analysis took to run
 * @param inputProcess The process used in the analysis
 */
@Serializable
public data class AudioAnalysisMeta(
    @SerialName("analyzer_version") val analyzerVersion: String,
    val platform: String,
    @SerialName("detailed_status") val detailedStatus: String,
    @SerialName("status_code") val statusCode: Int? = null,
    val timestamp: Long,
    @SerialName("analysis_time") val analysisTime: Float,
    @SerialName("input_process") val inputProcess: String
)

/**
 * Sections are defined by large variations in rhythm or timbre, e.g. chorus, verse, bridge, guitar solo, etc.
 * Each section contains its own descriptions of tempo, key, mode, time_signature, and loudness.*
 *
 * @param start The starting point (in seconds) of the section.
 * @param duration The duration (in seconds) of the section.
 * @param confidence The confidence, from 0.0 to 1.0, of the reliability of the section’s “designation”.
 * @param loudness The overall loudness of the section in decibels (dB). Loudness values are useful
 * for comparing relative loudness of sections within tracks.
 * @param tempo The overall estimated tempo of the section in beats per minute (BPM). In musical terminology, tempo
 * is the speed or pace of a given piece and derives directly from the average beat duration.
 * @param tempoConfidence The confidence, from 0.0 to 1.0, of the reliability of the tempo. Some tracks contain tempo
 * changes or sounds which don’t contain tempo (like pure speech) which would correspond to a low value in this field.
 * @param key The estimated overall key of the section. The values in this field ranging from 0 to 11 mapping to
 * pitches using standard Pitch Class notation (E.g. 0 = C, 1 = C♯/D♭, 2 = D, and so on). If no key was detected,
 * the value is -1.
 * @param keyConfidence The confidence, from 0.0 to 1.0, of the reliability of the key.
 * Songs with many key changes may correspond to low values in this field.
 * @param mode Indicates the modality (major or minor) of a track, the type of scale from which its melodic content is
 * derived. This field will contain a 0 for “minor”, a 1 for “major”, or a -1 for no result. Note that the major key
 * (e.g. C major) could more likely be confused with the minor key at 3 semitones lower (e.g. A minor) as both
 * keys carry the same pitches.
 * @param modeConfidence The confidence, from 0.0 to 1.0, of the reliability of the mode.
 * @param timeSignature An estimated overall time signature of a track. The time signature (meter) is a notational
 * convention to specify how many beats are in each bar (or measure). The time signature ranges from 3 to 7
 * indicating time signatures of “3/4”, to “7/4”.
 * @param timeSignatureConfidence The confidence, from 0.0 to 1.0, of the reliability of the time_signature.
 * Sections with time signature changes may correspond to low values in this field.
 */
@Serializable
public data class AudioSection(
    val start: Float = 0f,
    val duration: Float,
    val confidence: Float,
    val loudness: Float,
    val tempo: Float? = null,
    @SerialName("tempo_confidence") val tempoConfidence: Float? = null,
    val key: Int,
    @SerialName("key_confidence") val keyConfidence: Float? = null,
    val mode: Int? = null,
    @SerialName("mode_confidence") val modeConfidence: Float? = null,
    @SerialName("time_signature") val timeSignature: Int,
    @SerialName("time_signature_confidence") val timeSignatureConfidence: Float
)

/**
 * Audio segments attempts to subdivide a song into many segments, with each segment containing
 * a roughly consistent sound throughout its duration.
 *
 * @param start The starting point (in seconds) of the segment.
 * @param duration The duration (in seconds) of the segment.
 * @param confidence The confidence, from 0.0 to 1.0, of the reliability of the segmentation. Segments of the song which
 * are difficult to logically segment (e.g: noise) may correspond to low values in this field.
 * @param loudnessStart The onset loudness of the segment in decibels (dB). Combined with loudness_max and
 * loudness_max_time, these components can be used to desctibe the “attack” of the segment.
 * @param loudnessMaxTime The segment-relative offset of the segment peak loudness in seconds. Combined with
 * loudness_start and loudness_max, these components can be used to desctibe the “attack” of the segment.
 * @param loudnessMax The peak loudness of the segment in decibels (dB). Combined with loudness_start and
 * loudness_max_time, these components can be used to desctibe the “attack” of the segment.
 * @param loudnessEnd The offset loudness of the segment in decibels (dB). This value should be equivalent to the
 * loudness_start of the following segment.
 * @param pitches A “chroma” vector representing the pitch content of the segment, corresponding to the 12 pitch classes
 * C, C#, D to B, with values ranging from 0 to 1 that describe the relative dominance of every pitch in the chromatic scale
 * @param timbre Timbre is the quality of a musical note or sound that distinguishes different types of musical
 * instruments, or voices. Timbre vectors are best used in comparison with each other.
 */
@Serializable
public data class AudioSegment(
    val start: Float? = null,
    val duration: Float,
    val confidence: Float? = null,
    @SerialName("loudness_start") val loudnessStart: Float,
    @SerialName("loudness_max_time") val loudnessMaxTime: Float? = null,
    @SerialName("loudness_max") val loudnessMax: Float,
    @SerialName("loudness_end") val loudnessEnd: Float? = null,
    val pitches: List,
    val timbre: List
)

/**
 * General information about the track as a whole
 */
@Serializable
public data class TrackAnalysis(
    @SerialName("num_samples") val numSamples: Int,
    val duration: Float,
    @SerialName("sample_md5") val sampleMd5: String? = null,
    @SerialName("offset_seconds") val offsetSeconds: Int? = null,
    @SerialName("window_seconds") val windowSeconds: Int? = null,
    @SerialName("analysis_sample_rate") val analysisSampleRate: Float,
    @SerialName("analysis_channels") val analysisChannels: Int,
    @SerialName("end_of_fade_in") val endOfFadeIn: Float,
    @SerialName("start_of_fade_out") val startOfFadeOut: Float,
    val loudness: Float,
    val tempo: Float,
    @SerialName("tempo_confidence") val tempoConfidence: Float,
    @SerialName("time_signature") val timeSignature: Int,
    @SerialName("time_signature_confidence") val timeSignatureConfidence: Float,
    val key: Int,
    @SerialName("key_confidence") val keyConfidence: Float,
    val mode: Int? = null,
    @SerialName("mode_confidence") val modeConfidence: Float,
    val codestring: String,
    @SerialName("code_version") val codeVersion: Float,
    val echoprintstring: String,
    @SerialName("echoprint_version") val echoprintVersion: Float,
    val synchstring: String,
    @SerialName("synch_version") val synchVersion: Float,
    val rhythmstring: String,
    @SerialName("rhythm_version") val rhythmVersion: Float
)

/**
 * General attributes of a [Track]
 *
 * @param acousticness A confidence measure from 0.0 to 1.0 of whether the track is acoustic.
 * 1.0 represents high confidence the track is acoustic.
 * @param analysisUrl An HTTP URL to access the full audio analysis of this track.
 * An access token is required to access this data.
 * @param danceability Danceability describes how suitable a track is for dancing based on a combination
 * of musical elements including tempo, rhythm stability, beat strength, and overall regularity. A value of
 * 0.0 is least danceable and 1.0 is most danceable.
 * @param durationMs The duration of the track in milliseconds.
 * @param energy Energy is a measure from 0.0 to 1.0 and represents a perceptual measure of intensity and
 * activity. Typically, energetic tracks feel fast, loud, and noisy. For example, death metal has high energy,
 * while a Bach prelude scores low on the scale. Perceptual features contributing to this attribute include
 * dynamic range, perceived loudness, timbre, onset rate, and general entropy.
 * @param id The Spotify ID for the track.
 * @param instrumentalness Predicts whether a track contains no vocals. “Ooh” and “aah” sounds are
 * treated as instrumental in this context. Rap or spoken word tracks are clearly “vocal”. The closer
 * the instrumentalness value is to 1.0, the greater likelihood the track contains no vocal content.
 * Values above 0.5 are intended to represent instrumental tracks, but confidence is higher as
 * the value approaches 1.0.
 * @param key The key the track is in. Integers map to pitches using standard Pitch Class notation.
 * E.g. 0 = C, 1 = C♯/D♭, 2 = D, and so on.
 * @param liveness Detects the presence of an audience in the recording. Higher liveness values represent
 * an increased probability that the track was performed live. A value above 0.8 provides strong likelihood
 * that the track is live.
 * @param loudness The overall loudness of a track in decibels (dB). Loudness values are averaged across
 * the entire track and are useful for comparing relative loudness of tracks. Loudness is the quality of a
 * sound that is the primary psychological correlate of physical strength (amplitude). Values typical range
 * between -60 and 0 db.
 * @param mode Mode indicates the modality (major or minor) of a track, the type of scale from which
 * its melodic content is derived. Major is represented by 1 and minor is 0.
 * @param speechiness Speechiness detects the presence of spoken words in a track. The more exclusively
 * speech-like the recording (e.g. talk show, audio book, poetry), the closer to 1.0 the attribute value.
 * Values above 0.66 describe tracks that are probably made entirely of spoken words. Values between 0.33
 * and 0.66 describe tracks that may contain both music and speech, either in sections or layered, including
 * such cases as rap music. Values below 0.33 most likely represent music and other non-speech-like tracks.
 * @param tempo The overall estimated tempo of a track in beats per minute (BPM). In musical terminology, tempo
 * is the speed or pace of a given piece and derives directly from the average beat duration.
 * @param timeSignature An estimated overall time signature of a track. The time signature (meter) is a
 * notational convention to specify how many beats are in each bar (or measure).
 * @param trackHref A link to the Web API endpoint providing full details of the track.
 * @param type The object type: “audio_features”
 * @param uri The Spotify URI for the track.
 * @param valence A measure from 0.0 to 1.0 describing the musical positiveness conveyed by a track.
 * Tracks with high valence sound more positive (e.g. happy, cheerful, euphoric), while tracks with low
 * valence sound more negative (e.g. sad, depressed, angry).
 */
@Serializable
public data class AudioFeatures(
    val acousticness: Float,
    @SerialName("analysis_url") val analysisUrl: String,
    val danceability: Float,
    @SerialName("duration_ms") val durationMs: Int,
    val energy: Float,
    val id: String,
    val instrumentalness: Float,
    val key: Int,
    val liveness: Float,
    val loudness: Float,
    val mode: Int,
    val speechiness: Float,
    val tempo: Float,
    @SerialName("time_signature") val timeSignature: Int,
    @SerialName("track_href") val trackHref: String,
    val type: String,
    val uri: PlayableUri,
    val valence: Float
)

/**
 * This is a generic object used to represent various time intervals within Audio Analysis.
 *
 * @param start The starting point (in seconds) of the time interval.
 * @param duration The duration (in seconds) of the time interval.
 * @param confidence The confidence, from 0.0 to 1.0, of the reliability of the interval
 */
@Serializable
public data class TimeInterval(val start: Float, val duration: Float, val confidence: Float)

@Serializable
internal data class TrackList(val tracks: List)




© 2015 - 2024 Weber Informatics LLC | Privacy Policy