diff --git a/src/stream/stream_member.c b/src/stream/stream_member.c index 0f36f785..5d042a18 100644 --- a/src/stream/stream_member.c +++ b/src/stream/stream_member.c @@ -55,16 +55,18 @@ static int member_option(const char *key, const char *value, void *arg) { parse->seen |= 1; if (!value[0]) return 0; const char *p = value; - unsigned n, r, size; + unsigned n, r, size, audio; if (member_hex(&p, &parse->state.source.source_epoch) != STREAM_OK || *p++ != ':' || member_decimal(&p, 255, &n) != STREAM_OK || *p++ != ':' || member_decimal(&p, 254, &r) != STREAM_OK || *p++ != ':' - || member_decimal(&p, RS_MAX_BLOCK_SIZE, &size) != STREAM_OK || *p) return -1; + || member_decimal(&p, RS_MAX_BLOCK_SIZE, &size) != STREAM_OK || *p++ != ':' + || member_decimal(&p, 1, &audio) != STREAM_OK || *p) return -1; parse->state.source.n = (uint8_t)n; parse->state.source.r = (uint8_t)r; parse->state.source.block_size = (uint16_t)size; if (stream_descriptor_validate(&parse->state.source) != STREAM_OK) return -1; parse->state.published = 1; + parse->state.audio_enabled = (int)audio; } else if (!strcmp(key, STREAM_MEMBER_SUBSCRIPTIONS)) { if (parse->seen & 2) return -1; parse->seen |= 2; @@ -118,13 +120,14 @@ int stream_member_parse(uint64_t group_id, uint64_t member_id, const char *useri int stream_member_format(const struct stream_member_state *state, char source[MS_USERINFO_MAX + 1], char subscriptions[MS_USERINFO_MAX + 1]) { if (!state || !source || !subscriptions || state->count > STREAM_MEMBER_MAX_SUBSCRIPTIONS + || (state->audio_enabled != 0 && state->audio_enabled != 1) || (!state->published && state->audio_enabled) || (state->published && (stream_descriptor_validate(&state->source) != STREAM_OK || !stream_member_has_subscription(state, state->source.source_node_id, state->source.source_epoch)))) { DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "member format invalid state"); return STREAM_ERR_ARGUMENT; } char encoded_source[MS_USERINFO_MAX + 1] = "", encoded_subscriptions[MS_USERINFO_MAX + 1] = ""; - if (state->published) snprintf(encoded_source, sizeof(encoded_source), "%016llx:%u:%u:%u", - (unsigned long long)state->source.source_epoch, state->source.n, state->source.r, state->source.block_size); + if (state->published) snprintf(encoded_source, sizeof(encoded_source), "%016llx:%u:%u:%u:%d", + (unsigned long long)state->source.source_epoch, state->source.n, state->source.r, state->source.block_size, state->audio_enabled); size_t used = 0; for (size_t i = 0; i < state->count; i++) { const struct stream_subscription_key *entry = &state->subscriptions[i]; diff --git a/src/stream/stream_member.h b/src/stream/stream_member.h index 11fa8fa1..b13816ba 100644 --- a/src/stream/stream_member.h +++ b/src/stream/stream_member.h @@ -1,5 +1,5 @@ /* Строковые опции подписанного блока мембера, без отдельного протокола объявлений. - * stream_source = epoch(16 hex):n:r:max-RS-size; отсутствие/пустое значение — не публикует. + * stream_source = epoch(16 hex):n:r:max-RS-size:audio(0/1); отсутствие/пустое значение — не публикует. * stream_subscriptions = source(16 hex):epoch(16 hex)[:r],...; :r — только помощь, без локального зрителя. * Указанная в stream_source собственная трансляция также должна быть в subscriptions. * load проверяет подпись профиля и принадлежность ключа источника, BGP-доступность — отдельно. @@ -32,6 +32,7 @@ struct stream_member_state { size_t count; uint64_t version; int published; + int audio_enabled; }; int stream_member_parse(uint64_t group_id, uint64_t member_id, const char *userinfo, struct stream_member_state *state);