Страница 1 из 1

Ожидание окончания фразы

Добавлено: Чт июн 18, 2015 2:49 pm
Mescaline
Добрый день! :)
Мне уже стыдно создавать темы со своими нубо-вопросами, но некоторые моменты работы с системой пока не даются мне, поэтому вновь прошу помощи опытных умельцев...
В общем есть VLC и есть вот такой скрипт, который запускается в обработчике BeforeSay:

Код: Выделить всё

$MusicInfoDataFile = 'http://192.168.12.12:8080/requests/status.xml'; 
$xml_data = simplexml_load_file($MusicInfoDataFile); 
$state=$xml_data->state;
if ($state == "playing") {
    getURL("http://192.168.12.12:8080/requests/status.xml?command=pl_pause",0);
    $file = fopen('\\\192.168.12.12\c$\Program Files\VideoLAN\VLC\lua\http\requests\status.txt',"w");
    fwrite($file, "paused");
    fclose($file);
}
else {
    $file = fopen('\\\192.168.12.12\c$\Program Files\VideoLAN\VLC\lua\http\requests\status.txt',"w");
    ftruncate($file, 0);
    fclose($file);
}
который, проверяет статус воспроизведения и, если он активен, ставит на паузу.
А вот заставить снять с паузы не могу. Точнее могу, но результат мне не нравится. В AfterSay вставил такой код:

Код: Выделить всё

$file = fopen('\\\192.168.12.12\c$\Program Files\VideoLAN\VLC\lua\http\requests\status.txt',"r");
$file_str = fgets($file, "7");
fclose($file);
if ($file_str == 'paused') {
    getURL("http://192.168.12.12:8080/requests/status.xml?command=pl_pause",0);
    $file = fopen('\\\192.168.12.12\c$\Program Files\VideoLAN\VLC\lua\http\requests\status.txt',"w");
    ftruncate($file, 0);
    fclose($file);
}
который работает обратно первому. Проблема в том, что команда SAY не включает в себя само содержание (фразу) и может отличаться по длительности. Поэтому пришлось отказаться от идеи использовать sleep().
Подскажите, как можно заставить Алису сначала сказать то, что она должна, а уже после этого выполнить скрипт AfterSay?

Re: Ожидание окончания фразы

Добавлено: Пт июн 19, 2015 10:38 am
sergejey
Этот вопрос уже как-то поднимался и ответ был таким -- отловить момент окончания воспроизведения фразы сложно. Причина в том, что процедура синтеза речи выполняется в отдельном потоке, чтобы не тормозить выполнение сценария. Я у себя дома обошёлся тем, что в beforeSay снижаю громкость музыки, если она играет, затем расчитываю (приблизительно) время на произнесение фразы и ставлю таймер, чтобы вернуть громкость музыки назад.
КодПоказать

Код: Выделить всё

$ph=$params['ph'];
$level=$params['level'];

if (!$ph || !$level) {
 $ph='тест';
 $level=2;
}

if (!$ph || $level<getGlobal('minMsgLevel') || !getGlobal('VLCPlayer.isPlaying')) {
 //nothing to do
 return;
}

$tmp=explode(' ',$ph);
$total=count($tmp);
$word_delay=3; //пауза на каждое слово 3 секунды

$total_delay=$total*$word_delay;

//$restore_volume=getGlobal('VLCPlayer.Volume');
$restore_volume=256;

$data=getURL(getGlobal('VLCPlayer.URL').'/requests/status.xml?command=volume&val=120',0,getGlobal('VLCPlayer.Username'),getGlobal('VLCPlayer.Password'),0);
setTimeOut('volumeRestore',"getURL(getGlobal('VLCPlayer.URL').'/requests/status.xml?command=volume&val=".$restore_volume."',0,getGlobal('VLCPlayer.Username'),getGlobal('VLCPlayer.Password'),0);",$total_delay);
 

Re: Ожидание окончания фразы

