123 lines
4.0 KiB
Python
123 lines
4.0 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
"""
|
|||
|
|
Test script for Fish.audio TTS API
|
|||
|
|
Usage: python test_fish_tts.py "Your text here"
|
|||
|
|
"""
|
|||
|
|
import sys
|
|||
|
|
import os
|
|||
|
|
import requests
|
|||
|
|
|
|||
|
|
def test_fish_tts(text: str, output_file: str = "test_output.mp3"):
|
|||
|
|
"""
|
|||
|
|
Test Fish.audio TTS API with given text
|
|||
|
|
|
|||
|
|
Args:
|
|||
|
|
text: Text to convert to speech
|
|||
|
|
output_file: Output audio file path
|
|||
|
|
"""
|
|||
|
|
# Get credentials from environment or globals
|
|||
|
|
try:
|
|||
|
|
import globals
|
|||
|
|
api_key = globals.FISH_API_KEY
|
|||
|
|
voice_id = globals.MIKU_VOICE_ID
|
|||
|
|
except:
|
|||
|
|
api_key = os.getenv("FISH_API_KEY")
|
|||
|
|
voice_id = os.getenv("MIKU_VOICE_ID")
|
|||
|
|
|
|||
|
|
if not api_key or not voice_id:
|
|||
|
|
print("❌ Error: FISH_API_KEY or MIKU_VOICE_ID not set!")
|
|||
|
|
print("Please set them in your environment or globals.py")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
print(f"🎤 Testing Fish.audio TTS...")
|
|||
|
|
print(f"📝 Text: {text}")
|
|||
|
|
print(f"🎵 Voice ID: {voice_id[:8]}...")
|
|||
|
|
print(f"<EFBFBD> API Key: {api_key[:8]}...{api_key[-4:]} (length: {len(api_key)})")
|
|||
|
|
print(f"<EFBFBD>💾 Output: {output_file}")
|
|||
|
|
print()
|
|||
|
|
|
|||
|
|
# API endpoint
|
|||
|
|
url = "https://api.fish.audio/v1/tts"
|
|||
|
|
|
|||
|
|
# Headers
|
|||
|
|
headers = {
|
|||
|
|
"Authorization": f"Bearer {api_key}",
|
|||
|
|
"Content-Type": "application/json",
|
|||
|
|
"model": "s1" # Recommended model
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Request payload
|
|||
|
|
payload = {
|
|||
|
|
"text": text,
|
|||
|
|
"reference_id": voice_id,
|
|||
|
|
"format": "mp3",
|
|||
|
|
"latency": "balanced",
|
|||
|
|
"temperature": 0.9,
|
|||
|
|
"normalize": True
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
print("⏳ Sending request to Fish.audio API...")
|
|||
|
|
response = requests.post(url, json=payload, headers=headers, timeout=30)
|
|||
|
|
|
|||
|
|
if response.status_code == 200:
|
|||
|
|
# Save audio file
|
|||
|
|
with open(output_file, "wb") as f:
|
|||
|
|
f.write(response.content)
|
|||
|
|
|
|||
|
|
file_size = len(response.content)
|
|||
|
|
print(f"✅ Success! Audio generated ({file_size:,} bytes)")
|
|||
|
|
print(f"🎵 Saved to: {output_file}")
|
|||
|
|
print()
|
|||
|
|
print(f"▶️ Play with: mpg123 {output_file}")
|
|||
|
|
print(f" or just open the file in your media player")
|
|||
|
|
return True
|
|||
|
|
else:
|
|||
|
|
print(f"❌ Error {response.status_code}: {response.text}")
|
|||
|
|
|
|||
|
|
if response.status_code == 402:
|
|||
|
|
print()
|
|||
|
|
print("💡 Troubleshooting tips for 402 error:")
|
|||
|
|
print(" 1. Go to https://fish.audio/app/api-keys/")
|
|||
|
|
print(" 2. Make sure you're using the 'Secret Key' (not just the Key ID)")
|
|||
|
|
print(" 3. Try deleting and creating a new API key")
|
|||
|
|
print(" 4. Check your balance at https://fish.audio/app/billing/")
|
|||
|
|
print(" 5. Make sure you have sufficient credits for this request")
|
|||
|
|
elif response.status_code == 401:
|
|||
|
|
print()
|
|||
|
|
print("💡 Authentication failed:")
|
|||
|
|
print(" - Double-check your API key is correct")
|
|||
|
|
print(" - Make sure there are no extra spaces or quotes")
|
|||
|
|
print(f" - Your key length is {len(api_key)} characters")
|
|||
|
|
elif response.status_code == 422:
|
|||
|
|
print()
|
|||
|
|
print("💡 Invalid parameters:")
|
|||
|
|
print(" - Check if the voice model ID is correct")
|
|||
|
|
print(" - Verify the model exists at https://fish.audio/")
|
|||
|
|
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
except requests.exceptions.Timeout:
|
|||
|
|
print("❌ Request timed out. Please try again.")
|
|||
|
|
return False
|
|||
|
|
except Exception as e:
|
|||
|
|
print(f"❌ Error: {e}")
|
|||
|
|
return False
|
|||
|
|
|
|||
|
|
|
|||
|
|
def main():
|
|||
|
|
if len(sys.argv) < 2:
|
|||
|
|
print("Usage: python test_fish_tts.py \"Your text here\"")
|
|||
|
|
print()
|
|||
|
|
print("Example:")
|
|||
|
|
print(' python test_fish_tts.py "Hello! I am Hatsune Miku!"')
|
|||
|
|
sys.exit(1)
|
|||
|
|
|
|||
|
|
text = " ".join(sys.argv[1:])
|
|||
|
|
success = test_fish_tts(text)
|
|||
|
|
sys.exit(0 if success else 1)
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
main()
|