diff --git a/protocol/proto/audio_format.proto b/protocol/proto/audio_format.proto new file mode 100644 index 00000000..1985c37b --- /dev/null +++ b/protocol/proto/audio_format.proto @@ -0,0 +1,35 @@ +syntax = "proto3"; + +package spotify.stream_reporting_esperanto.proto; + +option java_package = "com.spotify.stream_reporting_esperanto.proto"; +option objc_class_prefix = "ESP"; + +enum AudioFormat { + FORMAT_UNKNOWN = 0; + FORMAT_OGG_VORBIS_96 = 1; + FORMAT_OGG_VORBIS_160 = 2; + FORMAT_OGG_VORBIS_320 = 3; + FORMAT_MP3_256 = 4; + FORMAT_MP3_320 = 5; + FORMAT_MP3_160 = 6; + FORMAT_MP3_96 = 7; + FORMAT_MP3_160_ENCRYPTED = 8; + FORMAT_AAC_24 = 9; + FORMAT_AAC_48 = 10; + FORMAT_MP4_128 = 11; + FORMAT_MP4_128_DUAL = 12; + FORMAT_MP4_128_CBCS = 13; + FORMAT_MP4_256 = 14; + FORMAT_MP4_256_DUAL = 15; + FORMAT_MP4_256_CBCS = 16; + FORMAT_FLAC_FLAC = 17; + FORMAT_MP4_FLAC = 18; + FORMAT_MP4_Unknown = 19; + FORMAT_MP3_Unknown = 20; + FORMAT_XHE_AAC_12 = 21; + FORMAT_XHE_AAC_16 = 22; + FORMAT_XHE_AAC_24 = 23; + FORMAT_FLAC_FLAC_24 = 24; +} + diff --git a/protocol/proto/collection_platform_items.proto b/protocol/proto/collection_platform_items.proto new file mode 100644 index 00000000..fde06a05 --- /dev/null +++ b/protocol/proto/collection_platform_items.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package spotify.collection_platform.proto; + +option java_package = "com.spotify.collection_platform.esperanto.proto"; +option java_multiple_files = true; +option objc_class_prefix = "ESP"; + +message CollectionPlatformItem { + string uri = 1; + int64 add_time = 2; +} + +message CollectionPlatformContextItem { + string uri = 1; + int64 add_time = 2; + string context_uri = 3; +} + diff --git a/protocol/proto/es_pauseresume_origin.proto b/protocol/proto/es_pauseresume_origin.proto new file mode 100644 index 00000000..20446a20 --- /dev/null +++ b/protocol/proto/es_pauseresume_origin.proto @@ -0,0 +1,11 @@ +syntax = "proto3"; + +package spotify.player.esperanto.proto; + +option java_package = "com.spotify.player.esperanto.proto"; +option objc_class_prefix = "ESP"; + +message PauseResumeOrigin { + string feature_identifier = 1; +} + diff --git a/protocol/proto/esperanto_options.proto b/protocol/proto/esperanto_options.proto new file mode 100644 index 00000000..5c914f06 --- /dev/null +++ b/protocol/proto/esperanto_options.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +package spotify.esperanto; + +import "google/protobuf/descriptor.proto"; + diff --git a/protocol/proto/lens-model.proto b/protocol/proto/lens-model.proto new file mode 100644 index 00000000..aa85defc --- /dev/null +++ b/protocol/proto/lens-model.proto @@ -0,0 +1,19 @@ +// Extracted from: Spotify 1.2.52.442 (windows) + +syntax = "proto3"; + +package spotify.lens.model.proto; + +option java_package = "com.spotify.lens.model.proto"; +option java_outer_classname = "LensModelProto"; +option optimize_for = CODE_SIZE; + +message Lens { + string identifier = 1; +} + +message LensState { + string identifier = 1; + bytes revision = 2; +} + diff --git a/protocol/proto/media.proto b/protocol/proto/media.proto new file mode 100644 index 00000000..5be102bf --- /dev/null +++ b/protocol/proto/media.proto @@ -0,0 +1,19 @@ +// Extracted from: Spotify 1.2.52.442 (windows) + +syntax = "proto3"; + +package spotify.common.media; + +option java_package = "com.spotify.common.proto"; +option optimize_for = CODE_SIZE; + +enum AudioQuality { + DEFAULT = 0; + LOW = 1; + NORMAL = 2; + HIGH = 3; + VERY_HIGH = 4; + HIFI = 5; + HIFI_24 = 6; +} + diff --git a/protocol/proto/pause_resume_origin.proto b/protocol/proto/pause_resume_origin.proto new file mode 100644 index 00000000..b65d3db2 --- /dev/null +++ b/protocol/proto/pause_resume_origin.proto @@ -0,0 +1,12 @@ +// Extracted from: Spotify 1.2.52.442 (windows) + +syntax = "proto2"; + +package spotify.player.proto; + +option optimize_for = CODE_SIZE; + +message PauseResumeOrigin { + optional string feature_identifier = 1; +} + diff --git a/protocol/proto/play_history.proto b/protocol/proto/play_history.proto new file mode 100644 index 00000000..f2a4a789 --- /dev/null +++ b/protocol/proto/play_history.proto @@ -0,0 +1,20 @@ +// Extracted from: Spotify 1.2.52.442 (windows) + +syntax = "proto2"; + +package spotify.player.proto.transfer; + +option optimize_for = CODE_SIZE; + +message PlayHistory { + message Item { + optional string context_id = 1; + optional string uid = 2; + optional bool disliked = 3; + repeated transfer.PlayHistory.Item children = 4; + } + + repeated transfer.PlayHistory.Item backward_items = 1; + repeated transfer.PlayHistory.Item forward_items = 2; +} + diff --git a/protocol/proto/playback_stack.proto b/protocol/proto/playback_stack.proto new file mode 100644 index 00000000..81ebf752 --- /dev/null +++ b/protocol/proto/playback_stack.proto @@ -0,0 +1,13 @@ +syntax = "proto3"; + +package spotify.stream_reporting_esperanto.proto; + +option java_package = "com.spotify.stream_reporting_esperanto.proto"; +option objc_class_prefix = "ESP"; + +enum PlaybackStack { + BOOMBOX = 0; + BETAMAX = 1; + UNKNOWN = 2; +} + diff --git a/protocol/proto/playback_stack_v2.proto b/protocol/proto/playback_stack_v2.proto new file mode 100644 index 00000000..302b1bb4 --- /dev/null +++ b/protocol/proto/playback_stack_v2.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package spotify.stream_reporting_esperanto.proto; + +option java_package = "com.spotify.stream_reporting_esperanto.proto"; +option objc_class_prefix = "ESP"; + +enum PlaybackStackV2 { + PLAYBACK_STACK_UNKNOWN = 0; + PLAYBACK_STACK_BOOMBOX = 1; + PLAYBACK_STACK_BETAMAX = 2; + PLAYBACK_STACK_KUBRICK = 3; +} + diff --git a/protocol/proto/playback_state.proto b/protocol/proto/playback_state.proto new file mode 100644 index 00000000..aaf34a77 --- /dev/null +++ b/protocol/proto/playback_state.proto @@ -0,0 +1,14 @@ +syntax = "proto3"; + +package spotify.stream_reporting_esperanto.proto; + +option java_package = "com.spotify.stream_reporting_esperanto.proto"; +option objc_class_prefix = "ESP"; + +enum PlaybackState { + ACTIVE = 0; + PAUSED = 1; + SUSPENDED = 2; + INVALID_PLAYBACK_STATE = 3; +} + diff --git a/protocol/proto/policy/supported_link_types_in_playlists.proto b/protocol/proto/policy/supported_link_types_in_playlists.proto new file mode 100644 index 00000000..4c1897a5 --- /dev/null +++ b/protocol/proto/policy/supported_link_types_in_playlists.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package spotify.playlist.cosmos.proto; + +option java_package = "com.spotify.playlist.policy.proto"; +option java_multiple_files = true; + +enum LinkType { + EMPTY = 0; + ARTIST = 1; + ALBUM = 2; + TRACK = 4; + LOCAL_TRACK = 9; + SHOW = 62; + EPISODE = 63; +} + diff --git a/protocol/proto/show_offline_state.proto b/protocol/proto/show_offline_state.proto new file mode 100644 index 00000000..a3cd8ae9 --- /dev/null +++ b/protocol/proto/show_offline_state.proto @@ -0,0 +1,9 @@ +syntax = "proto2"; + +package spotify.show_cosmos.proto; + +message ShowOfflineState { + optional string offline_state = 1; + optional uint32 sync_progress = 2; +} + diff --git a/protocol/proto/signal-model.proto b/protocol/proto/signal-model.proto new file mode 100644 index 00000000..d3824455 --- /dev/null +++ b/protocol/proto/signal-model.proto @@ -0,0 +1,16 @@ +// Extracted from: Spotify 1.2.52.442 (windows) + +syntax = "proto3"; + +package spotify.playlist.signal.proto; + +option java_package = "com.spotify.playlist_signal.model.proto"; +option java_outer_classname = "SignalModelProto"; +option optimize_for = CODE_SIZE; + +message Signal { + string identifier = 1; + bytes data = 2; + bytes client_payload = 3; +} + diff --git a/protocol/proto/spotify/audiobookcashier/v1/audiobook_price.proto b/protocol/proto/spotify/audiobookcashier/v1/audiobook_price.proto new file mode 100755 index 00000000..40352742 --- /dev/null +++ b/protocol/proto/spotify/audiobookcashier/v1/audiobook_price.proto @@ -0,0 +1,18 @@ +syntax = "proto3"; + +package spotify.audiobookcashier.v1; + +option java_package = "com.spotify.audiobookcashier.v1"; +option java_multiple_files = true; + +message Price { + double amount = 1; + string currency = 2; + string formatted_price = 3; +} + +message AudiobookPrice { + .spotify.audiobookcashier.v1.Price final_price = 1; + .spotify.audiobookcashier.v1.Price final_list_price = 2; +} + diff --git a/protocol/proto/state_restore/automix_rules.proto b/protocol/proto/state_restore/automix_rules.proto new file mode 100644 index 00000000..8421c7c8 --- /dev/null +++ b/protocol/proto/state_restore/automix_rules.proto @@ -0,0 +1,9 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +message AutomixRules { + required bool automix = 1; + required string current_track_uri = 2; +} + diff --git a/protocol/proto/state_restore/automix_talk_rules.proto b/protocol/proto/state_restore/automix_talk_rules.proto new file mode 100644 index 00000000..8fb15713 --- /dev/null +++ b/protocol/proto/state_restore/automix_talk_rules.proto @@ -0,0 +1,11 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +import "state_restore/provided_track.proto"; + +message AutomixTalkRules { + optional ProvidedTrack current_track = 1; + optional int64 narration_duration = 2; +} + diff --git a/protocol/proto/state_restore/context_loader.proto b/protocol/proto/state_restore/context_loader.proto new file mode 100644 index 00000000..ba016bb3 --- /dev/null +++ b/protocol/proto/state_restore/context_loader.proto @@ -0,0 +1,10 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +import "context.proto"; + +message ContextLoader { + required Context context = 1; +} + diff --git a/protocol/proto/state_restore/context_player_restorable.proto b/protocol/proto/state_restore/context_player_restorable.proto new file mode 100644 index 00000000..2f278da8 --- /dev/null +++ b/protocol/proto/state_restore/context_player_restorable.proto @@ -0,0 +1,23 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +import "state_restore/play_history.proto"; +import "state_restore/player_model.proto"; +import "state_restore/mft_state.proto"; +import "state_restore/mft_context_history.proto"; +import "state_restore/mft_fallback_page_history.proto"; +import "state_restore/pns_capper.proto"; + +message ContextPlayerRestorable { + reserved 8; + required int32 version = 1; + optional string version_suffix = 2; + required PlayerModel player_model = 3; + required PlayHistory play_history = 4; + required MftState mft_can_play_checker = 5; + required MftContextHistory mft_context_history = 6; + required MftFallbackPageHistory mft_fallback_page_history = 7; + optional PnsCapper pns_capper = 9; +} + diff --git a/protocol/proto/state_restore/context_player_state.proto b/protocol/proto/state_restore/context_player_state.proto new file mode 100644 index 00000000..74b66a65 --- /dev/null +++ b/protocol/proto/state_restore/context_player_state.proto @@ -0,0 +1,59 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +import "context_index.proto"; +import "restrictions.proto"; +import "play_origin.proto"; +import "state_restore/provided_track.proto"; +import "context_player_options.proto"; +import "prepare_play_options.proto"; +import "state_restore/playback_quality.proto"; + +message ContextPlayerState { + message ContextMetadataEntry { + optional string key = 1; + optional string value = 2; + } + + message PageMetadataEntry { + optional string key = 1; + optional string value = 2; + } + + message ModesEntry { + optional string key = 1; + optional string value = 2; + } + + optional uint64 timestamp = 1; + optional string context_uri = 2; + optional string context_url = 3; + optional Restrictions context_restrictions = 4; + optional PlayOrigin play_origin = 5; + optional ContextIndex index = 6; + optional ProvidedTrack track = 7; + optional bytes playback_id = 8; + optional PlaybackQuality playback_quality = 9; + optional double playback_speed = 10; + optional uint64 position_as_of_timestamp = 11; + optional uint64 duration = 12; + optional bool is_playing = 13; + optional bool is_paused = 14; + optional bool is_buffering = 15; + optional bool is_system_initiated = 16; + optional ContextPlayerOptions options = 17; + optional Restrictions restrictions = 18; + repeated string suppressions = 19; + repeated ProvidedTrack prev_tracks = 20; + repeated ProvidedTrack next_tracks = 21; + repeated ContextPlayerState.ContextMetadataEntry context_metadata = 22; + repeated ContextPlayerState.PageMetadataEntry page_metadata = 23; + optional string session_id = 24; + optional uint64 queue_revision = 25; + optional AudioStream audio_stream = 26; + repeated string signals = 27; + repeated ContextPlayerState.ModesEntry modes = 28; + optional string session_command_id = 29; +} + diff --git a/protocol/proto/state_restore/kitteh_box_rules.proto b/protocol/proto/state_restore/kitteh_box_rules.proto new file mode 100644 index 00000000..08de7d30 --- /dev/null +++ b/protocol/proto/state_restore/kitteh_box_rules.proto @@ -0,0 +1,30 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +message KittehBoxRules { + message NodeAspectsEntry { + optional string key = 1; + optional bytes value = 2; + } + + enum Transition { + ADVANCE = 0; + SKIP_NEXT = 1; + SKIP_PREV = 2; + } + + enum Position { + BETWEEN_TRACKS = 0; + ON_DELIMITER = 1; + ON_NODE_TRACK = 2; + } + + repeated KittehBoxRules.NodeAspectsEntry node_aspects = 1; + required KittehBoxRules.Position pos = 2; + required KittehBoxRules.Transition last_transition = 3; + required int32 context_iteration = 4; + required bool pending_skip_to = 5; + optional int64 page_index = 6; +} + diff --git a/protocol/proto/state_restore/playback_state.proto b/protocol/proto/state_restore/playback_state.proto new file mode 100644 index 00000000..1b995d1a --- /dev/null +++ b/protocol/proto/state_restore/playback_state.proto @@ -0,0 +1,15 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +import "state_restore/playback_quality.proto"; + +message PlaybackState { + optional int64 timestamp = 1; + optional int32 position_as_of_timestamp = 2; + optional int32 duration = 3; + optional bool is_buffering = 4; + optional PlaybackQuality playback_quality = 5; + optional double playback_speed = 6; +} + diff --git a/protocol/proto/state_restore/player_model.proto b/protocol/proto/state_restore/player_model.proto new file mode 100644 index 00000000..aa08495c --- /dev/null +++ b/protocol/proto/state_restore/player_model.proto @@ -0,0 +1,38 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +import "context_player_options.proto"; +import "state_restore/player_session_queue.proto"; + +message PlayerModel { + message ConfigurationEntry { + optional string key = 1; + optional string value = 2; + } + + enum AdvanceReason { + SKIP_TO_PREV_TRACK = 1; + SKIP_TO_NEXT_TRACK = 2; + EXTERNAL_ADVANCE = 3; + INTERRUPTED = 4; + SWITCHED_TO_VIDEO = 5; + SWITCHED_TO_AUDIO = 6; + } + + enum StartReason { + PLAY_CONTEXT = 1; + PLAY_CONTEXT_TRACK = 2; + STATE_RESTORE = 3; + REMOTE_TRANSFER = 4; + } + + required ContextPlayerOptions options = 1; + repeated PlayerModel.ConfigurationEntry configuration = 2; + required PlayerSessionQueue session_queue = 3; + required PlayerModel.AdvanceReason last_advance_reason = 4; + optional PlayerModel.StartReason last_start_reason = 5; + required string prev_state_id = 6; + optional string override_state_id = 7; +} + diff --git a/protocol/proto/state_restore/player_session.proto b/protocol/proto/state_restore/player_session.proto new file mode 100644 index 00000000..ee5d525f --- /dev/null +++ b/protocol/proto/state_restore/player_session.proto @@ -0,0 +1,39 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +import "context_track.proto"; +import "context_player_options.proto"; +import "logging_params.proto"; +import "play_origin.proto"; +import "player_license.proto"; +import "prepare_play_options.proto"; +import "state_restore/context_loader.proto"; +import "state_restore/context_player_rules.proto"; +import "state_restore/playback_state.proto"; +import "state_restore/player_session_fake.proto"; +import "state_restore/provided_track.proto"; + +message PlayerSession { + required PreparePlayOptions prepare_play_options = 1; + optional PlaybackState playback_state = 2; + optional ProvidedTrack track = 3; + optional ContextTrack track_to_skip_to = 4; + optional bytes given_playback_id = 5; + required LoggingParams next_command_logging_params = 6; + required LoggingParams curr_command_logging_params = 7; + required PlayOrigin play_origin = 8; + required bool is_playing = 9; + required bool is_paused = 10; + required bool is_system_initiated = 11; + required bool is_finished = 12; + required ContextPlayerOptions options = 13; + required uint64 playback_seed = 14; + required int32 num_advances = 15; + required bool did_skip_prev = 16; + required PlayerLicense license = 17; + required ContextPlayerRules rules = 18; + required ContextLoader loader = 19; + optional PlayerSessionFake fake = 100; +} + diff --git a/protocol/proto/state_restore/player_session_fake.proto b/protocol/proto/state_restore/player_session_fake.proto new file mode 100644 index 00000000..7f405127 --- /dev/null +++ b/protocol/proto/state_restore/player_session_fake.proto @@ -0,0 +1,13 @@ +syntax = "proto2"; + +package spotify.player.proto.state_restore; + +import "context.proto"; +import "state_restore/context_player_state.proto"; + +message PlayerSessionFake { + required ContextPlayerState player_state = 1; + required Context player_context = 2; + required bool is_finished = 3; +} + diff --git a/protocol/proto/your_library_config.proto b/protocol/proto/your_library_config.proto new file mode 100644 index 00000000..3030f34b --- /dev/null +++ b/protocol/proto/your_library_config.proto @@ -0,0 +1,57 @@ +syntax = "proto3"; + +package spotify.your_library.proto; + +message YourLibraryLabelAndImage { + string label = 1; + string image = 2; + bool include_empty = 3; +} + +message YourLibraryPseudoPlaylistConfig { + .spotify.your_library.proto.YourLibraryLabelAndImage liked_songs = 1; + .spotify.your_library.proto.YourLibraryLabelAndImage your_episodes = 2; + .spotify.your_library.proto.YourLibraryLabelAndImage new_episodes = 3; + .spotify.your_library.proto.YourLibraryLabelAndImage local_files = 4; + .spotify.your_library.proto.YourLibraryLabelAndImage cached_files = 5; + bool your_highlights = 6; + bool all_available_configs_provided = 99; +} + +message YourLibraryFilters { + enum Filter { + ALBUM = 0; + ARTIST = 1; + PLAYLIST = 2; + SHOW = 3; + BOOK = 4; + EVENT = 5; + AUTHOR = 7; + DOWNLOADED = 100; + WRITABLE = 101; + BY_YOU = 102; + BY_SPOTIFY = 103; + UNPLAYED = 104; + IN_PROGRESS = 105; + FINISHED = 106; + } + + repeated .spotify.your_library.proto.YourLibraryFilters.Filter filter = 1; +} + +message YourLibrarySortOrder { + enum SortOrder { + NAME = 0; + RECENTLY_ADDED = 1; + CREATOR = 2; + CUSTOM = 4; + RECENTLY_UPDATED = 5; + RECENTLY_PLAYED_OR_ADDED = 6; + RELEVANCE = 7; + EVENT_START_TIME = 8; + RELEASE_DATE = 9; + } + + .spotify.your_library.proto.YourLibrarySortOrder.SortOrder sort_order = 1; +} +