[PYTHON] DeepL translate YouTube Live chat and display it in real time

Operation image

DeepL Translator and display in real time. (Right window) メディア1.gif

Trigger

  1. I want to translate a foreign language chat on YouTube Live
  2. On Chrome, "Right click-> Translate to Japanese" can translate Google, but the accuracy is not good.
  3. DeepL translation seems to be more accurate than Google Translate (see graph below)
  4. Chats flow from moment to moment, so it's a hassle to copy and paste to DeepL Translator.

From the above, we have created a program that deepL translates YouTube Live chat and displays it in real time. image.png https://www.deepl.com/quality.html

How to use

image.png

code

translate_youtube_live_chat_gui.py


#Load the module.
import requests  #HTTP communication library
import tkinter  # Tcl/Tk Python interface
import time

#Load the function.
from tkinter import messagebox  #Create message box
from joblib import Parallel, delayed
from translator import deepl_translate  #DeepL Translator

# ======================================================================================================================
#Set the API URL.
YOUTUBE_API_VIDEO_URL = 'https://www.googleapis.com/youtube/v3/videos'  #YouTube video
YOUTUBE_API_CHAT_URL = 'https://www.googleapis.com/youtube/v3/liveChat/messages'  #YouTube chat

#Set the chat loading interval.(Note that if you make it too short, an error will occur.)
UPDATE_TIME = 5000  #millisecond
# ======================================================================================================================


#Performs processing when the button is clicked.
def click_button():
    #Get information from the GUI.
    youtube_live_url = edit_box1.get()  #YouTube Live URL
    youtube_api_key = edit_box2.get()  #YouTube API key
    deepl_api_key = edit_box3.get()  #DeepL API key
    target_lang = variable.get()  #Translated language

    #Get the video ID from the YouTube Live URL.
    video_id = youtube_live_url.replace('https://www.youtube.com/watch?v=', '')

    #Acquires the video data of the specified video ID.
    video_data = requests.get(
        YOUTUBE_API_VIDEO_URL, params={'key': youtube_api_key, 'id': video_id, 'part': 'liveStreamingDetails'}
    ).json()

    #If it is not YouTube Live, the process will be interrupted.
    if len(video_data['items']) == 0:
        messagebox.showerror('URL Error', 'Not Live')
        return  #Suspend processing.
    elif 'liveStreamingDetails' not in video_data['items'][0].keys():
        messagebox.showerror('URL Error', 'Not Live')
        return  #Suspend processing.
    elif 'activeLiveChatId' not in video_data['items'][0]['liveStreamingDetails'].keys():
        messagebox.showerror('URL Error', 'No Chat')
        return  #Suspend processing.

    #Get a chat ID.
    chat_id = video_data['items'][0]['liveStreamingDetails']['activeLiveChatId']

    #Add a message to the text box.
    add_message(chat_id, None, youtube_api_key, deepl_api_key, target_lang)  #Set the initial value of the page token to None.


#Add a message to the text box.
def add_message(chat_id, page_token, youtube_api_key, deepl_api_key, target_lang):
    #Cases are classified according to the presence or absence of pageToken. Avoid getting past chats.
    if type(page_token) == str:
        #Get the chat data of the specified chat ID.
        chat_data = requests.get(
            YOUTUBE_API_CHAT_URL,
            params={'key': youtube_api_key, 'liveChatId': chat_id, 'part': 'id,snippet,authorDetails',
                    'pageToken': page_token}
        ).json()

        #Record the time immediately after using the YouTube API.
        start_time = time.time()

        messages = []
        user_names = []
        for chat_item in chat_data['items']:  #Repeat as many times as there are chat items.
            #Create a message list.
            messages.append(chat_item['snippet']['displayMessage'])

            #Create a user name list.
            user_names.append(chat_item['authorDetails']['displayName'])

        #Translate with DeepL.
        trans_messages = Parallel(n_jobs=-1)(
            [delayed(deepl_translate)(message, target_lang, deepl_api_key) for message in messages]
        )

        for index, trans_message in enumerate(trans_messages):  #Repeat for the number of messages.
            #Get the user name.
            user_name = user_names[index]

            #Set the message to be displayed in the text box.
            display_message = '[' + user_name + '] ' + trans_message  # [username]+ Translated message

            #Add a message to the text box.
            txt_box.insert(tkinter.END, display_message)
            txt_box.insert(tkinter.END, '\n')
            txt_box.insert(tkinter.END, '\n')

        #Bring the scrollbar to the bottom.
        txt_box.see('end')

        #Update the window display.
        root.update()

    else:  #When pageToken is None
        #Get the chat data of the specified chat ID.
        chat_data = requests.get(
            YOUTUBE_API_CHAT_URL,
            params={'key': youtube_api_key, 'liveChatId': chat_id, 'part': 'id,snippet,authorDetails'}
        ).json()

        #Record the time immediately after using the YouTube API.
        start_time = time.time()

    #Update the page token.
    page_token = chat_data['nextPageToken']

    #Record the time just before using the YouTube API.
    end_time = time.time()

    #Calculate the time you are not using the YouTube API.
    elapsed_time_s = end_time - start_time  #Seconds
    elapsed_time_ms = round(elapsed_time_s * 1000)  #millisecond

    #Set the waiting time.
    wait_time = max({0, UPDATE_TIME - elapsed_time_ms})

    #Wait for the specified time.
    root.after(wait_time, add_message, chat_id, page_token, youtube_api_key, deepl_api_key, target_lang)


