breathaudio-backend/main.py

162 lines
4.7 KiB
Python
Raw Permalink Normal View History

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