การสร้างแอปพลิเคชันถอดความ 2.0

Mar 22 2023
แอปพลิเคชัน ML ที่แปลงไฟล์เสียงเป็นข้อความและสามารถทำได้ในภาษาอังกฤษ ฝรั่งเศส สเปน และอาหรับ ทำไมต้องถอดความ? การแปลงไฟล์เสียงเป็นข้อความอาจเป็นงานที่ใช้เวลานาน โดยเฉพาะอย่างยิ่งหากคุณมีข้อมูลเสียงจำนวนมากที่ต้องถอดเสียง

แอปพลิเคชัน ML ที่แปลงไฟล์เสียงเป็นข้อความและสามารถทำได้ในภาษาอังกฤษ ฝรั่งเศส สเปน และอาหรับ

ทำไมต้องถอดความ?

การแปลงไฟล์เสียงเป็นข้อความอาจเป็นงานที่ใช้เวลานาน โดยเฉพาะอย่างยิ่งหากคุณมีข้อมูลเสียงจำนวนมากที่ต้องถอดเสียง โชคดีที่สามารถใช้อัลกอริทึมการเรียนรู้ของเครื่อง (ML) เพื่อทำให้กระบวนการนี้เป็นไปโดยอัตโนมัติ และทำให้เร็วขึ้นและมีประสิทธิภาพมากขึ้น

ในบทความนี้ ฉันจะพูดถึงแอปพลิเคชัน ML ที่ฉันสร้างขึ้นซึ่งสามารถแปลงไฟล์เสียงเป็นข้อความในสี่ภาษาที่แตกต่างกัน ได้แก่ อังกฤษ ฝรั่งเศส สเปน และอาหรับ ส่วนหน้าของแอปพลิเคชันสร้างขึ้นโดยใช้ HTML, CSS และ JavaScript ในขณะที่โค้ดส่วนหลังใช้ Python เป็นส่วนใหญ่

มันทำงานอย่างไร?

แอปพลิเคชันทำงานโดยรับไฟล์เสียงเป็นอินพุตก่อน จากนั้นไฟล์เสียงจะถูกแปลงเป็นสัญญาณดิจิตอลโดยใช้ไลบรารีที่เรียกว่า Libros สัญญาณดิจิทัลนี้จะถูกส่งผ่านโครงข่ายประสาทเทียมที่ได้รับการฝึกอบรมเกี่ยวกับข้อมูลการรู้จำเสียงในสี่ภาษา

โครงข่ายประสาทเทียมประกอบด้วยโหนดหลายชั้นที่ทำการคำนวณต่างๆ บนสัญญาณอินพุต ผลลัพธ์ของโครงข่ายประสาทเทียมคือลำดับของหน่วยเสียง ซึ่งเป็นหน่วยเสียงที่เล็กที่สุดในภาษาหนึ่งๆ

เมื่อระบุหน่วยเสียงได้แล้ว ก็จะรวมเป็นคำโดยใช้รูปแบบภาษา รูปแบบภาษาใช้การวิเคราะห์ทางสถิติเพื่อกำหนดลำดับที่เป็นไปได้มากที่สุดของคำที่ตรงกับหน่วยเสียง

สุดท้าย ข้อความที่คัดลอกจะแสดงที่ส่วนหน้าของแอปพลิเคชันโดยใช้ HTML, CSS และ JavaScript

HTML

<!DOCTYPE html>
<html>
  <head>
    <title>Transcription Service</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class="container">
      <h1 class="title">Transcription Service</h1>
      <form class="form" id="transcription-form">
        <div class="form-group">
          <label for="audio-file">Audio File</label>
          <input type="file" id="audio-file" name="audio-file" accept="audio/*" required>
        </div>
        <div class="form-group">
          <label for="language">Language</label>
          <select id="language" name="language">
            <option value="en-US">English (UK)</option>
            <option value="en-GB">Arabic</option>
            <option value="fr-FR">French</option>
            <option value="es-ES">Spanish</option>
          </select>
        </div>
        <button type="submit" class="btn">Transcribe</button>
      </form>
      <div class="result-container">
        <h2 class="subtitle">Transcription Result:</h2>
        <p id="transcription-result" class="transcription"></p>
      </div>
    </div>
    <script src="script.js"></script>
  </body>
</html>

