Commit 4a689e82 authored by matteospanio's avatar matteospanio
Browse files

update

parent 00acb567
PROXY_PORT=8888 PROXY_PORT=8888
DATA_VOLUME=./data DATA_VOLUME=./data
LOGS_VOLUME=./logs LOGS_VOLUME=./logs
AUDIO_ANALYSER_PORT=50051 AUDIO_ANALYSER_PORT=50051
VIDEO_ANALYSER_PORT=50052 VIDEO_ANALYSER_PORT=50052
TAPE_IRREGULARITY_PORT=50053 TAPE_IRREGULARITY_PORT=50053
TAPE_AUDIO_RESTORATION_PORT=50054 TAPE_AUDIO_RESTORATION_PORT=50054
PACKAGER_PORT=50055 PACKAGER_PORT=50055
\ No newline at end of file
/data /data
/logs /logs
/opencv_source /opencv_source
/eq_detection /eq_detection
\ No newline at end of file **/__pycache__
\ No newline at end of file
[submodule "packager"] [submodule "packager"]
path = packager path = packager
url = https://gitlab.dei.unipd.it/mpai/packager.git url = https://gitlab.dei.unipd.it/mpai/packager.git
[submodule "tape-audio-restoration"] [submodule "tape-audio-restoration"]
path = tape-audio-restoration path = tape-audio-restoration
url = https://gitlab.dei.unipd.it/mpai/tape-audio-restoration.git url = https://gitlab.dei.unipd.it/mpai/tape-audio-restoration.git
[submodule "tape-irregularity-classifier"] [submodule "tape-irregularity-classifier"]
path = tape-irregularity-classifier path = tape-irregularity-classifier
url = https://gitlab.dei.unipd.it/mpai/tape-irregularity-classifier.git url = https://gitlab.dei.unipd.it/mpai/tape-irregularity-classifier.git
[submodule "video-analyzer"] [submodule "video-analyzer"]
path = video-analyzer path = video-analyzer
url = https://gitlab.dei.unipd.it/mpai/video-analyzer.git url = https://gitlab.dei.unipd.it/mpai/video-analyzer.git
[submodule "audio-analyzer"] [submodule "audio-analyzer"]
path = audio-analyzer path = audio-analyzer
url = https://gitlab.dei.unipd.it/mpai/audio-analyzer.git url = https://gitlab.dei.unipd.it/mpai/audio-analyzer.git
# MPAI-CAE ARP Workflow # MPAI-CAE ARP Workflow
[![MPAI-CAE ARP](https://img.shields.io/badge/MPAI%20CAE--ARP-gray?style=for-the-badge&logo=AppleMusic&logoColor=cyan&link=https://mpai.community/standards/mpai-cae/about-mpai-cae/)](https://mpai.community/standards/mpai-cae/about-mpai-cae/) [![MPAI-CAE ARP](https://img.shields.io/badge/MPAI%20CAE--ARP-gray?style=for-the-badge&logo=AppleMusic&logoColor=cyan&link=https://mpai.community/standards/mpai-cae/about-mpai-cae/)](https://mpai.community/standards/mpai-cae/about-mpai-cae/)
This is the repository containing the MPAI-CAE ARP workflow implementation. The workflow is composed of the following steps: This is the repository containing the MPAI-CAE ARP workflow implementation. The workflow is composed of the following steps:
1. Audio and video analysis; 1. Audio and video analysis;
2. Video irregularity classification; 2. Video irregularity classification;
3. Tape audio restoration; 3. Tape audio restoration;
4. Packaging. 4. Packaging.
The workflow is implemented as a set of docker containers, each one performing a specific task. The containers are orchestrated by docker-compose. Once the composition is started, the containers will communicate with each other through a shared volume, which will be used to store the intermediate results of the workflow. The starting point of the workflow is a client application, which will specify the input path. The client and the workflow containers communicate via gRPC. The workflow is implemented as a set of docker containers, each one performing a specific task. The containers are orchestrated by docker-compose. Once the composition is started, the containers will communicate with each other through a shared volume, which will be used to store the intermediate results of the workflow. The starting point of the workflow is a client application, which will specify the input path. The client and the workflow containers communicate via gRPC.
## Requirements ## Requirements
The following software is required to run the workflow: The following software is required to run the workflow:
* Docker; * Docker;
* Docker-compose; * Docker-compose;
* Python 3.10 or higher. * Python 3.10 or higher.
* poetry * poetry
* git * git
## Installation ## Installation
To install the workflow, clone the repository with (you may need to install git first, and request access to the repository): To install the workflow, clone the repository with (you may need to install git first, and request access to the repository):
```bash ```bash
git clone https://gitlab.dei.unipd.it/mpai/workflow.git git clone https://gitlab.dei.unipd.it/mpai/workflow.git
cd workflow cd workflow
``` ```
Then, since the workflow has been developed in many repositories (one for each step), you need to clone the submodules with: Then, since the workflow has been developed in many repositories (one for each step), you need to clone the submodules with:
```bash ```bash
git submodule update --init --recursive git submodule update --init --recursive
``` ```
Once the repository is cloned, you need to build the docker images. To do so start docker and run: Once the repository is cloned, you need to build the docker images. To do so start docker and run:
```bash ```bash
docker compose up -d docker compose up -d
``` ```
On the first run, docker will download the base images and build the custom ones. This may take a while. On the first run, docker will download the base images and build the custom ones. This may take a while.
If everithing went fine, you should be to see the containers running with: If everithing went fine, you should be to see the containers running with:
```bash ```bash
docker ps docker ps
``` ```
Create and copy your digital tape files in the following directories: Create and copy your digital tape files in the following directories:
```bash ```bash
mkdir data mkdir data
mkdir data/PreservationAudioFile mkdir data/PreservationAudioFile
mkdir data/PreservationAudioVisualFile mkdir data/PreservationAudioVisualFile
``` ```
To install the client application, you need to install poetry with: To install the client application, you need to install poetry with:
```bash ```bash
pip install poetry pip install poetry
``` ```
Then, you can install the client application by fisrt moving to the client directory: Then, you can install the client application by fisrt moving to the client directory:
```bash ```bash
cd client cd client
``` ```
And then running: And then running:
```bash ```bash
poetry install poetry install
``` ```
## Usage ## Usage
If the containers are not running, you can start them with: If the containers are not running, you can start them with:
```bash ```bash
docker compose up -d docker compose up -d
``` ```
To run the client application, you need to move to the client directory: To run the client application, you need to move to the client directory:
```bash ```bash
cd client cd client
``` ```
And then run: And then run:
```bash ```bash
poetry run mpai-cae-arp -h poetry run mpai-cae-arp -h
``` ```
It will show the help message with some instructions on how to use the client application: It will show the help message with some instructions on how to use the client application:
``` ```
usage: mpai-cae-arp [-h] -f FILES_NAME [-s HOST] usage: mpai-cae-arp [-h] -f FILES_NAME [-s HOST]
The MPAI-CAE ARP client. The MPAI-CAE ARP client.
options: options:
-h, --help show this help message and exit -h, --help show this help message and exit
-f FILES_NAME, --files-name FILES_NAME -f FILES_NAME, --files-name FILES_NAME
Specify the name of the Preservation files (without extension) Specify the name of the Preservation files (without extension)
-s HOST, --host HOST Specify the host of the server (default is localhost) -s HOST, --host HOST Specify the host of the server (default is localhost)
``` ```
The application expects to find the input files in the `data` directory, that is shared with the containers and should have the following structure: The application expects to find the input files in the `data` directory, that is shared with the containers and should have the following structure:
``` ```
data data
├── PreservationAudioFile ├── PreservationAudioFile
│   ├── BERIO052.wav │   ├── BERIO052.wav
│   └── BERIO100.wav │   └── BERIO100.wav
└── PreservationAudioVisualFile └── PreservationAudioVisualFile
    ├── BERIO052.mov     ├── BERIO052.mov
   └── BERIO100.mov    └── BERIO100.mov
``` ```
To execute this program for file `BERIO100` prompt: To execute this program for file `BERIO100` prompt:
``` ```
poetry run mpai-cae-arp -f BERIO100 poetry run mpai-cae-arp -f BERIO100
``` ```
It will take a while. When you see the message "Success", you can open the data folder where you will find the restoration files. It will take a while. When you see the message "Success", you can open the data folder where you will find the restoration files.
## Support ## Support
If you require additional information or have any problem running the software, please contact us at: If you require additional information or have any problem running the software, please contact us at:
* Matteo Spanio (dev2@audioinnova.com) * Matteo Spanio (dev2@audioinnova.com)
## Authors and acknowledgment ## Authors and acknowledgment
This project was developed by: This project was developed by:
* Nadir Dalla Pozza (University of Padova); * Nadir Dalla Pozza (University of Padova);
* Niccolò Pretto (University of Padova); * Niccolò Pretto (University of Padova);
* Sergio Canazza (University of Padova). * Sergio Canazza (University of Padova).
## License ## License
This project is licensed with [GNU GPL v3.0](https://www.gnu.org/licenses/gpl-3.0.html). This project is licensed with [GNU GPL v3.0](https://www.gnu.org/licenses/gpl-3.0.html).
This source diff could not be displayed because it is too large. You can view the blob instead.
[tool.poetry] [tool.poetry]
name = "client" name = "client"
version = "0.1.0" version = "0.1.0"
description = "" description = ""
authors = ["Matteo Spanio <dev2@audioinnova.com>"] authors = ["Matteo Spanio <dev2@audioinnova.com>"]
readme = "README.md" readme = "README.md"
packages = [ packages = [
{ include = "src" }, { include = "src" },
] ]
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.10" python = "^3.10"
rich = "^13.3.3" rich = "^13.3.3"
grpcio-tools = "^1.53.0" grpcio-tools = "^1.53.0"
mpai-cae-arp = "^0.4.1" mpai-cae-arp = "^0.4.1"
[build-system] [build-system]
requires = ["poetry-core"] requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"
[tool.poetry.scripts] [tool.poetry.scripts]
mpai-cae-arp = 'src.app:run' mpai-cae-arp = 'src.app:run'
from rich.console import Console from rich.console import Console
import os import os
from argparse import ArgumentParser from argparse import ArgumentParser
from time import sleep from time import sleep
import grpc import grpc
from mpai_cae_arp.network import arp_pb2 from mpai_cae_arp.network import arp_pb2
from mpai_cae_arp.network import arp_pb2_grpc from mpai_cae_arp.network import arp_pb2_grpc
channels = { channels = {
"AudioAnalyser": grpc.insecure_channel("localhost:50051"), "AudioAnalyser": grpc.insecure_channel("localhost:50051"),
"VideoAnalyser": grpc.insecure_channel("localhost:50052"), "VideoAnalyser": grpc.insecure_channel("localhost:50052"),
"TapeIrregularityClassifier": grpc.insecure_channel("localhost:50053"), "TapeIrregularityClassifier": grpc.insecure_channel("localhost:50053"),
"TapeAudioRestoration": grpc.insecure_channel("localhost:50054"), "TapeAudioRestoration": grpc.insecure_channel("localhost:50054"),
"Packager": grpc.insecure_channel("localhost:50055"), "Packager": grpc.insecure_channel("localhost:50055"),
} }
def get_args() -> tuple[str, str]: def get_args() -> tuple[str, str]:
parser = ArgumentParser( parser = ArgumentParser(
prog="mpai-cae-arp", prog="mpai-cae-arp",
description="The MPAI-CAE ARP client.", description="The MPAI-CAE ARP client.",
) )
parser.add_argument("-f", "--files-name", help="Specify the name of the Preservation files (without extension)", required=True) parser.add_argument("-f", "--files-name", help="Specify the name of the Preservation files (without extension)", required=True)
parser.add_argument("-s", "--host", help="Specify the host of the server (default is localhost)", default="localhost") parser.add_argument("-s", "--host", help="Specify the host of the server (default is localhost)", default="localhost")
args = parser.parse_args() args = parser.parse_args()
return args.files_name, args.host return args.files_name, args.host
def run(): def run():
console = Console() console = Console()
files_name, host = get_args() files_name, host = get_args()
if host != "localhost": if host != "localhost":
console.print("[red bold]Warning![/] :warning:") console.print("[red bold]Warning![/] :warning:")
console.print("[italic red]You are not using the default host. Make sure you are using the same host as the server.[/]") console.print("[italic red]You are not using the default host. Make sure you are using the same host as the server.[/]")
exit(os.EX_USAGE) exit(os.EX_USAGE)
audio_analyser = arp_pb2_grpc.AIMStub(channels["AudioAnalyser"]) audio_analyser = arp_pb2_grpc.AIMStub(channels["AudioAnalyser"])
video_analyser = arp_pb2_grpc.AIMStub(channels["VideoAnalyser"]) video_analyser = arp_pb2_grpc.AIMStub(channels["VideoAnalyser"])
tape_irreg_classifier = arp_pb2_grpc.AIMStub(channels["TapeIrregularityClassifier"]) tape_irreg_classifier = arp_pb2_grpc.AIMStub(channels["TapeIrregularityClassifier"])
tape_audio_restoration = arp_pb2_grpc.AIMStub(channels["TapeAudioRestoration"]) tape_audio_restoration = arp_pb2_grpc.AIMStub(channels["TapeAudioRestoration"])
packager = arp_pb2_grpc.AIMStub(channels["Packager"]) packager = arp_pb2_grpc.AIMStub(channels["Packager"])
request = arp_pb2.InfoRequest() request = arp_pb2.InfoRequest()
try: try:
for aim in [audio_analyser, video_analyser, tape_irreg_classifier, tape_audio_restoration, packager]: for aim in [audio_analyser, video_analyser, tape_irreg_classifier, tape_audio_restoration, packager]:
response = aim.getInfo(request) response = aim.getInfo(request)
console.print("[bold]{}[/], v{}".format(response.title, response.version)) console.print("[bold]{}[/], v{}".format(response.title, response.version))
sleep(0.3) sleep(0.3)
except grpc.RpcError as e: except grpc.RpcError as e:
console.print("[bold red]Error![/] :boom:") console.print("[bold red]Error![/] :boom:")
console.print(f"[italic red]{e.details()}[/]") console.print(f"[italic red]{e.details()}[/]")
exit(69) exit(69)
request = arp_pb2.JobRequest( request = arp_pb2.JobRequest(
working_dir="/data", working_dir="/data",
files_name=files_name, files_name=files_name,
index=1, index=1,
) )
with console.status("[bold]Computing AudioAnalyser IrregularityFile 1...", spinner="bouncingBall"): with console.status("[bold]Computing AudioAnalyser IrregularityFile 1...", spinner="bouncingBall"):
for result in audio_analyser.work(request): for result in audio_analyser.work(request):
if result.status == "error": if result.status == "error":
console.print("[bold red]Error![/] :boom:") console.print("[bold red]Error![/] :boom:")
console.print(f"[italic red]{result.message}") console.print(f"[italic red]{result.message}")
for channel in channels.values(): for channel in channels.values():
channel.close() channel.close()
exit(os.EX_SOFTWARE) exit(os.EX_SOFTWARE)
console.print(result.message) console.print(result.message)
request.files_name = f"{files_name}.mov" request.files_name = f"{files_name}.mov"
with console.status("[bold]Computing VideoAnalyser IrregularityFiles...", spinner="bouncingBall"): with console.status("[bold]Computing VideoAnalyser IrregularityFiles...", spinner="bouncingBall"):
for result in video_analyser.work(request): for result in video_analyser.work(request):
if result.status == "error": if result.status == "error":
console.print("[bold red]Error![/] :boom:") console.print("[bold red]Error![/] :boom:")
console.print(f"[italic red]{result.message}") console.print(f"[italic red]{result.message}")
for channel in channels.values(): for channel in channels.values():
channel.close() channel.close()
exit(os.EX_SOFTWARE) exit(os.EX_SOFTWARE)
console.print(result.message) console.print(result.message)
request.index = 2 request.index = 2
request.files_name = files_name request.files_name = files_name
with console.status("[bold]Computing AudioAnalyser IrregularityFile 2...", spinner="bouncingBall"): with console.status("[bold]Computing AudioAnalyser IrregularityFile 2...", spinner="bouncingBall"):
for result in audio_analyser.work(request): for result in audio_analyser.work(request):
if result.status == "error": if result.status == "error":
console.print("[bold red]Error![/] :boom:") console.print("[bold red]Error![/] :boom:")
console.print(f"[italic red]{result.message}") console.print(f"[italic red]{result.message}")
for channel in channels.values(): for channel in channels.values():
channel.close() channel.close()
exit(os.EX_SOFTWARE) exit(os.EX_SOFTWARE)
console.print(result.message) console.print(result.message)
with console.status("[bold]Computing TapeIrregularityClassifier...", spinner="bouncingBall"): with console.status("[bold]Computing TapeIrregularityClassifier...", spinner="bouncingBall"):
for result in tape_irreg_classifier.work(request): for result in tape_irreg_classifier.work(request):
if result.status == "error": if result.status == "error":
console.print("[bold red]Error![/] :boom:") console.print("[bold red]Error![/] :boom:")
console.print(f"[italic red]{result.message}") console.print(f"[italic red]{result.message}")
for channel in channels.values(): for channel in channels.values():
channel.close() channel.close()
exit(os.EX_SOFTWARE) exit(os.EX_SOFTWARE)
console.print(result.message) console.print(result.message)
with console.status("[bold]Computing TapeAudioRestoration...", spinner="bouncingBall"): with console.status("[bold]Computing TapeAudioRestoration...", spinner="bouncingBall"):
for result in tape_audio_restoration.work(request): for result in tape_audio_restoration.work(request):
if result.status == "error": if result.status == "error":
console.print("[bold red]Error![/] :boom:") console.print("[bold red]Error![/] :boom:")
console.print(f"[italic red]{result.message}") console.print(f"[italic red]{result.message}")
for channel in channels.values(): for channel in channels.values():
channel.close() channel.close()
exit(os.EX_SOFTWARE) exit(os.EX_SOFTWARE)
console.print(result.message) console.print(result.message)
with console.status("[bold]Packaging...", spinner="bouncingBall"): with console.status("[bold]Packaging...", spinner="bouncingBall"):
for result in packager.work(request): for result in packager.work(request):
if result.status == "error": if result.status == "error":
console.print("[bold red]Error![/] :boom:") console.print("[bold red]Error![/] :boom:")
console.print(f"[italic red]{result.message}") console.print(f"[italic red]{result.message}")
for channel in channels.values(): for channel in channels.values():
channel.close() channel.close()
exit(os.EX_SOFTWARE) exit(os.EX_SOFTWARE)
console.print(result.message) console.print(result.message)
channels["AudioAnalyser"].close() channels["AudioAnalyser"].close()
channels["VideoAnalyser"].close() channels["VideoAnalyser"].close()
channels["TapeIrregularityClassifier"].close() channels["TapeIrregularityClassifier"].close()
channels["TapeAudioRestoration"].close() channels["TapeAudioRestoration"].close()
channels["Packager"].close() channels["Packager"].close()
console.print("[bold green]Success![/] :tada:") console.print("[bold green]Success![/] :tada:")
if __name__ == '__main__': if __name__ == '__main__':
run() run()
version: '3.9' version: '3.9'
services: services:
audio-analyzer: audio-analyzer:
image: mpai-audio-analyzer image: mpai-audio-analyzer
build: ./audio-analyzer build: ./audio-analyzer
ports: ports:
- "${AUDIO_ANALYSER_PORT}:50051" - "${AUDIO_ANALYSER_PORT}:50051"
volumes: volumes:
- ${DATA_VOLUME}:/data - ${DATA_VOLUME}:/data
video-analyzer: video-analyzer:
image: mpai-video-analyzer image: mpai-video-analyzer
build: ./video-analyzer build: ./video-analyzer
ports: ports:
- "${VIDEO_ANALYSER_PORT}:50051" - "${VIDEO_ANALYSER_PORT}:50051"
volumes: volumes:
- ${DATA_VOLUME}:/data - ${DATA_VOLUME}:/data
tape-irregularity-classifier: tape-irregularity-classifier:
image: mpai-tape-irregularity-classifier image: mpai-tape-irregularity-classifier
build: ./tape-irregularity-classifier build: ./tape-irregularity-classifier
ports: ports:
- "${TAPE_IRREGULARITY_PORT}:50051" - "${TAPE_IRREGULARITY_PORT}:50051"
volumes: volumes:
- ${DATA_VOLUME}:/data - ${DATA_VOLUME}:/data
tape-audio-restoration: tape-audio-restoration:
image: mpai-tape-audio-restoration image: mpai-tape-audio-restoration
build: ./tape-audio-restoration build: ./tape-audio-restoration
ports: ports:
- "${TAPE_AUDIO_RESTORATION_PORT}:50051" - "${TAPE_AUDIO_RESTORATION_PORT}:50051"
volumes: volumes:
- ${DATA_VOLUME}:/data - ${DATA_VOLUME}:/data
packager: packager:
image: mpai-packager image: mpai-packager
build: ./packager build: ./packager
ports: ports:
- "${PACKAGER_PORT}:50051" - "${PACKAGER_PORT}:50051"
volumes: volumes:
- ${DATA_VOLUME}:/data - ${DATA_VOLUME}:/data
volumes: volumes:
data: data:
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment