diff --git a/README.md b/README.md index 52d48cd..6959ae6 100644 --- a/README.md +++ b/README.md @@ -41,13 +41,13 @@ docker compose up -d --build ### Результат работы бота -Бот сохраняет аудиофайлы с озвученными репликами в файлы `data//_.wav`, где `` - это номер реплики в сценарии (0-indexed), `` - это идентификатор диктора во всём датасете, по-сути, соответствует уникальному пользователю бота. Один диктор может озвучить несколько дорожек из разных совещаний. При этом он не может озвучивать две разные дорожки в рамках одного совещания, таким образом гарантируется, что разным `speaker_id` соответствуют разные дикторы в рамках одного совещания. +Бот сохраняет аудиофайлы с озвученными репликами в файлы `data//r_s_u.wav`, где `` — номер реплики в сценарии (0-indexed, с ведущими нулями), `` — идентификатор диктора в рамках сценария (с ведущими нулями), `` — уникальный идентификатор пользователя бота (с ведущими нулями). Пример: `r003_s01_u002.wav`. Один диктор может озвучить несколько дорожек из разных совещаний. При этом он не может озвучивать две разные дорожки в рамках одного совещания, таким образом гарантируется, что разным `speaker_id` соответствуют разные дикторы в рамках одного совещания. -В `data` попадают только полностью озвученные дорожки. Под дорожкой подразумевается набор всех реплик одного диктора в рамках сценария. Дорожки, озвученные частично, хранятся в `data_partial//_.wav`. Они автоматически переносятся в `data` после завершения озвучивания. +В `data` попадают только полностью озвученные дорожки. Под дорожкой подразумевается набор всех реплик одного диктора в рамках сценария. Дорожки, озвученные частично, хранятся в `data_partial//r_s_u.wav`. Они автоматически переносятся в `data` после завершения озвучивания. ### База данных -Служебные данные, такие как состояния пользовательских сессий, соответствие `dataset_speaker_id` и `telegram_user_id` и т. п., сохраняются в базе данных SQLite. После перезагрузки бота его состояние полностью восстанавливается из базы данных. +Служебные данные, такие как состояния пользовательских сессий, соответствие `user_id` и `telegram_user_id` и т. п., сохраняются в базе данных SQLite. После перезагрузки бота его состояние полностью восстанавливается из базы данных. ## Интерфейс бота diff --git a/src/audio.py b/src/audio.py index 1b1ab11..1699618 100644 --- a/src/audio.py +++ b/src/audio.py @@ -11,6 +11,7 @@ async def save_voice_message( file_id: str, user_id: int, scenario_id: str, + speaker_id: int, replica_index: int, duration: int, ) -> None: @@ -21,7 +22,7 @@ async def save_voice_message( # Скачиваем файл file = await bot.get_file(file_id) - filename = get_audio_filename(replica_index, user_id) + filename = get_audio_filename(replica_index, speaker_id, user_id) filepath = scenario_dir / filename await file.download_to_drive(filepath) diff --git a/src/database.py b/src/database.py index 48156fa..d55b865 100644 --- a/src/database.py +++ b/src/database.py @@ -30,7 +30,7 @@ class UserState(Enum): class User: """Пользователь бота (диктор в датасете).""" - id: int # dataset_speaker_id + id: int telegram_id: int created_at: datetime gender: str | None # "male" или "female" @@ -61,7 +61,7 @@ class Recording: """Запись озвучки реплики.""" id: int - user_id: int # dataset_speaker_id + user_id: int scenario_id: str replica_index: int duration: float # длительность в секундах @@ -190,7 +190,7 @@ def get_or_create_user(telegram_id: int) -> User: ) row = cursor.fetchone() conn.commit() - logger.info(f"Создан новый пользователь: dataset_speaker_id={row['id']}") + logger.info(f"Создан новый пользователь: user_id={row['id']}") return User( id=row["id"], telegram_id=row["telegram_id"], diff --git a/src/handlers.py b/src/handlers.py index a98de34..abe037b 100644 --- a/src/handlers.py +++ b/src/handlers.py @@ -878,6 +878,7 @@ async def handle_voice_message( voice.file_id, user.id, session.scenario_id, + session.speaker_id, real_replica_index, voice.duration, ) diff --git a/src/scenarios.py b/src/scenarios.py index 6f603a5..9a2f34c 100644 --- a/src/scenarios.py +++ b/src/scenarios.py @@ -222,9 +222,9 @@ def get_data_dir(scenario_id: str) -> Path: return DATA_DIR / scenario_id -def get_audio_filename(replica_index: int, user_id: int) -> str: +def get_audio_filename(replica_index: int, speaker_id: int, user_id: int) -> str: """Формирует имя файла для аудиозаписи.""" - return f"{replica_index}_{user_id}.wav" + return f"r{replica_index:03d}_s{speaker_id:02d}_u{user_id:03d}.wav" def is_scenario_complete(scenario_id: str) -> bool: @@ -302,7 +302,7 @@ def move_track_to_data(user_id: int, scenario_id: str, speaker_id: int) -> None: moved_count = 0 for replica in track_replicas: - filename = get_audio_filename(replica.replica_index, user_id) + filename = get_audio_filename(replica.replica_index, speaker_id, user_id) src = partial_dir / filename dst = data_dir / filename @@ -323,7 +323,7 @@ def delete_partial_track(user_id: int, scenario_id: str, speaker_id: int) -> Non deleted_count = 0 for replica in track_replicas: - filename = get_audio_filename(replica.replica_index, user_id) + filename = get_audio_filename(replica.replica_index, speaker_id, user_id) filepath = partial_dir / filename if filepath.exists(): filepath.unlink()