Spaces:
Running
Running
File size: 7,156 Bytes
1dcc163 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
#!/usr/bin/env python3
"""
Standalone script to generate sound effects using Hugging Face API.
Uses only built-in Python libraries (no external dependencies).
"""
import os
import json
import urllib.request
import time
from pathlib import Path
# Load environment variables from .env if present
env_path = Path(__file__).parent / ".env"
if env_path.exists():
with open(env_path) as f:
for line in f:
if line.strip() and not line.startswith("#"):
key, _, value = line.strip().partition("=")
os.environ[key] = value
# Get Hugging Face API token from environment variable
HF_API_TOKEN = os.environ.get("HF_API_TOKEN")
if not HF_API_TOKEN:
print("Warning: HF_API_TOKEN not set in environment or .env file.")
# Using your UnlimitedMusicGen Gradio Space
SPACE_URL = "https://surn-unlimitedmusicgen.hf.space"
GRADIO_API_URL = f"{SPACE_URL}/api/predict"
GRADIO_STATUS_URL = f"{SPACE_URL}/call/predict/{{event_id}}"
# Sound effects to generate
EFFECT_PROMPTS = {
"correct_guess": {"prompt": "A short, sharp ding sound for a correct guess", "duration": 2},
"incorrect_guess": {"prompt": "A low buzz sound for an incorrect guess", "duration": 2},
"miss": {"prompt": "A soft thud sound for a miss", "duration": 1},
"hit": {"prompt": "A bright chime sound for a hit", "duration": 1},
"congratulations": {"prompt": "A triumphant fanfare sound for congratulations", "duration": 3}
}
def generate_sound_effect_gradio(effect_name: str, prompt: str, duration: float, output_dir: Path) -> bool:
"""Generate a single sound effect using Gradio API (async call)."""
print(f"\nGenerating: {effect_name}")
print(f" Prompt: {prompt}")
print(f" Duration: {duration}s")
# Step 1: Submit generation request
payload = json.dumps({
"data": [prompt, duration]
}).encode('utf-8')
headers = {
"Content-Type": "application/json"
}
try:
print(f" Submitting request to Gradio API...")
# Submit the job
req = urllib.request.Request(GRADIO_API_URL, data=payload, headers=headers, method='POST')
with urllib.request.urlopen(req, timeout=30) as response:
if response.status == 200:
result = json.loads(response.read().decode())
event_id = result.get("event_id")
if not event_id:
print(f" β No event_id returned")
return False
print(f" Job submitted, event_id: {event_id}")
# Step 2: Poll for results
status_url = GRADIO_STATUS_URL.format(event_id=event_id)
for poll_attempt in range(30): # Poll for up to 5 minutes
time.sleep(10)
print(f" Polling for results (attempt {poll_attempt + 1}/30)...")
status_req = urllib.request.Request(status_url, headers=headers)
try:
with urllib.request.urlopen(status_req, timeout=30) as status_response:
# Gradio returns streaming events, read until we get the result
for line in status_response:
line = line.decode('utf-8').strip()
if line.startswith('data: '):
event_data = json.loads(line[6:]) # Remove 'data: ' prefix
if event_data.get('msg') == 'process_completed':
# Get the audio file URL
output_data = event_data.get('output', {}).get('data', [])
if output_data and len(output_data) > 0:
audio_url = output_data[0].get('url')
if audio_url:
# Download the audio file
full_audio_url = f"https://surn-unlimitedmusicgen.hf.space{audio_url}"
print(f" Downloading from: {full_audio_url}")
audio_req = urllib.request.Request(full_audio_url)
with urllib.request.urlopen(audio_req, timeout=30) as audio_response:
audio_data = audio_response.read()
# Save to file
output_path = output_dir / f"{effect_name}.wav"
with open(output_path, "wb") as f:
f.write(audio_data)
print(f" β Success! Saved to: {output_path}")
print(f" File size: {len(audio_data)} bytes")
return True
elif event_data.get('msg') == 'process_error':
print(f" β Generation error: {event_data.get('output')}")
return False
except Exception as poll_error:
print(f" Polling error: {poll_error}")
continue
print(f" β Timeout waiting for generation")
return False
else:
print(f" β Error {response.status}: {response.read().decode()}")
return False
except Exception as e:
print(f" β Error: {e}")
return False
def main():
"""Generate all sound effects."""
print("=" * 70)
print("Sound Effects Generator for BattleWords")
print("=" * 70)
print(f"Using UnlimitedMusicGen Gradio API")
print(f"API URL: {GRADIO_API_URL}")
print(f"\nGenerating {len(EFFECT_PROMPTS)} sound effects...\n")
# Create output directory
output_dir = Path(__file__).parent / "assets" / "audio"
output_dir.mkdir(parents=True, exist_ok=True)
print(f"Output directory: {output_dir}\n")
# Generate each effect
success_count = 0
for effect_name, config in EFFECT_PROMPTS.items():
if generate_sound_effect_gradio(
effect_name,
config["prompt"],
config["duration"],
output_dir
):
success_count += 1
# Small delay between requests
if effect_name != list(EFFECT_PROMPTS.keys())[-1]:
print(" Waiting 5 seconds before next request...")
time.sleep(5)
print("\n" + "=" * 70)
print(f"Generation complete! {success_count}/{len(EFFECT_PROMPTS)} successful")
print("=" * 70)
if success_count == len(EFFECT_PROMPTS):
print("\nβ All sound effects generated successfully!")
else:
print(f"\nβ {len(EFFECT_PROMPTS) - success_count} sound effects failed to generate")
if __name__ == "__main__":
main()
|