Темы



[Из песочницы] Голосовое управление мультимедиа центром

В этой статье хотелось бы описать свой опыт по применению web speech api в браузере Google Chrome для реализации голосового поиска и автоматического воспроизведения видеороликов с канала Youtube. Для демонстрации данного функционала нам понадобиться сделать следующие шаги:

  1. Установить набор: Apache2, PHP5(пакет curl обязательно).
  2. Иметь в наличии мультимедиа центр Dune HD или установить XBMC и настроить его для работы в сети INTERNET.
  3. Получить Youtube API Key для выполнения поисковых запросов.


Как сделать все вышеперечисленное, здесь описывать не буду, так как на эти темы полно статей. Принцип реализации такой:

  1. Распознаем фразу с помощью скрипта, написанного на JavaScript — работать будет только в Google Chrome.
  2. Ищем ролики, соответствующие поисковому запросу.
  3. Получаем прямые ссылки на ролики.
  4. Создаем плейлист из ссылок и названий роликов.
  5. Отправляем плейлист для воспроизведения на устройство.


Топология сети: Internet приходит в wan порт Wi-Fi роутера, а к нему подключаются:

  • устройство, с которого будем управлять (планшет, смартфон, ноутбук).
  • компьютер с web сервером Apache (если управление будет производится с него, то первое устройство может отсутствовать).
  • собственно сам мультимедиа центр (программный — XBMC, или аппаратный — Dune HD).


Скрипт распознавания речи на JavaScript — index.html:


Умный Дом
<script language="javascript" type="text/javascript">
/* Создание нового объекта XMLHttpRequest для общения с Web-сервером */
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}
@end @*/

if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
  xmlHttp = new XMLHttpRequest();
}
</script>




Кликни на микрофон чтобы начать раздавать команды.

Командуй!

Голос не обнаружен.

Микрофон не найден.

Твой браузер не поддерживает Web Speech API.

<script> var start_button = document.getElementById('start_button'), recognizing = false, // флаг идет ли распознование final_transcript = ''; // проверяем поддержку speach api if (!('webkitSpeechRecognition' in window)) { start_button.style.display = "none"; showInfo("info_upgrade"); } else { /* инициализируем api */ /* создаем объект */ var recognition = new webkitSpeechRecognition(); /* базовые настройки объекта */ recognition.lang = 'ru'; // язык, который будет распозноваться. Значение - lang code recognition.continuous = true; // не хотим чтобы когда пользователь прикратил говорить, распознование закончилось /* метод вызывается когда начинается распознование */ recognition.onstart = function() { recognizing = true; showInfo('info_speak_now'); // меняем инфо текст start_button.style.background = 'url(images/mic-animate.gif)'; // меняем вид кнопки }; /* обработчик ошибок */ recognition.onerror = function(event) { if (event.error == 'no-speech') { start_button.style.background = 'url(images/mic.gif)'; showInfo('info_no_speech'); } if (event.error == 'audio-capture') { start_button.style.background = 'url(images/mic.gif)'; showInfo('info_no_microphone'); } }; /* метод вызывается когда распознование закончено */ recognition.onend = function() { recognizing = false; recognition.start(); start_button.style.background = 'url(images/mic.gif)'; showInfo('info_start'); }; /* метод вызывается после каждой сказанной фразы. Параметра event используем атрибуты: - resultIndex - нижний индекс в результирующем массиве - results - массив всех результатов в текущей сессии */ recognition.onresult = function(event) { /* обход результирующего массива */ for (var i = event.resultIndex; i < event.results.length; ++i) { /* если фраза финальная (уже откорректированная) сохраняем в конечный результат */ if (event.results[i].isFinal) { final_transcript += event.results[i][0].transcript.toLowerCase(); } } final_span.innerHTML = final_transcript; var newText2 = final_transcript.replace(/(^\s+|\s+$)/g,''); var url = "/voice_search.php?q=" + encodeURI(newText2); xmlHttp.open("GET", url, true); xmlHttp.send(null); final_transcript = ''; // очищаем рапознанный текст }; } /* показ нужного сообщения */ function showInfo(id) { var messages = document.querySelectorAll('p'); for(i=0; i