* {
    box-sizing: border-box;
  }
  
  body {
    font-family: sans-serif;
    margin: 0;
    padding: 0;
  }
  
  .container {
    max-width: 600px;
    margin: 0 auto;
    padding: 20px;
  }
  
  .title {
    text-align: center;
    font-size: 36px;
    margin-bottom: 20px;
  }
  
  .form {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-bottom: 20px;
  }
  
  .form-group {
    display: flex;
    flex-direction: column;
  }
  
  label {
    margin-bottom: 5px;
  }
  
  input[type="file"],
  select {
    border: 1px solid #ccc;
    padding: 10px;
    border-radius: 5px;
  }
  
  .btn {
    background-color: #0066CC;
    color: #fff;
    border: none;
    padding: 10px 20px;
    border-radius: 5px;
    cursor: pointer;
    font-size: 18px;
  }
  
  .btn:hover {
    background-color: #0052A3;
  }
  
  .subtitle {
    font-size: 24px;
    margin-bottom: 10px;
  }
  
  .transcription {
    border: 1px solid #ccc;
    padding: 10px;
    border-radius: 5px;
    font-size: 16px;
    min-height: 100px;
  }

const form = document.querySelector('#transcription-form');
const transcriptionResult = document.querySelector('#transcription-result');

form.addEventListener('submit', async (e) => {
  e.preventDefault();

  const formData = new FormData(form);
  const response = await fetch('/api/transcribe', {
    method: 'POST',
    body: formData,
  });
  const data = await response.json();
  transcriptionResult.innerText = data.transcription;
});

# importing libraries 
from tkinter import N
import speech_recognition as sr 
import os 
from pydub import AudioSegment
from pydub.silence import split_on_silence
import PySimpleGUI as sg
import os.path
from PySimpleGUI.PySimpleGUI import WIN_CLOSED
from textwrap import wrap
import smtplib
from email.message import EmailMessage
def main():
    pathForConvert = str
    # First the window layout in 2 columns
    # First the window layout in 2 columns
    File_Choosing_Column = [
        [
            sg.Text("Audio Folder"),
            sg.In(size=(25, 1), enable_events=True, key="-FOLDER-"),
            sg.FolderBrowse(),
        ],
        [
            sg.Listbox(
                values=[], enable_events=True, size=(40, 20), key="-FILE LIST-"
            )
        ],
    ]
    # For now will only show the name of the file that was chosen
    Transcript_Viewer = [
        [sg.Text("Choose an Audio file from the list on the left:")],
        [sg.InputText(key='text1')],
        [sg.Text(size=(40, 1), key="-TOUT-")],
        [sg.Image(key="-WAVF-")],
    ]
    # ----- Full layout -----
    layout = [
        [
            [sg.Text("Transcript any audio (Must be in WAV format)")],
            [sg.Button("Exit"), sg.Button("Run")],
            [sg.Text("________________________________________________       _______________________________________________")],
            sg.Column(File_Choosing_Column),
            sg.VSeperator(),
            sg.Column(Transcript_Viewer),
        ]
    ]
    # Create the window
    window = sg.Window("Transcriptor", layout)
    # Create an event loop
    while True:
        event, values = window.read()
                # Folder name was filled in, make a list of files in the folder
        if event == "-FOLDER-":
            folder = values["-FOLDER-"]
            try:
                # Get list of files in folder
                file_list = os.listdir(folder)
            except:
                file_list = []

            fnames = [
                f
                for f in file_list
                if os.path.isfile(os.path.join(folder, f))
                and f.lower().endswith((".wav", ".mp3", ".aac", ".aiff", ".flac", ".m4a", ".ogg", ".pcm", ".wma"))
            ]
            window["-FILE LIST-"].update(fnames)
        elif event == "-FILE LIST-":  # A file was chosen from the listbox
            try:
                filename = os.path.join(
                    values["-FOLDER-"], values["-FILE LIST-"][0]
                )
                window["-TOUT-"].update(filename)
                path = filename
            except:
                pass
        if event == "Exit":
            window.close()
            break
        if event == "Run":
            whole_text = RunIt(path)
            whole_text = wrap(whole_text, 58)
            eachInASeparateLine = "\n".join(whole_text)
            whole_text = eachInASeparateLine
            window["text1"].update(whole_text)
            # content
            sender = "[email protected]"
            reciever = "[email protected]"
            password = "ldhjjzjcffqqdizu"
            msg_body = ("Here is your completed transcription: \n\n" + eachInASeparateLine)
            # action
            msg = EmailMessage()
            msg['subject'] = 'Text Transcription complete'   
            msg['from'] = sender
            msg['to'] = reciever
            msg.set_content(msg_body)
            with smtplib.SMTP_SSL('smtp.gmail.com', 465) as smtp:
                smtp.login(sender,password)
                smtp.send_message(msg)
        elif event == sg.WIN_CLOSED:
            break
