Monday, October 18, 2010

Про запись разговоров

Тут напишу про шаблон, который постоянно дорабатывается, и которым пользуюсь я.

Это касается записи в очереди, но может быть легко адаптировано к любому случаю

extensions.conf
[macro-QueueRoutine]
exten => s,1,Set(TIMESTAMP=${STRFTIME(${EPOCH},,%T)})
exten => s,n,Set(DATESTAMP=${STRFTIME(${EPOCH},,%Y:%m:%d)})
exten => s,n,Set(DB(${CHANNEL}T)=${TIMESTAMP})
exten => s,n,Set(DB(${CHANNEL}D)=${DATESTAMP})
exten => s,n,Set(MONITOR_FILENAME=${UNIQUEID})
exten => s,n,Set(AUDIOHOOK_INHERIT(MixMonitor)=yes)

exten => h,1,StopMixMonitor
exten => h,n,Set(MEMBERINTERFACE=${CUT(MEMBERINTERFACE,/,2)})
exten => h,n,Set(TIMESTAMP=${DB_DELETE(${CHANNEL}T)})
exten => h,n,Set(DATESTAMP=${DB_DELETE(${CHANNEL}D)})
exten => h,n,GotoIf($[ "x${DATESTAMP}${TIMESTAMP}" != "x"]?DatePresent)
exten => h,n,Set(TIMESTAMP=${STRFTIME(${EPOCH},,%T)})
exten => h,n,Set(DATESTAMP=${STRFTIME(${EPOCH},,%Y:%m:%d)})
exten => h,n(DatePresent),GotoIf($[ "x${CALLERID(num)}" != "x" ]?CIDPresent)
exten => h,n,Set(CALLERID(num)=0000)
exten => h,n(CIDPresent),GotoIf($[ "x${MEMBERINTERFACE}" = "x"]?NoRec)
exten => h,n,System(sh /etc/asterisk/bin/rec.sh /home/superuser/RecordCalls ${DATESTAMP} ${TIMESTAMP} ${CALLERID(num)} ${MEMBERINTERFACE} ${UNIQUEID} I)
exten => h,n,System(rm /var/spool/asterisk/monitor/${UNIQUEID}.wav)
exten => h,n(NoRec),Set(CDR(userfield)=${MEMBERINTERFACE})
exten => h,n,Verbose(Call from 0${CALLERID(num)} was answered by ${MEMBERINTERFACE})


Более доработанный вариант скрипта, для более точного определения ответившего можно сделать, использовав описанное тут

И, собсно, сам скрипт преобразования в mp3
/etc/asterisk/bin/rec.sh

#! /bin/sh

# Recording file script. v0.5
# Arg1 - In/Out removed
# Arg1 - Directory Arg2 - who calles, Arg3 - Answered, Arg4 - Time, Arg5 - Date
# Arg1 - Directory, Arg2 - Date, Arg3 - Time, Arg4 - First number, Arg5 - Second number
# Arg1 - Directory, Arg2 - Date, Arg3 - Time, Arg4 - First number, Arg5 - Second number, Arg6 - Time Attribute
# Arg1 - Directory, Arg2 - Date, Arg3 - Time, Arg4 - First number, Arg5 - Second number, Arg6 - FileName, Arg7 - Time Attribute

MAINDIR="$1"
DATESTAMP="$2"
TIMESTAMP="$3"
FIRSTN="$4"
SECONDN="$5"
FILENAME="$6"
TIMEATTR="$7"

