breathaudio-backend/main.py
2023-04-02 12:15:59 -04:00

161 lines
4.7 KiB
Python

import os
import pathlib
from fastapi import FastAPI
from fastapi.responses import FileResponse
from pydantic import BaseModel
from fastapi.testclient import TestClient
from AccelBrainBeat.brainbeat.binaural_beat import BinauralBeat
import pydub
import random
from animate_fractal import animategif
from blend_av import blend_av
app = FastAPI()
class App(BaseModel):
app: str
class AudioProperties(BaseModel):
"""
Audio properties
"""
main_frequency: int
lag_frequency: int
volume: float
breath_pattern_in: int
breath_pattern_out: int
bell_sound: str
class VideoProperties(BaseModel):
"""
Video properties
"""
main_frequency: int
breath_pattern_in: int
breath_pattern_out: int
color_scheme = str
class AvProperties(BaseModel):
"""
Audio and video properties
"""
main_frequency: int
lag_frequency: int
volume: float
breath_pattern_in: int
breath_pattern_out: int
bell_sound: str
color_palette = str
@app.get("/")
async def get_root():
appresponse = App(app='breathaudio')
return appresponse
@app.get("/generate_audio")
async def get_generate_audio(audio_properties: AudioProperties):
"""
Generate audio
:param audio_properties:
:return:
"""
tmp_dir = pathlib.Path("tmp_sound")
tmp_dir.mkdir(parents=True, exist_ok=True)
# Remove existing files in tmp_dir
for filename in os.listdir(tmp_dir):
os.remove(tmp_dir / str(filename))
bell_dir = pathlib.Path("bell")
filename_prefix = ''.join([random.choice('0123456789ABCDEF') for i in range(32)])
filename = f"{filename_prefix}.wav"
# Generate binaural beat
b = BinauralBeat()
b.save_beat(output_file_name=str(tmp_dir / "binaural_beat.wav"),
frequencys=(audio_properties.main_frequency,
audio_properties.lag_frequency),
play_time=(audio_properties.breath_pattern_in + audio_properties.breath_pattern_out) * 2,
volume=audio_properties.volume
)
pydub_background = pydub.AudioSegment.from_wav(tmp_dir / "binaural_beat.wav")
bell_file = ""
if audio_properties.bell_sound == "Cloche":
bell_file = "339810__inspectorj__hand-bells-a-single-mod.wav"
skip_bell = False
elif audio_properties.bell_sound == "Bol tibétain":
bell_file = "417116__dersinnsspace__tibetan-bowl_right-hit-mod.wav"
skip_bell = False
else:
skip_bell = True
if skip_bell:
pydub_mix = pydub_background
else:
pydub_bell = pydub.AudioSegment.from_wav(bell_dir / bell_file)
pydub_mix = pydub_background. \
overlay(pydub_bell, position=0). \
overlay(pydub_bell, position=audio_properties.breath_pattern_in * 1000). \
overlay(pydub_bell,
position=(audio_properties.breath_pattern_in + audio_properties.breath_pattern_out) * 1000). \
overlay(pydub_bell,
position=(audio_properties.breath_pattern_in * 2 + audio_properties.breath_pattern_out) * 1000)
pydub_mix.export(tmp_dir / filename, format="wav")
return FileResponse(tmp_dir / filename)
@app.get("/generate_video")
async def get_generate_video(video_properties: VideoProperties):
"""
Generate video
:param video_properties:
:return:
"""
tmp_dir = pathlib.Path("tmp_video")
tmp_dir.mkdir(parents=True, exist_ok=True)
# Remove existing files in tmp_dir
for filename in os.listdir(tmp_dir):
os.remove(tmp_dir / str(filename))
anim = animategif()
filename_prefix = ''.join([random.choice('0123456789ABCDEF') for i in range(32)])
filename = f"{filename_prefix}.gif"
anim.save(str(tmp_dir / filename), writer='imagemagick')
return FileResponse(str(tmp_dir / filename))
@app.get("/generate_av")
async def get_generate_av(av_properties: AvProperties):
"""
Generate audio and video using blend_av
:param av_properties:
:return:
"""
a = AudioProperties()
a.main_frequency = av_properties.main_frequency
a.breath_pattern_in = av_properties.breath_pattern_in
a.breath_pattern_out = av_properties.breath_pattern_out
a.bell_sound = av_properties.bell_sound
audio = get_generate_audio(a)
v = VideoProperties()
v.main_frequency = av_properties.main_frequency
v.breath_pattern_in = av_properties.breath_pattern_in
v.breath_pattern_out = av_properties.breath_pattern_out
v.color_palette = av_properties.color_palette
video = get_generate_video(v)
av = blend_av(audio, video)
return FileResponse(av)
client = TestClient(app)
def test_getroot():
response = client.get("/")
assert response.status_code == 200