bot commited on
Commit
e267014
Β·
verified Β·
1 Parent(s): 555c4d2

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -0
app.py ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import requests
3
+ from flask import Flask, request, jsonify, send_file
4
+ import uuid
5
+
6
+ app = Flask(__name__)
7
+
8
+ def get_firebase_token():
9
+ """Get a Firebase ID token using a refresh token"""
10
+ url = "https://securetoken.googleapis.com/v1/token?key=AIzaSyDbAIg5AN6Cb5kITejfovleb5VDWw0Kv7s"
11
+
12
+ headers = {
13
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
14
+ "x-client-data": "CIq2yQEIprbJAQipncoBCOLwygEIlaHLAQiKo8sBCJz+zAEIhaDNAQj2ps0BCJDfzgE=",
15
+ "x-client-version": "Chrome/JsCore/10.14.1/FirebaseCore-web",
16
+ "x-firebase-gmpid": "1:593863204797:web:0b6f963bf7dfea5a28bcd4"
17
+ }
18
+
19
+ data = {
20
+ "grant_type": "refresh_token",
21
+ "refresh_token": "AMf-vBzwgbfU1K3obVOps6iNiXSW7-_i8XvcCLNyRuBhn0wP4PiMdnL74SUooQqW1fNQS3m-echJJDYpeTDv2kgdTMYQ6TMbvFv2PvYiSjDudoa_QdYuHwe44hP9RhPwt65N0yH-KdVJA0tziY7ihmYCG-14Inhas88TcQOmRZJdbr3vrIoaE7XI0vA-dFNYzfqcOyGxeDZWHnOj8fq3WR5K6LBHacavxOSyfBPDIHAHSaxhirhejFtkx1GPpSZ5L3zMKPlCohJ8NnvYquabhp_Uw7qPytHkAQjPLAlcyeJ4MR2BK0KLfnpLq1sR_mVPJ-Gm8NE89UIwM2XvdcZ6JWgHGEIxTR-hrfgxC0Ku0ZAGA4oDdBlndPIfc13tc-bcw7SEKpgOI6Gmb-4GH4_Tl7jgfJX8wI0O1x08nmb86BYyugf2eGCIKinv091o9cPPSZEvnweE8rX0"
22
+ }
23
+
24
+ response = requests.post(url, headers=headers, data=data)
25
+
26
+ if response.status_code == 200:
27
+ json_response = response.json()
28
+ id_token = json_response.get("id_token")
29
+ if id_token:
30
+ print("βœ… Firebase token retrieved successfully")
31
+ return id_token
32
+ else:
33
+ raise ValueError("Firebase ID token not found in the response")
34
+ else:
35
+ raise Exception(f"❌ Failed to retrieve Firebase token. Status code: {response.status_code}, Response: {response.text}")
36
+
37
+ def get_speechify_auth_token(firebase_token):
38
+ """Exchange Firebase token for Speechify authentication token"""
39
+ url = f"https://audio.api.speechify.com/v1/auth/sign?id_token={firebase_token}"
40
+
41
+ headers = {
42
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36",
43
+ "Authorization": f"Bearer {firebase_token}",
44
+ "Content-Type": "application/json"
45
+ }
46
+
47
+ response = requests.get(url, headers=headers)
48
+
49
+ if response.status_code == 200:
50
+ speechify_token = response.json().get('token')
51
+ if speechify_token:
52
+ print("βœ… Speechify token retrieved successfully")
53
+ return speechify_token
54
+ else:
55
+ raise ValueError("Speechify token not found in the response")
56
+ else:
57
+ raise Exception(f"❌ Failed to retrieve Speechify token. Status code: {response.status_code}, Response: {response.text}")
58
+
59
+ def synthesize_speech(token, text, voice_id, output_file):
60
+ """Generate speech audio using Speechify API"""
61
+ url = "https://audio.api.speechify.com/v3/synthesis/get"
62
+
63
+ headers = {
64
+ "authorization": f"Bearer {token}",
65
+ "x-speechify-client": "WebApp",
66
+ "x-speechify-client-version": "2.3.0",
67
+ "Content-Type": "application/json"
68
+ }
69
+
70
+ payload = {
71
+ "ssml": f"<speak>{text}</speak>",
72
+ "voice": voice_id,
73
+ "forcedAudioFormat": "mp3"
74
+ }
75
+
76
+ try:
77
+ response = requests.post(url, headers=headers, json=payload)
78
+
79
+ if response.status_code == 200:
80
+ with open(output_file, "wb") as f:
81
+ f.write(response.content)
82
+ print(f"βœ… MP3 file saved as {output_file}")
83
+ return True
84
+ else:
85
+ print(f"❌ Failed to generate audio. Status code: {response.status_code}")
86
+ print(response.text)
87
+ return False
88
+ except Exception as e:
89
+ print(f"❌ An error occurred during speech synthesis: {str(e)}")
90
+ return False
91
+
92
+ # Create output directory if it doesn't exist
93
+ os.makedirs("output", exist_ok=True)
94
+
95
+ @app.route('/synthesize', methods=['POST'])
96
+ def api_synthesize_speech():
97
+ """API endpoint to synthesize speech from text"""
98
+ try:
99
+ # Get parameters from request
100
+ data = request.json
101
+
102
+ if not data:
103
+ return jsonify({"error": "No JSON data provided"}), 400
104
+
105
+ text = data.get('text')
106
+ voice_id = data.get('voice_id', 'PVL:4f4a27ef-2b17-424f-904c-30bd1ed60fb8') # Default voice if not provided
107
+
108
+ if not text:
109
+ return jsonify({"error": "No text provided"}), 400
110
+
111
+ # Generate a unique filename
112
+ filename = f"output/{uuid.uuid4()}.mp3"
113
+
114
+ # Get tokens and synthesize speech
115
+ firebase_token = get_firebase_token()
116
+ speechify_token = get_speechify_auth_token(firebase_token)
117
+
118
+ result = synthesize_speech(speechify_token, text, voice_id, filename)
119
+
120
+ if result:
121
+ # Return the audio file
122
+ return send_file(filename, mimetype='audio/mpeg', as_attachment=True)
123
+ else:
124
+ return jsonify({"error": "Failed to synthesize speech"}), 500
125
+
126
+ except Exception as e:
127
+ return jsonify({"error": str(e)}), 500
128
+
129
+ @app.route('/', methods=['GET'])
130
+ def home():
131
+ """Home page with usage instructions"""
132
+ return """
133
+ <html>
134
+ <head>
135
+ <title>Speechify API</title>
136
+ <style>
137
+ body { font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; }
138
+ code { background-color: #f4f4f4; padding: 2px 5px; border-radius: 3px; }
139
+ pre { background-color: #f4f4f4; padding: 10px; border-radius: 5px; overflow-x: auto; }
140
+ </style>
141
+ </head>
142
+ <body>
143
+ <h1>Speechify Text-to-Speech API</h1>
144
+ <p>Use this API to convert text to speech using Speechify.</p>
145
+
146
+ <h2>Endpoint</h2>
147
+ <code>POST /synthesize</code>
148
+
149
+ <h2>Request Format</h2>
150
+ <pre>
151
+ {
152
+ "text": "Your text to be converted to speech",
153
+ "voice_id": "PVL:4f4a27ef-2b17-424f-904c-30bd1ed60fb8" (optional)
154
+ }
155
+ </pre>
156
+
157
+ <h2>Example Usage with cURL</h2>
158
+ <pre>
159
+ curl -X POST http://localhost:7860/synthesize \\
160
+ -H "Content-Type: application/json" \\
161
+ -d '{"text": "Hello, this is a test", "voice_id": "PVL:4f4a27ef-2b17-424f-904c-30bd1ed60fb8"}'
162
+ </pre>
163
+
164
+ <h2>Response</h2>
165
+ <p>The API returns an MP3 audio file if successful, or a JSON error message if there's a problem.</p>
166
+ </body>
167
+ </html>
168
+ """
169
+
170
+ if __name__ == '__main__':
171
+ app.run(host='0.0.0.0', port=7860, debug=False)