Применение SpeechKit Cloud API для озвучивания погоды и новостей от Yandex

    Добрый день! В данной статье хотелось бы рассказать о том, как можно сделать на сайте «Голосовой погодный и новостной информер», который бы, например при выборе города не только показывал, но и рассказывал фактический прогноз погоды, а так же произвольную новость. На самом деле этот скрипт разрабатывался для информирования в системе «Умный Дом», но может быть с легкостью переделан под любой сайт, имеющий на хостинге поддержку PHP, что и было сделано для этой статьи. В примере для синтеза речи, будет использоваться технология SpeechKit Cloud API от компании Yandex и XML парсер Yandex погоды и новостей, написанные на PHP.

    Что понадобится для реализации:
    • Web сервер с поддержкой PHP (можно локальный типа Денвера).
    • Ключ Yandex SpeechKit (для некоммерческих проектов можно получить бесплатно).
    • Если ключ не дают без наличия у Вас сайта, то создать сайт можно на Hostinger.ru.
    • Список ID городов.

    Данный материал предоставляется исключительно в ознакомительных целях, поэтому процесс установки на сайт и добавления городов, здесь рассматриваться не будет.

    Принцип работы:
    • Отправляем запрос на получение mp3 файла, для выбранного города.
    • Парсим XML файл, получая необходимые параметры.
    • Корректируем окончания слов, для постановки правильного произношения.
    • Устанавливаем параметры генерации mp3 файла (голос, тембр, формат файла, язык, текст).
    • Генерируем mp3 файл.
    • Создаем объект Audio HTML 5 и воспроизводим файл.

    Скрипт с формой для выбора городов index.html
    <!DOCTYPE html>
    <html lang="ru">
    <head>
    <title>Тест SpeechKit Cloud API от компании Yandex.</title>
    <meta charset="utf-8">
    </head>
    <body>
    <script language="javascript" type="text/javascript">
    function Get_Weather()
    {
       var tts_text=document.getElementById('weather').value;
       console.log(tts_text);
    	var response="weather.php?&q="+encodeURI(tts_text); //путь до mp3 файла
    	var audio = document.getElementById("gameMusic");
    		if (audio)
    		{
    			audio.parentNode.removeChild(audio);
    		}
    	
    		// создаём новый элемент audio
    		audio = document.createElement("audio");
    		audio.setAttribute("id", "gameMusic");
    		audio.setAttribute("autoplay", "true");
    		//audio.setAttribute("loop", "false");
    	
    		var mp3 = document.createElement("source");
    		mp3.setAttribute("src", response);
    		mp3.setAttribute("type", "audio/mpeg");
    	
    		audio.appendChild(mp3);
    		audio.play();
    		document.body.appendChild(audio);
    }
    function Get_News()
    {
       var tts_text=document.getElementById('news').value;
       console.log(tts_text);
    	var response="news.php?&q="+encodeURI(tts_text); //путь до mp3 файла
    	var audio = document.getElementById("gameMusic");
    		if (audio)
    		{
    			audio.parentNode.removeChild(audio);
    		}
    	
    		// создаём новый элемент audio
    		audio = document.createElement("audio");
    		audio.setAttribute("id", "gameMusic");
    		audio.setAttribute("autoplay", "true");
    		//audio.setAttribute("loop", "false");
    	
    		var mp3 = document.createElement("source");
    		mp3.setAttribute("src", response);
    		mp3.setAttribute("type", "audio/mpeg");
    	
    		audio.appendChild(mp3);
    		audio.play();
    		document.body.appendChild(audio);
    }
    </script>
    <h1><span>Тест SpeechKit Cloud API от компании Yandex.</span></h1>
    <h2>Погода</h2>
    <select size="1" onclick="Get_Weather();" id="weather"> 
    			 <option disabled>Выберите город</option> 
    			 <option value="27612">Москва</option> 
    			 <option value="34880">Астрахань</option>
    			 <option value="26063">Санкт-Петербург</option>
    			 <option value="25913">Магадан</option>
    </select>
    <h2>Новости</h2>
    <select size="1" onclick="Get_News();" id="news"> 
    			 <option disabled>Выберите город</option> 
    			 <option selected value="Astrakhan">Астрахань</option> 
    				<option  value="Volgograd">Волгоград</option>
    				<option  value="Krasnodar">Краснодар</option>				
    				<option  value="Moscow">Москва</option>
    				<option  value="Saratov">Саратов</option>
    </select>
    </body>
    </html>
    


    Горда можно добавлять путём установки новых параметров option в элементе select.

    Скрипт генерации mp3 файла для погоды weather.php
    <?php
    	 $id=$_GET["q"]; // id города
    	 $url="http://export.yandex.ru/weather-ng/forecasts/".$id.".xml"; // url xml файла 
        $xml = simplexml_load_file($url); // интерпретируем XML-файл в объект
        //параметры:
        $city=$xml['city']; //город
        $temp=$xml->fact->temperature; // температура
        $weather_type=$xml->fact->weather_type; // тип погоды
        $humidity=$xml->fact->humidity; // влажность
        $wind_direction=$xml->fact->wind_direction; // направление ветра
        $wind_speed=$xml->fact->wind_speed; // скорость ветра
        $pressure=$xml->fact->pressure; // давление
           
       
    	$znak="плюс";
    	if($wind_direction=="e") {	$wind_direction_text="восточный";}
    	if($wind_direction=="w") {	$wind_direction_text="западный";}
    	if($wind_direction=="s") {	$wind_direction_text="южный";}
    	if($wind_direction=="n") {	$wind_direction_text="северный";}
    	if($wind_direction=="se") {	$wind_direction_text="юго-восточный";}
    	if($wind_direction=="ne") {	$wind_direction_text="северо-восточный";} 
    	if($wind_direction=="sw") {	$wind_direction_text="юго-западный";}
    	if($wind_direction=="nw") {	$wind_direction_text="северо-западный";} 
    												
    	$minus_arry=preg_match("/(-)/", $temp, $minus_out);
    	if (!empty($minus_out[1]))
    	{ $znak="минус";
    		$temp=str_replace("-","",$temp);
    	}
    							
    	 //градус
      	if(	$temp=="1" or $temp=="21" or $temp=="31" or $temp=="41" or $temp=="51" or $temp=="61" or $temp=="71" or $temp=="81" or $temp=="91" or $temp=="101") 
      	{
      			$text="градус";
      	} 
      	else 
      	{
    	//градуса	
      	if(   $temp=="2"  or $temp=="3"  or $temp=="4"
      			or $temp=="22" or $temp=="23" or $temp=="24" 
      			or $temp=="32" or $temp=="33" or $temp=="34" 
      			or $temp=="42" or $temp=="43" or $temp=="44" 
      			or $temp=="52" or $temp=="53" or $temp=="54"
      			or $temp=="62" or $temp=="63" or $temp=="64" 
      			or $temp=="72" or $temp=="73" or $temp=="74" 
      			or $temp=="82" or $temp=="83"	or $temp=="84" 
      			or $temp=="92" or $temp=="93" or $temp=="94"
      			or $temp=="102" or $temp=="103"
      		) {$text="градуса";} else {$text="градусов";}  											
      						
      	}
      									
      									
      									
      	//процент
      			
      	if(	$humidity=="1" or $humidity=="21" or $humidity=="31" or $humidity=="41" or $humidity=="51" or $humidity=="61" or $humidity=="71" or $humidity=="81" or $humidity=="91" or $humidity=="101") 
      	{
      		$humidity_text="процент";
      	} 
      	else 
      	{
    		//процента	
      		if(   $humidity=="2"  or $humidity=="3"  or $humidity=="4"
      				or $humidity=="22" or $humidity=="23" or $humidity=="24" 
      				or $humidity=="32" or $humidity=="33" or $humidity=="34" 
      				or $humidity=="42" or $humidity=="43" or $humidity=="44" 
      				or $humidity=="52" or $humidity=="53" or $humidity=="54"
      				or $humidity=="62" or $humidity=="63" or $humidity=="64" 
      				or $humidity=="72" or $humidity=="73" or $humidity=="74" 
      				or $humidity=="82" or $humidity=="83" or $humidity=="84" 
      				or $humidity=="92" or $humidity=="93" or $humidity=="94"
      				or $humidity=="102" or $humidity=="103"
      		) {$humidity_text="процента";} else {$humidity_text="процентов";}  											
      								
      	}	
      									
      									
      	 //миллиметр
      	if(	$pressure=="701" or $pressure=="721" or $pressure=="731" or $pressure=="741" or $pressure=="751" or $pressure=="761" or $pressure=="771" or $pressure=="781" or $pressure=="791" or $pressure=="801") 
      	{
      		$pressure_text="милиметр ртутного столба";
      	} 
      	else 
      	{
    		//миллиметра	
      		if(   $pressure=="702" or $pressure=="703" or $pressure=="704"
      				or $pressure=="722" or $pressure=="723" or $pressure=="724" 
      				or $pressure=="732" or $pressure=="733" or $pressure=="734" 
      				or $pressure=="742" or $pressure=="743" or $pressure=="744" 
      				or $pressure=="752" or $pressure=="753" or $pressure=="754"
      				or $pressure=="762" or $pressure=="763" or $pressure=="764" 
      				or $pressure=="772" or $pressure=="773" or $pressure=="774" 
      				or $pressure=="782" or $pressure=="783" or $pressure=="784" 
      				or $pressure=="792" or $pressure=="793" or $pressure=="794"
      				or $pressure=="802" or $pressure=="803"
      			) {$pressure_text="милиметра ртутного столба";} else {$pressure_text="милиметров ртутного столба";}  											
      							
      	}
      	$say_text="Сейчас в городе ".$city." ".$weather_type.". Tемпература воздуха ".$znak." ".$temp." ".$text.". Влажность ".$humidity." ".$humidity_text.". Ветер ".$wind_direction_text." ".$wind_speed." метров в секунду. Атмосферное давление ".$pressure." ".$pressure_text." !";
    	$qs = http_build_query(array("format" => "mp3","lang" => "ru-RU","speaker" => "jane","key" => "SpeechKit_Cloud_API_Key","emotion" => "good", "text" => $say_text)); // параметры запроса
    	$ctx = stream_context_create(array("http"=>array("method"=>"GET","header"=>"Referer: \r\n")));
    	$soundfile = file_get_contents("https://tts.voicetech.yandex.net/generate?".$qs, false, $ctx); // запрос на генерацию mp3 файла
     	echo($soundfile);
    ?>
    


    В скрипте нужно изменить SpeechKit_Cloud_API_Key на полученный Вами ключ.
    Скрипт генерации mp3 файла для новостей news.php
    <?php
    $city=$_GET['q'];
    	 
    $data_file="http://news.yandex.ru/".$city."/index.rss"; // адрес xml файла 
    $xml = simplexml_load_file($data_file); // раскладываем xml на массив
    
    $number= rand(1,13); //генерируем порядковый номер новости
    
    $news=$xml->channel->item[$number]->description; //новость
    $title=$xml->channel->item[$number]->title; //заголовок
        
    
    $content_news = trim(preg_replace('/\s{2,}/', ' ', $news));//удаляем весь хлам
    $content_title = trim(preg_replace('/\s{2,}/', ' ', $title));//удаляем весь хлам
    
    $text=$content_title." - ".$content_news;
    $search = array('"','"',' ',')','(');
    $replace   = array('');
    
    $text = str_replace($search, $replace, $text);
    $qs = http_build_query(array("format" => "mp3","lang" => "ru-RU","speaker" => "jane","key" => "SpeechKit_Cloud_API_Key","emotion" => "good", "text" => $text)); // параметры запроса
    $ctx = stream_context_create(array("http"=>array("method"=>"GET","header"=>"Referer: \r\n")));
    $soundfile = file_get_contents("https://tts.voicetech.yandex.net/generate?".$qs, false, $ctx); // запрос на генерацию mp3 файла
    echo($soundfile);    
    ?>
    



    В скрипте нужно изменить SpeechKit_Cloud_API_Key на полученный Вами ключ. Данную технологию можно также использовать и для озвучивания даты и времени. Есть возможность изменять язык, тембр, голоса (мужские и женские), описание всех параметров синтеза речи можно посмотреть по ссылке на SpeechKit Cloud API которая находится ниже.
    Приведенные выше скрипты, тестировались в браузерах Google Chrome и Iceweasel, но должны корректно работать и в других браузерах с поддержкой HTML 5 Web Audio.

    P.S. Используемая литература


    Публикация Яндекс.ТвояПогода
    Погода от Yandex
    Новости от Yandex
    SpeechKit Cloud API
    Проверить работу SpeechKit Cloud API можно тут. Посмотреть на Youtube, что получилось (пример в начале 7-ой минуты — синтез речи с помощью RHVoice ).

    Написанный код не претендует на идеальность и его всегда можно доработать.
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 4

    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.