[Freeswitch] TTS on python

Freeswitch 에서 TTS 서비스를 제공하는 방법은 크게 두가지가 있다.

1. Dialplan 에서 해당 모듈을 직접 호출하는 방법.
2. Python, Lua 와 같은 스크립트 모듈에서 호출하는 방법

여기에서는 Python 스크립트 모듈에서 사용하는 방법을 기술한다.

 

mod_tts_commandline 을 사용하는 방법

Freeswitch 에서는 TTS 서비스를 위해 여러가지 모듈들을 제공하는데, 그 중 mod_tts_commandline 모듈은 서버에 설치되어 있는 TTS 프로그램과 연동하여 TTS 서비스를 제공하는 모듈이다 .

먼저 mod_tts_commandline 모듈을 설치하자.

cd /freeswitch/souce/directory
vi 편집기로 modules.conf 파일에서 asr_tts/mod_tts_commandline 부분을 주석 해제하자.
./configure && make && make install

설치가 끝나면, 해당 모듈이 자동 로드될 수 있도록 해주자.

vi /freeswitch/config_directory/conf/autoload_configs/modules.conf.xml
<load module=”mod_tts_commandline”/> 부분을 주석해제해주자.

tts_commandline.conf.xml 파일을 수정해야 한다. 여러가지 명령어 구문들이 가능한데.. 다음은 epseak 를 사용한 예제 명령어 구문이다.

<param name=”command” value=”echo ${text} | espeak –stdin –stdout -v default| sox -t wav – -r ${rate} ${file}”/>

기타 다른 예시 명령어 문구는 https://wiki.freeswitch.org/wiki/Mod_tts_commandline 에서 확인할 수 있다.

이후 Python 스크립트에서 다음과 같이 호출하여 사용하면 된다.

session.set_tts_params("espeak", "default");
session.speak("Hello, world!");

 

mod_shout 를 사용하는 방법

본래, mod_shout 는 외부 자원을 재생시키는 모듈이다. 하지만 이를 이용하면 외부(웹)에서 제공하는 TTS 서비스를 사용할 수 있다.
외부(웹)에서 TTS 를 제공하는 곳은 크게, Bing/Google 이 있는데, 여기서는 Google 을 기준으로 설명한다.

간단하다. mod_shout 설치 후, 다음과 같이 사용하면 된다.

session.streamFile("shout://translate.google.com/translate_tts?tl=en&q=Hello+world", "")
# 혹은...
recvDtmf=session.playAndGetDigits(1, 1, 1, 1, "", "shout://translate.google.com/translate_tts?tl=en&q=Hello+world", "", "", "", 0, "")

 

참조:

https://wiki.freeswitch.org/wiki/Mod_shout

https://wiki.freeswitch.org/wiki/Session_streamFile

https://wiki.freeswitch.org/wiki/Playing_recording_external_media

https://wiki.freeswitch.org/wiki/Mod_tts_commandline

http://wiki.freeswitch.org/wiki/Category:TTS

https://wiki.freeswitch.org/wiki/Mod_lua

[CTI] TTS Service

TTS 란 Text To Speech 의 약자로서, 글자를 소리내어 읽어주는 서비스/프로그램 을 말한다.
흔히 IVR 같은 서비스에서 사용하는데, IVR 서비스 중에서도 정적으로 고정된 멘트(안녕하세요, *** 서비스에 오신것을 환영합니다)가 아닌 동적인 데이터(이름, 예금 잔고, 신용등급 등)를 나타낼 때 사용한다.

CTI 에서 TTS 기능을 사용하는 방법에는 크게 두가지가 있다.

1. 서버 내부에 설치된 TTS 프로그램 기능을 이용하는 방법.
2. 서버 외부에서 제공하는 TTS 서비스를 이용하는 방법.

 

– 서버 내부에 설치된 TTS 프로그램 기능을 이용하는 방법.

리눅스에서 사용가능한 Espeak 같은 프로그램을 예로 들 수 있다. 혹은 상용의 TTS 프로그램도 이에 해당된다.
이 방법을 사용하게 되면 고객에게 양질의 음성 서비스를 제공할 수 있는 장점이 있지만, 직접 서버 내에서 Text 를 음성으로 변조하는 과정을 거쳐야 하기 때문에 Computing Power 가 요구되는 단점도 있다.

 

– 서버 외부에서 제공하는 TTS 서비스를 이용하는 방법

대표적인 예로 구글의 Translate 서비스를 생각할 수 있다. Translate 서비스의 한 부분으로 입력한 문자열을 음성으로 들려주는 서비스이다.
이 방법을 사용하면 서버내의 Computing Power 를 사용하지 않고도 TTS 서비스를 제공할 수 있지만, 고객 데이터가 외부로 노출된다는 점, 트래픽 제한에 걸릴 수도 있다는 점 등의 단점이 있다.

