Spaces:
Runtime error
Runtime error
Update app.py
#3
by chawitzoon - opened
app.py
CHANGED
|
@@ -1,85 +1,102 @@
|
|
| 1 |
import gradio as gr
|
| 2 |
-
import lyricsgenius
|
| 3 |
import os
|
| 4 |
from langdetect import detect
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
"""
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
Args:
|
| 17 |
-
song_name: The name of the song to search for.
|
| 18 |
-
artist_name: The name of the artist (optional).
|
| 19 |
-
|
| 20 |
-
Returns:
|
| 21 |
-
A tuple containing the song's original lyrics, a placeholder translation,
|
| 22 |
-
and the YouTube embed HTML.
|
| 23 |
"""
|
| 24 |
-
if not
|
| 25 |
-
return "Please
|
| 26 |
-
|
| 27 |
-
# Search for the song using lyricsgenius
|
| 28 |
-
try:
|
| 29 |
-
# --- MODIFIED: Pass both song_name and artist_name to the search method ---
|
| 30 |
-
song = genius.search_song(song_name, artist_name, get_full_info=False)
|
| 31 |
-
if not song:
|
| 32 |
-
return "Song not found.", "", ""
|
| 33 |
-
except Exception as e:
|
| 34 |
-
return f"Error searching for song: {e}", "", ""
|
| 35 |
-
|
| 36 |
-
original_lyrics = song.lyrics
|
| 37 |
|
| 38 |
# Detect the language of the lyrics
|
| 39 |
try:
|
| 40 |
-
language = detect(
|
| 41 |
except Exception:
|
| 42 |
language = "unknown"
|
| 43 |
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
if language =
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
|
|
|
|
|
|
|
|
|
| 52 |
else:
|
| 53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
|
| 55 |
-
#
|
| 56 |
-
|
| 57 |
-
youtube_url = "https://www.youtube.com/embed/dQw4w9WgXcQ" # A classic Rick Roll for now!
|
| 58 |
-
youtube_embed = f'<iframe width="560" height="315" src="{youtube_url}" frameborder="0" allowfullscreen></iframe>'
|
| 59 |
|
| 60 |
-
return
|
| 61 |
|
| 62 |
# Define the Gradio interface
|
| 63 |
with gr.Blocks() as demo:
|
| 64 |
gr.Markdown("## Song Lyrics and Translation App")
|
| 65 |
-
gr.Markdown("
|
| 66 |
|
| 67 |
with gr.Row():
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
inputs=[song_input, artist_input],
|
| 82 |
-
outputs=[
|
| 83 |
)
|
| 84 |
|
| 85 |
# Launch the Gradio app
|
|
|
|
| 1 |
import gradio as gr
|
|
|
|
| 2 |
import os
|
| 3 |
from langdetect import detect
|
| 4 |
+
from transformers import pipeline
|
| 5 |
+
from pypinyin import pinyin, Style
|
| 6 |
+
from janome.tokenizer import Tokenizer
|
| 7 |
+
import re
|
| 8 |
+
|
| 9 |
+
# We'll use a placeholder for Youtube for now.
|
| 10 |
+
# We will implement this in the next step.
|
| 11 |
+
def search_youtube_video(query):
|
| 12 |
+
# Placeholder for the next step
|
| 13 |
+
return f'<iframe width="560" height="315" src="https://www.youtube.com/embed/dQw4w9WgXcQ" frameborder="0" allowfullscreen></iframe>'
|
| 14 |
+
|
| 15 |
+
# Hugging Face translation models
|
| 16 |
+
# We'll use a simple, general-purpose multilingual model for now.
|
| 17 |
+
# This might not be perfect, but it's a great starting point.
|
| 18 |
+
translation_pipeline = pipeline("translation", model="Helsinki-NLP/opus-mt-mul-en")
|
| 19 |
+
|
| 20 |
+
# Pinyin Romanization for Chinese
|
| 21 |
+
def get_pinyin_from_chinese(lyrics):
|
| 22 |
+
"""Converts Chinese characters to Pinyin with tone numbers."""
|
| 23 |
+
pinyin_result = pinyin(lyrics, style=Style.TONE)
|
| 24 |
+
# Flatten the list of lists and join the pinyin with spaces.
|
| 25 |
+
return " ".join(["".join(word) for word in pinyin_result])
|
| 26 |
+
|
| 27 |
+
# Romanization for Japanese (Romaji)
|
| 28 |
+
def get_romaji_from_japanese(lyrics):
|
| 29 |
+
"""Converts Japanese to Romaji using a tokenizer."""
|
| 30 |
+
t = Tokenizer()
|
| 31 |
+
romaji_lyrics = []
|
| 32 |
+
# Tokenize the lyrics and convert each word to its romaji form.
|
| 33 |
+
for token in t.tokenize(lyrics):
|
| 34 |
+
romaji_lyrics.append(token.reading.lower().replace("*", ""))
|
| 35 |
+
return " ".join(romaji_lyrics)
|
| 36 |
+
|
| 37 |
+
# The main function to handle all the logic
|
| 38 |
+
def process_lyrics(lyrics: str, song_name: str = "", artist_name: str = ""):
|
| 39 |
"""
|
| 40 |
+
Takes user-pasted lyrics and performs language detection, translation,
|
| 41 |
+
and Romanization if necessary.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 42 |
"""
|
| 43 |
+
if not lyrics:
|
| 44 |
+
return "Please paste some lyrics.", "", ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
|
| 46 |
# Detect the language of the lyrics
|
| 47 |
try:
|
| 48 |
+
language = detect(lyrics)
|
| 49 |
except Exception:
|
| 50 |
language = "unknown"
|
| 51 |
|
| 52 |
+
translated_text = ""
|
| 53 |
+
# We will use the translation model only if the language is not English.
|
| 54 |
+
if language != "en":
|
| 55 |
+
try:
|
| 56 |
+
# We must specify the source language for the model to work properly.
|
| 57 |
+
# `translation_pipeline` works with language codes like `>>zh<<`.
|
| 58 |
+
source_language_tag = f">>{language}<<"
|
| 59 |
+
translation_result = translation_pipeline(lyrics, src_lang=language, tgt_lang="en")[0]['translation_text']
|
| 60 |
+
translated_text = translation_result
|
| 61 |
+
except Exception as e:
|
| 62 |
+
translated_text = f"Translation error: {e}"
|
| 63 |
else:
|
| 64 |
+
translated_text = "Lyrics are in English."
|
| 65 |
+
|
| 66 |
+
# Handle Romanization based on the detected language
|
| 67 |
+
if language == "zh":
|
| 68 |
+
romanized_text = get_pinyin_from_chinese(lyrics)
|
| 69 |
+
translated_text = f"Pinyin: {romanized_text}\n\nTranslation: {translated_text}"
|
| 70 |
+
elif language == "ja":
|
| 71 |
+
romanized_text = get_romaji_from_japanese(lyrics)
|
| 72 |
+
translated_text = f"Romaji: {romanized_text}\n\nTranslation: {translated_text}"
|
| 73 |
|
| 74 |
+
# Get the YouTube video embed (we'll make this real in the next step)
|
| 75 |
+
youtube_embed = search_youtube_video(f"{song_name} {artist_name} lyrics")
|
|
|
|
|
|
|
| 76 |
|
| 77 |
+
return lyrics, translated_text, youtube_embed
|
| 78 |
|
| 79 |
# Define the Gradio interface
|
| 80 |
with gr.Blocks() as demo:
|
| 81 |
gr.Markdown("## Song Lyrics and Translation App")
|
| 82 |
+
gr.Markdown("Paste lyrics below and get a translation, romanization, and a YouTube video.")
|
| 83 |
|
| 84 |
with gr.Row():
|
| 85 |
+
with gr.Column(scale=2):
|
| 86 |
+
lyrics_input = gr.Textbox(label="Paste Lyrics Here", lines=10, placeholder="Paste your lyrics here...")
|
| 87 |
+
# We keep the song/artist inputs for the Youtube
|
| 88 |
+
song_input = gr.Textbox(label="Enter Song Name (for Youtube)", placeholder="e.g., 月亮代表我的心")
|
| 89 |
+
artist_input = gr.Textbox(label="Enter Artist Name (Optional)", placeholder="e.g., Teresa Teng")
|
| 90 |
+
process_button = gr.Button("Process")
|
| 91 |
+
|
| 92 |
+
with gr.Column(scale=1):
|
| 93 |
+
translation_output = gr.Textbox(label="Translation & Romanization", lines=10)
|
| 94 |
+
video_embed_output = gr.HTML(label="YouTube Video")
|
| 95 |
+
|
| 96 |
+
process_button.click(
|
| 97 |
+
fn=process_lyrics,
|
| 98 |
+
inputs=[lyrics_input, song_input, artist_input],
|
| 99 |
+
outputs=[lyrics_input, translation_output, video_embed_output]
|
| 100 |
)
|
| 101 |
|
| 102 |
# Launch the Gradio app
|