diff --git a/configure.ac b/configure.ac index e2c25e04..29443966 100644 --- a/configure.ac +++ b/configure.ac @@ -103,6 +103,9 @@ AC_SEARCH_LIBS([copy_file_range], [c], AC_SEARCH_LIBS([fcopyfile], [c], [AC_DEFINE([HAVE_FCOPYFILE], 1, [Define to 1 if you have fcopyfile])]) +AC_SEARCH_LIBS([mnt_new_monitor], [mount], + [AC_DEFINE([HAVE_LIBMOUNT], 1, + [Define to 1 if you have libmount])]) AC_SEARCH_LIBS([log10], [m]) AC_SEARCH_LIBS([lrint], [m]) @@ -192,6 +195,9 @@ PKG_CHECK_EXISTS([libplist], [OWNTONE_MODULES_CHECK([OWNTONE], [LIBPLIST], [libplist-2.0], [plist_dict_get_item], [plist/plist.h])]) +dnl AC_SEARCH_LIBS does not find plist_get_unix_date_val() on MacOS +OWNTONE_CHECK_DECLS([plist_get_unix_date_val], [plist/plist.h]) + AM_PATH_LIBGCRYPT([1:1.7.0]) OWNTONE_FUNC_REQUIRE([OWNTONE], [GNU Crypt Library], [LIBGCRYPT], [gcrypt], [gcry_control], [gcrypt.h]) diff --git a/docs/smart-playlists.md b/docs/smart-playlists.md index 45c7cfd9..3409e093 100644 --- a/docs/smart-playlists.md +++ b/docs/smart-playlists.md @@ -63,6 +63,9 @@ Valid operands include: * "string value" (string) * integer (int) +* `empty` + +The `empty` operand is only valid with the `is` operator and matches items with no value for the given field-name e.g. `comment` Valid operands for the enumeration `data_kind` are: @@ -155,6 +158,17 @@ This would match the last 10 music files added to the library. This generates a random set of, maximum of 10, rated Pop music tracks every time the playlist is queried. +``` +"All Jazz, No Foo" { + media_kind is music and + genre is "jazz" and + (not comment includes "foo" or + comment is empty) +} +``` + +This matches both the songs with comments that do not include "foo", but also the songs with no comment. + ## Date Operand Syntax One example of a valid date is a date in yyyy-mm-dd format: diff --git a/src/Makefile.am b/src/Makefile.am index 9dd91b70..ee93e0a7 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -88,6 +88,7 @@ owntone_SOURCES = main.c \ library/filescanner.c library/filescanner.h \ library/filescanner_ffmpeg.c library/filescanner_playlist.c \ library/filescanner_smartpl.c library/filescanner_itunes.c \ + library/filescanner_mountwatch.c \ library/rssscanner.c \ library.c library.h \ $(MDNS_SRC) mdns.h \ diff --git a/src/inputs/librespot-c/Makefile.am b/src/inputs/librespot-c/Makefile.am index 6916a28a..3362b294 100644 --- a/src/inputs/librespot-c/Makefile.am +++ b/src/inputs/librespot-c/Makefile.am @@ -22,7 +22,12 @@ HTTP_PROTO_SRC = \ src/proto/login5_challenges_hashcash.pb-c.h src/proto/login5_challenges_hashcash.pb-c.c \ src/proto/login5_challenges_code.pb-c.h src/proto/login5_challenges_code.pb-c.c \ src/proto/google_duration.pb-c.h src/proto/google_duration.pb-c.c \ - src/proto/storage_resolve.pb-c.h src/proto/storage_resolve.pb-c.c + src/proto/storage_resolve.pb-c.h src/proto/storage_resolve.pb-c.c \ + src/proto/extended_metadata.pb-c.h src/proto/extended_metadata.pb-c.c \ + src/proto/extension_kind.pb-c.h src/proto/extension_kind.pb-c.c \ + src/proto/entity_extension_data.pb-c.h src/proto/entity_extension_data.pb-c.c \ + src/proto/google_any.pb-c.h src/proto/google_any.pb-c.c + CORE_SRC = \ src/librespot-c.c src/connection.c src/channel.c src/crypto.c src/commands.c \ diff --git a/src/inputs/librespot-c/librespot-c.h b/src/inputs/librespot-c/librespot-c.h index 7b7da737..0f8d61f0 100644 --- a/src/inputs/librespot-c/librespot-c.h +++ b/src/inputs/librespot-c/librespot-c.h @@ -6,7 +6,7 @@ #include #define LIBRESPOT_C_VERSION_MAJOR 0 -#define LIBRESPOT_C_VERSION_MINOR 6 +#define LIBRESPOT_C_VERSION_MINOR 7 struct sp_session; diff --git a/src/inputs/librespot-c/src/connection.c b/src/inputs/librespot-c/src/connection.c index 38feee7d..c22121f8 100644 --- a/src/inputs/librespot-c/src/connection.c +++ b/src/inputs/librespot-c/src/connection.c @@ -1049,6 +1049,8 @@ handle_login5(struct sp_message *msg, struct sp_session *session) return ret; } +// If we don't get a proper response we fall back to requesting extended +// metadata, thus this function fails since that would abort the sequence static enum sp_error handle_metadata_get(struct sp_message *msg, struct sp_session *session) { @@ -1058,22 +1060,89 @@ handle_metadata_get(struct sp_message *msg, struct sp_session *session) int ret; if (hres->code != HTTP_OK) - RETURN_ERROR(SP_ERR_INVALID, "Request for metadata returned an error"); + goto fallback; - // FIXME Use Episode object for file.media_type == SP_MEDIA_EPISODE + // Also works for Episode response response = track__unpack(NULL, hres->body_len, hres->body); if (!response) - RETURN_ERROR(SP_ERR_INVALID, "Could not parse metadata response"); + goto fallback; ret = file_select(channel->file.id, sizeof(channel->file.id), response, session->bitrate_preferred); if (ret < 0) - RETURN_ERROR(SP_ERR_INVALID, "Could not find track data"); + goto fallback; track__free_unpacked(response, NULL); return SP_OK_DONE; - error: + fallback: + sp_cb.logmsg("Couldn't find file id in metadata response, will request extended metadata\n"); + track__free_unpacked(response, NULL); + return SP_OK_DONE; +} + +// We need to find the file.id (necessary to get the audio key) which is buried +// deep in the extended metadata response. Originally, it was also included in +// a metadata request, but that was broken by Spotify in spclient responses, +// except, weirdly, when requesting spclient.wg.spotify.com. The below method +// should match what go-librespot does. +static enum sp_error +handle_extended_metadata_get(struct sp_message *msg, struct sp_session *session) +{ + struct http_response *hres = &msg->payload.hres; + struct sp_channel *channel = session->now_streaming_channel; + Spotify__Extendedmetadata__BatchedExtensionResponse *response = NULL; + Spotify__Extendedmetadata__EntityExtensionData *entity_extension_data = NULL; + Track *track = NULL; + int i, j; + int ret; + + if (hres->code != HTTP_OK) + RETURN_ERROR(SP_ERR_INVALID, "Request for extended metadata returned a http error"); + + response = spotify__extendedmetadata__batched_extension_response__unpack(NULL, hres->body_len, hres->body); + if (!response) + RETURN_ERROR(SP_ERR_INVALID, "Could not parse extended metadata response"); + + for (i = 0; i < response->n_extended_metadata && !entity_extension_data; i++) + { + for (j = 0; j < response->extended_metadata[i]->n_extension_data && !entity_extension_data; j++) + { + entity_extension_data = response->extended_metadata[i]->extension_data[j]; + if (!entity_extension_data) + continue; + else if (!entity_extension_data->entity_uri || strcmp(entity_extension_data->entity_uri, channel->file.path) != 0) + entity_extension_data = NULL; + else if (!entity_extension_data->header || entity_extension_data->header->status_code != HTTP_OK) + entity_extension_data = NULL; + else if (!entity_extension_data->extension_data || !entity_extension_data->extension_data->type_url) + entity_extension_data = NULL; + } + } + + if (!entity_extension_data) + RETURN_ERROR(SP_ERR_INVALID, "Could not extract entity extension data from extended metadata response"); + + // Like go-librespot, we don't check entity_extension_data->extension_data->type_url, + // which should be either type.googleapis.com/spotify.metadata.Track or + // .Episode. If we get something else we will fail later anyway. + + // This also works for episodes + track = track__unpack(NULL, entity_extension_data->extension_data->value.len, entity_extension_data->extension_data->value.data); + if (!track) + RETURN_ERROR(SP_ERR_INVALID, "Could not parse track data in extended metadata response"); + + ret = file_select(channel->file.id, sizeof(channel->file.id), track, session->bitrate_preferred); + if (ret < 0) + RETURN_ERROR(SP_ERR_INVALID, "Could not find track data in extended metadata response"); + + spotify__extendedmetadata__batched_extension_response__free_unpacked(response, NULL); + track__free_unpacked(track, NULL); + return SP_OK_DONE; + + error: + spotify__extendedmetadata__batched_extension_response__free_unpacked(response, NULL); + track__free_unpacked(track, NULL); return ret; } @@ -1980,7 +2049,6 @@ msg_make_login5_challenges(struct sp_message *msg, struct sp_session *session) return msg_make_login5(msg, session); } -// Ref. spclient/spclient.go static int msg_make_metadata_get(struct sp_message *msg, struct sp_session *session) { @@ -2013,6 +2081,53 @@ msg_make_metadata_get(struct sp_message *msg, struct sp_session *session) return 0; } +// Ref. spclient/spclient.go +static int +msg_make_extended_metadata_get(struct sp_message *msg, struct sp_session *session) +{ + struct http_request *hreq = &msg->payload.hreq; + struct sp_server *server = &session->spclient; + Spotify__Extendedmetadata__BatchedEntityRequest req = SPOTIFY__EXTENDEDMETADATA__BATCHED_ENTITY_REQUEST__INIT; + Spotify__Extendedmetadata__EntityRequest entity_request = SPOTIFY__EXTENDEDMETADATA__ENTITY_REQUEST__INIT; + Spotify__Extendedmetadata__EntityRequest *entity_requests; + Spotify__Extendedmetadata__ExtensionQuery query = SPOTIFY__EXTENDEDMETADATA__EXTENSION_QUERY__INIT; + Spotify__Extendedmetadata__ExtensionQuery *queries; + struct sp_channel *channel = session->now_streaming_channel; + struct sp_file zerofile = { 0 }; + + if (memcmp(channel->file.id, zerofile.id, sizeof(channel->file.id)) != 0) + return 1; // Skip this request, we got the file id from metadata_get + + if (channel->file.media_type == SP_MEDIA_TRACK) + query.extension_kind = SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_V4; + else if (channel->file.media_type == SP_MEDIA_EPISODE) + query.extension_kind = SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_V4; + else + return -1; + + queries = &query; + entity_request.query = &queries; + entity_request.n_query = 1; + entity_request.entity_uri = channel->file.path; + + entity_requests = &entity_request; + req.entity_request = &entity_requests; + req.n_entity_request = 1; + + hreq->body_len = spotify__extendedmetadata__batched_entity_request__get_packed_size(&req); + hreq->body = malloc(hreq->body_len); + + spotify__extendedmetadata__batched_entity_request__pack(&req, hreq->body); + + hreq->url = asprintf_or_die("https://%s:%d/extended-metadata/v0/extended-metadata", server->address, server->port); + + hreq->headers[0] = asprintf_or_die("Accept: application/x-protobuf"); + hreq->headers[1] = asprintf_or_die("Client-Token: %s", session->http_clienttoken.value); + hreq->headers[2] = asprintf_or_die("Authorization: Bearer %s", session->http_accesstoken.value); + + return 0; +} + // Resolve storage, this will just be a GET request // Ref. spclient/spclient.go static int @@ -2064,7 +2179,7 @@ msg_make_media_get(struct sp_message *msg, struct sp_session *session) } // Must be large enough to also include null terminating elements -static struct sp_seq_request seq_requests[][7] = +static struct sp_seq_request seq_requests[][15] = { { // Just a dummy so that the array is aligned with the enum @@ -2083,6 +2198,7 @@ static struct sp_seq_request seq_requests[][7] = { SP_SEQ_MEDIA_OPEN, "LOGIN5", SP_PROTO_HTTP, msg_make_login5, NULL, handle_login5, }, { SP_SEQ_MEDIA_OPEN, "LOGIN5_CHALLENGES", SP_PROTO_HTTP, msg_make_login5_challenges, NULL, handle_login5, }, { SP_SEQ_MEDIA_OPEN, "METADATA_GET", SP_PROTO_HTTP, msg_make_metadata_get, NULL, handle_metadata_get, }, + { SP_SEQ_MEDIA_OPEN, "EXTENDED_METADATA_GET", SP_PROTO_HTTP, msg_make_extended_metadata_get, NULL, handle_extended_metadata_get, }, { SP_SEQ_MEDIA_OPEN, "AUDIO_KEY_GET", SP_PROTO_TCP, msg_make_audio_key_get, prepare_tcp, handle_tcp_generic, }, { SP_SEQ_MEDIA_OPEN, "STORAGE_RESOLVE", SP_PROTO_HTTP, msg_make_storage_resolve, NULL, handle_storage_resolve, }, { SP_SEQ_MEDIA_OPEN, "MEDIA_PREFETCH", SP_PROTO_HTTP, msg_make_media_get, NULL, handle_media_get, }, diff --git a/src/inputs/librespot-c/src/librespot-c-internal.h b/src/inputs/librespot-c/src/librespot-c-internal.h index 45d51040..b2c3e37e 100644 --- a/src/inputs/librespot-c/src/librespot-c-internal.h +++ b/src/inputs/librespot-c/src/librespot-c-internal.h @@ -37,6 +37,7 @@ #include "proto/authentication.pb-c.h" #include "proto/mercury.pb-c.h" #include "proto/metadata.pb-c.h" +#include "proto/extended_metadata.pb-c.h" #include "proto/clienttoken.pb-c.h" #include "proto/login5.pb-c.h" #include "proto/storage_resolve.pb-c.h" diff --git a/src/inputs/librespot-c/src/proto/entity_extension_data.pb-c.c b/src/inputs/librespot-c/src/proto/entity_extension_data.pb-c.c new file mode 100644 index 00000000..b215ec21 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/entity_extension_data.pb-c.c @@ -0,0 +1,495 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: entity_extension_data.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "entity_extension_data.pb-c.h" +void spotify__extendedmetadata__entity_extension_data_header__init + (Spotify__Extendedmetadata__EntityExtensionDataHeader *message) +{ + static const Spotify__Extendedmetadata__EntityExtensionDataHeader init_value = SPOTIFY__EXTENDEDMETADATA__ENTITY_EXTENSION_DATA_HEADER__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__entity_extension_data_header__get_packed_size + (const Spotify__Extendedmetadata__EntityExtensionDataHeader *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_header__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__entity_extension_data_header__pack + (const Spotify__Extendedmetadata__EntityExtensionDataHeader *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_header__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__entity_extension_data_header__pack_to_buffer + (const Spotify__Extendedmetadata__EntityExtensionDataHeader *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_header__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__EntityExtensionDataHeader * + spotify__extendedmetadata__entity_extension_data_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__EntityExtensionDataHeader *) + protobuf_c_message_unpack (&spotify__extendedmetadata__entity_extension_data_header__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__entity_extension_data_header__free_unpacked + (Spotify__Extendedmetadata__EntityExtensionDataHeader *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_header__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__entity_extension_data__init + (Spotify__Extendedmetadata__EntityExtensionData *message) +{ + static const Spotify__Extendedmetadata__EntityExtensionData init_value = SPOTIFY__EXTENDEDMETADATA__ENTITY_EXTENSION_DATA__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__entity_extension_data__get_packed_size + (const Spotify__Extendedmetadata__EntityExtensionData *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__entity_extension_data__pack + (const Spotify__Extendedmetadata__EntityExtensionData *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__entity_extension_data__pack_to_buffer + (const Spotify__Extendedmetadata__EntityExtensionData *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__EntityExtensionData * + spotify__extendedmetadata__entity_extension_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__EntityExtensionData *) + protobuf_c_message_unpack (&spotify__extendedmetadata__entity_extension_data__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__entity_extension_data__free_unpacked + (Spotify__Extendedmetadata__EntityExtensionData *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__plain_list_assoc__init + (Spotify__Extendedmetadata__PlainListAssoc *message) +{ + static const Spotify__Extendedmetadata__PlainListAssoc init_value = SPOTIFY__EXTENDEDMETADATA__PLAIN_LIST_ASSOC__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__plain_list_assoc__get_packed_size + (const Spotify__Extendedmetadata__PlainListAssoc *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__plain_list_assoc__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__plain_list_assoc__pack + (const Spotify__Extendedmetadata__PlainListAssoc *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__plain_list_assoc__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__plain_list_assoc__pack_to_buffer + (const Spotify__Extendedmetadata__PlainListAssoc *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__plain_list_assoc__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__PlainListAssoc * + spotify__extendedmetadata__plain_list_assoc__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__PlainListAssoc *) + protobuf_c_message_unpack (&spotify__extendedmetadata__plain_list_assoc__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__plain_list_assoc__free_unpacked + (Spotify__Extendedmetadata__PlainListAssoc *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__plain_list_assoc__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__assoc_header__init + (Spotify__Extendedmetadata__AssocHeader *message) +{ + static const Spotify__Extendedmetadata__AssocHeader init_value = SPOTIFY__EXTENDEDMETADATA__ASSOC_HEADER__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__assoc_header__get_packed_size + (const Spotify__Extendedmetadata__AssocHeader *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__assoc_header__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__assoc_header__pack + (const Spotify__Extendedmetadata__AssocHeader *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__assoc_header__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__assoc_header__pack_to_buffer + (const Spotify__Extendedmetadata__AssocHeader *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__assoc_header__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__AssocHeader * + spotify__extendedmetadata__assoc_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__AssocHeader *) + protobuf_c_message_unpack (&spotify__extendedmetadata__assoc_header__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__assoc_header__free_unpacked + (Spotify__Extendedmetadata__AssocHeader *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__assoc_header__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__assoc__init + (Spotify__Extendedmetadata__Assoc *message) +{ + static const Spotify__Extendedmetadata__Assoc init_value = SPOTIFY__EXTENDEDMETADATA__ASSOC__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__assoc__get_packed_size + (const Spotify__Extendedmetadata__Assoc *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__assoc__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__assoc__pack + (const Spotify__Extendedmetadata__Assoc *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__assoc__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__assoc__pack_to_buffer + (const Spotify__Extendedmetadata__Assoc *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__assoc__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__Assoc * + spotify__extendedmetadata__assoc__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__Assoc *) + protobuf_c_message_unpack (&spotify__extendedmetadata__assoc__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__assoc__free_unpacked + (Spotify__Extendedmetadata__Assoc *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__assoc__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor spotify__extendedmetadata__entity_extension_data_header__field_descriptors[5] = +{ + { + "status_code", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataHeader, status_code), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "etag", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataHeader, etag), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "locale", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataHeader, locale), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "cache_ttl_in_seconds", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT64, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataHeader, cache_ttl_in_seconds), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "offline_ttl_in_seconds", + 5, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT64, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataHeader, offline_ttl_in_seconds), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__entity_extension_data_header__field_indices_by_name[] = { + 3, /* field[3] = cache_ttl_in_seconds */ + 1, /* field[1] = etag */ + 2, /* field[2] = locale */ + 4, /* field[4] = offline_ttl_in_seconds */ + 0, /* field[0] = status_code */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__entity_extension_data_header__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 5 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_extension_data_header__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.EntityExtensionDataHeader", + "EntityExtensionDataHeader", + "Spotify__Extendedmetadata__EntityExtensionDataHeader", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__EntityExtensionDataHeader), + 5, + spotify__extendedmetadata__entity_extension_data_header__field_descriptors, + spotify__extendedmetadata__entity_extension_data_header__field_indices_by_name, + 1, spotify__extendedmetadata__entity_extension_data_header__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__entity_extension_data_header__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__extendedmetadata__entity_extension_data__field_descriptors[3] = +{ + { + "header", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionData, header), + &spotify__extendedmetadata__entity_extension_data_header__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "entity_uri", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionData, entity_uri), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "extension_data", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionData, extension_data), + &google__protobuf__any__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__entity_extension_data__field_indices_by_name[] = { + 1, /* field[1] = entity_uri */ + 2, /* field[2] = extension_data */ + 0, /* field[0] = header */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__entity_extension_data__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_extension_data__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.EntityExtensionData", + "EntityExtensionData", + "Spotify__Extendedmetadata__EntityExtensionData", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__EntityExtensionData), + 3, + spotify__extendedmetadata__entity_extension_data__field_descriptors, + spotify__extendedmetadata__entity_extension_data__field_indices_by_name, + 1, spotify__extendedmetadata__entity_extension_data__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__entity_extension_data__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__extendedmetadata__plain_list_assoc__field_descriptors[1] = +{ + { + "entity_uri", + 1, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_STRING, + offsetof(Spotify__Extendedmetadata__PlainListAssoc, n_entity_uri), + offsetof(Spotify__Extendedmetadata__PlainListAssoc, entity_uri), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__plain_list_assoc__field_indices_by_name[] = { + 0, /* field[0] = entity_uri */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__plain_list_assoc__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 1 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__plain_list_assoc__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.PlainListAssoc", + "PlainListAssoc", + "Spotify__Extendedmetadata__PlainListAssoc", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__PlainListAssoc), + 1, + spotify__extendedmetadata__plain_list_assoc__field_descriptors, + spotify__extendedmetadata__plain_list_assoc__field_indices_by_name, + 1, spotify__extendedmetadata__plain_list_assoc__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__plain_list_assoc__init, + NULL,NULL,NULL /* reserved[123] */ +}; +#define spotify__extendedmetadata__assoc_header__field_descriptors NULL +#define spotify__extendedmetadata__assoc_header__field_indices_by_name NULL +#define spotify__extendedmetadata__assoc_header__number_ranges NULL +const ProtobufCMessageDescriptor spotify__extendedmetadata__assoc_header__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.AssocHeader", + "AssocHeader", + "Spotify__Extendedmetadata__AssocHeader", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__AssocHeader), + 0, + spotify__extendedmetadata__assoc_header__field_descriptors, + spotify__extendedmetadata__assoc_header__field_indices_by_name, + 0, spotify__extendedmetadata__assoc_header__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__assoc_header__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__extendedmetadata__assoc__field_descriptors[2] = +{ + { + "header", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__Assoc, header), + &spotify__extendedmetadata__assoc_header__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "plain_list", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__Assoc, plain_list), + &spotify__extendedmetadata__plain_list_assoc__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__assoc__field_indices_by_name[] = { + 0, /* field[0] = header */ + 1, /* field[1] = plain_list */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__assoc__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__assoc__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.Assoc", + "Assoc", + "Spotify__Extendedmetadata__Assoc", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__Assoc), + 2, + spotify__extendedmetadata__assoc__field_descriptors, + spotify__extendedmetadata__assoc__field_indices_by_name, + 1, spotify__extendedmetadata__assoc__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__assoc__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/entity_extension_data.pb-c.h b/src/inputs/librespot-c/src/proto/entity_extension_data.pb-c.h new file mode 100644 index 00000000..94903291 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/entity_extension_data.pb-c.h @@ -0,0 +1,215 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: entity_extension_data.proto */ + +#ifndef PROTOBUF_C_entity_5fextension_5fdata_2eproto__INCLUDED +#define PROTOBUF_C_entity_5fextension_5fdata_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + +#include "google_any.pb-c.h" + +typedef struct Spotify__Extendedmetadata__EntityExtensionDataHeader Spotify__Extendedmetadata__EntityExtensionDataHeader; +typedef struct Spotify__Extendedmetadata__EntityExtensionData Spotify__Extendedmetadata__EntityExtensionData; +typedef struct Spotify__Extendedmetadata__PlainListAssoc Spotify__Extendedmetadata__PlainListAssoc; +typedef struct Spotify__Extendedmetadata__AssocHeader Spotify__Extendedmetadata__AssocHeader; +typedef struct Spotify__Extendedmetadata__Assoc Spotify__Extendedmetadata__Assoc; + + +/* --- enums --- */ + + +/* --- messages --- */ + +struct Spotify__Extendedmetadata__EntityExtensionDataHeader +{ + ProtobufCMessage base; + int32_t status_code; + char *etag; + char *locale; + int64_t cache_ttl_in_seconds; + int64_t offline_ttl_in_seconds; +}; +#define SPOTIFY__EXTENDEDMETADATA__ENTITY_EXTENSION_DATA_HEADER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__entity_extension_data_header__descriptor) \ + , 0, (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, 0, 0 } + + +struct Spotify__Extendedmetadata__EntityExtensionData +{ + ProtobufCMessage base; + Spotify__Extendedmetadata__EntityExtensionDataHeader *header; + char *entity_uri; + Google__Protobuf__Any *extension_data; +}; +#define SPOTIFY__EXTENDEDMETADATA__ENTITY_EXTENSION_DATA__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__entity_extension_data__descriptor) \ + , NULL, (char *)protobuf_c_empty_string, NULL } + + +struct Spotify__Extendedmetadata__PlainListAssoc +{ + ProtobufCMessage base; + size_t n_entity_uri; + char **entity_uri; +}; +#define SPOTIFY__EXTENDEDMETADATA__PLAIN_LIST_ASSOC__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__plain_list_assoc__descriptor) \ + , 0,NULL } + + +struct Spotify__Extendedmetadata__AssocHeader +{ + ProtobufCMessage base; +}; +#define SPOTIFY__EXTENDEDMETADATA__ASSOC_HEADER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__assoc_header__descriptor) \ + } + + +struct Spotify__Extendedmetadata__Assoc +{ + ProtobufCMessage base; + Spotify__Extendedmetadata__AssocHeader *header; + Spotify__Extendedmetadata__PlainListAssoc *plain_list; +}; +#define SPOTIFY__EXTENDEDMETADATA__ASSOC__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__assoc__descriptor) \ + , NULL, NULL } + + +/* Spotify__Extendedmetadata__EntityExtensionDataHeader methods */ +void spotify__extendedmetadata__entity_extension_data_header__init + (Spotify__Extendedmetadata__EntityExtensionDataHeader *message); +size_t spotify__extendedmetadata__entity_extension_data_header__get_packed_size + (const Spotify__Extendedmetadata__EntityExtensionDataHeader *message); +size_t spotify__extendedmetadata__entity_extension_data_header__pack + (const Spotify__Extendedmetadata__EntityExtensionDataHeader *message, + uint8_t *out); +size_t spotify__extendedmetadata__entity_extension_data_header__pack_to_buffer + (const Spotify__Extendedmetadata__EntityExtensionDataHeader *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__EntityExtensionDataHeader * + spotify__extendedmetadata__entity_extension_data_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__entity_extension_data_header__free_unpacked + (Spotify__Extendedmetadata__EntityExtensionDataHeader *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__EntityExtensionData methods */ +void spotify__extendedmetadata__entity_extension_data__init + (Spotify__Extendedmetadata__EntityExtensionData *message); +size_t spotify__extendedmetadata__entity_extension_data__get_packed_size + (const Spotify__Extendedmetadata__EntityExtensionData *message); +size_t spotify__extendedmetadata__entity_extension_data__pack + (const Spotify__Extendedmetadata__EntityExtensionData *message, + uint8_t *out); +size_t spotify__extendedmetadata__entity_extension_data__pack_to_buffer + (const Spotify__Extendedmetadata__EntityExtensionData *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__EntityExtensionData * + spotify__extendedmetadata__entity_extension_data__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__entity_extension_data__free_unpacked + (Spotify__Extendedmetadata__EntityExtensionData *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__PlainListAssoc methods */ +void spotify__extendedmetadata__plain_list_assoc__init + (Spotify__Extendedmetadata__PlainListAssoc *message); +size_t spotify__extendedmetadata__plain_list_assoc__get_packed_size + (const Spotify__Extendedmetadata__PlainListAssoc *message); +size_t spotify__extendedmetadata__plain_list_assoc__pack + (const Spotify__Extendedmetadata__PlainListAssoc *message, + uint8_t *out); +size_t spotify__extendedmetadata__plain_list_assoc__pack_to_buffer + (const Spotify__Extendedmetadata__PlainListAssoc *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__PlainListAssoc * + spotify__extendedmetadata__plain_list_assoc__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__plain_list_assoc__free_unpacked + (Spotify__Extendedmetadata__PlainListAssoc *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__AssocHeader methods */ +void spotify__extendedmetadata__assoc_header__init + (Spotify__Extendedmetadata__AssocHeader *message); +size_t spotify__extendedmetadata__assoc_header__get_packed_size + (const Spotify__Extendedmetadata__AssocHeader *message); +size_t spotify__extendedmetadata__assoc_header__pack + (const Spotify__Extendedmetadata__AssocHeader *message, + uint8_t *out); +size_t spotify__extendedmetadata__assoc_header__pack_to_buffer + (const Spotify__Extendedmetadata__AssocHeader *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__AssocHeader * + spotify__extendedmetadata__assoc_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__assoc_header__free_unpacked + (Spotify__Extendedmetadata__AssocHeader *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__Assoc methods */ +void spotify__extendedmetadata__assoc__init + (Spotify__Extendedmetadata__Assoc *message); +size_t spotify__extendedmetadata__assoc__get_packed_size + (const Spotify__Extendedmetadata__Assoc *message); +size_t spotify__extendedmetadata__assoc__pack + (const Spotify__Extendedmetadata__Assoc *message, + uint8_t *out); +size_t spotify__extendedmetadata__assoc__pack_to_buffer + (const Spotify__Extendedmetadata__Assoc *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__Assoc * + spotify__extendedmetadata__assoc__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__assoc__free_unpacked + (Spotify__Extendedmetadata__Assoc *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Extendedmetadata__EntityExtensionDataHeader_Closure) + (const Spotify__Extendedmetadata__EntityExtensionDataHeader *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__EntityExtensionData_Closure) + (const Spotify__Extendedmetadata__EntityExtensionData *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__PlainListAssoc_Closure) + (const Spotify__Extendedmetadata__PlainListAssoc *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__AssocHeader_Closure) + (const Spotify__Extendedmetadata__AssocHeader *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__Assoc_Closure) + (const Spotify__Extendedmetadata__Assoc *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_extension_data_header__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_extension_data__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__plain_list_assoc__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__assoc_header__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__assoc__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_entity_5fextension_5fdata_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/entity_extension_data.proto b/src/inputs/librespot-c/src/proto/entity_extension_data.proto new file mode 100644 index 00000000..7a83ea21 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/entity_extension_data.proto @@ -0,0 +1,30 @@ +syntax = "proto3"; + +package spotify.extendedmetadata; + +import "google_any.proto"; + +message EntityExtensionDataHeader { + int32 status_code = 1; + string etag = 2; + string locale = 3; + int64 cache_ttl_in_seconds = 4; + int64 offline_ttl_in_seconds = 5; +} + +message EntityExtensionData { + EntityExtensionDataHeader header = 1; + string entity_uri = 2; + google.protobuf.Any extension_data = 3; +} + +message PlainListAssoc { + repeated string entity_uri = 1; +} + +message AssocHeader {} + +message Assoc { + AssocHeader header = 1; + PlainListAssoc plain_list = 2; +} diff --git a/src/inputs/librespot-c/src/proto/extended_metadata.pb-c.c b/src/inputs/librespot-c/src/proto/extended_metadata.pb-c.c new file mode 100644 index 00000000..d751233a --- /dev/null +++ b/src/inputs/librespot-c/src/proto/extended_metadata.pb-c.c @@ -0,0 +1,826 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: extended_metadata.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "extended_metadata.pb-c.h" +void spotify__extendedmetadata__extension_query__init + (Spotify__Extendedmetadata__ExtensionQuery *message) +{ + static const Spotify__Extendedmetadata__ExtensionQuery init_value = SPOTIFY__EXTENDEDMETADATA__EXTENSION_QUERY__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__extension_query__get_packed_size + (const Spotify__Extendedmetadata__ExtensionQuery *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__extension_query__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__extension_query__pack + (const Spotify__Extendedmetadata__ExtensionQuery *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__extension_query__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__extension_query__pack_to_buffer + (const Spotify__Extendedmetadata__ExtensionQuery *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__extension_query__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__ExtensionQuery * + spotify__extendedmetadata__extension_query__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__ExtensionQuery *) + protobuf_c_message_unpack (&spotify__extendedmetadata__extension_query__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__extension_query__free_unpacked + (Spotify__Extendedmetadata__ExtensionQuery *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__extension_query__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__entity_request__init + (Spotify__Extendedmetadata__EntityRequest *message) +{ + static const Spotify__Extendedmetadata__EntityRequest init_value = SPOTIFY__EXTENDEDMETADATA__ENTITY_REQUEST__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__entity_request__get_packed_size + (const Spotify__Extendedmetadata__EntityRequest *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_request__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__entity_request__pack + (const Spotify__Extendedmetadata__EntityRequest *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_request__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__entity_request__pack_to_buffer + (const Spotify__Extendedmetadata__EntityRequest *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_request__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__EntityRequest * + spotify__extendedmetadata__entity_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__EntityRequest *) + protobuf_c_message_unpack (&spotify__extendedmetadata__entity_request__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__entity_request__free_unpacked + (Spotify__Extendedmetadata__EntityRequest *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__entity_request__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__batched_entity_request_header__init + (Spotify__Extendedmetadata__BatchedEntityRequestHeader *message) +{ + static const Spotify__Extendedmetadata__BatchedEntityRequestHeader init_value = SPOTIFY__EXTENDEDMETADATA__BATCHED_ENTITY_REQUEST_HEADER__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__batched_entity_request_header__get_packed_size + (const Spotify__Extendedmetadata__BatchedEntityRequestHeader *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_entity_request_header__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__batched_entity_request_header__pack + (const Spotify__Extendedmetadata__BatchedEntityRequestHeader *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_entity_request_header__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__batched_entity_request_header__pack_to_buffer + (const Spotify__Extendedmetadata__BatchedEntityRequestHeader *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_entity_request_header__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__BatchedEntityRequestHeader * + spotify__extendedmetadata__batched_entity_request_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__BatchedEntityRequestHeader *) + protobuf_c_message_unpack (&spotify__extendedmetadata__batched_entity_request_header__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__batched_entity_request_header__free_unpacked + (Spotify__Extendedmetadata__BatchedEntityRequestHeader *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__batched_entity_request_header__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__batched_entity_request__init + (Spotify__Extendedmetadata__BatchedEntityRequest *message) +{ + static const Spotify__Extendedmetadata__BatchedEntityRequest init_value = SPOTIFY__EXTENDEDMETADATA__BATCHED_ENTITY_REQUEST__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__batched_entity_request__get_packed_size + (const Spotify__Extendedmetadata__BatchedEntityRequest *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_entity_request__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__batched_entity_request__pack + (const Spotify__Extendedmetadata__BatchedEntityRequest *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_entity_request__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__batched_entity_request__pack_to_buffer + (const Spotify__Extendedmetadata__BatchedEntityRequest *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_entity_request__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__BatchedEntityRequest * + spotify__extendedmetadata__batched_entity_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__BatchedEntityRequest *) + protobuf_c_message_unpack (&spotify__extendedmetadata__batched_entity_request__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__batched_entity_request__free_unpacked + (Spotify__Extendedmetadata__BatchedEntityRequest *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__batched_entity_request__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__entity_extension_data_array_header__init + (Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message) +{ + static const Spotify__Extendedmetadata__EntityExtensionDataArrayHeader init_value = SPOTIFY__EXTENDEDMETADATA__ENTITY_EXTENSION_DATA_ARRAY_HEADER__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__entity_extension_data_array_header__get_packed_size + (const Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_array_header__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__entity_extension_data_array_header__pack + (const Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_array_header__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__entity_extension_data_array_header__pack_to_buffer + (const Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_array_header__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__EntityExtensionDataArrayHeader * + spotify__extendedmetadata__entity_extension_data_array_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *) + protobuf_c_message_unpack (&spotify__extendedmetadata__entity_extension_data_array_header__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__entity_extension_data_array_header__free_unpacked + (Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_array_header__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__entity_extension_data_array__init + (Spotify__Extendedmetadata__EntityExtensionDataArray *message) +{ + static const Spotify__Extendedmetadata__EntityExtensionDataArray init_value = SPOTIFY__EXTENDEDMETADATA__ENTITY_EXTENSION_DATA_ARRAY__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__entity_extension_data_array__get_packed_size + (const Spotify__Extendedmetadata__EntityExtensionDataArray *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_array__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__entity_extension_data_array__pack + (const Spotify__Extendedmetadata__EntityExtensionDataArray *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_array__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__entity_extension_data_array__pack_to_buffer + (const Spotify__Extendedmetadata__EntityExtensionDataArray *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_array__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__EntityExtensionDataArray * + spotify__extendedmetadata__entity_extension_data_array__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__EntityExtensionDataArray *) + protobuf_c_message_unpack (&spotify__extendedmetadata__entity_extension_data_array__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__entity_extension_data_array__free_unpacked + (Spotify__Extendedmetadata__EntityExtensionDataArray *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__entity_extension_data_array__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__batched_extension_response_header__init + (Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message) +{ + static const Spotify__Extendedmetadata__BatchedExtensionResponseHeader init_value = SPOTIFY__EXTENDEDMETADATA__BATCHED_EXTENSION_RESPONSE_HEADER__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__batched_extension_response_header__get_packed_size + (const Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_extension_response_header__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__batched_extension_response_header__pack + (const Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_extension_response_header__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__batched_extension_response_header__pack_to_buffer + (const Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_extension_response_header__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__BatchedExtensionResponseHeader * + spotify__extendedmetadata__batched_extension_response_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__BatchedExtensionResponseHeader *) + protobuf_c_message_unpack (&spotify__extendedmetadata__batched_extension_response_header__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__batched_extension_response_header__free_unpacked + (Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__batched_extension_response_header__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +void spotify__extendedmetadata__batched_extension_response__init + (Spotify__Extendedmetadata__BatchedExtensionResponse *message) +{ + static const Spotify__Extendedmetadata__BatchedExtensionResponse init_value = SPOTIFY__EXTENDEDMETADATA__BATCHED_EXTENSION_RESPONSE__INIT; + *message = init_value; +} +size_t spotify__extendedmetadata__batched_extension_response__get_packed_size + (const Spotify__Extendedmetadata__BatchedExtensionResponse *message) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_extension_response__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t spotify__extendedmetadata__batched_extension_response__pack + (const Spotify__Extendedmetadata__BatchedExtensionResponse *message, + uint8_t *out) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_extension_response__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t spotify__extendedmetadata__batched_extension_response__pack_to_buffer + (const Spotify__Extendedmetadata__BatchedExtensionResponse *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &spotify__extendedmetadata__batched_extension_response__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Spotify__Extendedmetadata__BatchedExtensionResponse * + spotify__extendedmetadata__batched_extension_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Spotify__Extendedmetadata__BatchedExtensionResponse *) + protobuf_c_message_unpack (&spotify__extendedmetadata__batched_extension_response__descriptor, + allocator, len, data); +} +void spotify__extendedmetadata__batched_extension_response__free_unpacked + (Spotify__Extendedmetadata__BatchedExtensionResponse *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &spotify__extendedmetadata__batched_extension_response__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor spotify__extendedmetadata__extension_query__field_descriptors[2] = +{ + { + "extension_kind", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__ExtensionQuery, extension_kind), + &spotify__extendedmetadata__extension_kind__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "etag", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__ExtensionQuery, etag), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__extension_query__field_indices_by_name[] = { + 1, /* field[1] = etag */ + 0, /* field[0] = extension_kind */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__extension_query__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__extension_query__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.ExtensionQuery", + "ExtensionQuery", + "Spotify__Extendedmetadata__ExtensionQuery", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__ExtensionQuery), + 2, + spotify__extendedmetadata__extension_query__field_descriptors, + spotify__extendedmetadata__extension_query__field_indices_by_name, + 1, spotify__extendedmetadata__extension_query__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__extension_query__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__extendedmetadata__entity_request__field_descriptors[2] = +{ + { + "entity_uri", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityRequest, entity_uri), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "query", + 2, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Extendedmetadata__EntityRequest, n_query), + offsetof(Spotify__Extendedmetadata__EntityRequest, query), + &spotify__extendedmetadata__extension_query__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__entity_request__field_indices_by_name[] = { + 0, /* field[0] = entity_uri */ + 1, /* field[1] = query */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__entity_request__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_request__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.EntityRequest", + "EntityRequest", + "Spotify__Extendedmetadata__EntityRequest", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__EntityRequest), + 2, + spotify__extendedmetadata__entity_request__field_descriptors, + spotify__extendedmetadata__entity_request__field_indices_by_name, + 1, spotify__extendedmetadata__entity_request__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__entity_request__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__extendedmetadata__batched_entity_request_header__field_descriptors[3] = +{ + { + "country", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__BatchedEntityRequestHeader, country), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "catalogue", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__BatchedEntityRequestHeader, catalogue), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "task_id", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__BatchedEntityRequestHeader, task_id), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__batched_entity_request_header__field_indices_by_name[] = { + 1, /* field[1] = catalogue */ + 0, /* field[0] = country */ + 2, /* field[2] = task_id */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__batched_entity_request_header__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__batched_entity_request_header__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.BatchedEntityRequestHeader", + "BatchedEntityRequestHeader", + "Spotify__Extendedmetadata__BatchedEntityRequestHeader", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__BatchedEntityRequestHeader), + 3, + spotify__extendedmetadata__batched_entity_request_header__field_descriptors, + spotify__extendedmetadata__batched_entity_request_header__field_indices_by_name, + 1, spotify__extendedmetadata__batched_entity_request_header__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__batched_entity_request_header__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__extendedmetadata__batched_entity_request__field_descriptors[2] = +{ + { + "header", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__BatchedEntityRequest, header), + &spotify__extendedmetadata__batched_entity_request_header__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "entity_request", + 2, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Extendedmetadata__BatchedEntityRequest, n_entity_request), + offsetof(Spotify__Extendedmetadata__BatchedEntityRequest, entity_request), + &spotify__extendedmetadata__entity_request__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__batched_entity_request__field_indices_by_name[] = { + 1, /* field[1] = entity_request */ + 0, /* field[0] = header */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__batched_entity_request__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__batched_entity_request__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.BatchedEntityRequest", + "BatchedEntityRequest", + "Spotify__Extendedmetadata__BatchedEntityRequest", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__BatchedEntityRequest), + 2, + spotify__extendedmetadata__batched_entity_request__field_descriptors, + spotify__extendedmetadata__batched_entity_request__field_indices_by_name, + 1, spotify__extendedmetadata__batched_entity_request__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__batched_entity_request__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__extendedmetadata__entity_extension_data_array_header__field_descriptors[4] = +{ + { + "provider_error_status", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataArrayHeader, provider_error_status), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "cache_ttl_in_seconds", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT64, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataArrayHeader, cache_ttl_in_seconds), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "offline_ttl_in_seconds", + 3, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_INT64, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataArrayHeader, offline_ttl_in_seconds), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "extension_type", + 4, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataArrayHeader, extension_type), + &spotify__extendedmetadata__extension_type__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__entity_extension_data_array_header__field_indices_by_name[] = { + 1, /* field[1] = cache_ttl_in_seconds */ + 3, /* field[3] = extension_type */ + 2, /* field[2] = offline_ttl_in_seconds */ + 0, /* field[0] = provider_error_status */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__entity_extension_data_array_header__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 4 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_extension_data_array_header__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.EntityExtensionDataArrayHeader", + "EntityExtensionDataArrayHeader", + "Spotify__Extendedmetadata__EntityExtensionDataArrayHeader", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__EntityExtensionDataArrayHeader), + 4, + spotify__extendedmetadata__entity_extension_data_array_header__field_descriptors, + spotify__extendedmetadata__entity_extension_data_array_header__field_indices_by_name, + 1, spotify__extendedmetadata__entity_extension_data_array_header__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__entity_extension_data_array_header__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__extendedmetadata__entity_extension_data_array__field_descriptors[3] = +{ + { + "header", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataArray, header), + &spotify__extendedmetadata__entity_extension_data_array_header__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "extension_kind", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__EntityExtensionDataArray, extension_kind), + &spotify__extendedmetadata__extension_kind__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "extension_data", + 3, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Extendedmetadata__EntityExtensionDataArray, n_extension_data), + offsetof(Spotify__Extendedmetadata__EntityExtensionDataArray, extension_data), + &spotify__extendedmetadata__entity_extension_data__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__entity_extension_data_array__field_indices_by_name[] = { + 2, /* field[2] = extension_data */ + 1, /* field[1] = extension_kind */ + 0, /* field[0] = header */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__entity_extension_data_array__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 3 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_extension_data_array__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.EntityExtensionDataArray", + "EntityExtensionDataArray", + "Spotify__Extendedmetadata__EntityExtensionDataArray", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__EntityExtensionDataArray), + 3, + spotify__extendedmetadata__entity_extension_data_array__field_descriptors, + spotify__extendedmetadata__entity_extension_data_array__field_indices_by_name, + 1, spotify__extendedmetadata__entity_extension_data_array__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__entity_extension_data_array__init, + NULL,NULL,NULL /* reserved[123] */ +}; +#define spotify__extendedmetadata__batched_extension_response_header__field_descriptors NULL +#define spotify__extendedmetadata__batched_extension_response_header__field_indices_by_name NULL +#define spotify__extendedmetadata__batched_extension_response_header__number_ranges NULL +const ProtobufCMessageDescriptor spotify__extendedmetadata__batched_extension_response_header__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.BatchedExtensionResponseHeader", + "BatchedExtensionResponseHeader", + "Spotify__Extendedmetadata__BatchedExtensionResponseHeader", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__BatchedExtensionResponseHeader), + 0, + spotify__extendedmetadata__batched_extension_response_header__field_descriptors, + spotify__extendedmetadata__batched_extension_response_header__field_indices_by_name, + 0, spotify__extendedmetadata__batched_extension_response_header__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__batched_extension_response_header__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor spotify__extendedmetadata__batched_extension_response__field_descriptors[2] = +{ + { + "header", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(Spotify__Extendedmetadata__BatchedExtensionResponse, header), + &spotify__extendedmetadata__batched_extension_response_header__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "extended_metadata", + 2, + PROTOBUF_C_LABEL_REPEATED, + PROTOBUF_C_TYPE_MESSAGE, + offsetof(Spotify__Extendedmetadata__BatchedExtensionResponse, n_extended_metadata), + offsetof(Spotify__Extendedmetadata__BatchedExtensionResponse, extended_metadata), + &spotify__extendedmetadata__entity_extension_data_array__descriptor, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned spotify__extendedmetadata__batched_extension_response__field_indices_by_name[] = { + 1, /* field[1] = extended_metadata */ + 0, /* field[0] = header */ +}; +static const ProtobufCIntRange spotify__extendedmetadata__batched_extension_response__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor spotify__extendedmetadata__batched_extension_response__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.BatchedExtensionResponse", + "BatchedExtensionResponse", + "Spotify__Extendedmetadata__BatchedExtensionResponse", + "spotify.extendedmetadata", + sizeof(Spotify__Extendedmetadata__BatchedExtensionResponse), + 2, + spotify__extendedmetadata__batched_extension_response__field_descriptors, + spotify__extendedmetadata__batched_extension_response__field_indices_by_name, + 1, spotify__extendedmetadata__batched_extension_response__number_ranges, + (ProtobufCMessageInit) spotify__extendedmetadata__batched_extension_response__init, + NULL,NULL,NULL /* reserved[123] */ +}; +static const ProtobufCEnumValue spotify__extendedmetadata__extension_type__enum_values_by_number[3] = +{ + { "UNKNOWN", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_TYPE__UNKNOWN", 0 }, + { "GENERIC", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_TYPE__GENERIC", 1 }, + { "ASSOC", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_TYPE__ASSOC", 2 }, +}; +static const ProtobufCIntRange spotify__extendedmetadata__extension_type__value_ranges[] = { +{0, 0},{0, 3} +}; +static const ProtobufCEnumValueIndex spotify__extendedmetadata__extension_type__enum_values_by_name[3] = +{ + { "ASSOC", 2 }, + { "GENERIC", 1 }, + { "UNKNOWN", 0 }, +}; +const ProtobufCEnumDescriptor spotify__extendedmetadata__extension_type__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.ExtensionType", + "ExtensionType", + "Spotify__Extendedmetadata__ExtensionType", + "spotify.extendedmetadata", + 3, + spotify__extendedmetadata__extension_type__enum_values_by_number, + 3, + spotify__extendedmetadata__extension_type__enum_values_by_name, + 1, + spotify__extendedmetadata__extension_type__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; diff --git a/src/inputs/librespot-c/src/proto/extended_metadata.pb-c.h b/src/inputs/librespot-c/src/proto/extended_metadata.pb-c.h new file mode 100644 index 00000000..a3dd6f7a --- /dev/null +++ b/src/inputs/librespot-c/src/proto/extended_metadata.pb-c.h @@ -0,0 +1,332 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: extended_metadata.proto */ + +#ifndef PROTOBUF_C_extended_5fmetadata_2eproto__INCLUDED +#define PROTOBUF_C_extended_5fmetadata_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + +#include "entity_extension_data.pb-c.h" +#include "extension_kind.pb-c.h" + +typedef struct Spotify__Extendedmetadata__ExtensionQuery Spotify__Extendedmetadata__ExtensionQuery; +typedef struct Spotify__Extendedmetadata__EntityRequest Spotify__Extendedmetadata__EntityRequest; +typedef struct Spotify__Extendedmetadata__BatchedEntityRequestHeader Spotify__Extendedmetadata__BatchedEntityRequestHeader; +typedef struct Spotify__Extendedmetadata__BatchedEntityRequest Spotify__Extendedmetadata__BatchedEntityRequest; +typedef struct Spotify__Extendedmetadata__EntityExtensionDataArrayHeader Spotify__Extendedmetadata__EntityExtensionDataArrayHeader; +typedef struct Spotify__Extendedmetadata__EntityExtensionDataArray Spotify__Extendedmetadata__EntityExtensionDataArray; +typedef struct Spotify__Extendedmetadata__BatchedExtensionResponseHeader Spotify__Extendedmetadata__BatchedExtensionResponseHeader; +typedef struct Spotify__Extendedmetadata__BatchedExtensionResponse Spotify__Extendedmetadata__BatchedExtensionResponse; + + +/* --- enums --- */ + +typedef enum _Spotify__Extendedmetadata__ExtensionType { + SPOTIFY__EXTENDEDMETADATA__EXTENSION_TYPE__UNKNOWN = 0, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_TYPE__GENERIC = 1, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_TYPE__ASSOC = 2 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__EXTENDEDMETADATA__EXTENSION_TYPE) +} Spotify__Extendedmetadata__ExtensionType; + +/* --- messages --- */ + +struct Spotify__Extendedmetadata__ExtensionQuery +{ + ProtobufCMessage base; + Spotify__Extendedmetadata__ExtensionKind extension_kind; + char *etag; +}; +#define SPOTIFY__EXTENDEDMETADATA__EXTENSION_QUERY__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__extension_query__descriptor) \ + , SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__UNKNOWN_EXTENSION, (char *)protobuf_c_empty_string } + + +struct Spotify__Extendedmetadata__EntityRequest +{ + ProtobufCMessage base; + char *entity_uri; + size_t n_query; + Spotify__Extendedmetadata__ExtensionQuery **query; +}; +#define SPOTIFY__EXTENDEDMETADATA__ENTITY_REQUEST__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__entity_request__descriptor) \ + , (char *)protobuf_c_empty_string, 0,NULL } + + +struct Spotify__Extendedmetadata__BatchedEntityRequestHeader +{ + ProtobufCMessage base; + char *country; + char *catalogue; + ProtobufCBinaryData task_id; +}; +#define SPOTIFY__EXTENDEDMETADATA__BATCHED_ENTITY_REQUEST_HEADER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__batched_entity_request_header__descriptor) \ + , (char *)protobuf_c_empty_string, (char *)protobuf_c_empty_string, {0,NULL} } + + +struct Spotify__Extendedmetadata__BatchedEntityRequest +{ + ProtobufCMessage base; + Spotify__Extendedmetadata__BatchedEntityRequestHeader *header; + size_t n_entity_request; + Spotify__Extendedmetadata__EntityRequest **entity_request; +}; +#define SPOTIFY__EXTENDEDMETADATA__BATCHED_ENTITY_REQUEST__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__batched_entity_request__descriptor) \ + , NULL, 0,NULL } + + +struct Spotify__Extendedmetadata__EntityExtensionDataArrayHeader +{ + ProtobufCMessage base; + int32_t provider_error_status; + int64_t cache_ttl_in_seconds; + int64_t offline_ttl_in_seconds; + Spotify__Extendedmetadata__ExtensionType extension_type; +}; +#define SPOTIFY__EXTENDEDMETADATA__ENTITY_EXTENSION_DATA_ARRAY_HEADER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__entity_extension_data_array_header__descriptor) \ + , 0, 0, 0, SPOTIFY__EXTENDEDMETADATA__EXTENSION_TYPE__UNKNOWN } + + +struct Spotify__Extendedmetadata__EntityExtensionDataArray +{ + ProtobufCMessage base; + Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *header; + Spotify__Extendedmetadata__ExtensionKind extension_kind; + size_t n_extension_data; + Spotify__Extendedmetadata__EntityExtensionData **extension_data; +}; +#define SPOTIFY__EXTENDEDMETADATA__ENTITY_EXTENSION_DATA_ARRAY__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__entity_extension_data_array__descriptor) \ + , NULL, SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__UNKNOWN_EXTENSION, 0,NULL } + + +struct Spotify__Extendedmetadata__BatchedExtensionResponseHeader +{ + ProtobufCMessage base; +}; +#define SPOTIFY__EXTENDEDMETADATA__BATCHED_EXTENSION_RESPONSE_HEADER__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__batched_extension_response_header__descriptor) \ + } + + +struct Spotify__Extendedmetadata__BatchedExtensionResponse +{ + ProtobufCMessage base; + Spotify__Extendedmetadata__BatchedExtensionResponseHeader *header; + size_t n_extended_metadata; + Spotify__Extendedmetadata__EntityExtensionDataArray **extended_metadata; +}; +#define SPOTIFY__EXTENDEDMETADATA__BATCHED_EXTENSION_RESPONSE__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&spotify__extendedmetadata__batched_extension_response__descriptor) \ + , NULL, 0,NULL } + + +/* Spotify__Extendedmetadata__ExtensionQuery methods */ +void spotify__extendedmetadata__extension_query__init + (Spotify__Extendedmetadata__ExtensionQuery *message); +size_t spotify__extendedmetadata__extension_query__get_packed_size + (const Spotify__Extendedmetadata__ExtensionQuery *message); +size_t spotify__extendedmetadata__extension_query__pack + (const Spotify__Extendedmetadata__ExtensionQuery *message, + uint8_t *out); +size_t spotify__extendedmetadata__extension_query__pack_to_buffer + (const Spotify__Extendedmetadata__ExtensionQuery *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__ExtensionQuery * + spotify__extendedmetadata__extension_query__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__extension_query__free_unpacked + (Spotify__Extendedmetadata__ExtensionQuery *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__EntityRequest methods */ +void spotify__extendedmetadata__entity_request__init + (Spotify__Extendedmetadata__EntityRequest *message); +size_t spotify__extendedmetadata__entity_request__get_packed_size + (const Spotify__Extendedmetadata__EntityRequest *message); +size_t spotify__extendedmetadata__entity_request__pack + (const Spotify__Extendedmetadata__EntityRequest *message, + uint8_t *out); +size_t spotify__extendedmetadata__entity_request__pack_to_buffer + (const Spotify__Extendedmetadata__EntityRequest *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__EntityRequest * + spotify__extendedmetadata__entity_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__entity_request__free_unpacked + (Spotify__Extendedmetadata__EntityRequest *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__BatchedEntityRequestHeader methods */ +void spotify__extendedmetadata__batched_entity_request_header__init + (Spotify__Extendedmetadata__BatchedEntityRequestHeader *message); +size_t spotify__extendedmetadata__batched_entity_request_header__get_packed_size + (const Spotify__Extendedmetadata__BatchedEntityRequestHeader *message); +size_t spotify__extendedmetadata__batched_entity_request_header__pack + (const Spotify__Extendedmetadata__BatchedEntityRequestHeader *message, + uint8_t *out); +size_t spotify__extendedmetadata__batched_entity_request_header__pack_to_buffer + (const Spotify__Extendedmetadata__BatchedEntityRequestHeader *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__BatchedEntityRequestHeader * + spotify__extendedmetadata__batched_entity_request_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__batched_entity_request_header__free_unpacked + (Spotify__Extendedmetadata__BatchedEntityRequestHeader *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__BatchedEntityRequest methods */ +void spotify__extendedmetadata__batched_entity_request__init + (Spotify__Extendedmetadata__BatchedEntityRequest *message); +size_t spotify__extendedmetadata__batched_entity_request__get_packed_size + (const Spotify__Extendedmetadata__BatchedEntityRequest *message); +size_t spotify__extendedmetadata__batched_entity_request__pack + (const Spotify__Extendedmetadata__BatchedEntityRequest *message, + uint8_t *out); +size_t spotify__extendedmetadata__batched_entity_request__pack_to_buffer + (const Spotify__Extendedmetadata__BatchedEntityRequest *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__BatchedEntityRequest * + spotify__extendedmetadata__batched_entity_request__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__batched_entity_request__free_unpacked + (Spotify__Extendedmetadata__BatchedEntityRequest *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__EntityExtensionDataArrayHeader methods */ +void spotify__extendedmetadata__entity_extension_data_array_header__init + (Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message); +size_t spotify__extendedmetadata__entity_extension_data_array_header__get_packed_size + (const Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message); +size_t spotify__extendedmetadata__entity_extension_data_array_header__pack + (const Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message, + uint8_t *out); +size_t spotify__extendedmetadata__entity_extension_data_array_header__pack_to_buffer + (const Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__EntityExtensionDataArrayHeader * + spotify__extendedmetadata__entity_extension_data_array_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__entity_extension_data_array_header__free_unpacked + (Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__EntityExtensionDataArray methods */ +void spotify__extendedmetadata__entity_extension_data_array__init + (Spotify__Extendedmetadata__EntityExtensionDataArray *message); +size_t spotify__extendedmetadata__entity_extension_data_array__get_packed_size + (const Spotify__Extendedmetadata__EntityExtensionDataArray *message); +size_t spotify__extendedmetadata__entity_extension_data_array__pack + (const Spotify__Extendedmetadata__EntityExtensionDataArray *message, + uint8_t *out); +size_t spotify__extendedmetadata__entity_extension_data_array__pack_to_buffer + (const Spotify__Extendedmetadata__EntityExtensionDataArray *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__EntityExtensionDataArray * + spotify__extendedmetadata__entity_extension_data_array__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__entity_extension_data_array__free_unpacked + (Spotify__Extendedmetadata__EntityExtensionDataArray *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__BatchedExtensionResponseHeader methods */ +void spotify__extendedmetadata__batched_extension_response_header__init + (Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message); +size_t spotify__extendedmetadata__batched_extension_response_header__get_packed_size + (const Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message); +size_t spotify__extendedmetadata__batched_extension_response_header__pack + (const Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message, + uint8_t *out); +size_t spotify__extendedmetadata__batched_extension_response_header__pack_to_buffer + (const Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__BatchedExtensionResponseHeader * + spotify__extendedmetadata__batched_extension_response_header__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__batched_extension_response_header__free_unpacked + (Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message, + ProtobufCAllocator *allocator); +/* Spotify__Extendedmetadata__BatchedExtensionResponse methods */ +void spotify__extendedmetadata__batched_extension_response__init + (Spotify__Extendedmetadata__BatchedExtensionResponse *message); +size_t spotify__extendedmetadata__batched_extension_response__get_packed_size + (const Spotify__Extendedmetadata__BatchedExtensionResponse *message); +size_t spotify__extendedmetadata__batched_extension_response__pack + (const Spotify__Extendedmetadata__BatchedExtensionResponse *message, + uint8_t *out); +size_t spotify__extendedmetadata__batched_extension_response__pack_to_buffer + (const Spotify__Extendedmetadata__BatchedExtensionResponse *message, + ProtobufCBuffer *buffer); +Spotify__Extendedmetadata__BatchedExtensionResponse * + spotify__extendedmetadata__batched_extension_response__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void spotify__extendedmetadata__batched_extension_response__free_unpacked + (Spotify__Extendedmetadata__BatchedExtensionResponse *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Spotify__Extendedmetadata__ExtensionQuery_Closure) + (const Spotify__Extendedmetadata__ExtensionQuery *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__EntityRequest_Closure) + (const Spotify__Extendedmetadata__EntityRequest *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__BatchedEntityRequestHeader_Closure) + (const Spotify__Extendedmetadata__BatchedEntityRequestHeader *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__BatchedEntityRequest_Closure) + (const Spotify__Extendedmetadata__BatchedEntityRequest *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__EntityExtensionDataArrayHeader_Closure) + (const Spotify__Extendedmetadata__EntityExtensionDataArrayHeader *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__EntityExtensionDataArray_Closure) + (const Spotify__Extendedmetadata__EntityExtensionDataArray *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__BatchedExtensionResponseHeader_Closure) + (const Spotify__Extendedmetadata__BatchedExtensionResponseHeader *message, + void *closure_data); +typedef void (*Spotify__Extendedmetadata__BatchedExtensionResponse_Closure) + (const Spotify__Extendedmetadata__BatchedExtensionResponse *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCEnumDescriptor spotify__extendedmetadata__extension_type__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__extension_query__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_request__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__batched_entity_request_header__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__batched_entity_request__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_extension_data_array_header__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__entity_extension_data_array__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__batched_extension_response_header__descriptor; +extern const ProtobufCMessageDescriptor spotify__extendedmetadata__batched_extension_response__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_extended_5fmetadata_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/extended_metadata.proto b/src/inputs/librespot-c/src/proto/extended_metadata.proto new file mode 100644 index 00000000..eb07d7f9 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/extended_metadata.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; + +package spotify.extendedmetadata; + +import "entity_extension_data.proto"; +import "extension_kind.proto"; + +message ExtensionQuery { + ExtensionKind extension_kind = 1; + string etag = 2; +} + +message EntityRequest { + string entity_uri = 1; + repeated ExtensionQuery query = 2; +} + +message BatchedEntityRequestHeader { + string country = 1; + string catalogue = 2; + bytes task_id = 3; +} + +message BatchedEntityRequest { + BatchedEntityRequestHeader header = 1; + repeated EntityRequest entity_request = 2; +} + +message EntityExtensionDataArrayHeader { + int32 provider_error_status = 1; + int64 cache_ttl_in_seconds = 2; + int64 offline_ttl_in_seconds = 3; + ExtensionType extension_type = 4; +} + +message EntityExtensionDataArray { + EntityExtensionDataArrayHeader header = 1; + ExtensionKind extension_kind = 2; + repeated EntityExtensionData extension_data = 3; +} + +message BatchedExtensionResponseHeader {} + +message BatchedExtensionResponse { + BatchedExtensionResponseHeader header = 1; + repeated EntityExtensionDataArray extended_metadata = 2; +} + +enum ExtensionType { + UNKNOWN = 0; + GENERIC = 1; + ASSOC = 2; +} diff --git a/src/inputs/librespot-c/src/proto/extension_kind.pb-c.c b/src/inputs/librespot-c/src/proto/extension_kind.pb-c.c new file mode 100644 index 00000000..37ab7d44 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/extension_kind.pb-c.c @@ -0,0 +1,411 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: extension_kind.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "extension_kind.pb-c.h" +static const ProtobufCEnumValue spotify__extendedmetadata__extension_kind__enum_values_by_number[189] = +{ + { "UNKNOWN_EXTENSION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__UNKNOWN_EXTENSION", 0 }, + { "CANVAZ", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CANVAZ", 1 }, + { "STORYLINES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__STORYLINES", 2 }, + { "PODCAST_TOPICS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_TOPICS", 3 }, + { "PODCAST_SEGMENTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_SEGMENTS", 4 }, + { "AUDIO_FILES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIO_FILES", 5 }, + { "TRACK_DESCRIPTOR", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_DESCRIPTOR", 6 }, + { "PODCAST_COUNTER", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_COUNTER", 7 }, + { "ARTIST_V4", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_V4", 8 }, + { "ALBUM_V4", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ALBUM_V4", 9 }, + { "TRACK_V4", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_V4", 10 }, + { "SHOW_V4", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_V4", 11 }, + { "EPISODE_V4", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_V4", 12 }, + { "PODCAST_HTML_DESCRIPTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_HTML_DESCRIPTION", 13 }, + { "PODCAST_QUOTES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_QUOTES", 14 }, + { "USER_PROFILE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__USER_PROFILE", 15 }, + { "CANVAS_V1", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CANVAS_V1", 16 }, + { "SHOW_V4_BASE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_V4_BASE", 17 }, + { "SHOW_V4_EPISODES_ASSOC", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_V4_EPISODES_ASSOC", 18 }, + { "TRACK_DESCRIPTOR_SIGNATURES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_DESCRIPTOR_SIGNATURES", 19 }, + { "PODCAST_AD_SEGMENTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_AD_SEGMENTS", 20 }, + { "EPISODE_TRANSCRIPTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_TRANSCRIPTS", 21 }, + { "PODCAST_SUBSCRIPTIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_SUBSCRIPTIONS", 22 }, + { "EXTRACTED_COLOR", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EXTRACTED_COLOR", 23 }, + { "PODCAST_VIRALITY", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_VIRALITY", 24 }, + { "IMAGE_SPARKLES_HACK", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__IMAGE_SPARKLES_HACK", 25 }, + { "PODCAST_POPULARITY_HACK", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_POPULARITY_HACK", 26 }, + { "AUTOMIX_MODE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUTOMIX_MODE", 27 }, + { "CUEPOINTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CUEPOINTS", 28 }, + { "PODCAST_POLL", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_POLL", 29 }, + { "EPISODE_ACCESS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_ACCESS", 30 }, + { "SHOW_ACCESS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_ACCESS", 31 }, + { "PODCAST_QNA", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_QNA", 32 }, + { "CLIPS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CLIPS", 33 }, + { "SHOW_V5", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_V5", 34 }, + { "EPISODE_V5", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_V5", 35 }, + { "PODCAST_CTA_CARDS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_CTA_CARDS", 36 }, + { "PODCAST_RATING", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_RATING", 37 }, + { "DISPLAY_SEGMENTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DISPLAY_SEGMENTS", 38 }, + { "GREENROOM", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__GREENROOM", 39 }, + { "USER_CREATED", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__USER_CREATED", 40 }, + { "SHOW_DESCRIPTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_DESCRIPTION", 41 }, + { "SHOW_HTML_DESCRIPTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_HTML_DESCRIPTION", 42 }, + { "SHOW_PLAYABILITY", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_PLAYABILITY", 43 }, + { "EPISODE_DESCRIPTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_DESCRIPTION", 44 }, + { "EPISODE_HTML_DESCRIPTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_HTML_DESCRIPTION", 45 }, + { "EPISODE_PLAYABILITY", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_PLAYABILITY", 46 }, + { "SHOW_EPISODES_ASSOC", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_EPISODES_ASSOC", 47 }, + { "CLIENT_CONFIG", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CLIENT_CONFIG", 48 }, + { "PLAYLISTABILITY", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYLISTABILITY", 49 }, + { "AUDIOBOOK_V5", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_V5", 50 }, + { "CHAPTER_V5", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CHAPTER_V5", 51 }, + { "AUDIOBOOK_SPECIFICS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_SPECIFICS", 52 }, + { "EPISODE_RANKING", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_RANKING", 53 }, + { "HTML_DESCRIPTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__HTML_DESCRIPTION", 54 }, + { "CREATOR_CHANNEL", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CREATOR_CHANNEL", 55 }, + { "AUDIOBOOK_PROVIDERS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_PROVIDERS", 56 }, + { "PLAY_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAY_TRAIT", 57 }, + { "CONTENT_WARNING", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_WARNING", 58 }, + { "IMAGE_CUE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__IMAGE_CUE", 59 }, + { "STREAM_COUNT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__STREAM_COUNT", 60 }, + { "AUDIO_ATTRIBUTES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIO_ATTRIBUTES", 61 }, + { "NAVIGABLE_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__NAVIGABLE_TRAIT", 62 }, + { "NEXT_BEST_EPISODE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__NEXT_BEST_EPISODE", 63 }, + { "AUDIOBOOK_PRICE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_PRICE", 64 }, + { "EXPRESSIVE_PLAYLISTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EXPRESSIVE_PLAYLISTS", 65 }, + { "DYNAMIC_SHOW_EPISODE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DYNAMIC_SHOW_EPISODE", 66 }, + { "LIVE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIVE", 67 }, + { "SKIP_PLAYED", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SKIP_PLAYED", 68 }, + { "AD_BREAK_FREE_PODCASTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AD_BREAK_FREE_PODCASTS", 69 }, + { "ASSOCIATIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ASSOCIATIONS", 70 }, + { "PLAYLIST_EVALUATION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYLIST_EVALUATION", 71 }, + { "CACHE_INVALIDATIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CACHE_INVALIDATIONS", 72 }, + { "LIVESTREAM_ENTITY", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIVESTREAM_ENTITY", 73 }, + { "SINGLE_TAP_REACTIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SINGLE_TAP_REACTIONS", 74 }, + { "USER_COMMENTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__USER_COMMENTS", 75 }, + { "CLIENT_RESTRICTIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CLIENT_RESTRICTIONS", 76 }, + { "PODCAST_GUEST", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_GUEST", 77 }, + { "PLAYABILITY", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYABILITY", 78 }, + { "COVER_IMAGE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__COVER_IMAGE", 79 }, + { "SHARE_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHARE_TRAIT", 80 }, + { "INSTANCE_SHARING", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__INSTANCE_SHARING", 81 }, + { "ARTIST_TOUR", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_TOUR", 82 }, + { "AUDIOBOOK_GENRE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_GENRE", 83 }, + { "CONCEPT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCEPT", 84 }, + { "ORIGINAL_VIDEO", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ORIGINAL_VIDEO", 85 }, + { "SMART_SHUFFLE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SMART_SHUFFLE", 86 }, + { "LIVE_EVENTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIVE_EVENTS", 87 }, + { "AUDIOBOOK_RELATIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_RELATIONS", 88 }, + { "HOME_POC_BASECARD", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__HOME_POC_BASECARD", 89 }, + { "AUDIOBOOK_SUPPLEMENTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_SUPPLEMENTS", 90 }, + { "PAID_PODCAST_BANNER", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PAID_PODCAST_BANNER", 91 }, + { "FEWER_ADS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__FEWER_ADS", 92 }, + { "WATCH_FEED_SHOW_EXPLORER", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__WATCH_FEED_SHOW_EXPLORER", 93 }, + { "TRACK_EXTRA_DESCRIPTORS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_EXTRA_DESCRIPTORS", 94 }, + { "TRACK_EXTRA_AUDIO_ATTRIBUTES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_EXTRA_AUDIO_ATTRIBUTES", 95 }, + { "TRACK_EXTENDED_CREDITS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_EXTENDED_CREDITS", 96 }, + { "SIMPLE_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SIMPLE_TRAIT", 97 }, + { "AUDIO_ASSOCIATIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIO_ASSOCIATIONS", 98 }, + { "VIDEO_ASSOCIATIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VIDEO_ASSOCIATIONS", 99 }, + { "PLAYLIST_TUNER", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYLIST_TUNER", 100 }, + { "ARTIST_VIDEOS_ENTRYPOINT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_VIDEOS_ENTRYPOINT", 101 }, + { "ALBUM_PRERELEASE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ALBUM_PRERELEASE", 102 }, + { "CONTENT_ALTERNATIVES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_ALTERNATIVES", 103 }, + { "SNAPSHOT_SHARING", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SNAPSHOT_SHARING", 105 }, + { "DISPLAY_SEGMENTS_COUNT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DISPLAY_SEGMENTS_COUNT", 106 }, + { "PODCAST_FEATURED_EPISODE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_FEATURED_EPISODE", 107 }, + { "PODCAST_SPONSORED_CONTENT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_SPONSORED_CONTENT", 108 }, + { "PODCAST_EPISODE_TOPICS_LLM", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_EPISODE_TOPICS_LLM", 109 }, + { "PODCAST_EPISODE_TOPICS_KG", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_EPISODE_TOPICS_KG", 110 }, + { "EPISODE_RANKING_POPULARITY", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_RANKING_POPULARITY", 111 }, + { "MERCH", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__MERCH", 112 }, + { "COMPANION_CONTENT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__COMPANION_CONTENT", 113 }, + { "WATCH_FEED_ENTITY_EXPLORER", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__WATCH_FEED_ENTITY_EXPLORER", 114 }, + { "ANCHOR_CARD_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ANCHOR_CARD_TRAIT", 115 }, + { "AUDIO_PREVIEW_PLAYBACK_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIO_PREVIEW_PLAYBACK_TRAIT", 116 }, + { "VIDEO_PREVIEW_STILL_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VIDEO_PREVIEW_STILL_TRAIT", 117 }, + { "PREVIEW_CARD_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PREVIEW_CARD_TRAIT", 118 }, + { "SHORTCUTS_CARD_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHORTCUTS_CARD_TRAIT", 119 }, + { "VIDEO_PREVIEW_PLAYBACK_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VIDEO_PREVIEW_PLAYBACK_TRAIT", 120 }, + { "COURSE_SPECIFICS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__COURSE_SPECIFICS", 121 }, + { "CONCERT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT", 122 }, + { "CONCERT_LOCATION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_LOCATION", 123 }, + { "CONCERT_MARKETING", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_MARKETING", 124 }, + { "CONCERT_PERFORMERS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_PERFORMERS", 125 }, + { "TRACK_PAIR_TRANSITION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_PAIR_TRANSITION", 126 }, + { "CONTENT_TYPE_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_TYPE_TRAIT", 127 }, + { "NAME_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__NAME_TRAIT", 128 }, + { "ARTWORK_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTWORK_TRAIT", 129 }, + { "RELEASE_DATE_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RELEASE_DATE_TRAIT", 130 }, + { "CREDITS_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CREDITS_TRAIT", 131 }, + { "RELEASE_URI_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RELEASE_URI_TRAIT", 132 }, + { "ENTITY_CAPPING", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ENTITY_CAPPING", 133 }, + { "LESSON_SPECIFICS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LESSON_SPECIFICS", 134 }, + { "CONCERT_OFFERS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_OFFERS", 135 }, + { "TRANSITION_MAPS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRANSITION_MAPS", 136 }, + { "ARTIST_HAS_CONCERTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_HAS_CONCERTS", 137 }, + { "PRERELEASE", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PRERELEASE", 138 }, + { "PLAYLIST_ATTRIBUTES_V2", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYLIST_ATTRIBUTES_V2", 139 }, + { "LIST_ATTRIBUTES_V2", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIST_ATTRIBUTES_V2", 140 }, + { "LIST_METADATA", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIST_METADATA", 141 }, + { "LIST_TUNER_AUDIO_ANALYSIS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIST_TUNER_AUDIO_ANALYSIS", 142 }, + { "LIST_TUNER_CUEPOINTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIST_TUNER_CUEPOINTS", 143 }, + { "CONTENT_RATING_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_RATING_TRAIT", 144 }, + { "COPYRIGHT_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__COPYRIGHT_TRAIT", 145 }, + { "SUPPORTED_BADGES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SUPPORTED_BADGES", 146 }, + { "BADGES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__BADGES", 147 }, + { "PREVIEW_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PREVIEW_TRAIT", 148 }, + { "ROOTLISTABILITY_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ROOTLISTABILITY_TRAIT", 149 }, + { "LOCAL_CONCERTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LOCAL_CONCERTS", 150 }, + { "RECOMMENDED_PLAYLISTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RECOMMENDED_PLAYLISTS", 151 }, + { "POPULAR_RELEASES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__POPULAR_RELEASES", 152 }, + { "RELATED_RELEASES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RELATED_RELEASES", 153 }, + { "SHARE_RESTRICTIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHARE_RESTRICTIONS", 154 }, + { "CONCERT_OFFER", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_OFFER", 155 }, + { "CONCERT_OFFER_PROVIDER", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_OFFER_PROVIDER", 156 }, + { "ENTITY_BOOKMARKS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ENTITY_BOOKMARKS", 157 }, + { "PRIVACY_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PRIVACY_TRAIT", 158 }, + { "DUPLICATE_ITEMS_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DUPLICATE_ITEMS_TRAIT", 159 }, + { "REORDERING_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__REORDERING_TRAIT", 160 }, + { "PODCAST_RESUMPTION_SEGMENTS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_RESUMPTION_SEGMENTS", 161 }, + { "ARTIST_EXPRESSION_VIDEO", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_EXPRESSION_VIDEO", 162 }, + { "PRERELEASE_VIDEO", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PRERELEASE_VIDEO", 163 }, + { "GATED_ENTITY_RELATIONS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__GATED_ENTITY_RELATIONS", 164 }, + { "RELATED_CREATORS_SECTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RELATED_CREATORS_SECTION", 165 }, + { "CREATORS_APPEARS_ON_SECTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CREATORS_APPEARS_ON_SECTION", 166 }, + { "PROMO_V1_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PROMO_V1_TRAIT", 167 }, + { "SPEECHLESS_SHARE_CARD", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SPEECHLESS_SHARE_CARD", 168 }, + { "TOP_PLAYABLES_SECTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TOP_PLAYABLES_SECTION", 169 }, + { "AUTO_LENS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUTO_LENS", 170 }, + { "PROMO_V3_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PROMO_V3_TRAIT", 171 }, + { "TRACK_CONTENT_FILTER", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_CONTENT_FILTER", 172 }, + { "HIGHLIGHTABILITY", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__HIGHLIGHTABILITY", 173 }, + { "LINK_CARD_WITH_IMAGE_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LINK_CARD_WITH_IMAGE_TRAIT", 174 }, + { "TRACK_CLOUD_SECTION", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_CLOUD_SECTION", 175 }, + { "EPISODE_TOPICS", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_TOPICS", 176 }, + { "VIDEO_THUMBNAIL", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VIDEO_THUMBNAIL", 177 }, + { "IDENTITY_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__IDENTITY_TRAIT", 178 }, + { "VISUAL_IDENTITY_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VISUAL_IDENTITY_TRAIT", 179 }, + { "CONTENT_TYPE_V2_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_TYPE_V2_TRAIT", 180 }, + { "PREVIEW_PLAYBACK_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PREVIEW_PLAYBACK_TRAIT", 181 }, + { "CONSUMPTION_EXPERIENCE_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONSUMPTION_EXPERIENCE_TRAIT", 182 }, + { "PUBLISHING_METADATA_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PUBLISHING_METADATA_TRAIT", 183 }, + { "DETAILED_EVALUATION_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DETAILED_EVALUATION_TRAIT", 184 }, + { "ON_PLATFORM_REPUTATION_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ON_PLATFORM_REPUTATION_TRAIT", 185 }, + { "CREDITS_V2_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CREDITS_V2_TRAIT", 186 }, + { "HIGHLIGHT_PLAYABILITY_TRAIT", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__HIGHLIGHT_PLAYABILITY_TRAIT", 187 }, + { "SHOW_EPISODE_LIST", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_EPISODE_LIST", 188 }, + { "AVAILABLE_RELEASES", "SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AVAILABLE_RELEASES", 189 }, +}; +static const ProtobufCIntRange spotify__extendedmetadata__extension_kind__value_ranges[] = { +{0, 0},{105, 104},{0, 189} +}; +static const ProtobufCEnumValueIndex spotify__extendedmetadata__extension_kind__enum_values_by_name[189] = +{ + { "AD_BREAK_FREE_PODCASTS", 69 }, + { "ALBUM_PRERELEASE", 102 }, + { "ALBUM_V4", 9 }, + { "ANCHOR_CARD_TRAIT", 114 }, + { "ARTIST_EXPRESSION_VIDEO", 161 }, + { "ARTIST_HAS_CONCERTS", 136 }, + { "ARTIST_TOUR", 82 }, + { "ARTIST_V4", 8 }, + { "ARTIST_VIDEOS_ENTRYPOINT", 101 }, + { "ARTWORK_TRAIT", 128 }, + { "ASSOCIATIONS", 70 }, + { "AUDIOBOOK_GENRE", 83 }, + { "AUDIOBOOK_PRICE", 64 }, + { "AUDIOBOOK_PROVIDERS", 56 }, + { "AUDIOBOOK_RELATIONS", 88 }, + { "AUDIOBOOK_SPECIFICS", 52 }, + { "AUDIOBOOK_SUPPLEMENTS", 90 }, + { "AUDIOBOOK_V5", 50 }, + { "AUDIO_ASSOCIATIONS", 98 }, + { "AUDIO_ATTRIBUTES", 61 }, + { "AUDIO_FILES", 5 }, + { "AUDIO_PREVIEW_PLAYBACK_TRAIT", 115 }, + { "AUTOMIX_MODE", 27 }, + { "AUTO_LENS", 169 }, + { "AVAILABLE_RELEASES", 188 }, + { "BADGES", 146 }, + { "CACHE_INVALIDATIONS", 72 }, + { "CANVAS_V1", 16 }, + { "CANVAZ", 1 }, + { "CHAPTER_V5", 51 }, + { "CLIENT_CONFIG", 48 }, + { "CLIENT_RESTRICTIONS", 76 }, + { "CLIPS", 33 }, + { "COMPANION_CONTENT", 112 }, + { "CONCEPT", 84 }, + { "CONCERT", 121 }, + { "CONCERT_LOCATION", 122 }, + { "CONCERT_MARKETING", 123 }, + { "CONCERT_OFFER", 154 }, + { "CONCERT_OFFERS", 134 }, + { "CONCERT_OFFER_PROVIDER", 155 }, + { "CONCERT_PERFORMERS", 124 }, + { "CONSUMPTION_EXPERIENCE_TRAIT", 181 }, + { "CONTENT_ALTERNATIVES", 103 }, + { "CONTENT_RATING_TRAIT", 143 }, + { "CONTENT_TYPE_TRAIT", 126 }, + { "CONTENT_TYPE_V2_TRAIT", 179 }, + { "CONTENT_WARNING", 58 }, + { "COPYRIGHT_TRAIT", 144 }, + { "COURSE_SPECIFICS", 120 }, + { "COVER_IMAGE", 79 }, + { "CREATORS_APPEARS_ON_SECTION", 165 }, + { "CREATOR_CHANNEL", 55 }, + { "CREDITS_TRAIT", 130 }, + { "CREDITS_V2_TRAIT", 185 }, + { "CUEPOINTS", 28 }, + { "DETAILED_EVALUATION_TRAIT", 183 }, + { "DISPLAY_SEGMENTS", 38 }, + { "DISPLAY_SEGMENTS_COUNT", 105 }, + { "DUPLICATE_ITEMS_TRAIT", 158 }, + { "DYNAMIC_SHOW_EPISODE", 66 }, + { "ENTITY_BOOKMARKS", 156 }, + { "ENTITY_CAPPING", 132 }, + { "EPISODE_ACCESS", 30 }, + { "EPISODE_DESCRIPTION", 44 }, + { "EPISODE_HTML_DESCRIPTION", 45 }, + { "EPISODE_PLAYABILITY", 46 }, + { "EPISODE_RANKING", 53 }, + { "EPISODE_RANKING_POPULARITY", 110 }, + { "EPISODE_TOPICS", 175 }, + { "EPISODE_TRANSCRIPTS", 21 }, + { "EPISODE_V4", 12 }, + { "EPISODE_V5", 35 }, + { "EXPRESSIVE_PLAYLISTS", 65 }, + { "EXTRACTED_COLOR", 23 }, + { "FEWER_ADS", 92 }, + { "GATED_ENTITY_RELATIONS", 163 }, + { "GREENROOM", 39 }, + { "HIGHLIGHTABILITY", 172 }, + { "HIGHLIGHT_PLAYABILITY_TRAIT", 186 }, + { "HOME_POC_BASECARD", 89 }, + { "HTML_DESCRIPTION", 54 }, + { "IDENTITY_TRAIT", 177 }, + { "IMAGE_CUE", 59 }, + { "IMAGE_SPARKLES_HACK", 25 }, + { "INSTANCE_SHARING", 81 }, + { "LESSON_SPECIFICS", 133 }, + { "LINK_CARD_WITH_IMAGE_TRAIT", 173 }, + { "LIST_ATTRIBUTES_V2", 139 }, + { "LIST_METADATA", 140 }, + { "LIST_TUNER_AUDIO_ANALYSIS", 141 }, + { "LIST_TUNER_CUEPOINTS", 142 }, + { "LIVE", 67 }, + { "LIVESTREAM_ENTITY", 73 }, + { "LIVE_EVENTS", 87 }, + { "LOCAL_CONCERTS", 149 }, + { "MERCH", 111 }, + { "NAME_TRAIT", 127 }, + { "NAVIGABLE_TRAIT", 62 }, + { "NEXT_BEST_EPISODE", 63 }, + { "ON_PLATFORM_REPUTATION_TRAIT", 184 }, + { "ORIGINAL_VIDEO", 85 }, + { "PAID_PODCAST_BANNER", 91 }, + { "PLAYABILITY", 78 }, + { "PLAYLISTABILITY", 49 }, + { "PLAYLIST_ATTRIBUTES_V2", 138 }, + { "PLAYLIST_EVALUATION", 71 }, + { "PLAYLIST_TUNER", 100 }, + { "PLAY_TRAIT", 57 }, + { "PODCAST_AD_SEGMENTS", 20 }, + { "PODCAST_COUNTER", 7 }, + { "PODCAST_CTA_CARDS", 36 }, + { "PODCAST_EPISODE_TOPICS_KG", 109 }, + { "PODCAST_EPISODE_TOPICS_LLM", 108 }, + { "PODCAST_FEATURED_EPISODE", 106 }, + { "PODCAST_GUEST", 77 }, + { "PODCAST_HTML_DESCRIPTION", 13 }, + { "PODCAST_POLL", 29 }, + { "PODCAST_POPULARITY_HACK", 26 }, + { "PODCAST_QNA", 32 }, + { "PODCAST_QUOTES", 14 }, + { "PODCAST_RATING", 37 }, + { "PODCAST_RESUMPTION_SEGMENTS", 160 }, + { "PODCAST_SEGMENTS", 4 }, + { "PODCAST_SPONSORED_CONTENT", 107 }, + { "PODCAST_SUBSCRIPTIONS", 22 }, + { "PODCAST_TOPICS", 3 }, + { "PODCAST_VIRALITY", 24 }, + { "POPULAR_RELEASES", 151 }, + { "PRERELEASE", 137 }, + { "PRERELEASE_VIDEO", 162 }, + { "PREVIEW_CARD_TRAIT", 117 }, + { "PREVIEW_PLAYBACK_TRAIT", 180 }, + { "PREVIEW_TRAIT", 147 }, + { "PRIVACY_TRAIT", 157 }, + { "PROMO_V1_TRAIT", 166 }, + { "PROMO_V3_TRAIT", 170 }, + { "PUBLISHING_METADATA_TRAIT", 182 }, + { "RECOMMENDED_PLAYLISTS", 150 }, + { "RELATED_CREATORS_SECTION", 164 }, + { "RELATED_RELEASES", 152 }, + { "RELEASE_DATE_TRAIT", 129 }, + { "RELEASE_URI_TRAIT", 131 }, + { "REORDERING_TRAIT", 159 }, + { "ROOTLISTABILITY_TRAIT", 148 }, + { "SHARE_RESTRICTIONS", 153 }, + { "SHARE_TRAIT", 80 }, + { "SHORTCUTS_CARD_TRAIT", 118 }, + { "SHOW_ACCESS", 31 }, + { "SHOW_DESCRIPTION", 41 }, + { "SHOW_EPISODES_ASSOC", 47 }, + { "SHOW_EPISODE_LIST", 187 }, + { "SHOW_HTML_DESCRIPTION", 42 }, + { "SHOW_PLAYABILITY", 43 }, + { "SHOW_V4", 11 }, + { "SHOW_V4_BASE", 17 }, + { "SHOW_V4_EPISODES_ASSOC", 18 }, + { "SHOW_V5", 34 }, + { "SIMPLE_TRAIT", 97 }, + { "SINGLE_TAP_REACTIONS", 74 }, + { "SKIP_PLAYED", 68 }, + { "SMART_SHUFFLE", 86 }, + { "SNAPSHOT_SHARING", 104 }, + { "SPEECHLESS_SHARE_CARD", 167 }, + { "STORYLINES", 2 }, + { "STREAM_COUNT", 60 }, + { "SUPPORTED_BADGES", 145 }, + { "TOP_PLAYABLES_SECTION", 168 }, + { "TRACK_CLOUD_SECTION", 174 }, + { "TRACK_CONTENT_FILTER", 171 }, + { "TRACK_DESCRIPTOR", 6 }, + { "TRACK_DESCRIPTOR_SIGNATURES", 19 }, + { "TRACK_EXTENDED_CREDITS", 96 }, + { "TRACK_EXTRA_AUDIO_ATTRIBUTES", 95 }, + { "TRACK_EXTRA_DESCRIPTORS", 94 }, + { "TRACK_PAIR_TRANSITION", 125 }, + { "TRACK_V4", 10 }, + { "TRANSITION_MAPS", 135 }, + { "UNKNOWN_EXTENSION", 0 }, + { "USER_COMMENTS", 75 }, + { "USER_CREATED", 40 }, + { "USER_PROFILE", 15 }, + { "VIDEO_ASSOCIATIONS", 99 }, + { "VIDEO_PREVIEW_PLAYBACK_TRAIT", 119 }, + { "VIDEO_PREVIEW_STILL_TRAIT", 116 }, + { "VIDEO_THUMBNAIL", 176 }, + { "VISUAL_IDENTITY_TRAIT", 178 }, + { "WATCH_FEED_ENTITY_EXPLORER", 113 }, + { "WATCH_FEED_SHOW_EXPLORER", 93 }, +}; +const ProtobufCEnumDescriptor spotify__extendedmetadata__extension_kind__descriptor = +{ + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "spotify.extendedmetadata.ExtensionKind", + "ExtensionKind", + "Spotify__Extendedmetadata__ExtensionKind", + "spotify.extendedmetadata", + 189, + spotify__extendedmetadata__extension_kind__enum_values_by_number, + 189, + spotify__extendedmetadata__extension_kind__enum_values_by_name, + 2, + spotify__extendedmetadata__extension_kind__value_ranges, + NULL,NULL,NULL,NULL /* reserved[1234] */ +}; diff --git a/src/inputs/librespot-c/src/proto/extension_kind.pb-c.h b/src/inputs/librespot-c/src/proto/extension_kind.pb-c.h new file mode 100644 index 00000000..8f13b02e --- /dev/null +++ b/src/inputs/librespot-c/src/proto/extension_kind.pb-c.h @@ -0,0 +1,230 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: extension_kind.proto */ + +#ifndef PROTOBUF_C_extension_5fkind_2eproto__INCLUDED +#define PROTOBUF_C_extension_5fkind_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + + + + +/* --- enums --- */ + +typedef enum _Spotify__Extendedmetadata__ExtensionKind { + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__UNKNOWN_EXTENSION = 0, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CANVAZ = 1, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__STORYLINES = 2, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_TOPICS = 3, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_SEGMENTS = 4, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIO_FILES = 5, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_DESCRIPTOR = 6, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_COUNTER = 7, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_V4 = 8, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ALBUM_V4 = 9, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_V4 = 10, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_V4 = 11, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_V4 = 12, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_HTML_DESCRIPTION = 13, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_QUOTES = 14, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__USER_PROFILE = 15, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CANVAS_V1 = 16, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_V4_BASE = 17, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_V4_EPISODES_ASSOC = 18, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_DESCRIPTOR_SIGNATURES = 19, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_AD_SEGMENTS = 20, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_TRANSCRIPTS = 21, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_SUBSCRIPTIONS = 22, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EXTRACTED_COLOR = 23, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_VIRALITY = 24, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__IMAGE_SPARKLES_HACK = 25, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_POPULARITY_HACK = 26, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUTOMIX_MODE = 27, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CUEPOINTS = 28, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_POLL = 29, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_ACCESS = 30, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_ACCESS = 31, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_QNA = 32, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CLIPS = 33, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_V5 = 34, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_V5 = 35, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_CTA_CARDS = 36, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_RATING = 37, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DISPLAY_SEGMENTS = 38, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__GREENROOM = 39, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__USER_CREATED = 40, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_DESCRIPTION = 41, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_HTML_DESCRIPTION = 42, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_PLAYABILITY = 43, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_DESCRIPTION = 44, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_HTML_DESCRIPTION = 45, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_PLAYABILITY = 46, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_EPISODES_ASSOC = 47, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CLIENT_CONFIG = 48, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYLISTABILITY = 49, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_V5 = 50, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CHAPTER_V5 = 51, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_SPECIFICS = 52, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_RANKING = 53, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__HTML_DESCRIPTION = 54, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CREATOR_CHANNEL = 55, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_PROVIDERS = 56, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAY_TRAIT = 57, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_WARNING = 58, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__IMAGE_CUE = 59, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__STREAM_COUNT = 60, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIO_ATTRIBUTES = 61, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__NAVIGABLE_TRAIT = 62, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__NEXT_BEST_EPISODE = 63, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_PRICE = 64, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EXPRESSIVE_PLAYLISTS = 65, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DYNAMIC_SHOW_EPISODE = 66, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIVE = 67, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SKIP_PLAYED = 68, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AD_BREAK_FREE_PODCASTS = 69, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ASSOCIATIONS = 70, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYLIST_EVALUATION = 71, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CACHE_INVALIDATIONS = 72, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIVESTREAM_ENTITY = 73, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SINGLE_TAP_REACTIONS = 74, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__USER_COMMENTS = 75, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CLIENT_RESTRICTIONS = 76, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_GUEST = 77, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYABILITY = 78, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__COVER_IMAGE = 79, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHARE_TRAIT = 80, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__INSTANCE_SHARING = 81, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_TOUR = 82, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_GENRE = 83, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCEPT = 84, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ORIGINAL_VIDEO = 85, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SMART_SHUFFLE = 86, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIVE_EVENTS = 87, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_RELATIONS = 88, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__HOME_POC_BASECARD = 89, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIOBOOK_SUPPLEMENTS = 90, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PAID_PODCAST_BANNER = 91, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__FEWER_ADS = 92, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__WATCH_FEED_SHOW_EXPLORER = 93, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_EXTRA_DESCRIPTORS = 94, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_EXTRA_AUDIO_ATTRIBUTES = 95, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_EXTENDED_CREDITS = 96, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SIMPLE_TRAIT = 97, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIO_ASSOCIATIONS = 98, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VIDEO_ASSOCIATIONS = 99, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYLIST_TUNER = 100, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_VIDEOS_ENTRYPOINT = 101, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ALBUM_PRERELEASE = 102, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_ALTERNATIVES = 103, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SNAPSHOT_SHARING = 105, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DISPLAY_SEGMENTS_COUNT = 106, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_FEATURED_EPISODE = 107, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_SPONSORED_CONTENT = 108, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_EPISODE_TOPICS_LLM = 109, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_EPISODE_TOPICS_KG = 110, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_RANKING_POPULARITY = 111, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__MERCH = 112, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__COMPANION_CONTENT = 113, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__WATCH_FEED_ENTITY_EXPLORER = 114, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ANCHOR_CARD_TRAIT = 115, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUDIO_PREVIEW_PLAYBACK_TRAIT = 116, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VIDEO_PREVIEW_STILL_TRAIT = 117, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PREVIEW_CARD_TRAIT = 118, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHORTCUTS_CARD_TRAIT = 119, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VIDEO_PREVIEW_PLAYBACK_TRAIT = 120, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__COURSE_SPECIFICS = 121, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT = 122, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_LOCATION = 123, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_MARKETING = 124, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_PERFORMERS = 125, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_PAIR_TRANSITION = 126, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_TYPE_TRAIT = 127, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__NAME_TRAIT = 128, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTWORK_TRAIT = 129, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RELEASE_DATE_TRAIT = 130, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CREDITS_TRAIT = 131, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RELEASE_URI_TRAIT = 132, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ENTITY_CAPPING = 133, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LESSON_SPECIFICS = 134, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_OFFERS = 135, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRANSITION_MAPS = 136, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_HAS_CONCERTS = 137, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PRERELEASE = 138, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PLAYLIST_ATTRIBUTES_V2 = 139, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIST_ATTRIBUTES_V2 = 140, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIST_METADATA = 141, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIST_TUNER_AUDIO_ANALYSIS = 142, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LIST_TUNER_CUEPOINTS = 143, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_RATING_TRAIT = 144, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__COPYRIGHT_TRAIT = 145, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SUPPORTED_BADGES = 146, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__BADGES = 147, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PREVIEW_TRAIT = 148, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ROOTLISTABILITY_TRAIT = 149, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LOCAL_CONCERTS = 150, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RECOMMENDED_PLAYLISTS = 151, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__POPULAR_RELEASES = 152, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RELATED_RELEASES = 153, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHARE_RESTRICTIONS = 154, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_OFFER = 155, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONCERT_OFFER_PROVIDER = 156, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ENTITY_BOOKMARKS = 157, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PRIVACY_TRAIT = 158, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DUPLICATE_ITEMS_TRAIT = 159, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__REORDERING_TRAIT = 160, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PODCAST_RESUMPTION_SEGMENTS = 161, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ARTIST_EXPRESSION_VIDEO = 162, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PRERELEASE_VIDEO = 163, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__GATED_ENTITY_RELATIONS = 164, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__RELATED_CREATORS_SECTION = 165, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CREATORS_APPEARS_ON_SECTION = 166, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PROMO_V1_TRAIT = 167, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SPEECHLESS_SHARE_CARD = 168, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TOP_PLAYABLES_SECTION = 169, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AUTO_LENS = 170, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PROMO_V3_TRAIT = 171, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_CONTENT_FILTER = 172, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__HIGHLIGHTABILITY = 173, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__LINK_CARD_WITH_IMAGE_TRAIT = 174, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__TRACK_CLOUD_SECTION = 175, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__EPISODE_TOPICS = 176, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VIDEO_THUMBNAIL = 177, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__IDENTITY_TRAIT = 178, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__VISUAL_IDENTITY_TRAIT = 179, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONTENT_TYPE_V2_TRAIT = 180, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PREVIEW_PLAYBACK_TRAIT = 181, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CONSUMPTION_EXPERIENCE_TRAIT = 182, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__PUBLISHING_METADATA_TRAIT = 183, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__DETAILED_EVALUATION_TRAIT = 184, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__ON_PLATFORM_REPUTATION_TRAIT = 185, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__CREDITS_V2_TRAIT = 186, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__HIGHLIGHT_PLAYABILITY_TRAIT = 187, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__SHOW_EPISODE_LIST = 188, + SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND__AVAILABLE_RELEASES = 189 + PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(SPOTIFY__EXTENDEDMETADATA__EXTENSION_KIND) +} Spotify__Extendedmetadata__ExtensionKind; + +/* --- messages --- */ + +/* --- per-message closures --- */ + + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCEnumDescriptor spotify__extendedmetadata__extension_kind__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_extension_5fkind_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/extension_kind.proto b/src/inputs/librespot-c/src/proto/extension_kind.proto new file mode 100644 index 00000000..fd94586e --- /dev/null +++ b/src/inputs/librespot-c/src/proto/extension_kind.proto @@ -0,0 +1,195 @@ +syntax = "proto3"; + +package spotify.extendedmetadata; + +enum ExtensionKind { + UNKNOWN_EXTENSION = 0; + CANVAZ = 1; + STORYLINES = 2; + PODCAST_TOPICS = 3; + PODCAST_SEGMENTS = 4; + AUDIO_FILES = 5; + TRACK_DESCRIPTOR = 6; + PODCAST_COUNTER = 7; + ARTIST_V4 = 8; + ALBUM_V4 = 9; + TRACK_V4 = 10; + SHOW_V4 = 11; + EPISODE_V4 = 12; + PODCAST_HTML_DESCRIPTION = 13; + PODCAST_QUOTES = 14; + USER_PROFILE = 15; + CANVAS_V1 = 16; + SHOW_V4_BASE = 17; + SHOW_V4_EPISODES_ASSOC = 18; + TRACK_DESCRIPTOR_SIGNATURES = 19; + PODCAST_AD_SEGMENTS = 20; + EPISODE_TRANSCRIPTS = 21; + PODCAST_SUBSCRIPTIONS = 22; + EXTRACTED_COLOR = 23; + PODCAST_VIRALITY = 24; + IMAGE_SPARKLES_HACK = 25; + PODCAST_POPULARITY_HACK = 26; + AUTOMIX_MODE = 27; + CUEPOINTS = 28; + PODCAST_POLL = 29; + EPISODE_ACCESS = 30; + SHOW_ACCESS = 31; + PODCAST_QNA = 32; + CLIPS = 33; + SHOW_V5 = 34; + EPISODE_V5 = 35; + PODCAST_CTA_CARDS = 36; + PODCAST_RATING = 37; + DISPLAY_SEGMENTS = 38; + GREENROOM = 39; + USER_CREATED = 40; + SHOW_DESCRIPTION = 41; + SHOW_HTML_DESCRIPTION = 42; + SHOW_PLAYABILITY = 43; + EPISODE_DESCRIPTION = 44; + EPISODE_HTML_DESCRIPTION = 45; + EPISODE_PLAYABILITY = 46; + SHOW_EPISODES_ASSOC = 47; + CLIENT_CONFIG = 48; + PLAYLISTABILITY = 49; + AUDIOBOOK_V5 = 50; + CHAPTER_V5 = 51; + AUDIOBOOK_SPECIFICS = 52; + EPISODE_RANKING = 53; + HTML_DESCRIPTION = 54; + CREATOR_CHANNEL = 55; + AUDIOBOOK_PROVIDERS = 56; + PLAY_TRAIT = 57; + CONTENT_WARNING = 58; + IMAGE_CUE = 59; + STREAM_COUNT = 60; + AUDIO_ATTRIBUTES = 61; + NAVIGABLE_TRAIT = 62; + NEXT_BEST_EPISODE = 63; + AUDIOBOOK_PRICE = 64; + EXPRESSIVE_PLAYLISTS = 65; + DYNAMIC_SHOW_EPISODE = 66; + LIVE = 67; + SKIP_PLAYED = 68; + AD_BREAK_FREE_PODCASTS = 69; + ASSOCIATIONS = 70; + PLAYLIST_EVALUATION = 71; + CACHE_INVALIDATIONS = 72; + LIVESTREAM_ENTITY = 73; + SINGLE_TAP_REACTIONS = 74; + USER_COMMENTS = 75; + CLIENT_RESTRICTIONS = 76; + PODCAST_GUEST = 77; + PLAYABILITY = 78; + COVER_IMAGE = 79; + SHARE_TRAIT = 80; + INSTANCE_SHARING = 81; + ARTIST_TOUR = 82; + AUDIOBOOK_GENRE = 83; + CONCEPT = 84; + ORIGINAL_VIDEO = 85; + SMART_SHUFFLE = 86; + LIVE_EVENTS = 87; + AUDIOBOOK_RELATIONS = 88; + HOME_POC_BASECARD = 89; + AUDIOBOOK_SUPPLEMENTS = 90; + PAID_PODCAST_BANNER = 91; + FEWER_ADS = 92; + WATCH_FEED_SHOW_EXPLORER = 93; + TRACK_EXTRA_DESCRIPTORS = 94; + TRACK_EXTRA_AUDIO_ATTRIBUTES = 95; + TRACK_EXTENDED_CREDITS = 96; + SIMPLE_TRAIT = 97; + AUDIO_ASSOCIATIONS = 98; + VIDEO_ASSOCIATIONS = 99; + PLAYLIST_TUNER = 100; + ARTIST_VIDEOS_ENTRYPOINT = 101; + ALBUM_PRERELEASE = 102; + CONTENT_ALTERNATIVES = 103; + SNAPSHOT_SHARING = 105; + DISPLAY_SEGMENTS_COUNT = 106; + PODCAST_FEATURED_EPISODE = 107; + PODCAST_SPONSORED_CONTENT = 108; + PODCAST_EPISODE_TOPICS_LLM = 109; + PODCAST_EPISODE_TOPICS_KG = 110; + EPISODE_RANKING_POPULARITY = 111; + MERCH = 112; + COMPANION_CONTENT = 113; + WATCH_FEED_ENTITY_EXPLORER = 114; + ANCHOR_CARD_TRAIT = 115; + AUDIO_PREVIEW_PLAYBACK_TRAIT = 116; + VIDEO_PREVIEW_STILL_TRAIT = 117; + PREVIEW_CARD_TRAIT = 118; + SHORTCUTS_CARD_TRAIT = 119; + VIDEO_PREVIEW_PLAYBACK_TRAIT = 120; + COURSE_SPECIFICS = 121; + CONCERT = 122; + CONCERT_LOCATION = 123; + CONCERT_MARKETING = 124; + CONCERT_PERFORMERS = 125; + TRACK_PAIR_TRANSITION = 126; + CONTENT_TYPE_TRAIT = 127; + NAME_TRAIT = 128; + ARTWORK_TRAIT = 129; + RELEASE_DATE_TRAIT = 130; + CREDITS_TRAIT = 131; + RELEASE_URI_TRAIT = 132; + ENTITY_CAPPING = 133; + LESSON_SPECIFICS = 134; + CONCERT_OFFERS = 135; + TRANSITION_MAPS = 136; + ARTIST_HAS_CONCERTS = 137; + PRERELEASE = 138; + PLAYLIST_ATTRIBUTES_V2 = 139; + LIST_ATTRIBUTES_V2 = 140; + LIST_METADATA = 141; + LIST_TUNER_AUDIO_ANALYSIS = 142; + LIST_TUNER_CUEPOINTS = 143; + CONTENT_RATING_TRAIT = 144; + COPYRIGHT_TRAIT = 145; + SUPPORTED_BADGES = 146; + BADGES = 147; + PREVIEW_TRAIT = 148; + ROOTLISTABILITY_TRAIT = 149; + LOCAL_CONCERTS = 150; + RECOMMENDED_PLAYLISTS = 151; + POPULAR_RELEASES = 152; + RELATED_RELEASES = 153; + SHARE_RESTRICTIONS = 154; + CONCERT_OFFER = 155; + CONCERT_OFFER_PROVIDER = 156; + ENTITY_BOOKMARKS = 157; + PRIVACY_TRAIT = 158; + DUPLICATE_ITEMS_TRAIT = 159; + REORDERING_TRAIT = 160; + PODCAST_RESUMPTION_SEGMENTS = 161; + ARTIST_EXPRESSION_VIDEO = 162; + PRERELEASE_VIDEO = 163; + GATED_ENTITY_RELATIONS = 164; + RELATED_CREATORS_SECTION = 165; + CREATORS_APPEARS_ON_SECTION = 166; + PROMO_V1_TRAIT = 167; + SPEECHLESS_SHARE_CARD = 168; + TOP_PLAYABLES_SECTION = 169; + AUTO_LENS = 170; + PROMO_V3_TRAIT = 171; + TRACK_CONTENT_FILTER = 172; + HIGHLIGHTABILITY = 173; + LINK_CARD_WITH_IMAGE_TRAIT = 174; + TRACK_CLOUD_SECTION = 175; + EPISODE_TOPICS = 176; + VIDEO_THUMBNAIL = 177; + IDENTITY_TRAIT = 178; + VISUAL_IDENTITY_TRAIT = 179; + CONTENT_TYPE_V2_TRAIT = 180; + PREVIEW_PLAYBACK_TRAIT = 181; + CONSUMPTION_EXPERIENCE_TRAIT = 182; + PUBLISHING_METADATA_TRAIT = 183; + DETAILED_EVALUATION_TRAIT = 184; + ON_PLATFORM_REPUTATION_TRAIT = 185; + CREDITS_V2_TRAIT = 186; + HIGHLIGHT_PLAYABILITY_TRAIT = 187; + SHOW_EPISODE_LIST = 188; + AVAILABLE_RELEASES = 189; +} diff --git a/src/inputs/librespot-c/src/proto/google_any.pb-c.c b/src/inputs/librespot-c/src/proto/google_any.pb-c.c new file mode 100644 index 00000000..748cb3ac --- /dev/null +++ b/src/inputs/librespot-c/src/proto/google_any.pb-c.c @@ -0,0 +1,105 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: google_any.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "google_any.pb-c.h" +void google__protobuf__any__init + (Google__Protobuf__Any *message) +{ + static const Google__Protobuf__Any init_value = GOOGLE__PROTOBUF__ANY__INIT; + *message = init_value; +} +size_t google__protobuf__any__get_packed_size + (const Google__Protobuf__Any *message) +{ + assert(message->base.descriptor == &google__protobuf__any__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t google__protobuf__any__pack + (const Google__Protobuf__Any *message, + uint8_t *out) +{ + assert(message->base.descriptor == &google__protobuf__any__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t google__protobuf__any__pack_to_buffer + (const Google__Protobuf__Any *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &google__protobuf__any__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Google__Protobuf__Any * + google__protobuf__any__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Google__Protobuf__Any *) + protobuf_c_message_unpack (&google__protobuf__any__descriptor, + allocator, len, data); +} +void google__protobuf__any__free_unpacked + (Google__Protobuf__Any *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &google__protobuf__any__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} +static const ProtobufCFieldDescriptor google__protobuf__any__field_descriptors[2] = +{ + { + "type_url", + 1, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(Google__Protobuf__Any, type_url), + NULL, + &protobuf_c_empty_string, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, + { + "value", + 2, + PROTOBUF_C_LABEL_NONE, + PROTOBUF_C_TYPE_BYTES, + 0, /* quantifier_offset */ + offsetof(Google__Protobuf__Any, value), + NULL, + NULL, + 0, /* flags */ + 0,NULL,NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned google__protobuf__any__field_indices_by_name[] = { + 0, /* field[0] = type_url */ + 1, /* field[1] = value */ +}; +static const ProtobufCIntRange google__protobuf__any__number_ranges[1 + 1] = +{ + { 1, 0 }, + { 0, 2 } +}; +const ProtobufCMessageDescriptor google__protobuf__any__descriptor = +{ + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "google.protobuf.Any", + "Any", + "Google__Protobuf__Any", + "google.protobuf", + sizeof(Google__Protobuf__Any), + 2, + google__protobuf__any__field_descriptors, + google__protobuf__any__field_indices_by_name, + 1, google__protobuf__any__number_ranges, + (ProtobufCMessageInit) google__protobuf__any__init, + NULL,NULL,NULL /* reserved[123] */ +}; diff --git a/src/inputs/librespot-c/src/proto/google_any.pb-c.h b/src/inputs/librespot-c/src/proto/google_any.pb-c.h new file mode 100644 index 00000000..81b1fbe4 --- /dev/null +++ b/src/inputs/librespot-c/src/proto/google_any.pb-c.h @@ -0,0 +1,72 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: google_any.proto */ + +#ifndef PROTOBUF_C_google_5fany_2eproto__INCLUDED +#define PROTOBUF_C_google_5fany_2eproto__INCLUDED + +#include + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1003000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1004001 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + + +typedef struct Google__Protobuf__Any Google__Protobuf__Any; + + +/* --- enums --- */ + + +/* --- messages --- */ + +struct Google__Protobuf__Any +{ + ProtobufCMessage base; + char *type_url; + ProtobufCBinaryData value; +}; +#define GOOGLE__PROTOBUF__ANY__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&google__protobuf__any__descriptor) \ + , (char *)protobuf_c_empty_string, {0,NULL} } + + +/* Google__Protobuf__Any methods */ +void google__protobuf__any__init + (Google__Protobuf__Any *message); +size_t google__protobuf__any__get_packed_size + (const Google__Protobuf__Any *message); +size_t google__protobuf__any__pack + (const Google__Protobuf__Any *message, + uint8_t *out); +size_t google__protobuf__any__pack_to_buffer + (const Google__Protobuf__Any *message, + ProtobufCBuffer *buffer); +Google__Protobuf__Any * + google__protobuf__any__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void google__protobuf__any__free_unpacked + (Google__Protobuf__Any *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*Google__Protobuf__Any_Closure) + (const Google__Protobuf__Any *message, + void *closure_data); + +/* --- services --- */ + + +/* --- descriptors --- */ + +extern const ProtobufCMessageDescriptor google__protobuf__any__descriptor; + +PROTOBUF_C__END_DECLS + + +#endif /* PROTOBUF_C_google_5fany_2eproto__INCLUDED */ diff --git a/src/inputs/librespot-c/src/proto/google_any.proto b/src/inputs/librespot-c/src/proto/google_any.proto new file mode 100644 index 00000000..887dde4c --- /dev/null +++ b/src/inputs/librespot-c/src/proto/google_any.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package google.protobuf; + +option csharp_namespace = "Google.Protobuf.WellKnownTypes"; +option objc_class_prefix = "GPB"; +option go_package = "google.golang.org/protobuf/types/known/anypb"; +option java_multiple_files = true; +option java_outer_classname = "AnyProto"; +option java_package = "com.google.protobuf"; + +message Any { + string type_url = 1; + bytes value = 2; +} diff --git a/src/library/filescanner.c b/src/library/filescanner.c index ffcf9e59..de3169a5 100644 --- a/src/library/filescanner.c +++ b/src/library/filescanner.c @@ -115,6 +115,7 @@ struct stacked_dir { static int inofd; static struct event *inoev; +static struct event *mntev; static struct deferred_pl *playlists; static struct stacked_dir *dirstack; @@ -1130,13 +1131,6 @@ process_inotify_dir(struct watch_info *wi, char *path, struct inotify_event *ie) DPRINTF(E_DBG, L_SCAN, "Directory event: 0x%08x, cookie 0x%08x, wd %d\n", ie->mask, ie->cookie, wi->wd); - if (ie->mask & IN_UNMOUNT) - { - db_file_disable_bymatch(path, STRIP_NONE, 0); - db_pl_disable_bymatch(path, STRIP_NONE, 0); - db_directory_disable_bymatch(path, STRIP_NONE, 0); - } - if (ie->mask & IN_MOVE_SELF) { /* A directory we know about, that got moved from a place @@ -1508,6 +1502,7 @@ inotify_cb(int fd, short event, void *arg) { struct inotify_event *ie; struct watch_info wi; + struct stat sb; uint8_t *buf; uint8_t *ptr; char path[PATH_MAX]; @@ -1565,8 +1560,16 @@ inotify_cb(int fd, short event, void *arg) DPRINTF(E_DBG, L_SCAN, "%s deleted or backing filesystem unmounted!\n", wi.path); db_watch_delete_bywd(ie->wd); - free_wi(&wi, 1); - continue; + + // Is the directory gone? + if (! (lstat(wi.path, &sb) == 0 && S_ISDIR(sb.st_mode))) + { + free_wi(&wi, 1); + continue; + } + + // After an unmount event the mount point is a regular dir that we must process + ie->mask |= IN_CREATE; } path[0] = '\0'; @@ -1614,28 +1617,77 @@ inotify_cb(int fd, short event, void *arg) event_add(inoev, NULL); } +static void +mount_cb(int fd, short event, void *arg) +{ + struct watch_info wi = { 0 }; + char *path = NULL; + enum mountwatch_event mev; + int parent_id; + int ret; + + mev = mountwatch_event_get(&path); + if (mev == MOUNTWATCH_ERR || mev == MOUNTWATCH_NONE) + goto readd; + + // Check if this is a location we are watching + ret = db_watch_get_bypath(&wi, path); + if (ret < 0) + goto readd; + + if (mev == MOUNTWATCH_MOUNT) + { + DPRINTF(E_DBG, L_SCAN, "MNT_MOUNT path %s\n", path); + + // After a mount, the inotify watch we had on the mount point will no + // longer be working, so remove. + inotify_rm_watch(inofd, wi.wd); + db_watch_delete_bywd(wi.wd); + + // Adds watches, scans and sets disabled = 0 + parent_id = get_parent_dir_id(path); + process_directories(path, parent_id, 0); + } + else if (mev == MOUNTWATCH_UNMOUNT) + { + DPRINTF(E_DBG, L_SCAN, "MNT_UNMOUNT path %s\n", path); + + db_file_disable_bymatch(path, STRIP_NONE, 0); + db_pl_disable_bymatch(path, STRIP_NONE, 0); + db_directory_disable_bymatch(path, STRIP_NONE, 0); + } + + readd: + free_wi(&wi, 1); + free(path); + event_add(mntev, NULL); +} + /* Thread: main & scan */ static int inofd_event_set(void) { + int mntfd; + inofd = inotify_init1(IN_CLOEXEC); if (inofd < 0) { DPRINTF(E_FATAL, L_SCAN, "Could not create inotify fd: %s\n", strerror(errno)); - return -1; } + else + CHECK_NULL(L_SCAN, inoev = event_new(evbase_lib, inofd, EV_READ, inotify_cb, NULL)); - inoev = event_new(evbase_lib, inofd, EV_READ, inotify_cb, NULL); + // If mountwatch cannot be initialized we create mntev as a timer (that will + // never trigger), so that all the event_add() don't need a "if (mntev)" test. + mntfd = mountwatch_init(); + if (mntfd >= 0) + CHECK_NULL(L_SCAN, mntev = event_new(evbase_lib, mntfd, EV_READ, mount_cb, NULL)); + else + CHECK_NULL(L_SCAN, mntev = evtimer_new(evbase_lib, mount_cb, NULL)); #ifndef __linux__ - deferred_inoev = evtimer_new(evbase_lib, inotify_deferred_cb, NULL); - if (!deferred_inoev) - { - DPRINTF(E_LOG, L_SCAN, "Could not create deferred inotify event\n"); - - return -1; - } + CHECK_NULL(L_SCAN, deferred_inoev = evtimer_new(evbase_lib, inotify_deferred_cb, NULL)); #endif return 0; @@ -1648,6 +1700,9 @@ inofd_event_unset(void) #ifndef __linux__ event_free(deferred_inoev); #endif + event_free(mntev); + mountwatch_deinit(); + event_free(inoev); close(inofd); } @@ -1674,6 +1729,7 @@ filescanner_initscan() { /* Enable inotify */ event_add(inoev, NULL); + event_add(mntev, NULL); } return 0; } @@ -1692,6 +1748,7 @@ filescanner_rescan() { /* Enable inotify */ event_add(inoev, NULL); + event_add(mntev, NULL); } return 0; } @@ -1710,6 +1767,7 @@ filescanner_metarescan() { /* Enable inotify */ event_add(inoev, NULL); + event_add(mntev, NULL); } return 0; } @@ -1727,6 +1785,7 @@ filescanner_fullrescan() { /* Enable inotify */ event_add(inoev, NULL); + event_add(mntev, NULL); } return 0; } @@ -2210,9 +2269,7 @@ filescanner_init(void) ret = inofd_event_set(); if (ret < 0) - { - return -1; - } + return -1; return 0; } diff --git a/src/library/filescanner.h b/src/library/filescanner.h index 52370c1e..ac749516 100644 --- a/src/library/filescanner.h +++ b/src/library/filescanner.h @@ -4,6 +4,13 @@ #include "db.h" +enum mountwatch_event +{ + MOUNTWATCH_ERR = -1, + MOUNTWATCH_NONE = 0, + MOUNTWATCH_MOUNT = 1, + MOUNTWATCH_UNMOUNT = 2, +}; /* --------------------------- Actual scanners ---------------------------- */ @@ -84,4 +91,13 @@ playlist_add(const char *path); int write_metadata_ffmpeg(const struct media_file_info *mfi); +int +mountwatch_event_get(char **path); + +void +mountwatch_deinit(void); + +int +mountwatch_init(void); + #endif /* !__FILESCANNER_H__ */ diff --git a/src/library/filescanner_itunes.c b/src/library/filescanner_itunes.c index bf83b09a..017b4d1b 100644 --- a/src/library/filescanner_itunes.c +++ b/src/library/filescanner_itunes.c @@ -219,8 +219,6 @@ static int get_dictval_date_from_key(plist_t dict, const char *key, uint32_t *val) { plist_t node; - int32_t secs; - int32_t dummy; node = plist_dict_get_item(dict, key); @@ -230,11 +228,22 @@ get_dictval_date_from_key(plist_t dict, const char *key, uint32_t *val) if (plist_get_node_type(node) != PLIST_DATE) return -1; +#if HAVE_DECL_PLIST_GET_UNIX_DATE_VAL + int64_t secs; + + plist_get_unix_date_val(node, &secs); + + *val = (uint32_t) secs; +#else + int32_t secs; + int32_t dummy; + // secs will be number of seconds since 01/01/2001 plist_get_date_val(node, &secs, &dummy); // make it a Unix Timestamp by adding seconds from 1/1/1970 to 1/1/2001 *val = (uint32_t) (secs + 978307200); +#endif return 0; } diff --git a/src/library/filescanner_mountwatch.c b/src/library/filescanner_mountwatch.c new file mode 100644 index 00000000..e9b55e82 --- /dev/null +++ b/src/library/filescanner_mountwatch.c @@ -0,0 +1,162 @@ +#include +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "filescanner.h" +#include "config.h" +#include "misc.h" +#include "logger.h" + +#ifdef HAVE_LIBMOUNT +#include + +static struct libmnt_monitor *mountwatch_monitor; +static struct libmnt_table *mountwatch_table; + +// path is allocated if a change is found +static int +compare_tables(char **path, struct libmnt_table *old_tab, struct libmnt_table *new_tab) +{ + struct libmnt_iter *iter; + struct libmnt_fs *fs; + const char *target; + + *path = NULL; + + CHECK_NULL(L_SCAN, iter = mnt_new_iter(MNT_ITER_FORWARD)); + + // Find new mounts (in new_tab but not in old_tab) + mnt_reset_iter(iter, MNT_ITER_FORWARD); + while (mnt_table_next_fs(new_tab, iter, &fs) == 0) + { + target = mnt_fs_get_target(fs); + if (!target || mnt_table_find_target(old_tab, target, MNT_ITER_FORWARD)) + continue; + + *path = strdup(target); + return MOUNTWATCH_MOUNT; + } + + // Find removed mounts (in old_tab but not in new_tab) + mnt_reset_iter(iter, MNT_ITER_FORWARD); + while (mnt_table_next_fs(old_tab, iter, &fs) == 0) + { + target = mnt_fs_get_target(fs); + if (!target || mnt_table_find_target(new_tab, target, MNT_ITER_FORWARD)) + continue; + + *path = strdup(target); + return MOUNTWATCH_UNMOUNT; + } + + mnt_free_iter(iter); + return MOUNTWATCH_NONE; +} + +int +mountwatch_event_get(char **path) +{ + struct libmnt_table *newtable = NULL; + enum mountwatch_event event; + int ret; + + *path = NULL; + + ret = mnt_monitor_event_cleanup(mountwatch_monitor); + if (ret < 0) + { + DPRINTF(E_WARN, L_SCAN, "Monitor cleanup failed: %s\n", strerror(-ret)); + goto error; + } + + CHECK_NULL(L_SCAN, newtable = mnt_new_table()); + + ret = mnt_table_parse_mtab(newtable, NULL); + if (ret < 0) + { + DPRINTF(E_WARN, L_SCAN, "Failed to reload mount table: %s\n", strerror(-ret)); + goto error; + } + + event = compare_tables(path, mountwatch_table, newtable); + + mnt_unref_table(mountwatch_table); + mountwatch_table = newtable; + + return event; + + error: + if (newtable) + mnt_unref_table(newtable); + + return MOUNTWATCH_ERR; +} + +void +mountwatch_deinit(void) +{ + mnt_unref_table(mountwatch_table); + mountwatch_table = NULL; + + mnt_unref_monitor(mountwatch_monitor); + mountwatch_monitor = NULL; +} + +int +mountwatch_init(void) +{ + int ret, fd; + + CHECK_NULL(L_SCAN, mountwatch_monitor = mnt_new_monitor()); + + ret = mnt_monitor_enable_kernel(mountwatch_monitor, 1); + if (ret < 0) + goto error; + + fd = mnt_monitor_get_fd(mountwatch_monitor); + if (fd < 0) + goto error; + + mountwatch_table = mnt_new_table(); + if (!mountwatch_table) + goto error; + + ret = mnt_table_parse_mtab(mountwatch_table, NULL); + if (ret < 0) + goto error; + + return fd; + + error: + DPRINTF(E_LOG, L_SCAN, "Error initializing libmount, mount/unmount events won't be detected\n"); + mountwatch_deinit(); + errno = -ret; //TODO + return -1; +} +#else +int +mountwatch_event_get(char **path) +{ + *path = NULL; + return MOUNTWATCH_NONE; +} + +void +mountwatch_deinit(void) +{ + return; +} + +int +mountwatch_init(void) +{ + DPRINTF(E_LOG, L_SCAN, "No libmount on this platform, mount/unmount events won't be detected\n"); + return -1; +} +#endif diff --git a/src/misc.c b/src/misc.c index b7b4fe6d..885e0a23 100644 --- a/src/misc.c +++ b/src/misc.c @@ -49,6 +49,7 @@ #endif #include +#include #include #include #include // getifaddrs @@ -321,14 +322,102 @@ net_if_get(char *ifname, size_t ifname_len, const char *addr) } static int -net_connect_impl(const char *addr, unsigned short port, int type, const char *log_service_name, bool set_nonblock) +net_connect_addrinfo(struct addrinfo *ai, int timeout_ms, bool set_nonblock, const char **errmsg) +{ + int fd = -1; + int flags; + struct pollfd pollfd; + socklen_t len; + int error; + int ret; + + fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (fd < 0) + { + *errmsg = strerror(errno); + goto error; + } + + // For Linux we could just give SOCK_CLOEXEC to socket(), but that won't work + // with MacOS, so we have to use fcntl() + flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) + { + *errmsg = "fcntl() with F_GETFL returned an error"; + goto error; + } + + ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK | O_CLOEXEC); + if (ret < 0) + { + *errmsg = "fcntl() with F_SETFL non-block returned an error"; + goto error; + } + + // We often need to wait for the connection. On Linux this seems always to be + // the case, but FreeBSD connect() sometimes returns immediate success. + ret = connect(fd, ai->ai_addr, ai->ai_addrlen); + if (ret < 0 && errno != EINPROGRESS) // EINPROGRESS in case of nonblock + { + *errmsg = strerror(errno); + goto error; + } + else if (ret != 0) + { + // Use poll here since select requires using fdset that would be + // overflowed in FreeBSD + pollfd.fd = fd; + pollfd.events = POLLOUT; + + ret = poll(&pollfd, 1, timeout_ms); + if (ret < 0) + { + *errmsg = strerror(errno); + goto error; + } + else if (ret == 0) + { + *errmsg = "Timed out trying to connect"; + goto error; + } + + len = sizeof(error); + ret = getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &len); + if (ret < 0 || error) + { + *errmsg = error ? strerror(error) : strerror(errno); + goto error; + } + } + + if (!set_nonblock) + { + ret = fcntl(fd, F_SETFL, flags | O_CLOEXEC); + if (ret < 0) + { + *errmsg = "fcntl() with F_SETFL block returned an error"; + goto error; + } + } + + return fd; + + error: + if (fd >= 0) + close(fd); + + return -1; +} + +static int +net_connect_impl(const char *addr, unsigned short port, int type, const char *log_service_name, int timeout_ms, bool set_nonblock) { struct addrinfo hints = { 0 }; struct addrinfo *servinfo; - struct addrinfo *ptr; + struct addrinfo *ai; char strport[8]; - int flags; - int fd; + const char *errmsg = NULL; + int fd = -1; int ret; DPRINTF(E_DBG, L_MISC, "Connecting to '%s' at %s (port %u)\n", log_service_name, addr, port); @@ -344,45 +433,20 @@ net_connect_impl(const char *addr, unsigned short port, int type, const char *lo return -1; } - for (ptr = servinfo; ptr; ptr = ptr->ai_next) + for (ai = servinfo; ai && fd < 0; ai = ai->ai_next) { - fd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); - if (fd < 0) - { - continue; - } - - // For Linux we could just give SOCK_CLOEXEC to socket(), but that won't - // work with MacOS, so we have to use fcntl() - flags = fcntl(fd, F_GETFL, 0); - if (flags < 0) - continue; - if (set_nonblock) - ret = fcntl(fd, F_SETFL, flags | O_NONBLOCK | O_CLOEXEC); - else - ret = fcntl(fd, F_SETFL, flags | O_CLOEXEC); - if (ret < 0) - continue; - - ret = connect(fd, ptr->ai_addr, ptr->ai_addrlen); - if (ret < 0 && errno != EINPROGRESS) // EINPROGRESS in case of nonblock - { - close(fd); - continue; - } - - break; + fd = net_connect_addrinfo(ai, timeout_ms, set_nonblock, &errmsg); } freeaddrinfo(servinfo); - if (!ptr) + if (fd < 0) { - DPRINTF(E_LOG, L_MISC, "Could not connect to '%s' at %s (port %u): %s\n", log_service_name, addr, port, strerror(errno)); + DPRINTF(E_LOG, L_MISC, "Could not connect to '%s' at %s (port %u): %s\n", log_service_name, addr, port, errmsg); return -1; } - // net_address_get(ipaddr, sizeof(ipaddr), (union net_sockaddr *)ptr->ai-addr); + // net_address_get(ipaddr, sizeof(ipaddr), (union net_sockaddr *)ai->ai-addr); return fd; } @@ -390,7 +454,7 @@ net_connect_impl(const char *addr, unsigned short port, int type, const char *lo int net_connect(const char *addr, unsigned short port, int type, const char *log_service_name) { - return net_connect_impl(addr, port, type, log_service_name, false); + return net_connect_impl(addr, port, type, log_service_name, NET_CONNECT_TIMEOUT_MS, false); } // If *port is 0 then a random port will be assigned, and *port will be updated diff --git a/src/misc.h b/src/misc.h index 7ac16b19..40612eb8 100644 --- a/src/misc.h +++ b/src/misc.h @@ -15,6 +15,8 @@ #include #include +#define NET_CONNECT_TIMEOUT_MS 3000 + union net_sockaddr { struct sockaddr_in sin; diff --git a/src/misc_xml.c b/src/misc_xml.c index b95a8029..a98cc7c7 100644 --- a/src/misc_xml.c +++ b/src/misc_xml.c @@ -61,6 +61,7 @@ char * xml_to_string(xml_node *top, const char *xml_declaration) { xmlBuffer *buf; + const xmlChar *xml_string; char *s; buf = xmlBufferCreate(); @@ -72,7 +73,9 @@ xml_to_string(xml_node *top, const char *xml_declaration) xmlNodeDump(buf, top->doc, top, 0, 0); - s = strdup((char *)buf->content); + xml_string = xmlBufferContent(buf); + + s = xml_string ? strdup((char *)xml_string) : NULL; xmlBufferFree(buf); diff --git a/src/parsers/smartpl_lexer.l b/src/parsers/smartpl_lexer.l index bfb45520..d1947045 100644 --- a/src/parsers/smartpl_lexer.l +++ b/src/parsers/smartpl_lexer.l @@ -150,6 +150,7 @@ ends\ with { return (yylval->ival = SMARTPL_T_ENDSWITH); } or { return SMARTPL_T_OR; } and { return SMARTPL_T_AND; } not { return SMARTPL_T_NOT; } +empty { return SMARTPL_T_EMPTY; } {quoted} { yylval->str=strdup(yytext+1); if(yylval->str[strlen(yylval->str)-1] == '"') diff --git a/src/parsers/smartpl_parser.y b/src/parsers/smartpl_parser.y index 2d3bc422..17120221 100644 --- a/src/parsers/smartpl_parser.y +++ b/src/parsers/smartpl_parser.y @@ -229,6 +229,7 @@ enum sql_append_type { SQL_APPEND_FIELD, SQL_APPEND_STR, SQL_APPEND_INT, + SQL_APPEND_NULL, SQL_APPEND_ORDER, SQL_APPEND_PARENS, SQL_APPEND_DATE_STRFTIME, @@ -339,6 +340,11 @@ static void sql_append_recursive(struct smartpl_result *result, struct result_pa assert(a->r == NULL); sql_append(result, part, "%d", a->ival); break; + case SQL_APPEND_NULL: + assert(a->l == NULL); + assert(a->r == NULL); + sql_append(result, part, "NULL", NULL); + break; case SQL_APPEND_ORDER: assert(a->l == NULL); assert(a->r == NULL); @@ -397,6 +403,8 @@ static void sql_from_ast(struct smartpl_result *result, struct result_part *part sql_append_recursive(result, part, a, ">=", "<", is_not, SQL_APPEND_OPERATOR); break; case SMARTPL_T_IS: sql_append_recursive(result, part, a, "=", "!=", is_not, SQL_APPEND_OPERATOR_STR); break; + case SMARTPL_T_IS_OPERATOR: + sql_append_recursive(result, part, a, "IS", "IS NOT", is_not, SQL_APPEND_OPERATOR); break; case SMARTPL_T_INCLUDES: case SMARTPL_T_STARTSWITH: case SMARTPL_T_ENDSWITH: @@ -437,6 +445,8 @@ static void sql_from_ast(struct smartpl_result *result, struct result_part *part sql_append_recursive(result, part, a, NULL, NULL, 0, SQL_APPEND_FIELD); break; case SMARTPL_T_NUM: sql_append_recursive(result, part, a, NULL, NULL, 0, SQL_APPEND_INT); break; + case SMARTPL_T_NULL: + sql_append_recursive(result, part, a, NULL, NULL, 0, SQL_APPEND_NULL); break; case SMARTPL_T_ORDERBY: sql_append_recursive(result, part, a, "ASC", "DESC", is_not, SQL_APPEND_ORDER); break; case SMARTPL_T_RANDOM: @@ -518,6 +528,9 @@ static int result_set(struct smartpl_result *result, char *title, struct ast *cr %token SMARTPL_T_OR %token SMARTPL_T_AND %token SMARTPL_T_NOT +%token SMARTPL_T_EMPTY +%token SMARTPL_T_NULL +%token SMARTPL_T_IS_OPERATOR %token SMARTPL_T_DAYS %token SMARTPL_T_WEEKS @@ -590,6 +603,7 @@ criteria: criteria SMARTPL_T_AND criteria { $$ = ast_new(SMART predicate: SMARTPL_T_STRTAG strbool SMARTPL_T_STRING { $$ = ast_new($2, ast_data(SMARTPL_T_STRTAG, $1), ast_data(SMARTPL_T_STRING, $3)); } | SMARTPL_T_INTTAG intbool SMARTPL_T_NUM { $$ = ast_new($2, ast_data(SMARTPL_T_INTTAG, $1), ast_int(SMARTPL_T_NUM, $3)); } | SMARTPL_T_DATETAG datebool dateexpr { $$ = ast_new($2, ast_data(SMARTPL_T_DATETAG, $1), $3); } +| SMARTPL_T_STRTAG SMARTPL_T_IS SMARTPL_T_EMPTY { $$ = ast_new(SMARTPL_T_IS_OPERATOR, ast_data(SMARTPL_T_STRTAG, $1), ast_data(SMARTPL_T_NULL, NULL)); } | enumexpr ; diff --git a/src/transcode.c b/src/transcode.c index dfff37d4..22f1e881 100644 --- a/src/transcode.c +++ b/src/transcode.c @@ -48,6 +48,8 @@ #define USE_NO_CLEAR_AVFMT_NOFILE (LIBAVFORMAT_VERSION_MAJOR > 59) || ((LIBAVFORMAT_VERSION_MAJOR == 59) && (LIBAVFORMAT_VERSION_MINOR > 15)) #define USE_CH_LAYOUT (LIBAVCODEC_VERSION_MAJOR > 59) || ((LIBAVCODEC_VERSION_MAJOR == 59) && (LIBAVCODEC_VERSION_MINOR > 24)) #define USE_CONST_AVIO_WRITE_PACKET (LIBAVFORMAT_VERSION_MAJOR > 61) || ((LIBAVFORMAT_VERSION_MAJOR == 61) && (LIBAVFORMAT_VERSION_MINOR > 0)) +#define USE_AVCODEC_GET_SUPPORTED_CONFIG (LIBAVCODEC_VERSION_MAJOR > 61) || ((LIBAVCODEC_VERSION_MAJOR == 61) && (LIBAVCODEC_VERSION_MINOR > 13)) +#define USE_INJECT_GLOBAL_SIDE_DATA (LIBAVFORMAT_VERSION_MAJOR < 61) || ((LIBAVFORMAT_VERSION_MAJOR == 61) && (LIBAVFORMAT_VERSION_MINOR < 8)) // Interval between ICY metadata checks for streams, in seconds #define METADATA_ICY_INTERVAL 5 @@ -621,6 +623,7 @@ stream_add(struct encode_ctx *ctx, struct stream_ctx *s, enum AVCodecID codec_id AVCodec *encoder; #endif AVDictionary *options = NULL; + const enum AVPixelFormat *pix_fmts = NULL; int ret; codec_desc = avcodec_descriptor_get(codec_id); @@ -646,7 +649,12 @@ stream_add(struct encode_ctx *ctx, struct stream_ctx *s, enum AVCodecID codec_id if (!s->codec->pix_fmt) { - s->codec->pix_fmt = avcodec_default_get_format(s->codec, encoder->pix_fmts); +#if USE_AVCODEC_GET_SUPPORTED_CONFIG + avcodec_get_supported_config(s->codec, NULL, AV_CODEC_CONFIG_PIX_FORMAT, 0, (const void **)&pix_fmts, NULL); +#else + pix_fmts = encoder->pix_fmts; +#endif + s->codec->pix_fmt = pix_fmts ? avcodec_default_get_format(s->codec, pix_fmts) : AV_PIX_FMT_NONE; DPRINTF(E_DBG, L_XCODE, "Pixel format set to %s (encoder is %s)\n", av_get_pix_fmt_name(s->codec->pix_fmt), codec_desc->name); } @@ -1438,11 +1446,13 @@ open_input(struct decode_ctx *ctx, const char *path, struct transcode_evbuf_io * goto out_fail; } +#if USE_INJECT_GLOBAL_SIDE_DATA // If the source has REPLAYGAIN_TRACK_GAIN metadata, this will inject the // values into the the next packet's side data (as AV_FRAME_DATA_REPLAYGAIN), // which has the effect that a volume replaygain filter works. Note that // ffmpeg itself uses another method in process_input() in ffmpeg.c. av_format_inject_global_side_data(ctx->ifmt_ctx); +#endif ret = avformat_find_stream_info(ctx->ifmt_ctx, NULL); if (ret < 0)