Spaces:
Sleeping
Sleeping
import os | |
import sys | |
import gradio as gr | |
# Install required packages if not already installed | |
try: | |
import sign_language_translator as slt | |
import requests | |
except ImportError: | |
print("Installing required packages...") | |
os.system("pip install sign-language-translator requests --quiet") | |
import sign_language_translator as slt | |
import requests | |
TITLE = "English to Pakistan Sign Language Translator" | |
DESCRIPTION = """This app translates English text to Pakistan Sign Language using two approaches: | |
1. Direct English to Pakistan Sign Language translation | |
2. English → Urdu → Pakistan Sign Language (as a fallback) | |
**NOTE:** | |
- The app will first try direct translation, then fallback to Urdu if needed | |
- Some simple phrases work better with direct translation | |
- For best results, use simple sentences | |
""" | |
# Common English phrases with their Urdu translations | |
COMMON_PHRASES = { | |
"how are you": "آپ کیسے ہیں", | |
"hello": "السلام علیکم", | |
"thank you": "شکریہ", | |
"good morning": "صبح بخیر", | |
"good afternoon": "دوپہر بخیر", | |
"good evening": "شام بخیر", | |
"good night": "شب بخیر", | |
"my name is": "میرا نام ہے", | |
"what is your name": "آپ کا نام کیا ہے", | |
"nice to meet you": "آپ سے مل کر خوشی ہوئی", | |
"i am fine": "میں ٹھیک ہوں", | |
"yes": "ہاں", | |
"no": "نہیں", | |
"please": "براہ کرم", | |
"sorry": "معذرت", | |
"goodbye": "خدا حافظ", | |
"i love you": "میں تم سے پیار کرتا ہوں", | |
"welcome": "خوش آمدید", | |
"excuse me": "معذرت", | |
"help": "مدد", | |
"where is": "کہاں ہے", | |
"what time is it": "کیا وقت ہوا ہے", | |
"how much is this": "یہ کتنے کا ہے", | |
"i understand": "میں سمجھتا ہوں", | |
"i don't understand": "میں نہیں سمجھتا", | |
} | |
# Global model variables | |
en_model = None | |
ur_model = None | |
def get_models(): | |
"""Initialize both translation models""" | |
try: | |
print("Loading English model...") | |
en_model = slt.models.ConcatenativeSynthesis("en", "pk-sl", "video") | |
print("Loading Urdu model...") | |
ur_model = slt.models.ConcatenativeSynthesis("ur", "pk-sl", "video") | |
return en_model, ur_model | |
except Exception as e: | |
print(f"Error initializing models: {str(e)}") | |
return None, None | |
def initialize_models(): | |
"""Ensure models are loaded""" | |
global en_model, ur_model | |
if en_model is None or ur_model is None: | |
en_model, ur_model = get_models() | |
return en_model is not None and ur_model is not None | |
def check_phrase_match(text): | |
"""Check if input matches any common phrases""" | |
text = text.lower().strip() | |
# Direct matches | |
if text in COMMON_PHRASES: | |
return COMMON_PHRASES[text] | |
# Check for partial matches at the beginning of the phrase | |
for eng, urdu in COMMON_PHRASES.items(): | |
if text.startswith(eng + " "): | |
return urdu + text[len(eng):] | |
return None | |
def english_to_urdu(text): | |
"""Translate English text to Urdu""" | |
if not text: | |
return "", "Please enter text to translate" | |
# First check our custom dictionary | |
phrase_match = check_phrase_match(text.lower()) | |
if phrase_match: | |
return phrase_match, f"Using known translation: {phrase_match}" | |
# Try multiple translation APIs for better reliability | |
try: | |
# First try Google Translate API via a proxy endpoint | |
url = "https://translate.googleapis.com/translate_a/single" | |
params = { | |
"client": "gtx", | |
"sl": "en", | |
"tl": "ur", | |
"dt": "t", | |
"q": text | |
} | |
response = requests.get(url, params=params) | |
if response.status_code == 200: | |
data = response.json() | |
try: | |
# Extract translation from response | |
translated_text = ''.join([sent[0] for sent in data[0]]) | |
return translated_text, f"Translated to Urdu: {translated_text}" | |
except: | |
pass | |
# Fallback to MyMemory API | |
url = f"https://api.mymemory.translated.net/get?q={text}&langpair=en|ur" | |
response = requests.get(url) | |
data = response.json() | |
if "responseData" in data and "translatedText" in data["responseData"]: | |
urdu_text = data["responseData"]["translatedText"] | |
return urdu_text, f"Translated to Urdu: {urdu_text}" | |
return "", "Error: Could not translate to Urdu" | |
except Exception as e: | |
print(f"Translation API error: {str(e)}") | |
return "", f"Error during Urdu translation: {str(e)}" | |
def english_to_sign_direct(english_text, format_type): | |
"""Try direct English to Sign Language translation""" | |
if not english_text: | |
return None, "No English text to translate" | |
# Initialize models if needed | |
if not initialize_models(): | |
return None, "Failed to initialize models" | |
try: | |
# Convert first letter to lowercase (required by model) | |
text = english_text[:1].lower() + english_text[1:] if english_text else "" | |
# Configure English model | |
en_model.text_language = "en" | |
en_model.sign_language = "pk-sl" | |
en_model.sign_format = format_type | |
if format_type == "landmarks": | |
en_model.sign_embedding_model = "mediapipe-world" | |
# Translate directly | |
output_path = "output_en.mp4" | |
sign = en_model.translate(text) | |
# Save output | |
if isinstance(sign, slt.Landmarks): | |
sign.data[:, 33:54, :3] += -sign.data[:, 33:34, :3] + sign.data[:, 15:16, :3] | |
sign.data[:, 54:, :3] += -sign.data[:, 54:55, :3] + sign.data[:, 16:17, :3] | |
sign.save_animation(output_path, overwrite=True) | |
else: | |
sign.save(output_path, overwrite=True, codec="mp4v") | |
return output_path, "Direct translation successful" | |
except Exception as e: | |
error_msg = str(e) | |
print(f"Direct translation error: {error_msg}") | |
return None, f"Direct translation failed: {error_msg}" | |
def urdu_to_sign(urdu_text, format_type): | |
"""Translate Urdu text to Pakistan Sign Language""" | |
if not urdu_text: | |
return None, "No Urdu text to translate" | |
# Initialize models if needed | |
if not initialize_models(): | |
return None, "Failed to initialize models" | |
try: | |
# Configure Urdu model | |
ur_model.text_language = "ur" | |
ur_model.sign_language = "pk-sl" | |
ur_model.sign_format = format_type | |
if format_type == "landmarks": | |
ur_model.sign_embedding_model = "mediapipe-world" | |
# Translate | |
output_path = "output_ur.mp4" | |
sign = ur_model.translate(urdu_text) | |
# Save output | |
if isinstance(sign, slt.Landmarks): | |
sign.data[:, 33:54, :3] += -sign.data[:, 33:34, :3] + sign.data[:, 15:16, :3] | |
sign.data[:, 54:, :3] += -sign.data[:, 54:55, :3] + sign.data[:, 16:17, :3] | |
sign.save_animation(output_path, overwrite=True) | |
else: | |
sign.save(output_path, overwrite=True, codec="mp4v") | |
return output_path, "Urdu translation successful" | |
except Exception as e: | |
error_msg = str(e) | |
print(f"Urdu translation error: {error_msg}") | |
return None, f"Urdu translation failed: {error_msg}" | |
def translate_english_to_sign(english_text, format_type): | |
"""Complete translation pipeline with fallback option""" | |
if not english_text: | |
return None, "", "" | |
# Try direct translation first | |
video, direct_status = english_to_sign_direct(english_text, format_type) | |
# If direct translation works, return it | |
if video: | |
return video, "", f"English: \"{english_text}\"\nDirect translation: {direct_status}" | |
# If direct translation fails, try via Urdu | |
urdu_text, urdu_status = english_to_urdu(english_text) | |
if not urdu_text: | |
return None, "", f"English: \"{english_text}\"\nDirect translation failed\n{urdu_status}" | |
# Translate Urdu to Sign Language | |
video, sign_status = urdu_to_sign(urdu_text, format_type) | |
# Combine status messages | |
status = f"English: \"{english_text}\"\nDirect translation failed\nUsing Urdu: \"{urdu_text}\"\n{sign_status}" | |
return video, urdu_text, status | |
# Create the Gradio interface | |
with gr.Blocks(title=TITLE) as demo: | |
gr.Markdown(f"# {TITLE}") | |
gr.Markdown(DESCRIPTION) | |
with gr.Row(): | |
with gr.Column(): | |
# Input area | |
english_input = gr.Textbox( | |
lines=4, | |
placeholder="Enter English text here...", | |
label="English Text" | |
) | |
format_dropdown = gr.Dropdown( | |
choices=["video", "landmarks"], | |
value="video", | |
label="Output Format" | |
) | |
with gr.Row(): | |
clear_btn = gr.Button("Clear") | |
translate_btn = gr.Button("Translate", variant="primary") | |
# Intermediate Urdu translation (may be empty if direct translation works) | |
urdu_output = gr.Textbox(label="Urdu Translation (if used)", interactive=False) | |
# Status area | |
status_output = gr.Textbox(label="Status", interactive=False) | |
with gr.Column(): | |
# Output video | |
video_output = gr.Video( | |
label="Sign Language Output", | |
format="mp4", | |
autoplay=True, | |
show_download_button=True | |
) | |
# Examples that work well with this model | |
gr.Examples( | |
examples=[ | |
["we are here", "video"], | |
["thank you", "video"], | |
["good morning", "video"], | |
["yes", "video"] | |
], | |
inputs=[english_input, format_dropdown], | |
outputs=[video_output, urdu_output, status_output], | |
fn=translate_english_to_sign | |
) | |
# Event handlers | |
translate_btn.click( | |
fn=translate_english_to_sign, | |
inputs=[english_input, format_dropdown], | |
outputs=[video_output, urdu_output, status_output] | |
) | |
clear_btn.click( | |
fn=lambda: ("", "", "Input cleared"), | |
inputs=None, | |
outputs=[english_input, urdu_output, status_output] | |
) | |
# Launch the app | |
if __name__ == "__main__": | |
demo.launch() |