Hewan peliharaan saya adalah LinguaPlayer

Hari ini, pada hari Jumat, saya ingin berbicara tentang salah satu proyek hewan peliharaan saya, hal-hal menarik apa yang harus saya lakukan saat mengerjakannya dan masalah apa yang tidak dapat saya selesaikan untuk pengembangan lebih lanjut.





Jadi, saya memiliki beberapa proyek hewan peliharaan dengan berbagai tingkat penyelesaian. Diantaranya: jejaring sosial untuk penulis, generator sprite CSS, bot Telegram untuk berkencan berdasarkan minat, dan banyak lagi. Hari ini kita akan berbicara tentang perkembangan terakhir saya.





Seperti banyak orang saat ini, saya sedang belajar bahasa Inggris. Saya pikir banyak orang juga tahu bahwa pendekatan yang efektif dalam hal ini adalah pencelupan maksimum dalam lingkungan. Antarmuka telepon dalam bahasa Inggris, catatan di buku catatan dalam bahasa Inggris, menonton film dalam bahasa Inggris dengan teks bahasa Inggris. Menonton film dalam bahasa aslinya, cepat atau lambat ada kebutuhan untuk menerjemahkan ini atau itu kata atau frase yang berkedip di layar setiap beberapa menit. Tanpa mereka, tidak ada yang jelas sama sekali.





Ide proyek

Jadi saya mendapatkan ide tentang pemutar video dengan teks yang dapat diterjemahkan. Aplikasi ini memungkinkan Anda menerjemahkan kata dan seluruh frasa saat menonton film. Dengannya, tidak perlu beralih antar aplikasi atau mengambil smartphone. Temui LinguaPlayer .





Skema kerjanya sederhana. Pengguna membuka file film dan file subtitle. Tonton filmnya seperti biasa. Namun, sekarang, selain hotkey standar, ia memiliki kunci untuk menerjemahkan setiap kata secara terpisah, menerjemahkan seluruh kalimat, memutar ulang dari satu baris ke baris lainnya. Ada juga terjemahan dengan mengarahkan kursor mouse ke atas kata-kata atau menyorot bagian teks yang diinginkan. Aplikasi ini tersedia untuk Windows dan MacOS. Semua detail dapat ditemukan di halaman aplikasi .





Tumpukan teknologi

Electron, . . Chromium, -. – . Visual Studio Code, Skype, Slack. Electron API, JavaScript, . . – , . JavaScript, Angular, jQuery, Vue – .





LinguaPlayer , : TypeScript, React, MobX, Webpack. , : , . . , , . . , DOM . , , , .





, . — srt- . – , .





 node-webvtt. « ». video- «timeupdate», . , «timeupdate» , . .





hash map. (, ), – , . :





{
	//    2 
	5: [1, 2]
	//    3  
	7: [3, 4, 5]
}
      
      



0 4 — . , , —  hash map. , . , , . 4 , . , :





//  :  ,    ( ),   , 
class Cue {
  public readonly index: number;
  public readonly startTime: number;
  public readonly endTime: number;
  public readonly text: string;

  constructor(index: number, startTime: number, endTime: number, text: string) {
    this.index = index;
    this.startTime = startTime;
    this.endTime = endTime;
    this.text = text;
  }
}

interface CueIndex {
  //      ( )     ,
  //        
  [key: number]: number[];
}

class SubtitlesTrack {
  private readonly cues: Cue[];
  private index: CueIndex = {};

  constructor(cues: Cue[]) {
    this.cues = cues;

    //       ,  
    this.indexCues();
  }

  private indexCues() {
    this.cues.forEach((cue: Cue) => {
      //               
      const startSecond = Math.floor(cue.startTime / 1000);
      const endSecond = Math.floor(cue.endTime / 1000);

      //   (  )  
      this.addToIndex(startSecond, cue);
      // ,      ,         
      //         
      if (endSecond !== startSecond) {
        this.addToIndex(endSecond, cue);
      }
    });
  }

  private addToIndex(secondNumber: number, cue: Cue): void {
    //       ,     
    if (!this.index[secondNumber]) {
      this.index[secondNumber] = [];
    }

    //         
    this.index[secondNumber].push(cue.index);
  }

  //   
  public findCueForTime(timeInSeconds: number): Cue|null {
    //   timeupdate     
    //     
    const flooredTime = Math.floor(timeInSeconds);
    //      
    const cues = this.index[flooredTime];
    let currentCue = null;

    //      
    if (cues) {
      //   
      for (let index of cues) {
        const cue = this.cues[index];

        //  ,             
        if (this.isCueInTime(timeInSeconds, cue)) {
          //  ,        
          currentCue = cue;
          break;
        }
      }
    }

    //     null,      
    return currentCue;
  }

  public isCueInTime(timeInSeconds: number, cue: Cue): boolean {
    const timeInMilliseconds: number = timeInSeconds * 1000;

    return timeInMilliseconds >= cue.startTime && timeInMilliseconds <= cue.endTime;
  }
}
      
      



, , 4 , , 1 4.





 node-sentence-tokenizer. div sentence word , . :





import Tokenizer from 'sentence-tokenizer';

function formatCue(text: string): string {
  const brMark: string = '[br]';
  const tokenizer = new Tokenizer();

  //            
  text = text
    .replace(/\r\n/g, ` ${brMark}`)
    .replace(/\r/g, ` ${brMark}`)
    .replace(/\n/g, ` ${brMark}`);

  //  text    
  tokenizer.setEntry(text);

  //    
  const sentenceTokens: string[] = tokenizer.getSentences();
  //   
  const sentencesHtml: string[] = sentenceTokens.map((sentenceToken: string, index: number) => {
    //    
    const wordTokens: string[] = tokenizer.getTokens(index);
    //    
    const wordsHtml: string[] = wordTokens.map((wordToken: string) => {
      let brTag: string = '';

      //      ,     html   
      if (wordToken.includes(brMark)) {
        wordToken = wordToken.replace(brMark, '');
        brTag = '<br/>';
      }

      //    span   word    br,  
      return `${brTag}<span class="word">${wordToken}</span>`;
    });

    //   ,  ,     span   sentence
    return `<span class="sentence">${wordsHtml.join(' ')}</span>`;
  });

  //     
  const html: string = sentencesHtml.join(' ');

  return html;
}
      
      



 Microsoft Translator  , .





,

, MVP, proof of concept. . , -, Urban Dictionary , . ,  LinguaLeo  Skyeng. .  Anki. .





, , . , , . , – Chromium.   , , H.264 FLAC MP3. , . – . , , .





Jadi, faktor pemblokiran utama saat ini adalah konten. Itu harus dimainkan tanpa masalah dalam aplikasi, itu harus bisa mendapatkannya dengan mudah dan cepat, dan juga, tidak boleh melanggar lisensi dan hak cipta. Segera setelah masalah konten teratasi, saya dengan senang hati akan terus mengerjakan proyek tersebut. Sementara itu, jika ada yang tertarik, Anda dapat  mengunduh dan mencoba  versi konsep aplikasi tersebut.








All Articles