音声制御マルチメディアセンター

この記事では、Google ChromeブラウザーでWeb Speech APIを使用して音声検索を実装し、Youtubeチャンネルから動画を自動的に再生した経験を説明したいと思います。 この機能を実証するには、次の手順を実行する必要があります。



  1. セットをインストールします:Apache2、PHP5(curlパッケージが必要です)。
  2. Dune HDマルチメディアセンターを使用するか、XBMCをインストールして、インターネットネットワークで動作するように構成します。
  3. Youtube APIキーを取得して、検索クエリを実行します。


これらのトピックに関する多くの記事があるため、上記のすべてを行う方法については説明しません。 実装の原則は次のとおりです。



  1. JavaScriptで記述されたスクリプトを使用してフレーズを認識します。GoogleChromeでのみ機能します
  2. 検索クエリに一致する動画を探しています。
  3. ビデオへの直接リンクを取得します。
  4. リンクとビデオタイトルのプレイリストを作成します。
  5. デバイスで再生するプレイリストを送信します。


ネットワークトポロジ:インターネットはWi-FiルーターのWANポートに到達し、それに接続します。





JavaScript音声認識スクリプト-index.html:
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ru" lang="ru"> <head> <title> </title> <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> <style> * { font-family: Verdana, Arial, sans-serif; font-size: 20px; } a:link { color:#000; text-decoration: none; } a:visited { color:#000; } a:hover { color:#33F; } body { text-align: center; } .button { background: -webkit-linear-gradient(top,#008dfd 0,#0370ea 100%); border: 1px solid #076bd2; border-radius: 3px; color: #fff; display: none; font-size: 13px; font-weight: bold; line-height: 1.3; padding: 8px 25px; text-align: center; text-shadow: 1px 1px 1px #076bd2; letter-spacing: normal; } .final { color: black; padding-right: 3px; } .interim { color: gray; } .info { font-size: 14px; text-align: center; color: #777; display: none; } .sidebyside { display: inline-block; width: 45%; min-height: 40px; text-align: left; vertical-align: top; } #headline { font-size: 40px; font-weight: 300; } #info { font-size: 20px; text-align: center; color: #777; visibility: hidden; } #results { font-size: 14px; font-weight: bold; border: 1px solid #ddd; padding: 15px; text-align: left; min-height: 30px; width: 500px; margin: 0 auto; } #start_button { border: 0; padding: 0; background: url(images/mic.gif); width: 50px; height: 50px; cursor: pointer; vertical-align: top; } #info_speak_now, #info_no_speech, #info_no_microphone, #info_upgrade { display: none; } </style> <meta charset="UTF-8" /> </head> <body> <div id="messages"> <input type="button" id="start_button" onclick="startButton(event);" /> <!--     --> <p id="info_start">      .</p> <p id="info_speak_now">!</p> <p id="info_no_speech">  .</p> <p id="info_no_microphone">  .</p> <p id="info_upgrade">    Web Speech API.</p> </div> <div id="results"> <span id="final_span" class="final"></span> </div> <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<messages.length; i++) messages[i].style.display = 'none'; document.getElementById(id).style.display = 'block'; } /*     */ function startButton(event) { if (recognizing) { //    ,   recognition.stop(); document.getElementById('final_span').innerHTML = ''; return; } recognition.start(); } </script> </body> </html>
      
      







スクリプトを機能させるには、 画像フォルダーを作成し、そこにマイク付きの写真を入れる必要もあります



このスクリプトは2つのことを行います-フレーズを認識し、PHPスクリプトへのリクエストによりAJAXに送信します。 また、すべてのスクリプトのエンコードはUTF-8でなければならないという事実にも注意を払う必要があります(Windowsでエンコードする場合は、VOMなしのUTF-8)。



PHPでビデオクリップを見つけるためのスクリプト-voice_search.php:
 <?php // send info into core function send_info($info) { echo $info; } function send_req($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_REFERER, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); $out = curl_exec($ch); curl_close($ch); return $out; } function get_video_url($videoId) { $url = 'http://www.youtube.com/get_video_info?&video_id='.$videoId.'&asv=3&el=detailpage&hl=en_US'; $first_found = ""; $last_found = ""; $first_quality = ""; $last_quality = ""; //$video_quality = 'medium'; $video_quality = 'hd1080'; $doc=send_req($url); $x=explode("&",$doc); $t=array(); $g=array(); $h=array(); foreach($x as $r) { $c=explode("=",$r); $n=$c[0]; $v=$c[1]; $y=urldecode($v); $t[$n]=$v; } $links = explode(',',urldecode($t['url_encoded_fmt_stream_map'])); $dlinks = array(); foreach ($links as $link) { parse_str($link,$linkarr); $itag = $linkarr['itag']; $quality = $linkarr['quality']; if (in_array($itag, array('18', '22', '37', '38'))) { if(isset($linkarr['s'])) { $linkarr['signature'] = file_get_contents('http://dune-club.info/echo?message=' . $linkarr['s']); unset($linkarr['s']); $dlinks[$linkarr['itag']] = $linkarr['url'] . "&signature=" . $linkarr['signature']; } else { $dlinks[$linkarr['itag']] = $linkarr['url']; $playback_url = $dlinks[$linkarr['itag']]; if ($first_found === "") { $first_found = $playback_url; $first_quality = $quality; } $last_found = $playback_url; $last_quality = $quality; if (($quality === $video_quality) || (($quality !== 'medium') && ($video_quality === 'hdonly'))) { $playback_url=(urldecode($playback_url)); return $playback_url; } } } } if (($last_found !== "") && ($video_quality !== 'hdonly')) { if ($video_quality === 'hd1080') { $first_found=(urldecode($first_found)); return $first_found; } else { $last_found=(urldecode($last_found)); return $last_found; } } else { //hd_print("--> 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=launch_media_url&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を編集して余分な部分を削除し、ApacheサーバーのIPアドレスのserver_ipテキストを修正してYoutube_API_Keyを挿入する必要があります。 ここで何が起こるか:音声認識スクリプトから、認識されたフレーズのテキストがここに来て、Youtube API v3を使用して、検索クエリに一致するビデオがビデオで検索され、ビデオへのリンクを受け取った後、ビデオファイルへのフルパスが抽出されるサイクルを通過しますプレイリストplay_list.m3uに記録されます。 このスクリプトは完全なコードのふりをするものではありません。純粋に情報提供を目的として書かれているため、ここではあらゆる種類のチェックが欠落しています。



以上で、IPアドレスのWebサーバーにアクセスできます。 どのデバイスからでも入力できます:タブレット、スマートフォン、ラップトップ、私が気づいた唯一のもの-最近Android搭載のスマートフォンで、それがない場合の音声認識スクリプトは、フレーズを再度送信します。 。



この資料に基づいて、VKでの音楽の音声検索や1-wireデバイスの制御など、さらに多くの興味深いことができます。 一般に、それがうまくいかない場合は試してみてください、それから喜んで質問してください。



PS:この記事は以下に基づいて書かれています:



W3C Web Speech API

YouTube API v3



直接リンクを取得するためのスクリプトは、Dune HDのYouTubeアプリケーションから取得され、ニーズに合わせて若干変更されています。 スクリプトを作成せずにマルチメディアセンターを管理したい場合は、 ここまたはここで行うことができます。



All Articles