[Asterisk] Defence of brute force attack

Asterisk Server 를 생성하고 계속해서 Brute-force Attack 이 들어왔다.
비록 뚫린 흔적은 발견하지 못했지만 계속해서 들어오는 Brute Force Attack 은 내게 계속해서 “방심하면 뚫린다”라는 긴장감을 주었다..

그래서 그 방지책으로 fail2ban 설정을 찾을 수 있었고, 아래의 내용으로 fail2ban 설정 후, 안심할 수 있었다.

Asterisk 관련 fail2ban 스크립트 설정법

jail2ban.conf

logpath 가 약간 이상하게 잡혀있는데, 이는 Freepbx 를 설치해서 기본 로그 파일 경로가 수정되었기 때문이다.

[asterisk-iptables]

enabled  = true
filter   = asterisk
action   = iptables-allports[name=ASTERISK, protocol=all]
logpath  = /var/log/asterisk/full
maxretry = 5
bantime = 259200
findtime = 8640

 

filter.d/asterisk.conf

# Fail2Ban configuration file
#
#
# $Revision: 250 $
#

[INCLUDES]

# Read common prefixes. If any customizations available -- read them from
# common.local
#before = common.conf


[Definition]

#_daemon = asterisk

# Option:  failregex
# Notes.:  regex to match the password failures messages in the logfile. The
#          host must be matched by a group named "host". The tag "<HOST>" can
#          be used for standard IP/hostname matching and is only an alias for
#          (?:::f{4,6}:)?(?P<host>S+)
# Values:  TEXT
#

# Asterisk 1.4 use the following failregex

failregex = NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Wrong password
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - Wrong password
            NOTICE.* .*: Registration from '.*' failed for '<HOST>:.*' - No matching peer found
            NOTICE.* .*: Registration from '.*' failed for '<HOST>' - No matching peer found
            NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Username/auth name mismatch
            NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Device does not match ACL
            NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Peer is not supposed to register
            NOTICE.* .*: Registration from '.*' failed for '<HOST>' - ACL error (permit/deny)
            NOTICE.* .*: Registration from '.*' failed for '<HOST>' - Device does not match ACL
            NOTICE.* <HOST> failed to authenticate as '.*'$
            NOTICE.* .*: No registration for peer '.*' (from <HOST>)
            NOTICE.* .*: Host <HOST> failed MD5 authentication for '.*' (.*)
            NOTICE.* .*: Failed to authenticate user .*@<HOST>.*
            NOTICE.* .*: Sending fake auth rejection for device .*<sip:.*@<HOST>>;tag=.*
            NOTICE.* .*: Registration from '".*".*' failed for '<HOST>' - No matching peer found
            NOTICE.* .*: Registration from '".*".*' failed for '<HOST>:.*' - No matching peer found
            NOTICE.* .*: Registration from '".*".*' failed for '<HOST>' - Wrong password
            NOTICE.* .*: Registration from '".*".*' failed for '<HOST>:.*' - Wrong password

# In Asterisk 1.8 use the same as above, but after <HOST> add :.* before the single quote. This is because in Asterisk 1.8, the log file includes a port number which 1.4 did not.

# Option:  ignoreregex
# Notes.:  regex to ignore. If this regex matches, the line is ignored.
# Values:  TEXT
#
ignoreregex =

 

출처: http://www.voip-info.org/wiki/view/Fail2Ban+%28with+iptables%29+And+Asterisk

 

 

[Freeswitch] python-bridge

Freeswitch 에서 Python 으로 dialplan 작성시…

Call-Bridge 를 해야 하는 경우..

call_addr = ‘sofia/profile_name/call_to@host_ip’
session.execute(“bridge”, call_addr)

과 같이 입력하면 된다.

Freeswitch Python 모듈에서 제공하는 Transfer 의 경우, 이미 작성되어 있는 Dailplan 으로 넘겨주는 역할밖에 하지 못한다.
즉, 다른 곳으로 전화를 걸어서 그쪽으로 넘겨주는 기능이 아닌 것이다.

가장 대표적인 기능이 음성 사서함에서의 콜백 기능인데, 콜백 기능을 Freeswitch Python 으로 작성할 경우, 위와 같이 작성하면 된다.

만약, Bridge 와 동시(즉, INVITE 시)에 특정 값들을 같이 넘겨 주어야 하는 경우, Originate 와 마찬가지로 call_addr 앞부분에 입력하고자 하는 파라미터 값을 넣어주면 된다.