# ======================================================================================================================


#Create a window.
root = tkinter.Tk()
root.title('YouTube Live Chat DeepL Translator')
root.geometry('600x650')
root.resizable(False, False)

#Create a frame.
frame = tkinter.Frame(root)
frame.pack()
frame.place(x=0, y=70)

#Create a text box.
txt_box = tkinter.Text(frame, font=('Arial', 10), width=82, height=29)
y_scroll = tkinter.Scrollbar(frame, orient=tkinter.VERTICAL, command=txt_box.yview)  #Vertical scroll bar
y_scroll.pack(side=tkinter.RIGHT, fill='y')  #Vertical scroll bar
txt_box['yscrollcommand'] = y_scroll.set  #Vertical scroll bar
txt_box.pack()

#Create a button.
button = tkinter.Button(root, text='Start', font=('Arial', 15), command=click_button)
button.pack()
button.place(x=500, y=20)

#Create a label.
label1 = tkinter.Label(root, text='YouTube Live URL', font=('Arial', 12))
label1.pack()
label1.place(x=20, y=5)

#Create a label.
label2 = tkinter.Label(root, text='YouTube API Key', font=('Arial', 10))
label2.pack()
label2.place(x=140, y=590)

#Create a label.
label3 = tkinter.Label(root, text='DeepL API Key', font=('Arial', 10))
label3.pack()
label3.place(x=370, y=590)

#Create a label.
label4 = tkinter.Label(root, text='Target Language', font=('Arial', 10))
label4.pack()
label4.place(x=10, y=590)

#Create an edit box to enter the YouTube Live URL.
edit_box1 = tkinter.Entry(root, font=('Arial', 12), width=50)
edit_box1.pack()
edit_box1.place(x=20, y=30)

#Create an edit box to enter the YouTube API key.
edit_box2 = tkinter.Entry(root, font=('Arial', 10), width=30, show='*')
edit_box2.pack()
edit_box2.place(x=140, y=610)

#Create an edit box to enter the DeepL API key.
edit_box3 = tkinter.Entry(root, font=('Arial', 10), width=30, show='*')
edit_box3.pack()
edit_box3.place(x=370, y=610)

#Create a pull-down menu to select the translation language.
option_list = [
    'German',      # DE
    'English',     # EN
    'French',      # FR
    'Italian',     # IT
    'Japanese',    # JA
    'Spanish',     # ES
    'Dutch',       # NL
    'Polish',      # PL
    'Portuguese',  # PT
    'Russian',     # RU
    'Chinese'      # ZH
]
variable = tkinter.StringVar(root)
variable.set(option_list[4])  # JA
pull_down_menu = tkinter.OptionMenu(root, variable, *option_list)
pull_down_menu.config(width=10, font=('Arial', 10))
pull_down_menu.pack()
pull_down_menu.place(x=10, y=610)

#Draw a window.
root.mainloop()

translator.py


#Load the module.
import requests  #HTTP communication library

# ======================================================================================================================
#Set the URL of DeepL API.
DEEPL_API_URL = 'https://api.deepl.com/v2/translate'
# ======================================================================================================================


#Translate with DeepL.
def deepl_translate(src_text, target_lang, deepl_api_key):
    #Set the translation language code.
    if target_lang == 'German':
        target_lang_code = 'DE'
    elif target_lang == 'English':
        target_lang_code = 'EN'
    elif target_lang == 'French':
        target_lang_code = 'FR'
    elif target_lang == 'Italian':
        target_lang_code = 'IT'
    elif target_lang == 'Japanese':
        target_lang_code = 'JA'
    elif target_lang == 'Spanish':
        target_lang_code = 'ES'
    elif target_lang == 'Dutch':
        target_lang_code = 'NL'
    elif target_lang == 'Polish':
        target_lang_code = 'PL'
    elif target_lang == 'Portuguese':
        target_lang_code = 'PT'
    elif target_lang == 'Russian':
        target_lang_code = 'RU'
    elif target_lang == 'Chinese':
        target_lang_code = 'ZH'
    else:
        target_lang_code = None

    deepl_trans_result = requests.post(
        DEEPL_API_URL, data={"auth_key": deepl_api_key, "text": src_text, "target_lang": target_lang_code}
    ).json()
    trans_text = deepl_trans_result["translations"][0]["text"]

    return trans_text

Recommended Posts

DeepL translate YouTube Live chat and display it in real time
Get YouTube Live chat field in real time with API
[Python] Display the elapsed time in hours, minutes, and seconds (00:00:00)
I displayed the chat of YouTube Live and tried playing
How to generate a QR code and barcode in Python and read it normally or in real time with OpenCV