beatcontent / app.py
BUBOUTLW's picture
Update app.py
7a358d5 verified
import gradio as gr
import numpy as np
import wave
import struct
import uuid
from content_generator.hooks import generate_hooks
from content_generator.captions import generate_captions
from content_generator.ideas import generate_content_ideas
from content_generator.scripts import generate_short_scripts
from pack_builder.zip_builder import build_creator_pack
# --------------------------------------------------
# CPU-SAFE BEAT GENERATOR (NO SCIPY)
# --------------------------------------------------
def generate_cpu_safe_beat(style, bpm):
sr = 44100
seconds = 8
t = np.linspace(0, seconds, int(sr * seconds))
beat = np.zeros_like(t)
if style == "Country Rap":
kick_freq, snare_freq, hat_freq = 55, 180, 8000
elif style == "Trap":
kick_freq, snare_freq, hat_freq = 45, 200, 10000
elif style == "Dark Outlaw":
kick_freq, snare_freq, hat_freq = 60, 150, 6000
elif style == "Drill":
kick_freq, snare_freq, hat_freq = 40, 160, 9000
else:
kick_freq, snare_freq, hat_freq = 70, 190, 7000
beat_interval = 60.0 / float(bpm)
hits = int(seconds / beat_interval)
for i in range(hits):
pos = int(i * beat_interval * sr)
if pos + 2000 <= len(beat):
beat[pos:pos+2000] += np.sin(2 * np.pi * kick_freq * t[:2000]) * 0.9
if i % 2 == 1 and pos + 2000 <= len(beat):
beat[pos:pos+2000] += np.sin(2 * np.pi * snare_freq * t[:2000]) * 0.5
if pos + 500 <= len(beat):
beat[pos:pos+500] += np.random.randn(500) * 0.1
max_val = float(np.max(np.abs(beat))) or 1.0
beat = beat / max_val
beat_int16 = (beat * 32767).astype(np.int16)
filename = f"beat_{uuid.uuid4().hex}.wav"
filepath = f"/tmp/{filename}"
with wave.open(filepath, "w") as wf:
wf.setnchannels(1)
wf.setsampwidth(2)
wf.setframerate(sr)
wf.writeframes(beat_int16.tobytes())
return filepath
def ui_generate_beats(style, bpm, loops):
audio = None
for _ in range(int(loops)):
audio = generate_cpu_safe_beat(style, bpm)
return audio
def ui_generate_content(niche, tone, goal):
return (
"\n".join(generate_hooks(niche, tone)),
"\n".join(generate_captions(niche, tone)),
"\n".join(generate_content_ideas(niche, goal)),
"\n".join(generate_short_scripts(niche, tone))
)
def ui_build_pack(niche, style, bpm, tone, goal):
return build_creator_pack(niche, style, bpm, tone, goal)
# --------------------------------------------------
# EMBEDDED BRUSHED GUNMETAL BACKGROUND (BASE64)
# --------------------------------------------------
gunmetal_bg = """
<style>
body {
margin: 0 !important;
padding: 0 !important;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAOEAAADhCAYAAAA+j9gPAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAABjBJREFUeJzt3b1u2kgQQNHTQF+giNBDbDE5jBqFaUGUcRgxN6E466+vWXTmFRrM8Nl1N8MPv+2MvmP0x+g6u40qGgfHdCqfpNNpJBWlAbIYWCA2PASi6DPd7OJbRRqtZIOSk5MTx0uvvZk90un0n0n0n0n0n0n0n0n0n0n8n2n2zcz5z7XnGO/czkRgZNpmjQqYh6gMPkTFogyXv3gZH/BqhGlywbn4T/6KrAE98FAd7iGouVp21HbQJseb3CidRubc4QpfAl8MwVzKhI6+w4n1vCLaYB9rqx8uxFazc2D/qKyfinBmMOPqlmkavRKu0kUQeFkCvhq/i323iDL49myIIZeF1P0uohsEiL/KZ8nfdXbra+XUl3Bd4mV9Ezg1QF/Nb+YPFQyu1HFDigONydMUuN1ZpFdEyAJ9MkdaZ7n0ANKPOuUMGAfJOyrUo9qeycGQ21MCH2RKDWE/YBYdz/BPZt6r9Ga6IpiObOqYkbKx2+Y8OobQIEkgyDAh9g0Rj62LF8oT+yQUwSWOSJyYwcmBHQYaWV7kngakdUSHcauD1ynjUTduVdJN9WewtG/XAIN5e8wZsM+dAf5BgC984wgKLF6t84yAogPSFqdtYY4cYNSeNBY0d5hDnzL2wv30IZHuZOKhHvJ3C0cFLbFhF38sZ4N2VNivg393XcX4Jt9V7H5P4xMIOKgHdwNwp0UrEGouGZWlznImPi0tLxe3LjXLp8dkUBaRdOy+nK8BPVKx/aRXefxWWEXUOYaL6VLdystD5nq2WEYLRh3SeDsICoZ6RiMUiP+6JGZveHFkNjEcNWef39/C4R2tQeM+c/37yHUsctNk6heAQ7Ez+KQEiC5EvhczHxMMz9Yx8RJWb1x1o1t4bm/FvGV8eK3opgDdBrYqYElw3ZTNhbmPDMv8YDn8ApX2HFqRSbVAAAAAElFTkSuQmCC');
background-size: cover !important;
background-position: center !important;
background-attachment: fixed !important;
}
/* HEADER */
#main-title {
font-size: 38px;
font-weight: 900;
color: #eeeeee;
text-align: center;
margin-bottom: 15px;
text-shadow:
0px 0px 18px #00f0ff,
0px 0px 28px #00f0ff,
0px 0px 18px #ff4800;
}
/* PANEL STYLING */
.gradio-container {
background: rgba(10, 10, 10, 0.55) !important;
backdrop-filter: blur(8px) !important;
border-radius: 14px !important;
border: 1px solid rgba(0,255,255,0.25) !important;
box-shadow: 0px 0px 22px rgba(0,255,255,0.35);
}
/* BUTTONS */
button {
background: linear-gradient(90deg, #00eaff, #0088cc) !important;
color: black !important;
font-weight: bold !important;
border-radius: 10px !important;
padding: 12px !important;
border: none !important;
font-size: 18px !important;
box-shadow: 0px 0px 15px #00eaff;
transition: 0.15s ease-in-out;
}
button:hover {
transform: scale(1.06);
box-shadow: 0px 0px 25px #00ffff;
}
/* INPUTS */
input, textarea, select {
background: rgba(20,20,20,0.8) !important;
color: #e5e5e5 !important;
border: 1px solid #0099aa !important;
}
/* AUDIO PLAYER */
audio {
outline: 2px solid #00ffff !important;
border-radius: 8px;
}
label {
color: #e5e5e5 !important;
}
</style>
"""
# --------------------------------------------------
# APP UI
# --------------------------------------------------
with gr.Blocks(title="304 Reaper AI Content + Beat Generator") as demo:
gr.HTML(gunmetal_bg)
gr.HTML("<h1 id='main-title'>πŸ”₯ 304 REAPER β€” AI CONTENT & BEAT FORGE πŸ”₯</h1>")
with gr.Tab("🎡 Beat Forge"):
gr.Markdown("### Build outlaw beats with neon precision.")
style = gr.Dropdown(
["Country Rap", "Trap", "Dark Outlaw", "Drill", "BoomBap"],
label="Beat Style"
)
bpm = gr.Slider(60, 180, value=120, label="BPM")
loops = gr.Slider(1, 5, value=1, label="Number of Loops")
gen_btn = gr.Button("⚑ Generate Beat")
audio_out = gr.Audio(label="Beat Output", type="filepath")
gen_btn.click(
ui_generate_beats,
inputs=[style, bpm, loops],
outputs=audio_out
)
with gr.Tab("🧠 Content Lab"):
gr.Markdown("### Hooks, captions, ideas, and scripts β€” outlaw branded.")
niche = gr.Textbox(label="Niche")
tone = gr.Textbox(label="Tone")
goal = gr.Textbox(label="Goal")
gen_btn2 = gr.Button("⚑ Generate Content")
hooks_out = gr.Textbox(label="Hooks")
captions_out = gr.Textbox(label="Captions")
ideas_out = gr.Textbox(label="Ideas")
scripts_out = gr.Textbox(label="Scripts")
gen_btn2.click(
ui_generate_content,
inputs=[niche, tone, goal],
outputs=[hooks_out, captions_out, ideas_out, scripts_out]
)
with gr.Tab("πŸ“¦ Creator Pack"):
gr.Markdown("### One click. Full outlaw creator pack.")
niche2 = gr.Textbox(label="Niche")
style2 = gr.Dropdown(
["Country Rap", "Trap", "Dark Outlaw", "Drill", "BoomBap"],
label="Beat Style"
)
bpm2 = gr.Slider(60, 180, value=120, label="BPM")
tone2 = gr.Textbox(label="Tone")
goal2 = gr.Textbox(label="Goal")
build_btn = gr.Button("⚑ Build Pack")
zip_out = gr.File(label="Download ZIP")
build_btn.click(
ui_build_pack,
inputs=[niche2, style2, bpm2, tone2, goal2],
outputs=zip_out
)
demo.launch()