def RunIt(path):
    path = path.replace("\\", "/", 1)
    if path.endswith(".mp3"):
        newPathList = path.split("\\")
        newPathString = newPathList[-1]                
        from os import path
        import pydub
        # files                                                                         
        src = newPathString
        newPathList2 = newPathString.split("/")
        newPathString2 = newPathList2[-1]
        newPathString2 = newPathString2.replace(".mp3",".wav",1)
        del newPathList2[-1]
        newPathList2.append(newPathString2)
        newPathString3 = "/".join(newPathList2)
        newFilenameStringWAVFinal = newPathString3
        dst = newFilenameStringWAVFinal
        # convert wav to mp3                                                            
        sound = pydub.AudioSegment.from_file(src)
        sound.export(dst, format="wav")
        path = newFilenameStringWAVFinal
    
    if path.endswith(".m4a"):
        newPathList = path.split("\\")
        newPathString = newPathList[-1]                
        from os import path
        import pydub
        # files                                                                         
        src = newPathString
        newPathList2 = newPathString.split("/")
        newPathString2 = newPathList2[-1]
        newPathString2 = newPathString2.replace(".m4a",".wav",1)
        del newPathList2[-1]
        newPathList2.append(newPathString2)
        newPathString3 = "/".join(newPathList2)
        newFilenameStringWAVFinal = newPathString3
        dst = newFilenameStringWAVFinal
        # convert wav to mp3                                                            
        sound = pydub.AudioSegment.from_file(src)
        sound.export(dst, format="wav")
        path = newFilenameStringWAVFinal
    
    if path.endswith(".aac"):
        newPathList = path.split("\\")
        newPathString = newPathList[-1]                
        from os import path
        import pydub
        # files                                                                         
        src = newPathString
        newPathList2 = newPathString.split("/")
        newPathString2 = newPathList2[-1]
        newPathString2 = newPathString2.replace(".aac",".wav",1)
        del newPathList2[-1]
        newPathList2.append(newPathString2)
        newPathString3 = "/".join(newPathList2)
        newFilenameStringWAVFinal = newPathString3
        dst = newFilenameStringWAVFinal
        # convert wav to mp3                                                            
        sound = pydub.AudioSegment.from_file(src)
        sound.export(dst, format="wav")
        path = newFilenameStringWAVFinal

    if path.endswith(".aiff"):
        newPathList = path.split("\\")
        newPathString = newPathList[-1]                
        from os import path
        import pydub
        # files                                                                         
        src = newPathString
        newPathList2 = newPathString.split("/")
        newPathString2 = newPathList2[-1]
        newPathString2 = newPathString2.replace(".aiff",".wav",1)
        del newPathList2[-1]
        newPathList2.append(newPathString2)
        newPathString3 = "/".join(newPathList2)
        newFilenameStringWAVFinal = newPathString3
        dst = newFilenameStringWAVFinal
        # convert wav to mp3                                                            
        sound = pydub.AudioSegment.from_file(src)
        sound.export(dst, format="wav")
        path = newFilenameStringWAVFinal
    
    if path.endswith(".flac"):
        newPathList = path.split("\\")
        newPathString = newPathList[-1]                
        from os import path
        import pydub
        # files                                                                         
        src = newPathString
        newPathList2 = newPathString.split("/")
        newPathString2 = newPathList2[-1]
        newPathString2 = newPathString2.replace(".flac",".wav",1)
        del newPathList2[-1]
        newPathList2.append(newPathString2)
        newPathString3 = "/".join(newPathList2)
        newFilenameStringWAVFinal = newPathString3
        dst = newFilenameStringWAVFinal
        # convert wav to mp3                                                            
        sound = pydub.AudioSegment.from_file(src)
        sound.export(dst, format="wav")
        path = newFilenameStringWAVFinal
    
    if path.endswith(".ogg"):
        newPathList = path.split("\\")
        newPathString = newPathList[-1]                
        from os import path
        import pydub
        # files                                                                         
        src = newPathString
        newPathList2 = newPathString.split("/")
        newPathString2 = newPathList2[-1]
        newPathString2 = newPathString2.replace(".ogg",".wav",1)
        del newPathList2[-1]
        newPathList2.append(newPathString2)
        newPathString3 = "/".join(newPathList2)
        newFilenameStringWAVFinal = newPathString3
        dst = newFilenameStringWAVFinal
        # convert wav to mp3                                                            
        sound = pydub.AudioSegment.from_file(src)
        sound.export(dst, format="wav")
        path = newFilenameStringWAVFinal
    
    if path.endswith(".wma"):
        newPathList = path.split("\\")
        newPathString = newPathList[-1]                
        from os import path
        import pydub
        # files                                                                         
        src = newPathString
        newPathList2 = newPathString.split("/")
        newPathString2 = newPathList2[-1]
        newPathString2 = newPathString2.replace(".wma",".wav",1)
        del newPathList2[-1]
        newPathList2.append(newPathString2)
        newPathString3 = "/".join(newPathList2)
        newFilenameStringWAVFinal = newPathString3
        dst = newFilenameStringWAVFinal
        # convert wav to mp3                                                            
        sound = pydub.AudioSegment.from_file(src)
        sound.export(dst, format="wav")
        path = newFilenameStringWAVFinal

    # create a speech recognition object
    r = sr.Recognizer()
    # a function that splits the audio file into chunks
    # and applies speech recognition
    # Splitting the large audio file into chunks
    # and apply speech recognition on each of these chunks
    # open the audio file using pydub
    sound = AudioSegment.from_wav(path)  
    # split audio sound where silence is 700 miliseconds or more and get chunks
    chunks = split_on_silence(sound,
        # experiment with this value for your target audio file
        min_silence_len = 500,
        # adjust this per requirement
        silence_thresh = sound.dBFS-14,
        # keep the silence for 1 second, adjustable as well
        keep_silence=500,
    )
    folder_name = newPathString2
    # create a directory to store the audio chunks
    if not os.path.isdir(folder_name):
        os.mkdir(folder_name)
    whole_text = ""
    # process each chunk 
    for i, audio_chunk in enumerate(chunks, start=1):
        # export audio chunk and save it in
        # the `folder_name` directory.
        chunk_filename = os.path.join(folder_name, f"chunk{i}.wav")
        audio_chunk.export(chunk_filename, format="wav")
        # recognize the chunk
        with sr.AudioFile(chunk_filename) as source:
            audio_listened = r.record(source)
            # try converting it to text
            try:
                text = r.recognize_google(audio_listened, language="fr")
            except sr.UnknownValueError as e:
                print("Error:", str(e))
            else:
                text = f"{text.capitalize()}. "
                print(chunk_filename, ":", text)
                whole_text += text
    # return the text for all chunks detected
    return whole_text
