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()