Для полноценной работы скрипта, нужно еще создать папку images и положить в неё картинки с микрофончиками, которые можно взять здесь и здесь.

Данный скрипт делает всего два действия — распознает фразу и отправляет её AJAX запросом PHP скрипту. Также необходимо обратить внимание на то, что кодировка во всех скриптах должна быть UTF-8 (если делаете в Windows, то UTF-8 без ВОМ).

Скрипт поиска видео роликов на PHP — voice_search.php:
 video: $id; no mp4-stream.");
            return false;
                        }
 
 
}
   if(isset($_GET['q']) == false or $_GET['q']=="" ) 
        {
                
                        $url = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=голосовое%20управление%20телевизором&type=video&maxResults=10&key=Youtube_API_key";
                
        }
        else 
        {
                $url = "https://www.googleapis.com/youtube/v3/search?part=snippet&q=".urlencode($_GET['q'])."&type=video&maxResults=10&key=Youtube_API_key";
                
        }
 
  $res = json_decode(send_req($url));
  if(isset($res->items) == false or ($res->items)=="" ) 
        {
                $info="похоже что-то пошло не так!";                                                                                                                          
                send_info($info);
        }
        else 
        {
                $res = $res->items;
                //print_r($res);
                $fp = fopen('play_list.m3u', 'w+t');
                $start="#EXTM3U\r\n";
                fwrite($fp, $start);
                foreach ($res as $searchResult) 
                {                       
                        $title=($searchResult->snippet->title);
                        $videoId = ($searchResult->id->videoId) ; 
                        $clip_url = get_video_url($videoId);
                        if(isset($clip_url) == false or $clip_url=="") 
                        {
                                $info="клип не найден!";                                                                                                                              
                                send_info($info);
                        }
                        else 
                        {       
                                $clip="#EXTINF:-1,$title\r\n$clip_url\r\n";
                                fwrite($fp, $clip);
                        }
                }
                fclose($fp);
                $info="плейлист создан";                                                                                                                              
                send_info($info);
                //url для Dune HD 
               $url="http://ip_addr_dune/cgi-bin/do?cmd=start_file_playback&media_url=http://server_ip/play_list.m3u";
              //url для XBMC 
              $url="http://логин:пароль@ip-адрес:8080/jsonrpc?request={"jsonrpc":"2.0","id":"1","method":"Player.Open","params":{"item":{"file":"http://server_ip/play_list.m3u"}}}";
              $curl = curl_init();
              curl_setopt($curl, CURLOPT_URL, $url);
              curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
             $out = curl_exec($curl);
             curl_close($curl);
        }
?>



В данном скрипте в самом конце нужно будет отредактировать $url под настройки вашего мультимедиа центра и удалить лишний, а также исправить текст server_ip на ip адрес вашего Apache сервера и вставить свой Youtube_API_Key. Что происходит здесь: из скрипта распознавания речи сюда приходит текст распознанной фразы, далее с помощью Youtube API v3 производится поиск видео роликов подходящих под поисковой запрос, получив ссылки на ролики, мы пропускаем их через цикл, в котором извлекаются полные пути до видеофайлов, которые и записываются в плейлист play_list.m3u. Данный скрипт не претендует на идеальный код, так как написан чисто в ознакомительных целях, поэтому всевозможные проверки здесь отсутствуют.

Вот и всё, теперь заходим на наш web сервер по его ip адресу. Можно заходить с любого устройства: планшет, смартфон, ноутбук, единственное, что я заметил — в последнее время на смартфонах с Android, скрипт распознавания речи при отсутствии её, отправляет фразу повторно, с чем это связанно пока не понятно, но раньше такого не было.

На основе данного материала можно сделать еще много интересных вещей, таких как голосовой поиск музыки в VK и управления 1-wire устройствами. В общем пробуйте, если что не получится, то спрашивайте с удовольствием отвечу на все ваши вопросы.

P.S.: Статья написана по материалам:

W3C Web Speech API
YouTube api v3

Скрипт получения прямых ссылок взят из приложения YouTube для Dune HD и немного доработан под свои нужды. Для тех, кто хочет просто попробовать управлять мультимедиа центрами, без написания скриптов — можно почитать здесь. Результат моей работы на YouTube

© Habrahabr.ru