스크립트의 텍스트 음성 변환

스크립트의 텍스트 음성 변환

현재 저는 텍스트를 음성으로 사용 wine하고 적용하고 있습니다.Windows TTSApp.exe

SAPI-5 음성과 잘 작동하는 GUI 애플리케이션입니다. 텍스트 파일을 선택하고 WAV몇 번의 클릭만으로 파일로 변환하겠습니다.

하지만 나는 또한 다른 일을 하고 싶었습니다.

변환을 위한 명령줄 스크립트를 작성하고 다음과 같이 실행하고 싶습니다.

wine ttsUtil.exe text.txt -voice=nick -output=speech.wav

와인 아래에서 이것이 가능합니까? 제가 가장 좋아하는 사운드는 Windows에서만 실행되기 때문에 와인을 사용해야 합니다. 내 GUI TTSApp.exe 대신 일부 ttsUtil.exe(이름은 중요하지 않음)를 사용하고 싶습니다.

변환할 작은 텍스트 파일 각각을 클릭할 시간이 없기 때문에 이 작업을 자동화해야 합니다.

답변1

내 제안은 와인을 없애고 Linux pico2wave 프로그램을 사용하는 것입니다.

Ubuntu 14.04에서 pico2wave는 libttspico-utils의 일부입니다.

명령은 다음과 같습니다:

pico2wave --wave=test.wav "$(cat filename.txt)"

답변2

가지고 있는 명령이 작동하고 자동화만 하면 된다고 말하면 몇 가지 옵션이 있습니다.

변환하려는 파일 디렉터리가 있는 경우 다음을 수행할 수 있습니다.


#!/bin/bash
ARG=$1

