diff --git a/README.md b/README.md index 4d5aaa2..a2223fc 100644 --- a/README.md +++ b/README.md @@ -1,93 +1,87 @@ -# docker-whisper +# Sistema Distribuido de Transcripción con Whisper +Este proyecto implementa un sistema distribuido para la transcripción de archivos de audio utilizando el modelo Whisper de OpenAI. El sistema divide los archivos de audio en segmentos más pequeños (de 5 minutos), procesa estos segmentos en paralelo utilizando múltiples contenedores, y luego unifica las transcripciones para generar un archivo de subtítulos. +## Arquitectura del Sistema -## Getting started +El sistema está compuesto por cuatro tipos de componentes principales: -To make it easy for you to get started with GitLab, here's a list of recommended next steps. +1. **Receptor (Receiver)**: Monitorea el directorio de entrada para nuevos archivos de audio y los envía a RabbitMQ para su procesamiento. +2. **Particionador (Splitter)**: Divide los archivos de audio en segmentos de 5 minutos. +3. **Procesadores (Processors)**: Transcriben los segmentos de audio utilizando Whisper (7 contenedores en paralelo). +4. **Unificador (Unifier)**: Recopila todas las transcripciones, las ordena y genera un archivo final de subtítulos (.srt). -Already a pro? Just edit this README.md and make it your own. Want to make it easy? [Use the template at the bottom](#editing-this-readme)! +## Requisitos previos -## Add your files +- Docker +- Docker Compose -- [ ] [Create](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#create-a-file) or [upload](https://docs.gitlab.com/ee/user/project/repository/web_editor.html#upload-a-file) files -- [ ] [Add files using the command line](https://docs.gitlab.com/topics/git/add_files/#add-files-to-a-git-repository) or push an existing Git repository with the following command: +## Estructura del proyecto ``` -cd existing_repo -git remote add origin http://gitlab.local/root/docker-whisper.git -git branch -M main -git push -uf origin main +whisper-distributed/ +├── docker-compose.yml # Definición de los servicios +├── input/ # Directorio para colocar los archivos de audio a transcribir +├── output/ # Directorio donde se guardarán los subtítulos generados +├── shared/ # Directorio compartido para almacenamiento temporal +├── processor/ # Código del procesador Whisper +│ ├── app.py +│ └── Dockerfile +├── receiver/ # Código del receptor +│ ├── app.py +│ └── Dockerfile +├── splitter/ # Código del particionador +│ ├── app.py +│ └── Dockerfile +└── unifier/ # Código del unificador + ├── app.py + └── Dockerfile ``` -## Integrate with your tools +## Uso del sistema -- [ ] [Set up project integrations](http://gitlab.local/root/docker-whisper/-/settings/integrations) +1. **Preparación**: + ```bash + docker-compose build + ``` -## Collaborate with your team +2. **Iniciar el sistema**: + ```bash + docker-compose up -d + ``` -- [ ] [Invite team members and collaborators](https://docs.gitlab.com/ee/user/project/members/) -- [ ] [Create a new merge request](https://docs.gitlab.com/ee/user/project/merge_requests/creating_merge_requests.html) -- [ ] [Automatically close issues from merge requests](https://docs.gitlab.com/ee/user/project/issues/managing_issues.html#closing-issues-automatically) -- [ ] [Enable merge request approvals](https://docs.gitlab.com/ee/user/project/merge_requests/approvals/) -- [ ] [Set auto-merge](https://docs.gitlab.com/user/project/merge_requests/auto_merge/) +3. **Uso**: + - Coloca los archivos de audio que deseas transcribir en el directorio `input/`. + - El sistema detectará automáticamente los archivos y comenzará a procesarlos. + - Los subtítulos resultantes se guardarán en el directorio `output/` con el formato `nombre_original_transcription.srt`. -## Test and Deploy +4. **Monitoreo de logs**: + ```bash + docker-compose logs -f + ``` -Use the built-in continuous integration in GitLab. +5. **Detener el sistema**: + ```bash + docker-compose down + ``` -- [ ] [Get started with GitLab CI/CD](https://docs.gitlab.com/ee/ci/quick_start/) -- [ ] [Analyze your code for known vulnerabilities with Static Application Security Testing (SAST)](https://docs.gitlab.com/ee/user/application_security/sast/) -- [ ] [Deploy to Kubernetes, Amazon EC2, or Amazon ECS using Auto Deploy](https://docs.gitlab.com/ee/topics/autodevops/requirements.html) -- [ ] [Use pull-based deployments for improved Kubernetes management](https://docs.gitlab.com/ee/user/clusters/agent/) -- [ ] [Set up protected environments](https://docs.gitlab.com/ee/ci/environments/protected_environments.html) +## Flujo de trabajo -*** +1. El **receptor** detecta un nuevo archivo de audio en el directorio `input/` y lo envía a la cola `audio_split_queue`. +2. El **particionador** recibe el archivo, lo divide en segmentos de 5 minutos y envía cada segmento a la cola `audio_process_queue`. +3. Los **procesadores** (7 contenedores) reciben los segmentos, los transcriben utilizando Whisper y envían las transcripciones a la cola `text_unify_queue`. +4. El **unificador** recopila todas las transcripciones de un mismo archivo, las ordena según su posición original y genera un archivo de subtítulos en formato SRT. -# Editing this README +## Configuración -When you're ready to make this README your own, just edit this file and use the handy template below (or feel free to structure it however you want - this is just a starting point!). Thanks to [makeareadme.com](https://www.makeareadme.com/) for this template. +El sistema viene configurado con valores predeterminados, pero se pueden ajustar varios parámetros: -## Suggestions for a good README +- **Tamaño de los segmentos**: Por defecto, 5 minutos. Se puede modificar en `splitter/app.py` (variable `SEGMENT_DURATION_MS`). +- **Modelo de Whisper**: Por defecto, "base". Se puede cambiar a "tiny", "small", "medium" o "large" en `processor/app.py` (variable `WHISPER_MODEL`). +- **Número de procesadores**: Se pueden agregar o quitar procesadores modificando el archivo `docker-compose.yml`. -Every project is different, so consider which of these sections apply to yours. The sections used in the template are suggestions for most open source projects. Also keep in mind that while a README can be too long and detailed, too long is better than too short. If you think your README is too long, consider utilizing another form of documentation rather than cutting out information. +## Notas -## Name -Choose a self-explaining name for your project. - -## Description -Let people know what your project can do specifically. Provide context and add a link to any reference visitors might be unfamiliar with. A list of Features or a Background subsection can also be added here. If there are alternatives to your project, this is a good place to list differentiating factors. - -## Badges -On some READMEs, you may see small images that convey metadata, such as whether or not all the tests are passing for the project. You can use Shields to add some to your README. Many services also have instructions for adding a badge. - -## Visuals -Depending on what you are making, it can be a good idea to include screenshots or even a video (you'll frequently see GIFs rather than actual videos). Tools like ttygif can help, but check out Asciinema for a more sophisticated method. - -## Installation -Within a particular ecosystem, there may be a common way of installing things, such as using Yarn, NuGet, or Homebrew. However, consider the possibility that whoever is reading your README is a novice and would like more guidance. Listing specific steps helps remove ambiguity and gets people to using your project as quickly as possible. If it only runs in a specific context like a particular programming language version or operating system or has dependencies that have to be installed manually, also add a Requirements subsection. - -## Usage -Use examples liberally, and show the expected output if you can. It's helpful to have inline the smallest example of usage that you can demonstrate, while providing links to more sophisticated examples if they are too long to reasonably include in the README. - -## Support -Tell people where they can go to for help. It can be any combination of an issue tracker, a chat room, an email address, etc. - -## Roadmap -If you have ideas for releases in the future, it is a good idea to list them in the README. - -## Contributing -State if you are open to contributions and what your requirements are for accepting them. - -For people who want to make changes to your project, it's helpful to have some documentation on how to get started. Perhaps there is a script that they should run or some environment variables that they need to set. Make these steps explicit. These instructions could also be useful to your future self. - -You can also document commands to lint the code or run tests. These steps help to ensure high code quality and reduce the likelihood that the changes inadvertently break something. Having instructions for running tests is especially helpful if it requires external setup, such as starting a Selenium server for testing in a browser. - -## Authors and acknowledgment -Show your appreciation to those who have contributed to the project. - -## License -For open source projects, say how it is licensed. - -## Project status -If you have run out of energy or time for your project, put a note at the top of the README saying that development has slowed down or stopped completely. Someone may choose to fork your project or volunteer to step in as a maintainer or owner, allowing your project to keep going. You can also make an explicit request for maintainers. +- El modelo "base" de Whisper ofrece un buen equilibrio entre precisión y velocidad. Los modelos más grandes (como "medium" o "large") son más precisos pero requieren más recursos. +- Para archivos muy largos, el sistema puede tardar bastante tiempo en procesarlos, especialmente con modelos grandes. +- Asegúrate de tener suficiente espacio en disco para los archivos temporales. \ No newline at end of file diff --git a/logs/log_processor1.log b/logs/log_processor1.log new file mode 100644 index 0000000..e69de29 diff --git a/logs/log_rabbitMQ.log b/logs/log_rabbitMQ.log new file mode 100644 index 0000000..95d6608 --- /dev/null +++ b/logs/log_rabbitMQ.log @@ -0,0 +1,308 @@ +2025-05-08 00:39:50 2025-05-07 22:39:50.662362+00:00 [notice] <0.44.0> Application syslog exited with reason: stopped +2025-05-08 00:39:50 2025-05-07 22:39:50.668550+00:00 [notice] <0.254.0> Logging: switching to configured handler(s); following messages may not be visible in this log output +2025-05-08 00:39:50 2025-05-07 22:39:50.669346+00:00 [notice] <0.254.0> Logging: configured log handlers are now ACTIVE +2025-05-08 00:39:50 2025-05-07 22:39:50.681515+00:00 [info] <0.254.0> ra: starting system quorum_queues +2025-05-08 00:39:50 2025-05-07 22:39:50.681675+00:00 [info] <0.254.0> starting Ra system: quorum_queues in directory: /var/lib/rabbitmq/mnesia/rabbit@62947c89d30c/quorum/rabbit@62947c89d30c +2025-05-08 00:39:50 2025-05-07 22:39:50.750228+00:00 [info] <0.268.0> ra system 'quorum_queues' running pre init for 0 registered servers +2025-05-08 00:39:50 2025-05-07 22:39:50.760336+00:00 [info] <0.269.0> ra: meta data store initialised for system quorum_queues. 0 record(s) recovered +2025-05-08 00:39:50 2025-05-07 22:39:50.776980+00:00 [notice] <0.274.0> WAL: ra_log_wal init, open tbls: ra_log_open_mem_tables, closed tbls: ra_log_closed_mem_tables +2025-05-08 00:39:50 2025-05-07 22:39:50.815739+00:00 [info] <0.254.0> ra: starting system coordination +2025-05-08 00:39:50 2025-05-07 22:39:50.815953+00:00 [info] <0.254.0> starting Ra system: coordination in directory: /var/lib/rabbitmq/mnesia/rabbit@62947c89d30c/coordination/rabbit@62947c89d30c +2025-05-08 00:39:50 2025-05-07 22:39:50.824238+00:00 [info] <0.282.0> ra system 'coordination' running pre init for 0 registered servers +2025-05-08 00:39:50 2025-05-07 22:39:50.827046+00:00 [info] <0.283.0> ra: meta data store initialised for system coordination. 0 record(s) recovered +2025-05-08 00:39:50 2025-05-07 22:39:50.827537+00:00 [notice] <0.288.0> WAL: ra_coordination_log_wal init, open tbls: ra_coordination_log_open_mem_tables, closed tbls: ra_coordination_log_closed_mem_tables +2025-05-08 00:39:50 2025-05-07 22:39:50.838825+00:00 [info] <0.254.0> ra: starting system coordination +2025-05-08 00:39:50 2025-05-07 22:39:50.838959+00:00 [info] <0.254.0> starting Ra system: coordination in directory: /var/lib/rabbitmq/mnesia/rabbit@62947c89d30c/coordination/rabbit@62947c89d30c +2025-05-08 00:39:51 2025-05-07 22:39:51.018518+00:00 [info] <0.254.0> Waiting for Khepri leader for 30000 ms, 9 retries left +2025-05-08 00:39:51 2025-05-07 22:39:51.048630+00:00 [notice] <0.292.0> RabbitMQ metadata store: candidate -> leader in term: 1 machine version: 1 +2025-05-08 00:39:51 2025-05-07 22:39:51.059311+00:00 [info] <0.254.0> Khepri leader elected +2025-05-08 00:39:51 2025-05-07 22:39:51.059415+00:00 [info] <0.254.0> Waiting for Khepri projections for 30000 ms, 9 retries left +2025-05-08 00:39:51 2025-05-07 22:39:51.554340+00:00 [info] <0.254.0> +2025-05-08 00:39:51 2025-05-07 22:39:51.554340+00:00 [info] <0.254.0> Starting RabbitMQ 3.13.7 on Erlang 26.2.5.11 [jit] +2025-05-08 00:39:51 2025-05-07 22:39:51.554340+00:00 [info] <0.254.0> Copyright (c) 2007-2024 Broadcom Inc and/or its subsidiaries +2025-05-08 00:39:51 2025-05-07 22:39:51.554340+00:00 [info] <0.254.0> Licensed under the MPL 2.0. Website: https://rabbitmq.com +2025-05-08 00:39:51 +2025-05-08 00:39:51 ## ## RabbitMQ 3.13.7 +2025-05-08 00:39:51 ## ## +2025-05-08 00:39:51 ########## Copyright (c) 2007-2024 Broadcom Inc and/or its subsidiaries +2025-05-08 00:39:51 ###### ## +2025-05-08 00:39:51 ########## Licensed under the MPL 2.0. Website: https://rabbitmq.com +2025-05-08 00:39:51 +2025-05-08 00:39:51 Erlang: 26.2.5.11 [jit] +2025-05-08 00:39:51 TLS Library: OpenSSL - OpenSSL 3.1.8 11 Feb 2025 +2025-05-08 00:39:51 Release series support status: see https://www.rabbitmq.com/release-information +2025-05-08 00:39:51 +2025-05-08 00:39:51 Doc guides: https://www.rabbitmq.com/docs +2025-05-08 00:39:51 Support: https://www.rabbitmq.com/docs/contact +2025-05-08 00:39:51 Tutorials: https://www.rabbitmq.com/tutorials +2025-05-08 00:39:51 Monitoring: https://www.rabbitmq.com/docs/monitoring +2025-05-08 00:39:51 Upgrading: https://www.rabbitmq.com/docs/upgrade +2025-05-08 00:39:51 +2025-05-08 00:39:51 Logs: +2025-05-08 00:39:51 +2025-05-08 00:39:51 Config file(s): /etc/rabbitmq/conf.d/10-defaults.conf +2025-05-08 00:39:51 +2025-05-08 00:39:51 Starting broker...2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> +2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> node : rabbit@62947c89d30c +2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> home dir : /var/lib/rabbitmq +2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> config file(s) : /etc/rabbitmq/conf.d/10-defaults.conf +2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> cookie hash : I86zuTAeUmEN7sUO2/OmLw== +2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> log(s) : +2025-05-08 00:39:51 2025-05-07 22:39:51.555311+00:00 [info] <0.254.0> data dir : /var/lib/rabbitmq/mnesia/rabbit@62947c89d30c +2025-05-08 00:39:52 2025-05-07 22:39:52.138572+00:00 [info] <0.254.0> Running boot step pre_boot defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.138716+00:00 [info] <0.254.0> Running boot step rabbit_global_counters defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.138936+00:00 [info] <0.254.0> Running boot step rabbit_osiris_metrics defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.139028+00:00 [info] <0.254.0> Running boot step rabbit_core_metrics defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.140039+00:00 [info] <0.254.0> Running boot step rabbit_alarm defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.148091+00:00 [info] <0.329.0> Memory high watermark set to 1899 MiB (1991522713 bytes) of 4748 MiB (4978806784 bytes) total +2025-05-08 00:39:52 2025-05-07 22:39:52.150701+00:00 [info] <0.331.0> Enabling free disk space monitoring (disk free space: 994872799232, total memory: 4978806784) +2025-05-08 00:39:52 2025-05-07 22:39:52.150797+00:00 [info] <0.331.0> Disk free limit set to 50MB +2025-05-08 00:39:52 2025-05-07 22:39:52.152232+00:00 [info] <0.254.0> Running boot step code_server_cache defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.152342+00:00 [info] <0.254.0> Running boot step file_handle_cache defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.156605+00:00 [info] <0.334.0> Limiting to approx 1048479 file handles (943629 sockets) +2025-05-08 00:39:52 2025-05-07 22:39:52.156820+00:00 [info] <0.335.0> FHC read buffering: OFF +2025-05-08 00:39:52 2025-05-07 22:39:52.156868+00:00 [info] <0.335.0> FHC write buffering: ON +2025-05-08 00:39:52 2025-05-07 22:39:52.157230+00:00 [info] <0.254.0> Running boot step worker_pool defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.157360+00:00 [info] <0.315.0> Will use 8 processes for default worker pool +2025-05-08 00:39:52 2025-05-07 22:39:52.157393+00:00 [info] <0.315.0> Starting worker pool 'worker_pool' with 8 processes in it +2025-05-08 00:39:52 2025-05-07 22:39:52.157880+00:00 [info] <0.254.0> Running boot step database defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.158346+00:00 [info] <0.254.0> Peer discovery: configured backend: rabbit_peer_discovery_classic_config +2025-05-08 00:39:52 2025-05-07 22:39:52.159944+00:00 [notice] <0.316.0> Feature flags: attempt to enable `detailed_queues_endpoint`... +2025-05-08 00:39:52 2025-05-07 22:39:52.241270+00:00 [notice] <0.316.0> Feature flags: `detailed_queues_endpoint` enabled +2025-05-08 00:39:52 2025-05-07 22:39:52.241471+00:00 [notice] <0.316.0> Feature flags: attempt to enable `quorum_queue_non_voters`... +2025-05-08 00:39:52 2025-05-07 22:39:52.318612+00:00 [notice] <0.316.0> Feature flags: `quorum_queue_non_voters` enabled +2025-05-08 00:39:52 2025-05-07 22:39:52.318879+00:00 [notice] <0.316.0> Feature flags: attempt to enable `stream_update_config_command`... +2025-05-08 00:39:52 2025-05-07 22:39:52.395204+00:00 [notice] <0.316.0> Feature flags: `stream_update_config_command` enabled +2025-05-08 00:39:52 2025-05-07 22:39:52.395479+00:00 [notice] <0.316.0> Feature flags: attempt to enable `stream_filtering`... +2025-05-08 00:39:52 2025-05-07 22:39:52.485430+00:00 [notice] <0.316.0> Feature flags: `stream_filtering` enabled +2025-05-08 00:39:52 2025-05-07 22:39:52.485608+00:00 [notice] <0.316.0> Feature flags: attempt to enable `stream_sac_coordinator_unblock_group`... +2025-05-08 00:39:52 2025-05-07 22:39:52.569301+00:00 [notice] <0.316.0> Feature flags: `stream_sac_coordinator_unblock_group` enabled +2025-05-08 00:39:52 2025-05-07 22:39:52.569692+00:00 [notice] <0.316.0> Feature flags: attempt to enable `restart_streams`... +2025-05-08 00:39:52 2025-05-07 22:39:52.653870+00:00 [notice] <0.316.0> Feature flags: `restart_streams` enabled +2025-05-08 00:39:52 2025-05-07 22:39:52.654465+00:00 [notice] <0.316.0> Feature flags: attempt to enable `message_containers`... +2025-05-08 00:39:52 2025-05-07 22:39:52.742245+00:00 [notice] <0.316.0> Feature flags: `message_containers` enabled +2025-05-08 00:39:52 2025-05-07 22:39:52.742447+00:00 [notice] <0.316.0> Feature flags: attempt to enable `message_containers_deaths_v2`... +2025-05-08 00:39:52 2025-05-07 22:39:52.826180+00:00 [notice] <0.316.0> Feature flags: `message_containers_deaths_v2` enabled +2025-05-08 00:39:52 2025-05-07 22:39:52.826431+00:00 [info] <0.254.0> DB: virgin node -> run peer discovery +2025-05-08 00:39:52 2025-05-07 22:39:52.826525+00:00 [warning] <0.254.0> Classic peer discovery backend: list of nodes does not contain the local node [] +2025-05-08 00:39:52 2025-05-07 22:39:52.836796+00:00 [notice] <0.44.0> Application mnesia exited with reason: stopped +2025-05-08 00:39:52 2025-05-07 22:39:52.979237+00:00 [info] <0.254.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:39:52 2025-05-07 22:39:52.979423+00:00 [info] <0.254.0> Successfully synced tables from a peer +2025-05-08 00:39:52 2025-05-07 22:39:52.979552+00:00 [info] <0.254.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:39:52 2025-05-07 22:39:52.979670+00:00 [info] <0.254.0> Successfully synced tables from a peer +2025-05-08 00:39:52 2025-05-07 22:39:52.987684+00:00 [info] <0.254.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:39:52 2025-05-07 22:39:52.988064+00:00 [info] <0.254.0> Successfully synced tables from a peer +2025-05-08 00:39:52 2025-05-07 22:39:52.988311+00:00 [info] <0.254.0> Running boot step tracking_metadata_store defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.988509+00:00 [info] <0.562.0> Setting up a table for connection tracking on this node: tracked_connection +2025-05-08 00:39:52 2025-05-07 22:39:52.988576+00:00 [info] <0.562.0> Setting up a table for per-vhost connection counting on this node: tracked_connection_per_vhost +2025-05-08 00:39:52 2025-05-07 22:39:52.988699+00:00 [info] <0.562.0> Setting up a table for per-user connection counting on this node: tracked_connection_per_user +2025-05-08 00:39:52 2025-05-07 22:39:52.988775+00:00 [info] <0.562.0> Setting up a table for channel tracking on this node: tracked_channel +2025-05-08 00:39:52 2025-05-07 22:39:52.988891+00:00 [info] <0.562.0> Setting up a table for channel tracking on this node: tracked_channel_per_user +2025-05-08 00:39:52 2025-05-07 22:39:52.989007+00:00 [info] <0.254.0> Running boot step networking_metadata_store defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.989172+00:00 [info] <0.254.0> Running boot step feature_flags defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.989469+00:00 [info] <0.254.0> Running boot step codec_correctness_check defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.989589+00:00 [info] <0.254.0> Running boot step external_infrastructure defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.989669+00:00 [info] <0.254.0> Running boot step rabbit_event defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.989895+00:00 [info] <0.254.0> Running boot step rabbit_registry defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.989984+00:00 [info] <0.254.0> Running boot step rabbit_auth_mechanism_amqplain defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990074+00:00 [info] <0.254.0> Running boot step rabbit_auth_mechanism_cr_demo defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990135+00:00 [info] <0.254.0> Running boot step rabbit_auth_mechanism_plain defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990189+00:00 [info] <0.254.0> Running boot step rabbit_exchange_type_direct defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990262+00:00 [info] <0.254.0> Running boot step rabbit_exchange_type_fanout defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990316+00:00 [info] <0.254.0> Running boot step rabbit_exchange_type_headers defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990381+00:00 [info] <0.254.0> Running boot step rabbit_exchange_type_topic defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990437+00:00 [info] <0.254.0> Running boot step rabbit_mirror_queue_mode_all defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990494+00:00 [info] <0.254.0> Running boot step rabbit_mirror_queue_mode_exactly defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990555+00:00 [info] <0.254.0> Running boot step rabbit_mirror_queue_mode_nodes defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990618+00:00 [info] <0.254.0> Running boot step rabbit_priority_queue defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990647+00:00 [info] <0.254.0> Priority queues enabled, real BQ is rabbit_variable_queue +2025-05-08 00:39:52 2025-05-07 22:39:52.990693+00:00 [info] <0.254.0> Running boot step rabbit_queue_location_client_local defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990744+00:00 [info] <0.254.0> Running boot step rabbit_queue_location_min_masters defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990814+00:00 [info] <0.254.0> Running boot step rabbit_queue_location_random defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990862+00:00 [info] <0.254.0> Running boot step kernel_ready defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.990888+00:00 [info] <0.254.0> Running boot step rabbit_sysmon_minder defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.991053+00:00 [info] <0.254.0> Running boot step rabbit_epmd_monitor defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.991707+00:00 [info] <0.570.0> epmd monitor knows us, inter-node communication (distribution) port: 25672 +2025-05-08 00:39:52 2025-05-07 22:39:52.991820+00:00 [info] <0.254.0> Running boot step guid_generator defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.994121+00:00 [info] <0.254.0> Running boot step rabbit_node_monitor defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.994475+00:00 [info] <0.574.0> Starting rabbit_node_monitor (in ignore mode) +2025-05-08 00:39:52 2025-05-07 22:39:52.994618+00:00 [info] <0.254.0> Running boot step delegate_sup defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.995245+00:00 [info] <0.254.0> Running boot step rabbit_memory_monitor defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.995645+00:00 [info] <0.254.0> Running boot step rabbit_fifo_dlx_sup defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.995793+00:00 [info] <0.254.0> Running boot step core_initialized defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.995875+00:00 [info] <0.254.0> Running boot step rabbit_channel_tracking_handler defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.995941+00:00 [info] <0.254.0> Running boot step rabbit_connection_tracking_handler defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.996042+00:00 [info] <0.254.0> Running boot step rabbit_definitions_hashing defined by app rabbit +2025-05-08 00:39:52 2025-05-07 22:39:52.996109+00:00 [info] <0.254.0> Running boot step rabbit_exchange_parameters defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.037017+00:00 [info] <0.254.0> Running boot step rabbit_mirror_queue_misc defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.037701+00:00 [info] <0.254.0> Running boot step rabbit_policies defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.038025+00:00 [info] <0.254.0> Running boot step rabbit_policy defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.038137+00:00 [info] <0.254.0> Running boot step rabbit_queue_location_validator defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.038446+00:00 [info] <0.254.0> Running boot step rabbit_quorum_memory_manager defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.038497+00:00 [info] <0.254.0> Running boot step rabbit_quorum_queue defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.038560+00:00 [info] <0.254.0> Running boot step rabbit_stream_coordinator defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.038722+00:00 [info] <0.254.0> Running boot step rabbit_vhost_limit defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.038916+00:00 [info] <0.254.0> Running boot step rabbit_federation_parameters defined by app rabbitmq_federation +2025-05-08 00:39:53 2025-05-07 22:39:53.039082+00:00 [info] <0.254.0> Running boot step rabbit_federation_supervisor defined by app rabbitmq_federation +2025-05-08 00:39:53 2025-05-07 22:39:53.048561+00:00 [info] <0.254.0> Running boot step rabbit_federation_queue defined by app rabbitmq_federation +2025-05-08 00:39:53 2025-05-07 22:39:53.048929+00:00 [info] <0.254.0> Running boot step rabbit_federation_upstream_exchange defined by app rabbitmq_federation +2025-05-08 00:39:53 2025-05-07 22:39:53.049101+00:00 [info] <0.254.0> Running boot step rabbit_mgmt_reset_handler defined by app rabbitmq_management +2025-05-08 00:39:53 2025-05-07 22:39:53.049203+00:00 [info] <0.254.0> Running boot step rabbit_mgmt_db_handler defined by app rabbitmq_management_agent +2025-05-08 00:39:53 2025-05-07 22:39:53.049249+00:00 [info] <0.254.0> Management plugin: using rates mode 'basic' +2025-05-08 00:39:53 2025-05-07 22:39:53.049570+00:00 [info] <0.254.0> Running boot step recovery defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.065051+00:00 [info] <0.254.0> Running boot step empty_db_check defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.065272+00:00 [info] <0.254.0> Will seed default virtual host and user... +2025-05-08 00:39:53 2025-05-07 22:39:53.065643+00:00 [info] <0.254.0> Adding vhost '/' (description: 'Default virtual host', tags: []) +2025-05-08 00:39:53 2025-05-07 22:39:53.086530+00:00 [info] <0.634.0> Making sure data directory '/var/lib/rabbitmq/mnesia/rabbit@62947c89d30c/msg_stores/vhosts/628WB79CIFDYO9LJI6DKMI09L' for vhost '/' exists +2025-05-08 00:39:53 2025-05-07 22:39:53.088241+00:00 [info] <0.634.0> Setting segment_entry_count for vhost '/' with 0 queues to '2048' +2025-05-08 00:39:53 2025-05-07 22:39:53.097360+00:00 [info] <0.634.0> Starting message stores for vhost '/' +2025-05-08 00:39:53 2025-05-07 22:39:53.097592+00:00 [info] <0.643.0> Message store "628WB79CIFDYO9LJI6DKMI09L/msg_store_transient": using rabbit_msg_store_ets_index to provide index +2025-05-08 00:39:53 2025-05-07 22:39:53.100863+00:00 [info] <0.634.0> Started message store of type transient for vhost '/' +2025-05-08 00:39:53 2025-05-07 22:39:53.101137+00:00 [info] <0.647.0> Message store "628WB79CIFDYO9LJI6DKMI09L/msg_store_persistent": using rabbit_msg_store_ets_index to provide index +2025-05-08 00:39:53 2025-05-07 22:39:53.101782+00:00 [warning] <0.647.0> Message store "628WB79CIFDYO9LJI6DKMI09L/msg_store_persistent": rebuilding indices from scratch +2025-05-08 00:39:53 2025-05-07 22:39:53.102437+00:00 [info] <0.634.0> Started message store of type persistent for vhost '/' +2025-05-08 00:39:53 2025-05-07 22:39:53.102574+00:00 [info] <0.634.0> Recovering 0 queues of type rabbit_classic_queue took 13ms +2025-05-08 00:39:53 2025-05-07 22:39:53.102629+00:00 [info] <0.634.0> Recovering 0 queues of type rabbit_quorum_queue took 0ms +2025-05-08 00:39:53 2025-05-07 22:39:53.102676+00:00 [info] <0.634.0> Recovering 0 queues of type rabbit_stream_queue took 0ms +2025-05-08 00:39:53 2025-05-07 22:39:53.107559+00:00 [info] <0.254.0> Created user 'user' +2025-05-08 00:39:53 2025-05-07 22:39:53.110154+00:00 [info] <0.254.0> Successfully set user tags for user 'user' to [administrator] +2025-05-08 00:39:53 2025-05-07 22:39:53.112408+00:00 [info] <0.254.0> Successfully set permissions for user 'user' in virtual host '/' to '.*', '.*', '.*' +2025-05-08 00:39:53 2025-05-07 22:39:53.112490+00:00 [info] <0.254.0> Running boot step rabbit_observer_cli defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.112766+00:00 [info] <0.254.0> Running boot step rabbit_looking_glass defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.112830+00:00 [info] <0.254.0> Running boot step rabbit_core_metrics_gc defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.113033+00:00 [info] <0.254.0> Running boot step background_gc defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.113192+00:00 [info] <0.254.0> Running boot step routing_ready defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.113230+00:00 [info] <0.254.0> Running boot step pre_flight defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.113268+00:00 [info] <0.254.0> Running boot step notify_cluster defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.113305+00:00 [info] <0.254.0> Running boot step networking defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.113352+00:00 [info] <0.254.0> Running boot step rabbit_quorum_queue_periodic_membership_reconciliation defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.113466+00:00 [info] <0.254.0> Running boot step definition_import_worker_pool defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.113521+00:00 [info] <0.315.0> Starting worker pool 'definition_import_pool' with 8 processes in it +2025-05-08 00:39:53 2025-05-07 22:39:53.114143+00:00 [info] <0.254.0> Running boot step cluster_name defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.114227+00:00 [info] <0.254.0> Initialising internal cluster ID to 'rabbitmq-cluster-id-npKafAOABkeMhPtpDbOVuw' +2025-05-08 00:39:53 2025-05-07 22:39:53.116441+00:00 [info] <0.254.0> Running boot step virtual_host_reconciliation defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.116731+00:00 [info] <0.254.0> Running boot step direct_client defined by app rabbit +2025-05-08 00:39:53 2025-05-07 22:39:53.116820+00:00 [info] <0.254.0> Running boot step rabbit_federation_exchange defined by app rabbitmq_federation +2025-05-08 00:39:53 2025-05-07 22:39:53.116952+00:00 [info] <0.254.0> Running boot step rabbit_management_load_definitions defined by app rabbitmq_management +2025-05-08 00:39:53 2025-05-07 22:39:53.117033+00:00 [info] <0.688.0> Resetting node maintenance status +2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> Deprecated features: `management_metrics_collection`: Feature `management_metrics_collection` is deprecated. +2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> By default, this feature can still be used for now. +2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> Its use will not be permitted by default in a future minor RabbitMQ version and the feature will be removed from a future major RabbitMQ version; actual versions to be determined. +2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> To continue using this feature when it is not permitted by default, set the following parameter in your configuration: +2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> "deprecated_features.permit.management_metrics_collection = true" +2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> To test RabbitMQ as if the feature was removed, set this in your configuration: +2025-05-08 00:39:53 2025-05-07 22:39:53.277583+00:00 [warning] <0.717.0> "deprecated_features.permit.management_metrics_collection = false" +2025-05-08 00:39:56 2025-05-07 22:39:56.676986+00:00 [info] <0.754.0> Management plugin: HTTP (non-TLS) listener started on port 15672 +2025-05-08 00:39:56 2025-05-07 22:39:56.677233+00:00 [info] <0.784.0> Statistics database started. +2025-05-08 00:39:56 2025-05-07 22:39:56.677362+00:00 [info] <0.783.0> Starting worker pool 'management_worker_pool' with 3 processes in it +2025-05-08 00:39:56 2025-05-07 22:39:56.688467+00:00 [info] <0.802.0> Prometheus metrics: HTTP (non-TLS) listener started on port 15692 +2025-05-08 00:39:56 2025-05-07 22:39:56.688698+00:00 [info] <0.688.0> Ready to start client connection listeners +2025-05-08 00:39:56 2025-05-07 22:39:56.690341+00:00 [info] <0.846.0> started TCP listener on [::]:5672 +2025-05-08 00:39:56 completed with 5 plugins. +2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> Server startup complete; 5 plugins started. +2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_prometheus +2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_federation +2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_management +2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_management_agent +2025-05-08 00:39:56 2025-05-07 22:39:56.752686+00:00 [info] <0.688.0> * rabbitmq_web_dispatch +2025-05-08 00:39:56 2025-05-07 22:39:56.763812+00:00 [info] <0.9.0> Time to start RabbitMQ: 21128 ms +2025-05-08 00:39:57 2025-05-07 22:39:57.325312+00:00 [info] <0.850.0> accepting AMQP connection <0.850.0> (172.18.0.10:54858 -> 172.18.0.2:5672) +2025-05-08 00:39:57 2025-05-07 22:39:57.329386+00:00 [info] <0.850.0> connection <0.850.0> (172.18.0.10:54858 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:40:01 2025-05-07 22:40:01.156082+00:00 [info] <0.875.0> accepting AMQP connection <0.875.0> (172.18.0.5:44442 -> 172.18.0.2:5672) +2025-05-08 00:40:01 2025-05-07 22:40:01.158843+00:00 [info] <0.875.0> connection <0.875.0> (172.18.0.5:44442 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:40:15 2025-05-07 22:40:15.943110+00:00 [info] <0.893.0> accepting AMQP connection <0.893.0> (172.18.0.6:41738 -> 172.18.0.2:5672) +2025-05-08 00:40:15 2025-05-07 22:40:15.960296+00:00 [info] <0.893.0> connection <0.893.0> (172.18.0.6:41738 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:40:17 2025-05-07 22:40:17.098095+00:00 [info] <0.906.0> accepting AMQP connection <0.906.0> (172.18.0.8:35750 -> 172.18.0.2:5672) +2025-05-08 00:40:17 2025-05-07 22:40:17.232657+00:00 [info] <0.906.0> connection <0.906.0> (172.18.0.8:35750 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:40:18 2025-05-07 22:40:18.059680+00:00 [info] <0.919.0> accepting AMQP connection <0.919.0> (172.18.0.4:33952 -> 172.18.0.2:5672) +2025-05-08 00:40:18 2025-05-07 22:40:18.076198+00:00 [info] <0.919.0> connection <0.919.0> (172.18.0.4:33952 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:40:19 2025-05-07 22:40:19.149330+00:00 [info] <0.932.0> accepting AMQP connection <0.932.0> (172.18.0.11:58748 -> 172.18.0.2:5672) +2025-05-08 00:40:19 2025-05-07 22:40:19.155624+00:00 [info] <0.932.0> connection <0.932.0> (172.18.0.11:58748 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:40:20 2025-05-07 22:40:20.125333+00:00 [info] <0.945.0> accepting AMQP connection <0.945.0> (172.18.0.9:35214 -> 172.18.0.2:5672) +2025-05-08 00:40:20 2025-05-07 22:40:20.137163+00:00 [info] <0.945.0> connection <0.945.0> (172.18.0.9:35214 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:40:24 2025-05-07 22:40:24.253787+00:00 [info] <0.959.0> accepting AMQP connection <0.959.0> (172.18.0.7:44718 -> 172.18.0.2:5672) +2025-05-08 00:40:24 2025-05-07 22:40:24.261729+00:00 [info] <0.959.0> connection <0.959.0> (172.18.0.7:44718 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:40:28 2025-05-07 22:40:28.129182+00:00 [info] <0.972.0> accepting AMQP connection <0.972.0> (172.18.0.12:54626 -> 172.18.0.2:5672) +2025-05-08 00:40:28 2025-05-07 22:40:28.136032+00:00 [info] <0.972.0> connection <0.972.0> (172.18.0.12:54626 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:40:36 2025-05-07 22:40:36.606102+00:00 [notice] <0.86.0> alarm_handler: {set,{system_memory_high_watermark,[]}} +2025-05-08 00:42:28 2025-05-07 22:42:28.420562+00:00 [info] <0.1062.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:42:28 2025-05-07 22:42:28.421247+00:00 [info] <0.1062.0> Successfully synced tables from a peer +2025-05-08 00:42:32 2025-05-07 22:42:32.812303+00:00 [info] <0.1076.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:42:32 2025-05-07 22:42:32.812482+00:00 [info] <0.1076.0> Successfully synced tables from a peer +2025-05-08 00:42:42 2025-05-07 22:42:42.667226+00:00 [info] <0.1088.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:42:42 2025-05-07 22:42:42.667489+00:00 [info] <0.1088.0> Successfully synced tables from a peer +2025-05-08 00:45:46 2025-05-07 22:45:46.674479+00:00 [info] <0.1176.0> accepting AMQP connection <0.1176.0> (172.18.0.3:56882 -> 172.18.0.2:5672) +2025-05-08 00:45:46 2025-05-07 22:45:46.685208+00:00 [info] <0.1176.0> connection <0.1176.0> (172.18.0.3:56882 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:45:46 2025-05-07 22:45:46.707040+00:00 [info] <0.1176.0> closing AMQP connection <0.1176.0> (172.18.0.3:56882 -> 172.18.0.2:5672, vhost: '/', user: 'user') +2025-05-08 00:45:51 2025-05-07 22:45:51.693391+00:00 [info] <0.1195.0> accepting AMQP connection <0.1195.0> (172.18.0.10:42554 -> 172.18.0.2:5672) +2025-05-08 00:45:51 2025-05-07 22:45:51.708567+00:00 [info] <0.1195.0> connection <0.1195.0> (172.18.0.10:42554 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 00:45:51 2025-05-07 22:45:51.810772+00:00 [info] <0.1195.0> closing AMQP connection <0.1195.0> (172.18.0.10:42554 -> 172.18.0.2:5672, vhost: '/', user: 'user') +2025-05-08 00:46:08 2025-05-07 22:46:08.987067+00:00 [info] <0.1225.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:46:08 2025-05-07 22:46:08.987347+00:00 [info] <0.1225.0> Successfully synced tables from a peer +2025-05-08 00:46:11 2025-05-07 22:46:11.806552+00:00 [info] <0.1237.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:46:11 2025-05-07 22:46:11.806923+00:00 [info] <0.1237.0> Successfully synced tables from a peer +2025-05-08 00:46:24 2025-05-07 22:46:24.475575+00:00 [info] <0.1257.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:46:24 2025-05-07 22:46:24.475750+00:00 [info] <0.1257.0> Successfully synced tables from a peer +2025-05-08 00:46:30 2025-05-07 22:46:30.968293+00:00 [info] <0.1266.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:46:30 2025-05-07 22:46:30.968504+00:00 [info] <0.1266.0> Successfully synced tables from a peer +2025-05-08 00:46:34 2025-05-07 22:46:34.967466+00:00 [info] <0.1276.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:46:34 2025-05-07 22:46:34.967651+00:00 [info] <0.1276.0> Successfully synced tables from a peer +2025-05-08 00:46:35 2025-05-07 22:46:35.535311+00:00 [info] <0.1288.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:46:35 2025-05-07 22:46:35.535482+00:00 [info] <0.1288.0> Successfully synced tables from a peer +2025-05-08 00:48:15 2025-05-07 22:48:15.939642+00:00 [error] <0.893.0> closing AMQP connection <0.893.0> (172.18.0.6:41738 -> 172.18.0.2:5672): +2025-05-08 00:48:15 2025-05-07 22:48:15.939642+00:00 [error] <0.893.0> missed heartbeats from client, timeout: 60s +2025-05-08 00:48:17 2025-05-07 22:48:17.212677+00:00 [error] <0.906.0> closing AMQP connection <0.906.0> (172.18.0.8:35750 -> 172.18.0.2:5672): +2025-05-08 00:48:17 2025-05-07 22:48:17.212677+00:00 [error] <0.906.0> missed heartbeats from client, timeout: 60s +2025-05-08 00:48:18 2025-05-07 22:48:18.058676+00:00 [error] <0.919.0> closing AMQP connection <0.919.0> (172.18.0.4:33952 -> 172.18.0.2:5672): +2025-05-08 00:48:18 2025-05-07 22:48:18.058676+00:00 [error] <0.919.0> missed heartbeats from client, timeout: 60s +2025-05-08 00:48:19 2025-05-07 22:48:19.138623+00:00 [error] <0.932.0> closing AMQP connection <0.932.0> (172.18.0.11:58748 -> 172.18.0.2:5672): +2025-05-08 00:48:19 2025-05-07 22:48:19.138623+00:00 [error] <0.932.0> missed heartbeats from client, timeout: 60s +2025-05-08 00:49:47 2025-05-07 22:49:47.411874+00:00 [info] <0.1503.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:49:47 2025-05-07 22:49:47.423869+00:00 [info] <0.1503.0> Successfully synced tables from a peer +2025-05-08 00:49:49 2025-05-07 22:49:49.041300+00:00 [info] <0.1510.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:49:49 2025-05-07 22:49:49.065891+00:00 [info] <0.1510.0> Successfully synced tables from a peer +2025-05-08 00:50:10 2025-05-07 22:50:10.530545+00:00 [info] <0.1528.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:50:10 2025-05-07 22:50:10.545653+00:00 [info] <0.1528.0> Successfully synced tables from a peer +2025-05-08 00:50:20 2025-05-07 22:50:20.045026+00:00 [info] <0.1542.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:50:20 2025-05-07 22:50:20.081418+00:00 [info] <0.1542.0> Successfully synced tables from a peer +2025-05-08 00:50:20 2025-05-07 22:50:20.116816+00:00 [error] <0.945.0> closing AMQP connection <0.945.0> (172.18.0.9:35214 -> 172.18.0.2:5672): +2025-05-08 00:50:20 2025-05-07 22:50:20.116816+00:00 [error] <0.945.0> missed heartbeats from client, timeout: 60s +2025-05-08 00:50:24 2025-05-07 22:50:24.253931+00:00 [error] <0.959.0> closing AMQP connection <0.959.0> (172.18.0.7:44718 -> 172.18.0.2:5672): +2025-05-08 00:50:24 2025-05-07 22:50:24.253931+00:00 [error] <0.959.0> missed heartbeats from client, timeout: 60s +2025-05-08 00:50:28 2025-05-07 22:50:28.133809+00:00 [error] <0.972.0> closing AMQP connection <0.972.0> (172.18.0.12:54626 -> 172.18.0.2:5672): +2025-05-08 00:50:28 2025-05-07 22:50:28.133809+00:00 [error] <0.972.0> missed heartbeats from client, timeout: 60s +2025-05-08 00:52:17 2025-05-07 22:52:17.044407+00:00 [info] <0.1708.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:52:17 2025-05-07 22:52:17.092956+00:00 [info] <0.1708.0> Successfully synced tables from a peer +2025-05-08 00:52:25 2025-05-07 22:52:25.275627+00:00 [info] <0.1717.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:52:25 2025-05-07 22:52:25.277749+00:00 [info] <0.1717.0> Successfully synced tables from a peer +2025-05-08 00:52:26 2025-05-07 22:52:26.569660+00:00 [info] <0.1726.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:52:26 2025-05-07 22:52:26.597496+00:00 [info] <0.1726.0> Successfully synced tables from a peer +2025-05-08 00:52:27 2025-05-07 22:52:27.695674+00:00 [info] <0.1736.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:52:27 2025-05-07 22:52:27.698046+00:00 [info] <0.1736.0> Successfully synced tables from a peer +2025-05-08 00:52:28 2025-05-07 22:52:28.216426+00:00 [info] <0.1745.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:52:28 2025-05-07 22:52:28.301230+00:00 [info] <0.1745.0> Successfully synced tables from a peer +2025-05-08 00:52:35 2025-05-07 22:52:35.577230+00:00 [info] <0.1759.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:52:35 2025-05-07 22:52:35.581596+00:00 [info] <0.1759.0> Successfully synced tables from a peer +2025-05-08 00:52:40 2025-05-07 22:52:40.549543+00:00 [info] <0.1772.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:52:40 2025-05-07 22:52:40.621826+00:00 [info] <0.1772.0> Successfully synced tables from a peer +2025-05-08 00:52:49 2025-05-07 22:52:49.753059+00:00 [warning] <0.1777.0> AMQP 0-9-1 client call timeout was 70000 ms, is updated to a safe effective value of 130000 ms +2025-05-08 00:57:02 2025-05-07 22:57:02.200826+00:00 [info] <0.1954.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:57:02 2025-05-07 22:57:02.224175+00:00 [info] <0.1954.0> Successfully synced tables from a peer +2025-05-08 00:57:09 2025-05-07 22:57:09.305246+00:00 [info] <0.1968.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:57:09 2025-05-07 22:57:09.323530+00:00 [info] <0.1968.0> Successfully synced tables from a peer +2025-05-08 00:57:18 2025-05-07 22:57:18.337609+00:00 [info] <0.1982.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:57:18 2025-05-07 22:57:18.392710+00:00 [info] <0.1982.0> Successfully synced tables from a peer +2025-05-08 00:57:21 2025-05-07 22:57:21.654491+00:00 [info] <0.1990.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 00:57:21 2025-05-07 22:57:21.660117+00:00 [info] <0.1990.0> Successfully synced tables from a peer +2025-05-08 01:02:00 2025-05-07 23:02:00.731071+00:00 [info] <0.2166.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 01:02:00 2025-05-07 23:02:00.755919+00:00 [info] <0.2166.0> Successfully synced tables from a peer +2025-05-08 01:04:00 2025-05-07 23:04:00.787526+00:00 [info] <0.2286.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 01:04:00 2025-05-07 23:04:00.803380+00:00 [info] <0.2286.0> Successfully synced tables from a peer +2025-05-08 01:07:34 2025-05-07 23:07:34.311979+00:00 [info] <0.2406.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 01:07:34 2025-05-07 23:07:34.360990+00:00 [info] <0.2406.0> Successfully synced tables from a peer +2025-05-08 01:12:09 2025-05-07 23:12:09.342192+00:00 [info] <0.2664.0> Waiting for Mnesia tables for 30000 ms, 9 retries left +2025-05-08 01:12:09 2025-05-07 23:12:09.352579+00:00 [info] <0.2664.0> Successfully synced tables from a peer +2025-05-08 01:21:27 2025-05-07 23:21:27.224944+00:00 [info] <0.2998.0> accepting AMQP connection <0.2998.0> (172.18.0.11:50692 -> 172.18.0.2:5672) +2025-05-08 01:21:27 2025-05-07 23:21:27.235852+00:00 [info] <0.2998.0> connection <0.2998.0> (172.18.0.11:50692 -> 172.18.0.2:5672): user 'user' authenticated and granted access to vhost '/' +2025-05-08 01:21:27 2025-05-07 23:21:27.277399+00:00 [info] <0.2998.0> closing AMQP connection <0.2998.0> (172.18.0.11:50692 -> 172.18.0.2:5672, vhost: '/', user: 'user') + diff --git a/logs/log_unifier.log b/logs/log_unifier.log new file mode 100644 index 0000000..a63af07 --- /dev/null +++ b/logs/log_unifier.log @@ -0,0 +1,74 @@ +2025-05-08 00:39:36 2025-05-07 22:39:36,064 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672) +2025-05-08 00:39:36 2025-05-07 22:39:36,073 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: ; error=111 (Connection refused) +2025-05-08 00:39:36 2025-05-07 22:39:36,074 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(, , 6, '', ('172.18.0.2', 5672)) +2025-05-08 00:39:36 2025-05-07 22:39:36,074 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused') +2025-05-08 00:39:36 2025-05-07 22:39:36,074 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None. +2025-05-08 00:39:36 2025-05-07 22:39:36,074 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:36 2025-05-07 22:39:36,075 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:36 2025-05-07 22:39:36,075 - pika.adapters.blocking_connection - ERROR - Error in _create_connection(). +2025-05-08 00:39:36 Traceback (most recent call last): +2025-05-08 00:39:36 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection +2025-05-08 00:39:36 raise self._reap_last_connection_workflow_error(error) +2025-05-08 00:39:36 pika.exceptions.AMQPConnectionError +2025-05-08 00:39:36 2025-05-07 22:39:36,085 - unifier - WARNING - Intento 1: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos... +2025-05-08 00:39:41 2025-05-07 22:39:41,115 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672) +2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: ; error=111 (Connection refused) +2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(, , 6, '', ('172.18.0.2', 5672)) +2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused') +2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None. +2025-05-08 00:39:41 2025-05-07 22:39:41,117 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:41 2025-05-07 22:39:41,118 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:41 2025-05-07 22:39:41,118 - pika.adapters.blocking_connection - ERROR - Error in _create_connection(). +2025-05-08 00:39:41 Traceback (most recent call last): +2025-05-08 00:39:41 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection +2025-05-08 00:39:41 raise self._reap_last_connection_workflow_error(error) +2025-05-08 00:39:41 pika.exceptions.AMQPConnectionError +2025-05-08 00:39:41 2025-05-07 22:39:41,118 - unifier - WARNING - Intento 2: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos... +2025-05-08 00:39:46 2025-05-07 22:39:46,134 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672) +2025-05-08 00:39:46 2025-05-07 22:39:46,135 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: ; error=111 (Connection refused) +2025-05-08 00:39:46 2025-05-07 22:39:46,135 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(, , 6, '', ('172.18.0.2', 5672)) +2025-05-08 00:39:46 2025-05-07 22:39:46,135 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused') +2025-05-08 00:39:46 2025-05-07 22:39:46,136 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None. +2025-05-08 00:39:46 2025-05-07 22:39:46,136 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:46 2025-05-07 22:39:46,136 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:46 2025-05-07 22:39:46,136 - pika.adapters.blocking_connection - ERROR - Error in _create_connection(). +2025-05-08 00:39:46 Traceback (most recent call last): +2025-05-08 00:39:46 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection +2025-05-08 00:39:46 raise self._reap_last_connection_workflow_error(error) +2025-05-08 00:39:46 pika.exceptions.AMQPConnectionError +2025-05-08 00:39:46 2025-05-07 22:39:46,138 - unifier - WARNING - Intento 3: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos... +2025-05-08 00:39:51 2025-05-07 22:39:51,140 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672) +2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: ; error=111 (Connection refused) +2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(, , 6, '', ('172.18.0.2', 5672)) +2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused') +2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None. +2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:51 2025-05-07 22:39:51,141 - pika.adapters.blocking_connection - ERROR - Error in _create_connection(). +2025-05-08 00:39:51 Traceback (most recent call last): +2025-05-08 00:39:51 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection +2025-05-08 00:39:51 raise self._reap_last_connection_workflow_error(error) +2025-05-08 00:39:51 pika.exceptions.AMQPConnectionError +2025-05-08 00:39:51 2025-05-07 22:39:51,141 - unifier - WARNING - Intento 4: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos... +2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672) +2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.io_services_utils - ERROR - Socket failed to connect: ; error=111 (Connection refused) +2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - ERROR - TCP Connection attempt failed: ConnectionRefusedError(111, 'Connection refused'); dest=(, , 6, '', ('172.18.0.2', 5672)) +2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnector - reporting failure: AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused') +2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - ERROR - AMQP connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None. +2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.utils.connection_workflow - ERROR - AMQPConnectionWorkflow - reporting failure: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:56 2025-05-07 22:39:56,150 - pika.adapters.blocking_connection - ERROR - Connection workflow failed: AMQPConnectionWorkflowFailed: 1 exceptions in all; last exception - AMQPConnectorSocketConnectError: ConnectionRefusedError(111, 'Connection refused'); first exception - None +2025-05-08 00:39:56 2025-05-07 22:39:56,151 - pika.adapters.blocking_connection - ERROR - Error in _create_connection(). +2025-05-08 00:39:56 Traceback (most recent call last): +2025-05-08 00:39:56 File "/usr/local/lib/python3.9/site-packages/pika/adapters/blocking_connection.py", line 451, in _create_connection +2025-05-08 00:39:56 raise self._reap_last_connection_workflow_error(error) +2025-05-08 00:39:56 pika.exceptions.AMQPConnectionError +2025-05-08 00:39:56 2025-05-07 22:39:56,151 - unifier - WARNING - Intento 5: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos... +2025-05-08 00:40:01 2025-05-07 22:40:01,154 - pika.adapters.utils.connection_workflow - INFO - Pika version 1.3.2 connecting to ('172.18.0.2', 5672) +2025-05-08 00:40:01 2025-05-07 22:40:01,155 - pika.adapters.utils.io_services_utils - INFO - Socket connected: +2025-05-08 00:40:01 2025-05-07 22:40:01,155 - pika.adapters.utils.connection_workflow - INFO - Streaming transport linked up: (, _StreamingProtocolShim: params=>). +2025-05-08 00:40:01 2025-05-07 22:40:01,158 - pika.adapters.utils.connection_workflow - INFO - AMQPConnector - reporting success: params=> +2025-05-08 00:40:01 2025-05-07 22:40:01,158 - pika.adapters.utils.connection_workflow - INFO - AMQPConnectionWorkflow - reporting success: params=> +2025-05-08 00:40:01 2025-05-07 22:40:01,159 - pika.adapters.blocking_connection - INFO - Connection workflow succeeded: params=> +2025-05-08 00:40:01 2025-05-07 22:40:01,159 - pika.adapters.blocking_connection - INFO - Created channel=1 +2025-05-08 00:40:01 2025-05-07 22:40:01,213 - unifier - INFO - Servicio unificador iniciado. Esperando transcripciones... +2025-05-08 01:21:27 2025-05-07 23:21:27,297 - unifier - INFO - Recibida transcripción 4/4 para 1746657946_Episodios.mp3 diff --git a/whisper-distributed/docker-compose.yml b/whisper-distributed/docker-compose.yml new file mode 100644 index 0000000..69474bd --- /dev/null +++ b/whisper-distributed/docker-compose.yml @@ -0,0 +1,169 @@ +services: + rabbitmq: + image: rabbitmq:3-management + ports: + - "5672:5672" # AMQP port + - "15672:15672" # Management UI + environment: + - RABBITMQ_DEFAULT_USER=user + - RABBITMQ_DEFAULT_PASS=password + volumes: + - rabbitmq_data:/var/lib/rabbitmq + networks: + - whisper_network + + receiver: + build: + context: ./receiver + volumes: + - ./input:/app/input + - ./shared:/app/shared + depends_on: + - rabbitmq + networks: + - whisper_network + + splitter: + build: + context: ./splitter + volumes: + - ./shared:/app/shared + depends_on: + - rabbitmq + networks: + - whisper_network + + processor1: + build: + context: ./processor + volumes: + - ./shared:/app/shared + depends_on: + - rabbitmq + environment: + - PROCESSOR_ID=1 + networks: + - whisper_network + + processor2: + build: + context: ./processor + volumes: + - ./shared:/app/shared + depends_on: + - rabbitmq + environment: + - PROCESSOR_ID=2 + networks: + - whisper_network + + # processor3: + # build: + # context: ./processor + # volumes: + # - ./shared:/app/shared + # depends_on: + # - rabbitmq + # environment: + # - PROCESSOR_ID=3 + # networks: + # - whisper_network + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: 1 + # capabilities: [gpu] + + # processor4: + # build: + # context: ./processor + # volumes: + # - ./shared:/app/shared + # depends_on: + # - rabbitmq + # environment: + # - PROCESSOR_ID=4 + # networks: + # - whisper_network + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: 1 + # capabilities: [gpu] + + # processor5: + # build: + # context: ./processor + # volumes: + # - ./shared:/app/shared + # depends_on: + # - rabbitmq + # environment: + # - PROCESSOR_ID=5 + # networks: + # - whisper_network + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: 1 + # capabilities: [gpu] + # processor6: + # build: + # context: ./processor + # volumes: + # - ./shared:/app/shared + # depends_on: + # - rabbitmq + # environment: + # - PROCESSOR_ID=6 + # networks: + # - whisper_network + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: 1 + # capabilities: [gpu] + + # processor7: + # build: + # context: ./processor + # volumes: + # - ./shared:/app/shared + # depends_on: + # - rabbitmq + # environment: + # - PROCESSOR_ID=7 + # networks: + # - whisper_network + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: 1 + # capabilities: [gpu] + + unifier: + build: + context: ./unifier + volumes: + - ./shared:/app/shared + - ./output:/app/output + depends_on: + - rabbitmq + networks: + - whisper_network + +networks: + whisper_network: + +volumes: + rabbitmq_data: \ No newline at end of file diff --git a/whisper-distributed/input/hoy_por_hoy.mp3 b/whisper-distributed/input/hoy_por_hoy.mp3 new file mode 100644 index 0000000..5c6d06d Binary files /dev/null and b/whisper-distributed/input/hoy_por_hoy.mp3 differ diff --git a/whisper-distributed/output/hoy_por_hoy_transcription.srt b/whisper-distributed/output/hoy_por_hoy_transcription.srt new file mode 100644 index 0000000..23def5b --- /dev/null +++ b/whisper-distributed/output/hoy_por_hoy_transcription.srt @@ -0,0 +1,32 @@ +1 +00:00:00,000 --> 00:02:00,000 +Ser Podcast La socho de hoy por hoy en Ser Podcast Hola muy buenos días, lo que pasó ayer en Alemania no solo explica la situación allí en la primera potencia europea, sino que explica de alguna manera cómo están los tiempos y cómo se extiende la inestabilidad y la incertidumbres, si uno de los países con la política más previsible de las últimas décadas vive con sorpresa y hasta contraiciones la elección de su canciller tras el acuerdo entre conservadores y social democratas. Por si faltaran cosas, esta madrugada hemos asistido a la escala de militar entre India y Pakistan, que son dos potencias nucleares y que añaden incertidumbre a un mundo removido por un donaltram que ahora busca acercar posturas con China. Esta es otra de las novedades con las que amanecemos hoy, una delegación de Washington y otra de Pequín, prevén reunirse a finales de esta misma semana para hablar de los araceles será la primera vez que se vean desde que Trump empezó la guerra comercial y se va a ver en Suiza. Sastre, buenos días. Buenos días, Barceló. Bueno, con este contexto internacional de fondo y con el rear me envoca de todos los gobiernos, esta mañana comparece a quien España, Pedro Sanchez, para hablar de un insólito a Pagón cuyas causas aún desconocemos. También para explicar cómo puede subir el gastón de fence al 2% aunque no tenga presupuestos generales. De hecho, en este momento el gobierno no tiene una mayoría que garantice para empezar, lo último que aprobó ayer mismo el Consejo de Ministros, la reducción de la jornada laboral contra la que Xi'unz ha presentado una enmienda a la totalidad. Pues ya decíamos que la incertidumbre explica buena parte de lo que ocurre y esa es la palabra que define precisamente lo que desde hoy va a pasar en Roma. Hoy por hoy noticias. Ser podcast. El conclave. Que empieza esta tarde a las 4 y media, con tantos nombres en las quinielas que sea hay algo en lo que coincide en los pronósticos es que toda punta a que vamos a un conclave que no se va a resolver el primer día, seguramente tampoco el segundo, aunque en verdad nadie sabe si todo está rodeado no solo de una gran... + +2 +00:02:00,000 --> 00:04:00,000 +en la liturgia, sino de un silencio que se alarga. Vamos a Roma con responsabil John Soles. Al término de la última congregación en la que intervenieron otros 26 cardenales sobre las prioridades de la iglesia católica en el mundo, no se había definido el perfil del próximo pontífice que deberá ser elegido a partir de esta tarde y según se desprende de comentarios de algunos purporados. Francisco era Francisco, no habrá otro Francisco, ha invertido el cardenal francés Vesco. Él abrió las puertas y yo deseo añadido que estas puertas sigan abiertas con el nuevo papa y que siga la línea trazada. La 17a mañana empezará la misa proeligiendo romano pontífice tras el almuerzo los electores podrán descansar, pero a primera hora de la tarde se han trasladado en microbuses de la residencia de Santa Marta al otro extremo del ápcide de la basilica de San Pedro. Se dirigirán a la capilla paulina y en procesión a la 16a juraran mantener el secreto de las deliberaciones y a continuación el maestro de ceremonias papales pronunciará al tradicional extra-omnes, es decir, todos fuera salvo los electores. La primera fuma tallegara, previsiblemente, entre las 6 y las 7 de la tarde. Los focos de la actualidad internacional empezan a apuntar a Roma esta tarde para cuando veamos entrar a los cardenales uno en uno en la capilla 16. De momento, los grandes asuntos en la crónica del mundo son dos, como les decía al empezar, por un lado, la reunión que tendrá en China y Estados Unidos a finales de semana con la esperanza de que puedan aliviar la guerra que ha agitado el mundo, la guerra de los aranceles. Y el otro gran asunto es ese ataque de India contra varias tonas de Pakistan en una serie de bombardeos que nueva Delhi ha justificado como represalias después de los atentados de abril en la cachemira India. Estados Unidos ha dicho ya que está pendiente de lo que pase entre estos dos países, las dos, los dos son potencias nucleares y cuyo enfrentamiento vayan bienete de lejos. Hace más de siete décadas que India y Pakistan se disputan ese territorio fronterizo de cachemira, uno de los puntos calientes de... + +3 +00:04:00,000 --> 00:06:00,000 +y donde ambas potencias han librado ya cuatro guerras desde 1947. Así sonaba noche, el intercambio de disparos en la denominada línea de control, escaramuzas fronterizas que siguieron al ataque con misiles por parte de India, contra varios objetivos en territorio paquistánín. El gobierno de Islamabad habla de un ataque injustificado por parte de India que deja al menos 26 civiles muertos en ese país. En paquistán, otras 10 personas han fallecido esta noche en el lado indio de la frontera, mientras se suceden los llamamientos a la contención para evitar una escalada bélica. En esta habilidad, y escalada militar en Asia, en esta habilidad política en el país, cuya política se prefiaba de su estabilidad desde el final de la Segunda Guerra Mundial, que es Alemania, corresponde a Lemberlín Carmen Vinyas, buenos días. Hola, buenos días, señor. Todo el mundo Carmen se hace allí esta mañana la misma pregunta, quién trató de boicotear la elección de Merst como Canciller, en una votación secreta que sumió al país en la incertidumbre durante unas horas, hasta que se precipitó una nueva votación y pudo salir elegido, pero salió elegido y a Carmen exhibiendo su debilidad. Pues sí, sigue siendo un incógnita porque todo era secreto, aunque motivos para la disidencia no faltaban. El caos que conservadores y social democratas han provocado en el Bundestak, ha supuesto un duro golpe. Es un revés sobre todo para los líderes de ambos grupos que no han podido convencer a los suyos de la necesidad de un gobierno conjunto. Muchos conservadores están molestos por la relajación del Freno a la deuda y muchos social democratas se sienten frustrados por el endurecimiento de la política migratoria. También hay malestar por elección del gabinete a las derechas de la acusa de buscar perfiles muy empresariales y los social democratas de arriesgar con juventud y inexperiencia. A sus señorías, Ángeles hizo falta recordarles que Alemania necesita esta habilidad en tiempos de guerra con Ucrania, de frágil relación con Estados Unidos y de fortaleza de la estrema derecha. Quizá una mirada a la bismo sirvió para elegir finalmente a Merch. Seguimos en el abierto. Hasta luego. Hay una imagen internacional más, todavía señal también de los tiempos de los que estamos. El encuentro en el despacho Val de la... + +4 +00:06:00,000 --> 00:08:00,000 +Casa Blanca entre Donald Trump y luego primer ministro de Canadá, Marcarnei, que dijo a Trump, Canadá no está en venta. Y esta es la respuesta que le dio ayer la Casa Blanca Donald Trump. Pero nunca he dicho, nunca he dicho, nunca. Nunca digas nunca. Aquí en España también va a ser noticia hoy el Parlamento, porque hoy es el pleno del Congreso, en el que va a comparecer Pedro Sánchez para hablar del aumento del gasto en defensa, aunque en realidad va a hablar también de la pagón Guillermo Lermabu nos días. ¿Qué tal, Buenos días, Angelo? Y el pleno servirá de nuevo cómo termómetro de la legislatura. Sí, una legislatura que el gobierno da por hecho, que va a estar marcada por ese debate sobre la defensa y la seguridad, algo que en el ejecutivo dicen conecta precisamente con la necesidad de reforzar las capacidades de España para prever esos imprevistos como el apagón. En el gobierno, dan por hecho, que la pregunta que más se va a repetir o bien el pleno es esa que ocurrió, lo que está en el origen de eso apagón, que dejó a España sin electricidad del pasado lunes. No hay ninguna certeza sobre el origen de ese cero eléctrico, Sánchez acude al pleno, sin poder aportar respuestas claras. Así que el jefe del ejecutivo va a defender que todas las posibilidades están abiertas. No hay ninguna certeza sobre el origen, así que en el ejecutivo, creo que sería una responsabilidad a apuntar a cualquier posibilidad, sin haber analizado todos los datos técnicos. Sánchez va a insistir en no descartar ninguna opción. Ayer el pleno del Senado vivió una peritivo de lo que va a ser la sesión de hoy, desde esa comparecencia Sara Gensen, pedía rigor y responsable. Lo peor que podríamos hacer por la ciudadanía, por la seguridad del suministro de este país, es empezar a hacer hipótesis de lo más variopinto sin ninguna certeza. Por favor, rigor para la ciudadanía, rigor en la aportación de soluciones. El presidente intentará sobre todo desmontar la imagen de colapso y caos que intenta fijar... + +5 +00:08:00,000 --> 00:10:00,000 +la derecha, una realidad paralela dicen en la mongla. Y, gracias. Hasta luego. Fejo por su parte su maral apagó en el robo del domingo en los cables de alta velocidad para denunciar eso una situación de caos en el país de habito en que era buenos días. Hola, Angel Sanctismo, en fase de paranoia. Es el resumen que hacen en Genova de los que ellos califican como los dos lunes negros. En la herida de la paón, en la herida del caos ferroviario quiere urgar hoy fejó que hacear al presidente que siempre culpa a terceros sin pruebas. Mucho ciber ataque, muchos a botaje, pero pocas explicaciones y pocas disculpas. Tampoco vea el tema de gasto en defensa, remarcando que poco podemos aportar como país para solucionar la inestabilidad que se acude a Europa cuando nuestro gobierno no es capaz de garantizar el suministro eléctrico las comunicaciones o las redes de transporte en España. Es lo que quiere dejar patente el líder de un PP desde el que ironizan. Para hacer tan valer, se abruselas, Putin tiene que empeñarse a fondo, pero para poner a España en hacke, basta con una socialista como Beatriz Corredor al frente de Recelectrica. Hoy por hoy, noticias. Ser podcast. El juez peinado ha imputado al actual delegado del gobierno en Madrid por el caso begóña Gómez. El juez admite en parte la crey de box, por tanto imputa el delito de malversación, al delegado guberramental en Madrid, Francisco Martín, por la contratación de Cristina Álvarez. El juez, que se mantuvo con Martín, continuó en el cargo ahora con Judí González en la Secretaría General General. El juez sortía a González en el caso de la Secretaría General General General, y se mantuvo con Martín, al que atribuye el juez esta supuesta en malversación. ¿Qué tal, Álvarez? ¿Cuáles son? La razón es de peinado. Pues dice el juez que Francisco Martín era el responsable y superior gerar quico de Cristina Álvarez, la sesora de Begoña Gómez, que se nombró con Feliz Bolaños como Secretario General de Presidencia, que se mantuvo con Martín, y que continúan el cargo ahora con Judí González y al Ministro Bolaños, que está aforado ante el Supremo y se queda con el delegado del Gobierno, al que atribuye la malversación, porque sostiene que se pagó a… + +6 +00:10:00,000 --> 00:12:00,000 +Cristina Álvarez con fondos públicos para ayudar en las actividades privadas de Begoña Gómez. Juan Carlos Peinado vuelve a dar un nuevo giro de timón esta vez en la última línea de investigación que abrió para mantener viva la causa, pone el foco en Francisco Martín y ahora decide exculpar a la asesora porque dice que se limitó a hacer su trabajo y a cobrar por ello, por lo tanto no cometió delito y también a la mujer de Pedro Sánchez, porque dice que se limitó a contar con esos servicios profesionales aunque fuera para fines personales. Gracias, Pedro. Hasta luego. Así es como se refiere a esta instrucción judicial de Peinado, el ministro de Justicia Félix volaños. Esta instrucción ya no es motivo de preocupación para la gente honesta y con la conciencia tranquila que se está viendo afectada. Es motivo de preocupación máxima para todos los que defendemos el buen nombre y la impartialidad de los jueces imaginados de nuestro país. Y en Valencia mientras sigue la investigación de la bana que está llevando a cabo la jueza de Catarrotjante, la que ayer declaró uno de los técnicos que envió la alerta a los teléfonos móviles el día de la catástrofe. A la alerta que llegó, como saben, cuando la mayoría de las víctimas ya habían muerto, este técnico explicó que las concelleras salomepradas les ordenó que no envías en el mensaje hasta que ella lo hubiera visto a Natalense Von Diem. Bon día, el técnico declaró un calidad de testigo con la obligación de decir la verdad y contestar a todas las partes. A firmó que la ex-consellera Pradas le dijo que no envía a nada hasta que ella diera el visto bueno. Indicó que hubo un primer borrador de mensajes sobre la situación del barranco de Forata que se descartó y que se decidió redactar otro para toda la provincia. El técnico añade que pasó una hora desde que se decidió enviar el mensaje hasta que efectivamente se remitió a las ocho y once minutos de la tarde. Aunque considera que no debía haberse tardado más de 20 minutos. Por su parte fuentes pero próximas a la ex-consellera Pradas han negado a la ser cualquier retraso en el visto bueno el envío el mensaje y se remiten a la literalidad de su declaración no a la transcripción que se filtró a los medios. Dicen que en esa declaración quedó claro que el visto bueno en mensaje que introdujen los técnicos en el sistema informático fue inmediato y tenía que ver con la situación de Forata. + +7 +00:12:00,000 --> 00:14:00,000 +Esas fuentes aseguran también que efectivamente se tardó una hora entre la propuesta del subdirector para el borrador del mensaje hasta que se envió, pero añada en que el técnico no dijo en ningún momento que ese tiempo fuera, porque Pradas le dijera que esperase a que ella lidera el visto bueno. Y además, el poder judicial va a seguir investigando los jueces el hoy Velasco y Carros del Valle, persa que quien lleva su expediente había propuesto que se archivara. Se trata del juez que interrogó a un humorista actor de Miguel y también del juez que cuestionó la legitimidad del gobierno y que llegó a decir que no iba a ser Irene Montero desde la caja del Mercadona, dijo, la que les iba a explicar a ellos a los magistrados que es el consentimiento. Más de cuatro millones de personas ya han cobrado la devolución de la renta, acaba de cumplirse un mes del inicio de la campaña y haciendo informa de que ha recibido menos declaraciones. O bastante menos, en concreto se han presentado en total siete millones, lo que supone casi un cinco por ciento menos que es el mismo periodo de 2024. La agencia tributaria recuerda que el plazo para presentar la declaración termina el 30 de junio, Jordi Fabregam. Después del furor inicial este año y menos prisa por presentar la declaración de la renta. En el primer mes de campaña, la agencia tributaria ha recibido siete millones y cientos mil declaraciones. Es un 4,7 por ciento menos que el año pasado. Es verdad que esta vez, dentro del periodo en el que se ha podido presentar la declaración entra la semana santa y eso ha condicionado las cifras. En el 16 de diciembre, la agencia tributaria ha puesto en marcha el plan de ayuda telefónica para elaborar la declaración. Un equipo del Centro Nacional de Investigaciones Oncológicas ha identificado el interruptor clave en el desarrollo del cáncer de colon. El estudio lo publica la revista net huri muestra que cuando falta una proteína, se puede poner en marcha el desarrollo del tumor. Es decir, que con la dieta con lo que comemos, se puede evitar que se actenmarina farmández. En bruto este descubrim... + +8 +00:14:00,000 --> 00:15:59,269 +que publican eiturpodes sonarnos poco asequible. Hemos demostrado que degradar la proteína P53 es un evento necesario para la iniciación del proceso tumoral. Pero la investigadora Irene Erranzo, una de las autoras lo traduce para que entendamos su potencial. Efectivamente evitar la degradación de P53 evitaría el desarrollo de tumores en pacientes humanos. Lo han comprobado en modelos animales y también en muestras humanas y su hallazgo va más allá. Describimos que otra proteína, llamada URI, favorece la degradación de P53. Sabemos que la dieta puede influir en los niveles de URI y con ello influir en los niveles de P53. Y de esta manera, promover o prevenir el desarrollo de los tumores. El cáncer color dectales es más frecuente en España, en la población general, con más de 40.000 nuevos diagnósticos al año. Y los mirlos nuevos médicos quieren ser dermatólogos y no médicos de familia y eso andan la carencia que ya sufren los centros de salud en buena parte del país, Mario Lleuridón. 15.000 mil a por una de las 9.000 plazas estos días se eligen su futuro. ¿Y oftándolo, Xi'a? Yo, cardiología. Gené, golgón. Ecogi de neurociología. Hay una especialidad estrella, las plazas se agotaron en tiempo record. Yo he elegido dermatología. Es una especialidad que tiene muy buenas salidas, laborales actualmente. También están ajudicadas ya en cirugía plástica, ambasón el top. Yo creo que hermar montas tu consulta privada con muy poca inversión y ves muchos pacientes. Curros de Córdoba le toca elegir hoy. Yo, por más y lo facial, tiene muy buena calidad de vida y tiene muy buena privada, la verdad. La Cenecienta es medicina familiar de las 2.500 plazas ofertadas, solo 22 han elegido de momento la atención primaria. No, no está tan bien reconocida, igual. También tiene mucho trabajo burocrático, que igual a la gente después de medicina no es lo que más la petece. Hay una pena que hayan bien que las cosas mejoraron para los médicos de familia. Desde hace tres años hay vacantes, si no se cubren todas las plazas en un servicio muy debilitado y con falta de personal. Y en diez minutos se la abiertó. Cone de guarda Madina, a victor la puente y elisa de la 9. ¿Para no perder ningún episodio? Sigue no ser la aplicación o la web de la ser, podí un podcast o tu plataforma de audio favorita. + diff --git a/whisper-distributed/processor/Dockerfile b/whisper-distributed/processor/Dockerfile new file mode 100644 index 0000000..61d59ca --- /dev/null +++ b/whisper-distributed/processor/Dockerfile @@ -0,0 +1,29 @@ +FROM python:3.9 + +WORKDIR /app + +# Instalar dependencias básicas +RUN apt-get update && apt-get install -y ffmpeg + +# Instalar torch con soporte CUDA y otras dependencias +RUN pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 +RUN pip install pika openai-whisper + +# Crear un script para descargar el modelo +RUN echo '\ +import whisper\n\ +import torch\n\ +print("Verificando disponibilidad de CUDA:", torch.cuda.is_available())\n\ +if torch.cuda.is_available():\n\ + print("Dispositivo CUDA:", torch.cuda.get_device_name(0))\n\ +print("Descargando modelo Whisper base...")\n\ +whisper.load_model("base")\n\ +print("Modelo descargado correctamente")\ +' > download_model.py + +# Ejecutar el script para descargar el modelo durante la construcción +RUN python download_model.py + +COPY app.py . + +CMD ["python", "app.py"] \ No newline at end of file diff --git a/whisper-distributed/processor/app.py b/whisper-distributed/processor/app.py new file mode 100644 index 0000000..84fbe2e --- /dev/null +++ b/whisper-distributed/processor/app.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python +import os +import time +import json +import pika +import logging +import whisper +import torch +from datetime import datetime + +# Configuración de logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger('processor') + +# Configuración de RabbitMQ +RABBITMQ_HOST = 'rabbitmq' +RABBITMQ_USER = 'user' +RABBITMQ_PASS = 'password' +PROCESS_QUEUE = 'audio_process_queue' +UNIFY_QUEUE = 'text_unify_queue' + +# Configuración de Whisper +WHISPER_MODEL = "base" # Opciones: "tiny", "base", "small", "medium", "large" + +# Directorios +SHARED_DIR = '/app/shared' + +# ID del procesador para logs +PROCESSOR_ID = os.environ.get('PROCESSOR_ID', 'unknown') + +def connect_to_rabbitmq(): + """Establece conexión con RabbitMQ""" + tries = 0 + while True: + try: + credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS) + connection = pika.BlockingConnection( + pika.ConnectionParameters( + host=RABBITMQ_HOST, + credentials=credentials, + heartbeat=600 # 10 minutos + ) + ) + return connection + except pika.exceptions.AMQPConnectionError: + tries += 1 + logger.warning(f"Intento {tries}: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...") + time.sleep(5) + +def load_whisper_model(): + """Carga el modelo de Whisper""" + # Verificar si hay GPU disponible + device = "cuda" if torch.cuda.is_available() else "cpu" + + if device == "cuda": + gpu_name = torch.cuda.get_device_name(0) + logger.info(f"Procesador {PROCESSOR_ID}: GPU detectada: {gpu_name}") + else: + logger.info(f"Procesador {PROCESSOR_ID}: No se detectó GPU, usando CPU") + + logger.info(f"Procesador {PROCESSOR_ID}: Cargando modelo Whisper '{WHISPER_MODEL}' en {device}...") + model = whisper.load_model(WHISPER_MODEL, device=device) + logger.info(f"Procesador {PROCESSOR_ID}: Modelo Whisper cargado correctamente") + return model + +def transcribe_audio(model, audio_path): + """Transcribe un archivo de audio usando Whisper""" + logger.info(f"Procesador {PROCESSOR_ID}: Transcribiendo {audio_path}") + + # Realizar transcripción + result = model.transcribe(audio_path) + + logger.info(f"Procesador {PROCESSOR_ID}: Transcripción completada para {audio_path}") + + return result + +def save_transcription(result, segment_info): + """Guarda la transcripción en un archivo de texto""" + segment_id = segment_info['segment_id'] + original_file_id = segment_info['original_file_id'] + segments_dir = segment_info['segments_dir'] + + # Crear directorio para transcripciones + transcriptions_dir = os.path.join(segments_dir, "transcriptions") + os.makedirs(transcriptions_dir, exist_ok=True) + + # Generar nombre para archivo de transcripción + transcription_filename = f"transcription_{segment_id:03d}_{original_file_id}.txt" + transcription_path = os.path.join(transcriptions_dir, transcription_filename) + + # Guardar texto en archivo + with open(transcription_path, 'w', encoding='utf-8') as f: + f.write(result['text']) + + logger.info(f"Procesador {PROCESSOR_ID}: Transcripción guardada en {transcription_path}") + + return transcription_path + +def send_to_unify_queue(channel, transcription_path, segment_info): + """Envía la transcripción a la cola de unificación""" + + # Preparar mensaje + message = { + **segment_info, + 'transcription_path': transcription_path, + 'processor_id': PROCESSOR_ID, + 'processed_timestamp': datetime.now().isoformat() + } + + # Publicar mensaje + channel.basic_publish( + exchange='', + routing_key=UNIFY_QUEUE, + body=json.dumps(message), + properties=pika.BasicProperties( + delivery_mode=2 # mensaje persistente + ) + ) + + logger.info(f"Procesador {PROCESSOR_ID}: Transcripción enviada a la cola de unificación") + +def callback(ch, method, properties, body): + """Callback para procesar mensajes de la cola de procesamiento""" + try: + # Decodificar mensaje + segment_info = json.loads(body) + segment_id = segment_info['segment_id'] + segment_path = segment_info['segment_path'] + original_file_id = segment_info['original_file_id'] + total_segments = segment_info['total_segments'] + + logger.info(f"Procesador {PROCESSOR_ID}: Recibido segmento {segment_id+1}/{total_segments} para {original_file_id}") + + # Transcribir audio + result = transcribe_audio(model, segment_path) + + # Guardar transcripción + transcription_path = save_transcription(result, segment_info) + + # Enviar a cola de unificación + send_to_unify_queue(ch, transcription_path, segment_info) + + # Confirmar procesamiento + ch.basic_ack(delivery_tag=method.delivery_tag) + + logger.info(f"Procesador {PROCESSOR_ID}: Transcripción completada para segmento {segment_id+1}/{total_segments}") + + except Exception as e: + logger.error(f"Procesador {PROCESSOR_ID}: Error procesando mensaje: {str(e)}") + # Rechazar mensaje en caso de error para reintentarlo + ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True) + +def main(): + """Función principal""" + global model + + # Cargar modelo Whisper + model = load_whisper_model() + + # Conexión a RabbitMQ + connection = connect_to_rabbitmq() + channel = connection.channel() + + # Declarar colas + channel.queue_declare(queue=PROCESS_QUEUE, durable=True) + channel.queue_declare(queue=UNIFY_QUEUE, durable=True) + + # Configurar prefetch count -> 1 mensaje a la vez + channel.basic_qos(prefetch_count=1) + + # Configurar callback + channel.basic_consume(queue=PROCESS_QUEUE, on_message_callback=callback) + + logger.info(f"Procesador {PROCESSOR_ID}: Servicio iniciado. Esperando segmentos...") + + # Iniciar consumo + try: + channel.start_consuming() + except KeyboardInterrupt: + logger.info(f"Procesador {PROCESSOR_ID}: Servicio detenido") + channel.stop_consuming() + + connection.close() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/whisper-distributed/receiver/Dockerfile b/whisper-distributed/receiver/Dockerfile new file mode 100644 index 0000000..54c0799 --- /dev/null +++ b/whisper-distributed/receiver/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.9-slim + +WORKDIR /app + +# Instalar dependencias +RUN pip install pika + +COPY app.py . + +CMD ["python", "app.py"] \ No newline at end of file diff --git a/whisper-distributed/receiver/app.py b/whisper-distributed/receiver/app.py new file mode 100644 index 0000000..fb7d080 --- /dev/null +++ b/whisper-distributed/receiver/app.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python +import os +import time +import pika +import json +import logging +from pathlib import Path +from datetime import datetime + +# Configuración de logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger('receiver') + +# Configuración de RabbitMQ +RABBITMQ_HOST = 'rabbitmq' +RABBITMQ_USER = 'user' +RABBITMQ_PASS = 'password' +SPLIT_QUEUE = 'audio_split_queue' + +# Directorios +INPUT_DIR = '/app/input' +SHARED_DIR = '/app/shared' + +def connect_to_rabbitmq(): + """Establece conexión con RabbitMQ""" + tries = 0 + while True: + try: + credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS) + connection = pika.BlockingConnection( + pika.ConnectionParameters( + host=RABBITMQ_HOST, + credentials=credentials + ) + ) + return connection + except pika.exceptions.AMQPConnectionError: + tries += 1 + logger.warning(f"Intento {tries}: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...") + time.sleep(5) + +def process_audio_file(filepath): + """Procesa un archivo de audio y lo envía a la cola de RabbitMQ""" + filename = os.path.basename(filepath) + file_id = f"{int(datetime.now().timestamp())}_{filename}" + + # Guardar una copia en el directorio compartido + shared_path = os.path.join(SHARED_DIR, file_id) + os.system(f"cp {filepath} {shared_path}") + + # Enviar mensaje a RabbitMQ para procesamiento + connection = connect_to_rabbitmq() + channel = connection.channel() + + # Declarar la cola + channel.queue_declare(queue=SPLIT_QUEUE, durable=True) + + # Preparar mensaje + message = { + 'file_id': file_id, + 'filename': filename, + 'filepath': shared_path, + 'timestamp': datetime.now().isoformat() + } + + # Publicar mensaje + channel.basic_publish( + exchange='', + routing_key=SPLIT_QUEUE, + body=json.dumps(message), + properties=pika.BasicProperties( + delivery_mode=2 # mensaje persistente + ) + ) + + logger.info(f"Archivo {filename} enviado a la cola {SPLIT_QUEUE} con ID {file_id}") + connection.close() + +def monitor_input_directory(): + """Monitorea el directorio de entrada para nuevos archivos de audio""" + # Asegurar que el directorio compartido existe + os.makedirs(SHARED_DIR, exist_ok=True) + + # Crear conjunto de archivos ya procesados + processed_files = set() + + logger.info(f"Iniciando monitoreo del directorio {INPUT_DIR}") + + while True: + # Buscar archivos de audio en el directorio de entrada + audio_extensions = ['.mp3', '.wav', '.flac', '.m4a', '.ogg'] + for ext in audio_extensions: + for audio_file in Path(INPUT_DIR).glob(f'*{ext}'): + filepath = str(audio_file) + if filepath not in processed_files: + logger.info(f"Nuevo archivo detectado: {filepath}") + process_audio_file(filepath) + processed_files.add(filepath) + + # Esperar antes de volver a comprobar + time.sleep(10) + +if __name__ == "__main__": + logger.info("Servicio receptor iniciado") + monitor_input_directory() \ No newline at end of file diff --git a/whisper-distributed/shared/1746709097_hoy_por_hoy.mp3 b/whisper-distributed/shared/1746709097_hoy_por_hoy.mp3 new file mode 100644 index 0000000..5c6d06d Binary files /dev/null and b/whisper-distributed/shared/1746709097_hoy_por_hoy.mp3 differ diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_000_1746709097_hoy_por_hoy.mp3.wav b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_000_1746709097_hoy_por_hoy.mp3.wav new file mode 100644 index 0000000..b10b4f1 Binary files /dev/null and b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_000_1746709097_hoy_por_hoy.mp3.wav differ diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_001_1746709097_hoy_por_hoy.mp3.wav b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_001_1746709097_hoy_por_hoy.mp3.wav new file mode 100644 index 0000000..508f467 Binary files /dev/null and b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_001_1746709097_hoy_por_hoy.mp3.wav differ diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_002_1746709097_hoy_por_hoy.mp3.wav b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_002_1746709097_hoy_por_hoy.mp3.wav new file mode 100644 index 0000000..4eba4a1 Binary files /dev/null and b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_002_1746709097_hoy_por_hoy.mp3.wav differ diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_003_1746709097_hoy_por_hoy.mp3.wav b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_003_1746709097_hoy_por_hoy.mp3.wav new file mode 100644 index 0000000..6c33147 Binary files /dev/null and b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_003_1746709097_hoy_por_hoy.mp3.wav differ diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_004_1746709097_hoy_por_hoy.mp3.wav b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_004_1746709097_hoy_por_hoy.mp3.wav new file mode 100644 index 0000000..780ad82 Binary files /dev/null and b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_004_1746709097_hoy_por_hoy.mp3.wav differ diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_005_1746709097_hoy_por_hoy.mp3.wav b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_005_1746709097_hoy_por_hoy.mp3.wav new file mode 100644 index 0000000..bf56ac8 Binary files /dev/null and b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_005_1746709097_hoy_por_hoy.mp3.wav differ diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_006_1746709097_hoy_por_hoy.mp3.wav b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_006_1746709097_hoy_por_hoy.mp3.wav new file mode 100644 index 0000000..1d3de1b Binary files /dev/null and b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_006_1746709097_hoy_por_hoy.mp3.wav differ diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_007_1746709097_hoy_por_hoy.mp3.wav b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_007_1746709097_hoy_por_hoy.mp3.wav new file mode 100644 index 0000000..eadc4ef Binary files /dev/null and b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/segment_007_1746709097_hoy_por_hoy.mp3.wav differ diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_000_1746709097_hoy_por_hoy.mp3.txt b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_000_1746709097_hoy_por_hoy.mp3.txt new file mode 100644 index 0000000..50700ae --- /dev/null +++ b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_000_1746709097_hoy_por_hoy.mp3.txt @@ -0,0 +1 @@ + Ser Podcast La socho de hoy por hoy en Ser Podcast Hola muy buenos días, lo que pasó ayer en Alemania no solo explica la situación allí en la primera potencia europea, sino que explica de alguna manera cómo están los tiempos y cómo se extiende la inestabilidad y la incertidumbres, si uno de los países con la política más previsible de las últimas décadas vive con sorpresa y hasta contraiciones la elección de su canciller tras el acuerdo entre conservadores y social democratas. Por si faltaran cosas, esta madrugada hemos asistido a la escala de militar entre India y Pakistan, que son dos potencias nucleares y que añaden incertidumbre a un mundo removido por un donaltram que ahora busca acercar posturas con China. Esta es otra de las novedades con las que amanecemos hoy, una delegación de Washington y otra de Pequín, prevén reunirse a finales de esta misma semana para hablar de los araceles será la primera vez que se vean desde que Trump empezó la guerra comercial y se va a ver en Suiza. Sastre, buenos días. Buenos días, Barceló. Bueno, con este contexto internacional de fondo y con el rear me envoca de todos los gobiernos, esta mañana comparece a quien España, Pedro Sanchez, para hablar de un insólito a Pagón cuyas causas aún desconocemos. También para explicar cómo puede subir el gastón de fence al 2% aunque no tenga presupuestos generales. De hecho, en este momento el gobierno no tiene una mayoría que garantice para empezar, lo último que aprobó ayer mismo el Consejo de Ministros, la reducción de la jornada laboral contra la que Xi'unz ha presentado una enmienda a la totalidad. Pues ya decíamos que la incertidumbre explica buena parte de lo que ocurre y esa es la palabra que define precisamente lo que desde hoy va a pasar en Roma. Hoy por hoy noticias. Ser podcast. El conclave. Que empieza esta tarde a las 4 y media, con tantos nombres en las quinielas que sea hay algo en lo que coincide en los pronósticos es que toda punta a que vamos a un conclave que no se va a resolver el primer día, seguramente tampoco el segundo, aunque en verdad nadie sabe si todo está rodeado no solo de una gran... \ No newline at end of file diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_001_1746709097_hoy_por_hoy.mp3.txt b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_001_1746709097_hoy_por_hoy.mp3.txt new file mode 100644 index 0000000..72cf7be --- /dev/null +++ b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_001_1746709097_hoy_por_hoy.mp3.txt @@ -0,0 +1 @@ + en la liturgia, sino de un silencio que se alarga. Vamos a Roma con responsabil John Soles. Al término de la última congregación en la que intervenieron otros 26 cardenales sobre las prioridades de la iglesia católica en el mundo, no se había definido el perfil del próximo pontífice que deberá ser elegido a partir de esta tarde y según se desprende de comentarios de algunos purporados. Francisco era Francisco, no habrá otro Francisco, ha invertido el cardenal francés Vesco. Él abrió las puertas y yo deseo añadido que estas puertas sigan abiertas con el nuevo papa y que siga la línea trazada. La 17a mañana empezará la misa proeligiendo romano pontífice tras el almuerzo los electores podrán descansar, pero a primera hora de la tarde se han trasladado en microbuses de la residencia de Santa Marta al otro extremo del ápcide de la basilica de San Pedro. Se dirigirán a la capilla paulina y en procesión a la 16a juraran mantener el secreto de las deliberaciones y a continuación el maestro de ceremonias papales pronunciará al tradicional extra-omnes, es decir, todos fuera salvo los electores. La primera fuma tallegara, previsiblemente, entre las 6 y las 7 de la tarde. Los focos de la actualidad internacional empezan a apuntar a Roma esta tarde para cuando veamos entrar a los cardenales uno en uno en la capilla 16. De momento, los grandes asuntos en la crónica del mundo son dos, como les decía al empezar, por un lado, la reunión que tendrá en China y Estados Unidos a finales de semana con la esperanza de que puedan aliviar la guerra que ha agitado el mundo, la guerra de los aranceles. Y el otro gran asunto es ese ataque de India contra varias tonas de Pakistan en una serie de bombardeos que nueva Delhi ha justificado como represalias después de los atentados de abril en la cachemira India. Estados Unidos ha dicho ya que está pendiente de lo que pase entre estos dos países, las dos, los dos son potencias nucleares y cuyo enfrentamiento vayan bienete de lejos. Hace más de siete décadas que India y Pakistan se disputan ese territorio fronterizo de cachemira, uno de los puntos calientes de... \ No newline at end of file diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_002_1746709097_hoy_por_hoy.mp3.txt b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_002_1746709097_hoy_por_hoy.mp3.txt new file mode 100644 index 0000000..5a7e8d1 --- /dev/null +++ b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_002_1746709097_hoy_por_hoy.mp3.txt @@ -0,0 +1 @@ + y donde ambas potencias han librado ya cuatro guerras desde 1947. Así sonaba noche, el intercambio de disparos en la denominada línea de control, escaramuzas fronterizas que siguieron al ataque con misiles por parte de India, contra varios objetivos en territorio paquistánín. El gobierno de Islamabad habla de un ataque injustificado por parte de India que deja al menos 26 civiles muertos en ese país. En paquistán, otras 10 personas han fallecido esta noche en el lado indio de la frontera, mientras se suceden los llamamientos a la contención para evitar una escalada bélica. En esta habilidad, y escalada militar en Asia, en esta habilidad política en el país, cuya política se prefiaba de su estabilidad desde el final de la Segunda Guerra Mundial, que es Alemania, corresponde a Lemberlín Carmen Vinyas, buenos días. Hola, buenos días, señor. Todo el mundo Carmen se hace allí esta mañana la misma pregunta, quién trató de boicotear la elección de Merst como Canciller, en una votación secreta que sumió al país en la incertidumbre durante unas horas, hasta que se precipitó una nueva votación y pudo salir elegido, pero salió elegido y a Carmen exhibiendo su debilidad. Pues sí, sigue siendo un incógnita porque todo era secreto, aunque motivos para la disidencia no faltaban. El caos que conservadores y social democratas han provocado en el Bundestak, ha supuesto un duro golpe. Es un revés sobre todo para los líderes de ambos grupos que no han podido convencer a los suyos de la necesidad de un gobierno conjunto. Muchos conservadores están molestos por la relajación del Freno a la deuda y muchos social democratas se sienten frustrados por el endurecimiento de la política migratoria. También hay malestar por elección del gabinete a las derechas de la acusa de buscar perfiles muy empresariales y los social democratas de arriesgar con juventud y inexperiencia. A sus señorías, Ángeles hizo falta recordarles que Alemania necesita esta habilidad en tiempos de guerra con Ucrania, de frágil relación con Estados Unidos y de fortaleza de la estrema derecha. Quizá una mirada a la bismo sirvió para elegir finalmente a Merch. Seguimos en el abierto. Hasta luego. Hay una imagen internacional más, todavía señal también de los tiempos de los que estamos. El encuentro en el despacho Val de la... \ No newline at end of file diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_003_1746709097_hoy_por_hoy.mp3.txt b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_003_1746709097_hoy_por_hoy.mp3.txt new file mode 100644 index 0000000..67a9c7a --- /dev/null +++ b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_003_1746709097_hoy_por_hoy.mp3.txt @@ -0,0 +1 @@ + Casa Blanca entre Donald Trump y luego primer ministro de Canadá, Marcarnei, que dijo a Trump, Canadá no está en venta. Y esta es la respuesta que le dio ayer la Casa Blanca Donald Trump. Pero nunca he dicho, nunca he dicho, nunca. Nunca digas nunca. Aquí en España también va a ser noticia hoy el Parlamento, porque hoy es el pleno del Congreso, en el que va a comparecer Pedro Sánchez para hablar del aumento del gasto en defensa, aunque en realidad va a hablar también de la pagón Guillermo Lermabu nos días. ¿Qué tal, Buenos días, Angelo? Y el pleno servirá de nuevo cómo termómetro de la legislatura. Sí, una legislatura que el gobierno da por hecho, que va a estar marcada por ese debate sobre la defensa y la seguridad, algo que en el ejecutivo dicen conecta precisamente con la necesidad de reforzar las capacidades de España para prever esos imprevistos como el apagón. En el gobierno, dan por hecho, que la pregunta que más se va a repetir o bien el pleno es esa que ocurrió, lo que está en el origen de eso apagón, que dejó a España sin electricidad del pasado lunes. No hay ninguna certeza sobre el origen de ese cero eléctrico, Sánchez acude al pleno, sin poder aportar respuestas claras. Así que el jefe del ejecutivo va a defender que todas las posibilidades están abiertas. No hay ninguna certeza sobre el origen, así que en el ejecutivo, creo que sería una responsabilidad a apuntar a cualquier posibilidad, sin haber analizado todos los datos técnicos. Sánchez va a insistir en no descartar ninguna opción. Ayer el pleno del Senado vivió una peritivo de lo que va a ser la sesión de hoy, desde esa comparecencia Sara Gensen, pedía rigor y responsable. Lo peor que podríamos hacer por la ciudadanía, por la seguridad del suministro de este país, es empezar a hacer hipótesis de lo más variopinto sin ninguna certeza. Por favor, rigor para la ciudadanía, rigor en la aportación de soluciones. El presidente intentará sobre todo desmontar la imagen de colapso y caos que intenta fijar... \ No newline at end of file diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_004_1746709097_hoy_por_hoy.mp3.txt b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_004_1746709097_hoy_por_hoy.mp3.txt new file mode 100644 index 0000000..c4653c3 --- /dev/null +++ b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_004_1746709097_hoy_por_hoy.mp3.txt @@ -0,0 +1 @@ + la derecha, una realidad paralela dicen en la mongla. Y, gracias. Hasta luego. Fejo por su parte su maral apagó en el robo del domingo en los cables de alta velocidad para denunciar eso una situación de caos en el país de habito en que era buenos días. Hola, Angel Sanctismo, en fase de paranoia. Es el resumen que hacen en Genova de los que ellos califican como los dos lunes negros. En la herida de la paón, en la herida del caos ferroviario quiere urgar hoy fejó que hacear al presidente que siempre culpa a terceros sin pruebas. Mucho ciber ataque, muchos a botaje, pero pocas explicaciones y pocas disculpas. Tampoco vea el tema de gasto en defensa, remarcando que poco podemos aportar como país para solucionar la inestabilidad que se acude a Europa cuando nuestro gobierno no es capaz de garantizar el suministro eléctrico las comunicaciones o las redes de transporte en España. Es lo que quiere dejar patente el líder de un PP desde el que ironizan. Para hacer tan valer, se abruselas, Putin tiene que empeñarse a fondo, pero para poner a España en hacke, basta con una socialista como Beatriz Corredor al frente de Recelectrica. Hoy por hoy, noticias. Ser podcast. El juez peinado ha imputado al actual delegado del gobierno en Madrid por el caso begóña Gómez. El juez admite en parte la crey de box, por tanto imputa el delito de malversación, al delegado guberramental en Madrid, Francisco Martín, por la contratación de Cristina Álvarez. El juez, que se mantuvo con Martín, continuó en el cargo ahora con Judí González en la Secretaría General General. El juez sortía a González en el caso de la Secretaría General General General, y se mantuvo con Martín, al que atribuye el juez esta supuesta en malversación. ¿Qué tal, Álvarez? ¿Cuáles son? La razón es de peinado. Pues dice el juez que Francisco Martín era el responsable y superior gerar quico de Cristina Álvarez, la sesora de Begoña Gómez, que se nombró con Feliz Bolaños como Secretario General de Presidencia, que se mantuvo con Martín, y que continúan el cargo ahora con Judí González y al Ministro Bolaños, que está aforado ante el Supremo y se queda con el delegado del Gobierno, al que atribuye la malversación, porque sostiene que se pagó a… \ No newline at end of file diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_005_1746709097_hoy_por_hoy.mp3.txt b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_005_1746709097_hoy_por_hoy.mp3.txt new file mode 100644 index 0000000..523a06f --- /dev/null +++ b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_005_1746709097_hoy_por_hoy.mp3.txt @@ -0,0 +1 @@ + Cristina Álvarez con fondos públicos para ayudar en las actividades privadas de Begoña Gómez. Juan Carlos Peinado vuelve a dar un nuevo giro de timón esta vez en la última línea de investigación que abrió para mantener viva la causa, pone el foco en Francisco Martín y ahora decide exculpar a la asesora porque dice que se limitó a hacer su trabajo y a cobrar por ello, por lo tanto no cometió delito y también a la mujer de Pedro Sánchez, porque dice que se limitó a contar con esos servicios profesionales aunque fuera para fines personales. Gracias, Pedro. Hasta luego. Así es como se refiere a esta instrucción judicial de Peinado, el ministro de Justicia Félix volaños. Esta instrucción ya no es motivo de preocupación para la gente honesta y con la conciencia tranquila que se está viendo afectada. Es motivo de preocupación máxima para todos los que defendemos el buen nombre y la impartialidad de los jueces imaginados de nuestro país. Y en Valencia mientras sigue la investigación de la bana que está llevando a cabo la jueza de Catarrotjante, la que ayer declaró uno de los técnicos que envió la alerta a los teléfonos móviles el día de la catástrofe. A la alerta que llegó, como saben, cuando la mayoría de las víctimas ya habían muerto, este técnico explicó que las concelleras salomepradas les ordenó que no envías en el mensaje hasta que ella lo hubiera visto a Natalense Von Diem. Bon día, el técnico declaró un calidad de testigo con la obligación de decir la verdad y contestar a todas las partes. A firmó que la ex-consellera Pradas le dijo que no envía a nada hasta que ella diera el visto bueno. Indicó que hubo un primer borrador de mensajes sobre la situación del barranco de Forata que se descartó y que se decidió redactar otro para toda la provincia. El técnico añade que pasó una hora desde que se decidió enviar el mensaje hasta que efectivamente se remitió a las ocho y once minutos de la tarde. Aunque considera que no debía haberse tardado más de 20 minutos. Por su parte fuentes pero próximas a la ex-consellera Pradas han negado a la ser cualquier retraso en el visto bueno el envío el mensaje y se remiten a la literalidad de su declaración no a la transcripción que se filtró a los medios. Dicen que en esa declaración quedó claro que el visto bueno en mensaje que introdujen los técnicos en el sistema informático fue inmediato y tenía que ver con la situación de Forata. \ No newline at end of file diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_006_1746709097_hoy_por_hoy.mp3.txt b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_006_1746709097_hoy_por_hoy.mp3.txt new file mode 100644 index 0000000..1579bb5 --- /dev/null +++ b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_006_1746709097_hoy_por_hoy.mp3.txt @@ -0,0 +1 @@ + Esas fuentes aseguran también que efectivamente se tardó una hora entre la propuesta del subdirector para el borrador del mensaje hasta que se envió, pero añada en que el técnico no dijo en ningún momento que ese tiempo fuera, porque Pradas le dijera que esperase a que ella lidera el visto bueno. Y además, el poder judicial va a seguir investigando los jueces el hoy Velasco y Carros del Valle, persa que quien lleva su expediente había propuesto que se archivara. Se trata del juez que interrogó a un humorista actor de Miguel y también del juez que cuestionó la legitimidad del gobierno y que llegó a decir que no iba a ser Irene Montero desde la caja del Mercadona, dijo, la que les iba a explicar a ellos a los magistrados que es el consentimiento. Más de cuatro millones de personas ya han cobrado la devolución de la renta, acaba de cumplirse un mes del inicio de la campaña y haciendo informa de que ha recibido menos declaraciones. O bastante menos, en concreto se han presentado en total siete millones, lo que supone casi un cinco por ciento menos que es el mismo periodo de 2024. La agencia tributaria recuerda que el plazo para presentar la declaración termina el 30 de junio, Jordi Fabregam. Después del furor inicial este año y menos prisa por presentar la declaración de la renta. En el primer mes de campaña, la agencia tributaria ha recibido siete millones y cientos mil declaraciones. Es un 4,7 por ciento menos que el año pasado. Es verdad que esta vez, dentro del periodo en el que se ha podido presentar la declaración entra la semana santa y eso ha condicionado las cifras. En el 16 de diciembre, la agencia tributaria ha puesto en marcha el plan de ayuda telefónica para elaborar la declaración. Un equipo del Centro Nacional de Investigaciones Oncológicas ha identificado el interruptor clave en el desarrollo del cáncer de colon. El estudio lo publica la revista net huri muestra que cuando falta una proteína, se puede poner en marcha el desarrollo del tumor. Es decir, que con la dieta con lo que comemos, se puede evitar que se actenmarina farmández. En bruto este descubrim... \ No newline at end of file diff --git a/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_007_1746709097_hoy_por_hoy.mp3.txt b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_007_1746709097_hoy_por_hoy.mp3.txt new file mode 100644 index 0000000..f73fc7e --- /dev/null +++ b/whisper-distributed/shared/segments_1746709097_hoy_por_hoy.mp3/transcriptions/transcription_007_1746709097_hoy_por_hoy.mp3.txt @@ -0,0 +1 @@ + que publican eiturpodes sonarnos poco asequible. Hemos demostrado que degradar la proteína P53 es un evento necesario para la iniciación del proceso tumoral. Pero la investigadora Irene Erranzo, una de las autoras lo traduce para que entendamos su potencial. Efectivamente evitar la degradación de P53 evitaría el desarrollo de tumores en pacientes humanos. Lo han comprobado en modelos animales y también en muestras humanas y su hallazgo va más allá. Describimos que otra proteína, llamada URI, favorece la degradación de P53. Sabemos que la dieta puede influir en los niveles de URI y con ello influir en los niveles de P53. Y de esta manera, promover o prevenir el desarrollo de los tumores. El cáncer color dectales es más frecuente en España, en la población general, con más de 40.000 nuevos diagnósticos al año. Y los mirlos nuevos médicos quieren ser dermatólogos y no médicos de familia y eso andan la carencia que ya sufren los centros de salud en buena parte del país, Mario Lleuridón. 15.000 mil a por una de las 9.000 plazas estos días se eligen su futuro. ¿Y oftándolo, Xi'a? Yo, cardiología. Gené, golgón. Ecogi de neurociología. Hay una especialidad estrella, las plazas se agotaron en tiempo record. Yo he elegido dermatología. Es una especialidad que tiene muy buenas salidas, laborales actualmente. También están ajudicadas ya en cirugía plástica, ambasón el top. Yo creo que hermar montas tu consulta privada con muy poca inversión y ves muchos pacientes. Curros de Córdoba le toca elegir hoy. Yo, por más y lo facial, tiene muy buena calidad de vida y tiene muy buena privada, la verdad. La Cenecienta es medicina familiar de las 2.500 plazas ofertadas, solo 22 han elegido de momento la atención primaria. No, no está tan bien reconocida, igual. También tiene mucho trabajo burocrático, que igual a la gente después de medicina no es lo que más la petece. Hay una pena que hayan bien que las cosas mejoraron para los médicos de familia. Desde hace tres años hay vacantes, si no se cubren todas las plazas en un servicio muy debilitado y con falta de personal. Y en diez minutos se la abiertó. Cone de guarda Madina, a victor la puente y elisa de la 9. ¿Para no perder ningún episodio? Sigue no ser la aplicación o la web de la ser, podí un podcast o tu plataforma de audio favorita. \ No newline at end of file diff --git a/whisper-distributed/splitter/Dockerfile b/whisper-distributed/splitter/Dockerfile new file mode 100644 index 0000000..9565ba9 --- /dev/null +++ b/whisper-distributed/splitter/Dockerfile @@ -0,0 +1,11 @@ +FROM python:3.9-slim + +WORKDIR /app + +# Instalar dependencias +RUN apt-get update && apt-get install -y ffmpeg +RUN pip install pika pydub + +COPY app.py . + +CMD ["python", "app.py"] \ No newline at end of file diff --git a/whisper-distributed/splitter/app.py b/whisper-distributed/splitter/app.py new file mode 100644 index 0000000..09f352c --- /dev/null +++ b/whisper-distributed/splitter/app.py @@ -0,0 +1,187 @@ +#!/usr/bin/env python +import os +import time +import json +import pika +import logging +from pydub import AudioSegment +from datetime import datetime + +# Configuración de logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger('splitter') + +# Configuración de RabbitMQ +RABBITMQ_HOST = 'rabbitmq' +RABBITMQ_USER = 'user' +RABBITMQ_PASS = 'password' +SPLIT_QUEUE = 'audio_split_queue' +PROCESS_QUEUE = 'audio_process_queue' + +# Configuración de segmentos +SEGMENT_DURATION_MS = 2 * 60 * 1000 # 1 minuto en milisegundos + +# Directorios +SHARED_DIR = '/app/shared' + +def connect_to_rabbitmq(): + """Establece conexión con RabbitMQ""" + tries = 0 + while True: + try: + credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS) + connection = pika.BlockingConnection( + pika.ConnectionParameters( + host=RABBITMQ_HOST, + credentials=credentials + ) + ) + return connection + except pika.exceptions.AMQPConnectionError: + tries += 1 + logger.warning(f"Intento {tries}: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...") + time.sleep(5) + +def split_audio(filepath, file_id, original_filename): + """Divide un archivo de audio en segmentos de 5 minutos""" + logger.info(f"Dividiendo archivo: {filepath}") + + # Cargar audio con pydub + audio = AudioSegment.from_file(filepath) + + # Calcular número de segmentos + total_duration_ms = len(audio) + num_segments = (total_duration_ms + SEGMENT_DURATION_MS - 1) // SEGMENT_DURATION_MS + + logger.info(f"Audio de duración {total_duration_ms}ms será dividido en {num_segments} segmentos") + + # Crear directorio para segmentos + segments_dir = os.path.join(SHARED_DIR, f"segments_{file_id}") + os.makedirs(segments_dir, exist_ok=True) + + # Dividir en segmentos + segments_info = [] + + for i in range(num_segments): + start_ms = i * SEGMENT_DURATION_MS + end_ms = min(start_ms + SEGMENT_DURATION_MS, total_duration_ms) + + # Extraer segmento + segment = audio[start_ms:end_ms] + + # Generar nombre de archivo para segmento + segment_filename = f"segment_{i:03d}_{file_id}.wav" + segment_path = os.path.join(segments_dir, segment_filename) + + # Guardar segmento como WAV para Whisper + segment.export(segment_path, format="wav") + + segments_info.append({ + 'segment_id': i, + 'segment_path': segment_path, + 'segment_filename': segment_filename, + 'start_ms': start_ms, + 'end_ms': end_ms, + 'duration_ms': end_ms - start_ms + }) + + logger.info(f"Creado segmento {i+1}/{num_segments}: {segment_filename}") + + return segments_info, segments_dir + +def send_segments_to_process_queue(segments_info, original_file_id, original_filename, segments_dir): + """Envía los segmentos a la cola para procesamiento con Whisper""" + connection = connect_to_rabbitmq() + channel = connection.channel() + + # Declarar cola para procesamiento + channel.queue_declare(queue=PROCESS_QUEUE, durable=True) + + # Información del trabajo completo + job_info = { + 'original_file_id': original_file_id, + 'original_filename': original_filename, + 'total_segments': len(segments_info), + 'segments_dir': segments_dir, + 'timestamp': datetime.now().isoformat() + } + + # Enviar cada segmento a la cola + for segment in segments_info: + # Mensaje con información del segmento y trabajo + message = { + **segment, + **job_info + } + + channel.basic_publish( + exchange='', + routing_key=PROCESS_QUEUE, + body=json.dumps(message), + properties=pika.BasicProperties( + delivery_mode=2 # mensaje persistente + ) + ) + + logger.info(f"Segmento {segment['segment_id']+1}/{job_info['total_segments']} enviado a la cola de procesamiento") + + connection.close() + +def callback(ch, method, properties, body): + """Callback para procesar mensajes de la cola de división""" + try: + # Decodificar mensaje + message = json.loads(body) + file_id = message['file_id'] + filepath = message['filepath'] + filename = message['filename'] + + logger.info(f"Recibido archivo para división: {filename} ({file_id})") + + # Dividir audio en segmentos + segments_info, segments_dir = split_audio(filepath, file_id, filename) + + # Enviar segmentos a la cola de procesamiento + send_segments_to_process_queue(segments_info, file_id, filename, segments_dir) + + # Confirmar procesamiento + ch.basic_ack(delivery_tag=method.delivery_tag) + + logger.info(f"División completada para {filename} ({file_id})") + + except Exception as e: + logger.error(f"Error procesando mensaje: {str(e)}") + # Rechazar mensaje en caso de error para reintentarlo + ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True) + +def main(): + """Función principal""" + connection = connect_to_rabbitmq() + channel = connection.channel() + + # Declarar colas + channel.queue_declare(queue=SPLIT_QUEUE, durable=True) + channel.queue_declare(queue=PROCESS_QUEUE, durable=True) + + # Configurar prefetch count + channel.basic_qos(prefetch_count=1) + + # Configurar callback + channel.basic_consume(queue=SPLIT_QUEUE, on_message_callback=callback) + + logger.info("Servicio de división iniciado. Esperando mensajes...") + + # Iniciar consumo + try: + channel.start_consuming() + except KeyboardInterrupt: + logger.info("Servicio de división detenido") + channel.stop_consuming() + + connection.close() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/whisper-distributed/unifier/Dockerfile b/whisper-distributed/unifier/Dockerfile new file mode 100644 index 0000000..54c0799 --- /dev/null +++ b/whisper-distributed/unifier/Dockerfile @@ -0,0 +1,10 @@ +FROM python:3.9-slim + +WORKDIR /app + +# Instalar dependencias +RUN pip install pika + +COPY app.py . + +CMD ["python", "app.py"] \ No newline at end of file diff --git a/whisper-distributed/unifier/app.py b/whisper-distributed/unifier/app.py new file mode 100644 index 0000000..6e0a957 --- /dev/null +++ b/whisper-distributed/unifier/app.py @@ -0,0 +1,176 @@ +#!/usr/bin/env python +import os +import time +import json +import pika +import logging +from collections import defaultdict +from datetime import datetime + +# Configuración de logging +logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' +) +logger = logging.getLogger('unifier') + +# Configuración de RabbitMQ +RABBITMQ_HOST = 'rabbitmq' +RABBITMQ_USER = 'user' +RABBITMQ_PASS = 'password' +UNIFY_QUEUE = 'text_unify_queue' + +# Directorios +SHARED_DIR = '/app/shared' +OUTPUT_DIR = '/app/output' + +# Almacenamiento temporal de transcripciones por trabajo +pending_transcriptions = defaultdict(dict) +job_metadata = {} + +def connect_to_rabbitmq(): + """Establece conexión con RabbitMQ""" + tries = 0 + while True: + try: + credentials = pika.PlainCredentials(RABBITMQ_USER, RABBITMQ_PASS) + connection = pika.BlockingConnection( + pika.ConnectionParameters( + host=RABBITMQ_HOST, + credentials=credentials + ) + ) + return connection + except pika.exceptions.AMQPConnectionError: + tries += 1 + logger.warning(f"Intento {tries}: No se pudo conectar a RabbitMQ. Reintentando en 5 segundos...") + time.sleep(5) + +def process_transcription(segment_info): + """Procesa una transcripción recibida""" + original_file_id = segment_info['original_file_id'] + segment_id = segment_info['segment_id'] + transcription_path = segment_info['transcription_path'] + total_segments = segment_info['total_segments'] + + # Almacenar metadatos del trabajo si no existen + if original_file_id not in job_metadata: + job_metadata[original_file_id] = { + 'original_filename': segment_info['original_filename'], + 'total_segments': total_segments, + 'start_time': datetime.now() + } + + # Leer transcripción + with open(transcription_path, 'r', encoding='utf-8') as f: + text = f.read() + + # Almacenar transcripción + pending_transcriptions[original_file_id][segment_id] = { + 'text': text, + 'start_ms': segment_info['start_ms'], + 'end_ms': segment_info['end_ms'] + } + + logger.info(f"Recibida transcripción {segment_id+1}/{total_segments} para {original_file_id}") + + # Verificar si se han recibido todas las transcripciones para este trabajo + if len(pending_transcriptions[original_file_id]) == total_segments: + unify_transcriptions(original_file_id) + +def convert_milliseconds_to_srt_time(ms): + """Convierte milisegundos a formato de tiempo SRT (HH:MM:SS,mmm)""" + seconds, milliseconds = divmod(ms, 1000) + minutes, seconds = divmod(seconds, 60) + hours, minutes = divmod(minutes, 60) + return f"{hours:02d}:{minutes:02d}:{seconds:02d},{milliseconds:03d}" + +def unify_transcriptions(original_file_id): + """Unifica las transcripciones de un trabajo y genera el archivo de subtítulos""" + logger.info(f"Unificando transcripciones para {original_file_id}") + + # Obtener metadatos del trabajo + metadata = job_metadata[original_file_id] + original_filename = metadata['original_filename'] + + # Preparar nombre de archivo de salida + base_filename = os.path.splitext(original_filename)[0] + output_filename = f"{base_filename}_transcription.srt" + output_path = os.path.join(OUTPUT_DIR, output_filename) + + # Ordenar transcripciones por segment_id + sorted_segments = sorted(pending_transcriptions[original_file_id].items(), key=lambda x: x[0]) + + # Crear directorio de salida si no existe + os.makedirs(OUTPUT_DIR, exist_ok=True) + + # Generar archivo SRT (formato de subtítulos) + with open(output_path, 'w', encoding='utf-8') as f: + for i, (segment_id, segment_data) in enumerate(sorted_segments): + # Formatear tiempo de inicio y fin + start_time = convert_milliseconds_to_srt_time(segment_data['start_ms']) + end_time = convert_milliseconds_to_srt_time(segment_data['end_ms']) + + # Escribir entrada de subtítulo + f.write(f"{i+1}\n") + f.write(f"{start_time} --> {end_time}\n") + f.write(f"{segment_data['text'].strip()}\n\n") + + # Calcular tiempo total de procesamiento + total_time = datetime.now() - metadata['start_time'] + + logger.info(f"Archivo de subtítulos generado: {output_path}") + logger.info(f"Tiempo total de procesamiento: {total_time}") + + # Limpiar datos del trabajo completado + del pending_transcriptions[original_file_id] + del job_metadata[original_file_id] + +def callback(ch, method, properties, body): + """Callback para procesar mensajes de la cola de unificación""" + try: + # Decodificar mensaje + segment_info = json.loads(body) + + # Procesar transcripción + process_transcription(segment_info) + + # Confirmar procesamiento + ch.basic_ack(delivery_tag=method.delivery_tag) + + except Exception as e: + logger.error(f"Error procesando mensaje: {str(e)}") + # Rechazar mensaje en caso de error para reintentarlo + ch.basic_nack(delivery_tag=method.delivery_tag, requeue=True) + +def main(): + """Función principal""" + # Asegurar que directorios existen + os.makedirs(OUTPUT_DIR, exist_ok=True) + + # Conexión a RabbitMQ + connection = connect_to_rabbitmq() + channel = connection.channel() + + # Declarar cola + channel.queue_declare(queue=UNIFY_QUEUE, durable=True) + + # Configurar prefetch count + channel.basic_qos(prefetch_count=1) + + # Configurar callback + channel.basic_consume(queue=UNIFY_QUEUE, on_message_callback=callback) + + logger.info("Servicio unificador iniciado. Esperando transcripciones...") + + # Iniciar consumo + try: + channel.start_consuming() + except KeyboardInterrupt: + logger.info("Servicio unificador detenido") + channel.stop_consuming() + + connection.close() + +if __name__ == "__main__": + main() \ No newline at end of file