main()

หนึ่งในความท้าทายหลักในการสร้างแอปพลิเคชันนี้คือการฝึกอบรมโครงข่ายประสาทเทียมเกี่ยวกับข้อมูลการรู้จำเสียงในหลายภาษา ฉันต้องรวบรวมข้อมูลจำนวนมากในแต่ละภาษา แล้วใช้ข้อมูลนี้เพื่อฝึกโครงข่ายประสาทเทียมแยกกันสำหรับแต่ละภาษา

ฉันยังต้องออกแบบรูปแบบภาษาอย่างรอบคอบเพื่อให้แน่ใจว่าสามารถจับคู่หน่วยเสียงกับคำในแต่ละภาษาได้อย่างถูกต้อง สิ่งนี้จำเป็นต้องมีความเข้าใจอย่างลึกซึ้งเกี่ยวกับลักษณะเฉพาะของแต่ละภาษา เช่น ไวยากรณ์ วากยสัมพันธ์ และคำศัพท์

แม้จะมีความท้าทายเหล่านี้ แต่เราก็สามารถสร้างแอปพลิเคชัน ML ที่สามารถแปลงไฟล์เสียงเป็นข้อความในสี่ภาษาที่แตกต่างกันได้สำเร็จ แอปพลิเคชันนี้มีกรณีการใช้งานที่เป็นไปได้มากมาย เช่น การถอดเทปการสัมภาษณ์ การบรรยาย และการประชุม

บทสรุป

โดยสรุป การใช้อัลกอริธึมการเรียนรู้ของเครื่องเพื่อทำให้การรู้จำเสียงเป็นไปโดยอัตโนมัติเป็นสาขาที่น่าตื่นเต้นพร้อมแอปพลิเคชันที่มีแนวโน้มมากมาย แอปพลิเคชันของเราซึ่งสามารถแปลงไฟล์เสียงเป็นข้อความในภาษาอังกฤษ ฝรั่งเศส สเปน และอาหรับ เป็นเพียงตัวอย่างหนึ่งของศักยภาพของเทคโนโลยีนี้ เมื่อมีข้อมูลมากขึ้นและความเข้าใจเกี่ยวกับการรู้จำเสียงของเราก็ดีขึ้น เราจึงคาดหวังได้ว่าจะได้เห็นแอปพลิเคชันขั้นสูงยิ่งขึ้นไปอีกในอนาคต

ขอบคุณมากสำหรับการอ่าน!