for i in "${ARG}"/* ;
do
wine ttsUtil.exe "${i}" -voice=nick -output="${i}".wav
done

파일로 저장하고(ttsconvert.sh라고도 함) 실행 가능하게 만듭니다.

chmod +x ttsconvert.sh

이제 변환하려는 파일 디렉터리의 경로를 제공하여 스크립트를 실행할 수 있습니다.

./ttsconvert.sh ~/path/to/stash/of/files

파일별로 사용하려면 .desktop 파일을 사용하여 고유한 실행 프로그램을 만들 수 있습니다.

예를 들어 ttsconvert.desktop이라는 파일을 만듭니다.


[Desktop Entry]
Version=0.1
Name=TTSConvert
Exec=wine ttsUtil.exe %U -voice=nick -output=speech.wav
Icon=multimedia-volume-control
MimeType=text/plain;

루트로서 이 파일을 /usr/share/applications에 배치하면 다음을 사용할 수 있습니다.다음으로 열기마우스 오른쪽 버튼 클릭 메뉴의 옵션은 새 변환기를 사용하여 텍스트 파일을 엽니다. 작동 중이라는 사실을 알려주지는 않습니다. GUI 알림을 사용하기 위해 고급 스크립트를 작성할 수 있지만 이것이 모든 작업을 수행할 수 있는 곳은 아닙니다.

답변3

다음과 같은 SAPI5 명령줄 유틸리티를 사용해 보겠습니다.http://www.nirsoft.net/articles/speak_from_command_line.html

또한 다음을 시도해보세요:http://jampal.sourceforge.net/ptts.html

답변4

패치워크이지만 안정적으로 작동하도록 했습니다. Xepyr 창에서 TTSApp.exe를 스크립팅하고 마우스 및 키보드 입력을 시뮬레이션합니다.

Ubuntu 패키지를 설치합니다. xserver-xephyr metacity xdotool libav-tools

기본 말하기 속도 이외의 것을 원하는 경우 각 텍스트 파일의 시작 부분에 다음을 추가 <prosody rate="medium"><prosody rate="+36%">하고 끝에 적절한 종료 단어를 추가하십시오. ( </prosody></prosody>8-9장에 더 많은 XML 옵션이 있습니다.AT&T Natural 음성 시스템 개발자 가이드).

i원하는 음성을 선택하려면 스크립트를 key --delay 100 iTTSApp.exe의 필수 키로 바꾸세요.

변환 성공 후 소스 파일을 삭제하려면 스크립트 끝부분의 unlink() 주석을 제거하세요.

다음을 통해 이 스크립트를 실행하세요.

find . -name 'chapter*.txt' -print0 |xargs -0 txt2ogg

다음은 Perl 스크립트입니다 txt2ogg(잊지 마세요 chmod +x):

#!/usr/bin/perl -CS -w
#
use strict;
use warnings;
use utf8;
#

my $homeDir=$ENV{HOME};
$homeDir .= '/' if(substr($homeDir,length($homeDir)-1,1) ne '/');

my $oldDir = `pwd`;
chomp($oldDir);
$oldDir .= '/' if(substr($oldDir,length($oldDir)-1,1) ne '/');
chdir($homeDir) or die($!);
system( q(Xephyr :4 -screen 600x480 >/dev/null 2>/dev/null &) ); # using the user's display works until you try to get other work done or the screensaver starts
system( q(DISPLAY=:4 metacity >/dev/null 2>/dev/null &) ); # xdotool needs a window manager
foreach(@ARGV) {
  s|^\./||;
  my $thisArg = $_;
  my $ttsIn = $oldDir.$thisArg; # make path absolute
  (my $ttsOut = $ttsIn) =~ s|\.[^\./]*$||; # strip file extension
  $ttsOut .= '.ogg';
  my $attempt = 0;
  my $errorCodes = ""; # list of codes for recoverable errors
  my $closeDialogCmd = q(export DISPLAY=:4; xdotool search --name "File Saved" windowactivate --sync %@ key space 2>/dev/null);
  my $ExitCmd = q(export DISPLAY=:4; xdotool search --name "SAPI5 TTSAPP" windowactivate --sync %@ windowkill 2>/dev/null);
  while(1) {
    print("\r$thisArg ... ");
    unlink("ttsin");
    unlink("ttsout.wav");
    unlink("ttsout.ogg");
    symlink($ttsIn,"ttsin") or die($!);
    #xdotool is sometimes too fast, even with ''--delay 100'', so BackSpace makes sure the full name gets entered
    my $stallLimit = 10;
    my $seconds = 0;
    my $priorWavSize = 0;
    my $stalledTime = 0;
    my $wavSize = 0;
    #start TTSApp.exe in the background
    system( q(DISPLAY=:4 wine "C:\Program Files\eSpeak\TTSApp.exe" 2>/dev/null >/dev/null &) );
    #in TTSApp.exe, enable XML; select proper voice; open "ttsin"; and save as "ttsout.wav"
    system( q(export DISPLAY=:4; xdotool search --sync --name "SAPI5 TTSAPP" windowactivate --sync %@ mousemove --window %@ 36 339 click 1 mousemove --window %@ 426 233 click 1 key --delay 100 i mousemove --window %@ 500 37 click 1 key --delay 100 BackSpace BackSpace t t s i n Return mousemove --window %@ 500 288 click 1 key --delay 100 BackSpace BackSpace t t s o u t Return 2>/dev/null >/dev/null) );
    while(1) { # wait for "File Saved" dialog
      sleep(2);
      $seconds += 2;
      #check if "File Saved" dialog exists yet
      last if(system( q(export DISPLAY=:4; xdotool search --name "File Saved" >/dev/null) ) == 0);
      my $wavSizeCmd = q(stat --printf '%s' ttsout.wav 2>/dev/null);
      $wavSize = `$wavSizeCmd`;
      $wavSize = 0 if(!defined($wavSize) or length($wavSize) == 0);
      if($wavSize <= $priorWavSize) {
        $stalledTime += 2;
        if($stalledTime >= $stallLimit) {
          $errorCodes .= " 282"; # TTSApp.exe not responding
          if(system($ExitCmd) != 0) { # kill TTSApp.exe and try again
            $errorCodes .= " 443"; # TTSApp.exe still not responding
            sleep(2);
            system($ExitCmd);
          }
          last;
        }
      } else {
        $stalledTime = 0;
      }
      $priorWavSize = $wavSize;
      print("\r$thisArg ...$wavSize bytes");
    }
    if(($stalledTime < $stallLimit)) { # above loop not stalled
      if($wavSize == 11639) {
        $errorCodes .= " 639"; # size of .wav is exactly the size for "Enter text you whish spoken here" in the default voice
      } else {
        last; # success
      }
    }
    if($attempt++ >= 5) {
      die("unable to process file with TTSApp.exe");
    }
  }
  #close "File Saved" dialog and exit TTSApp.exe
  if(system($closeDialogCmd) != 0) {
    $errorCodes .= " 934"; # closing dialog failed
    sleep(2);
    if(system($closeDialogCmd) != 0) {
      $errorCodes .= " 818"; # closing dialog failed again
      sleep(2);
      system($closeDialogCmd);
    }
  }
  if(system($ExitCmd) != 0) {
    $errorCodes .= " 245"; # closing TTSApp.exe failed
    sleep(2);
    if(system($ExitCmd) != 0) {
      $errorCodes .= " 871"; # closing TTSApp.exe failed again
      sleep(2);
      system($ExitCmd);
    }
  }
  print("\r$thisArg ... converting to .ogg  ");
  #''-qscale 0'' (24Kbps) has noticable whisper-like overtones and ''1'' (30Kbps) and ''2'' (35Kbps) are quite close, so I decided on ''-qscale 1''
  system('cat ttsout.wav |avconv -i pipe:0 -codec:a libvorbis -qscale 1 ttsout.ogg 2>/dev/null >/dev/null') == 0 or die($!);
  unlink("ttsin");
  unlink("ttsout.wav");
  rename("ttsout.ogg",$ttsOut) or die($!);
  if(length($errorCodes) == 0) {
    print("\r$thisArg ... done                \n");
  } else {
    print("\r$thisArg ... done (recovered from: $errorCodes)            \n");
  }
  #unlink($ttsIn); # delete original only after .ogg is in place
}

관련 정보