mkdir -p $MAINDIR
mkdir -p $MAINDIR/$DATESTAMP
case $TIMEATTR in
'D')
mkdir -p $MAINDIR/$DATESTAMP/$SECONDN
mkdir -p $MAINDIR/$DATESTAMP/$SECONDN/DayTime
lame /var/spool/asterisk/monitor/$FILENAME.wav $MAINDIR/$DATESTAMP/$SECONDN/DayTime/$TIMESTAMP--$FIRSTN.mp3
chmod 777 $TIMESTAMP--$FIRSTN.mp3
;;
*)
mkdir -p $MAINDIR/$DATESTAMP/$SECONDN
lame /var/spool/asterisk/monitor/$FILENAME.wav $MAINDIR/$DATESTAMP/$SECONDN/$TIMESTAMP--$FIRSTN.mp3
chmod 777 $TIMESTAMP--$FIRSTN.mp3
;;
esac

Суть проста, как угол дома. Файл, который пишет MixMonitor имеет формат ${UNIQUEID}.vaw
После разговора фай, в экстешнене h обрабатывается, как то, выяснение того, кто взял трубку, обработка ошибок на предмет того, что некоторых полей может не быть, вызов скрипта, который жмет в mp3 и удаление wav файла. Поле CDR(userfield) устанавливается для того, чтобы выяснить, какой абонент из очереди взял трубку.

Chmod используется, чтобы пользователи могли удалять файлы из ftp-сервера. Саму политику удаления/записи лучше настроить на самом ftp.

UPD: При трансфере отвеченного звонка лучше сделать доработку: Причем при входящем звонке нужно на канале ставить переменную, чтобы при окончании звонка в случае трансфера можно было определить, что звонок были именно входящий.

exten => h,1,StopMixMonitor
exten => h,n,GoToIf($[ "${LEN(${MONITOR_FILENAME})}" = "0"]?MixMonitorPresent)
exten => h,n,Set(FileName=${MONITOR_FILENAME})
exten => h,n(MixMonitorPresent),GoToIf($[ "${LEN(${SIPREFERREDBYHDR})}" = "0"]?NoTransferDetected)
exten => h,n,Set(FileName=${UNIQUEID})
exten => h,n(NoTransferDetected),Set(AnsweredPeer=${CUT(BRIDGEPEER,/,2)})
exten => h,n,Set(AnsweredPeer=${CUT(AnsweredPeer,-,1)})
exten => h,n,Set(MEMBERINTERFACE=${CUT(MEMBERINTERFACE,/,2)})
exten => h,n,Set(TIMESTAMP=${DB_DELETE(${CHANNEL}T)})
exten => h,n,GotoIf($[ "x${TIMESTAMP}" != "x"]?TimePresent)
exten => h,n,Set(TIMESTAMP=${STRFTIME(${EPOCH},,%T)})
exten => h,n(TimePresent),Set(DATESTAMP=${DB_DELETE(${CHANNEL}D)})
exten => h,n,GotoIf($[ "x${DATESTAMP}" != "x"]?DatePresent)
exten => h,n,Set(DATESTAMP=${STRFTIME(${EPOCH},,%Y:%m:%d)})
exten => h,n(DatePresent),GotoIf($[ "x${CALLERID(num)}" != "x" ]?CIDPresent)
exten => h,n,Set(CALLERID(num)=0000)
exten => h,n(CIDPresent),GotoIf($[ "x${MEMBERINTERFACE}" != "x"]?CheckPickup)
exten => h,n,Set(MEMBERINTERFACE=${DIALEDPEERNUMBER})
exten => h,n(CheckPickup),GotoIf($[ "${MEMBERINTERFACE}" = "${AnsweredPeer}"]?GoRec)
exten => h,n,GoToIf($[ "${LEN(${AnsweredPeer})}" != "3" ]?GoRec)
exten => h,n,Set(MEMBERINTERFACE=${AnsweredPeer})
exten => h,n(GoRec),System(sh /etc/asterisk/bin/rec.sh /home/record  ${DATESTAMP} ${TIMESTAMP} ${CALLERID(num)} ${MEMBERINTERFACE} ${FileName} Q)
exten => h,n(NoRec),System(rm /var/spool/asterisk/monitor/${FileName}.wav)
exten => h,n,Set(CDR(userfield)=${MEMBERINTERFACE})