Добавлено: Пт июн 19, 2015 12:59 pm
Mescaline
sergejey писал(а):Этот вопрос уже как-то поднимался и ответ был таким -- отловить момент окончания воспроизведения фразы сложно. Причина в том, что процедура синтеза речи выполняется в отдельном потоке, чтобы не тормозить выполнение сценария. Я у себя дома обошёлся тем, что в beforeSay снижаю громкость музыки, если она играет, затем расчитываю (приблизительно) время на произнесение фразы и ставлю таймер, чтобы вернуть громкость музыки назад.
КодПоказать

Код: Выделить всё

$ph=$params['ph'];
$level=$params['level'];

if (!$ph || !$level) {
 $ph='тест';
 $level=2;
}

if (!$ph || $level<getGlobal('minMsgLevel') || !getGlobal('VLCPlayer.isPlaying')) {
 //nothing to do
 return;
}

$tmp=explode(' ',$ph);
$total=count($tmp);
$word_delay=3; //пауза на каждое слово 3 секунды

$total_delay=$total*$word_delay;

//$restore_volume=getGlobal('VLCPlayer.Volume');
$restore_volume=256;

$data=getURL(getGlobal('VLCPlayer.URL').'/requests/status.xml?command=volume&val=120',0,getGlobal('VLCPlayer.Username'),getGlobal('VLCPlayer.Password'),0);
setTimeOut('volumeRestore',"getURL(getGlobal('VLCPlayer.URL').'/requests/status.xml?command=volume&val=".$restore_volume."',0,getGlobal('VLCPlayer.Username'),getGlobal('VLCPlayer.Password'),0);",$total_delay);
Спасибо за подсказку, изначально я тоже планировал использовать таймер, но в какой-то момент захотелось пойти сложным путем)))
Ну раз уж не получится отследить синтез речи, тогда последний вопрос, поясните вот эту часть кода:

Код: Выделить всё

setTimeOut('volumeRestore',"getURL(getGlobal('VLCPlayer.URL').'/requests/status.xml?command=volume&val=".$restore_volume."',0,getGlobal('VLCPlayer.Username'),getGlobal('VLCPlayer.Password'),0);",$total_delay); 
а точнее 'volumeRestore'. Что это за параметр? А то я в гугле не нашел такой конструкции использования settimeout в PHP, он выдает только по Java :(

Re: Ожидание окончания фразы

Добавлено: Пт июн 19, 2015 1:26 pm
sergejey
settimeout это специфическая для majordomo функция, в стандартном php её нет. сделана по аналогии с javascript.
$restore_volume это переменная, которой присываивается 256 (100% для vlc).

Re: Ожидание окончания фразы

Добавлено: Пт июн 19, 2015 1:51 pm
Mescaline
sergejey писал(а):settimeout это специфическая для majordomo функция, в стандартном php её нет. сделана по аналогии с javascript.
$restore_volume это переменная, которой присываивается 256 (100% для vlc).
Теперь понятно, откуда столько результатов по Java :)
$restore_volume я понял что означает, я просто не могу понять, что за 1-ый аргумент в setTimeOut - volumeRestore. Просто на сайтах по Java (увы, с этим языком я не знаком вовсе) этот метод имеет только два аргумента: код и задержку, а у Вас получается так:

Код: Выделить всё

setTimeOut('volumeRestore',"запрос для изменения громкости",задержка).
У меня в конечном итоге (перед выполнением) это выглядит так:

Код: Выделить всё

setTimeOut('getURL("http://192.168.12.12:8080/requests/status.xml?command=pl_play")',16);
И Алиса ругается на недостающий 3 аргумент (missing argument 3 for setTimeOut () ).

Re: Ожидание окончания фразы

Добавлено: Пт июн 19, 2015 3:11 pm
sergejey
Первый аргумент это название таймера, просто любая уникальная строка -- оно обязательно.

Re: Ожидание окончания фразы

Добавлено: Пт июн 19, 2015 4:39 pm
Mescaline
Все работает, спасибо :)