<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:series="http://organizeseries.com/"
	>

<channel>
	<title>河合良哉 &#8211; HTML5Experts.jp</title>
	<atom:link href="/ryoyakawai/feed/" rel="self" type="application/rss+xml" />
	<link>https://html5experts.jp</link>
	<description>日本に、もっとエキスパートを。</description>
	<lastBuildDate>Sat, 07 Jul 2018 03:14:05 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.19</generator>
	<item>
		<title>進化を続けるChrome DevToolsの最新情報 2017 ──Google I/O 2017 セッションレポート</title>
		<link>/ryoyakawai/23548/</link>
		<pubDate>Fri, 09 Jun 2017 01:01:10 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>

		<guid isPermaLink="false">/?p=23548</guid>
		<description><![CDATA[連載： Google I/O 2017特集 (2)この記事は2017年5月17、18、19日に米国カリフォルニア州マウンテンビューにあるAmphitheatreで行われたGoogleの開発者向けカンファレンスGoogle...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google-io-2017/" class="series-450" title="Google I/O 2017特集" data-wpel-link="internal">Google I/O 2017特集</a> (2)</div><p>この記事は2017年5月17、18、19日に米国カリフォルニア州マウンテンビューにあるAmphitheatreで行われたGoogleの開発者向けカンファレンスGoogle I/Oの3日目に「DevTools: State of the Union 2017」というタイトルで行われたセッションの内容です。</p>

<h1>はじめに</h1>

<p>Google I/O、Chrome Dev Summitと日に日に進化をし続けているChromeのDevTools。Google I/O 2017でも多くの進化が報告されました。</p>

<p>登壇者はwebっ子ならば泣く子も黙るDeveloper AdvocateのPaul Irish。軽快なトークで淡々と新機能が話された40分をまとめてみました。</p>

<p><img src="/wp-content/uploads/2017/05/PaulIrish.png" alt="" width="400" class="aligncenter size-full wp-image-23550" srcset="/wp-content/uploads/2017/05/PaulIrish.png 640w, /wp-content/uploads/2017/05/PaulIrish-300x210.png 300w, /wp-content/uploads/2017/05/PaulIrish-207x145.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h1>ConsoleでのDebug</h1>

<p>ConsoleはDebugには欠かせない機能。なので、我々はConsoleの進化に対して投資を惜しまず、かつ、楽しんで行っています。</p>

<h3>Object Preview</h3>

<p>今までも、ConosleでObjectの値の閲覧は可能でしたが、要素要素でクリックしないと内容の閲覧はできませんでした。それを解消しました。</p>

<p><img src="/wp-content/uploads/2017/05/ObjectPreview00.png" alt="" width="640" class="aligncenter size-full wp-image-23561" srcset="/wp-content/uploads/2017/05/ObjectPreview00.png 640w, /wp-content/uploads/2017/05/ObjectPreview00-300x178.png 300w, /wp-content/uploads/2017/05/ObjectPreview00-207x123.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>旧表示が左側、現在Canaryでの表示は右側のような表示になっています。</p>

<h3>Autocomplete</h3>

<p>開発者の皆さんにはConsoleでの作業はできるだけ素早く、ストレスなく行ってもらいたいと思っています。ですので、Consoleでは常にAutocompleteがされるようになっています。</p>

<p><img src="/wp-content/uploads/2017/05/Autocmplete-1.png" alt="" width="640" class="aligncenter size-full wp-image-23564" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/Autocmplete-1.png 640w, /wp-content/uploads/2017/05/Autocmplete-1-300x194.png 300w, /wp-content/uploads/2017/05/Autocmplete-1-207x134.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>例えば、<code>document.head.childNodes</code>の内容を参照したい場合、<code>document.head</code>の要素が何であるかをDevToolsは知っているので<code>childNodes</code>など要素名をサジェストをすることもできましたし、続けて例えば0番目の要素にアクセスをするために<code>document.head.childNodes[0]</code>と入力して内容を参照することも可能でした。</p>

<p>しかし、その先はどうでしょう。今までですと、続けて<code>.</code>を入力して<code>document.head.childNodes[0].</code>とし、その要素を参照しようとしても表示されずにエラーとなっていました。しかし、現在では要素へのアクセスも可能で、もちろん要素名もサジェストしてくれます。</p>

<p>そして、例えば要素名に「-(ダッシュ)」が入っているObject。今までであれば<code>classes[</code>まで入力してもサジェストは表示されなかったのですが、現在ではサジェストされるようになっています。</p>

<p><img src="/wp-content/uploads/2017/05/classes.png" alt="" width="640" class="aligncenter size-full wp-image-23582" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/classes.png 640w, /wp-content/uploads/2017/05/classes-300x132.png 300w, /wp-content/uploads/2017/05/classes-207x91.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>Consoleへ直接コードを入力する場合の便利機能</h3>

<p>ObjectをMapに変換する場合、Consoleへキーボードから入力するだけで変換可能になりました。</p>

<p><img src="/wp-content/uploads/2017/05/Screen-Shot-2017-05-29-at-9.21.32-PM.png" alt="" width="600" class="aligncenter size-full wp-image-23577" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/Screen-Shot-2017-05-29-at-9.21.32-PM.png 640w, /wp-content/uploads/2017/05/Screen-Shot-2017-05-29-at-9.21.32-PM-300x73.png 300w, /wp-content/uploads/2017/05/Screen-Shot-2017-05-29-at-9.21.32-PM-207x50.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>また、コードを直接Consoleへ入力する場合、今までは1行で入力する必要がありましたが現在では改行もコードの一部として受け付けるようになりました。インテント、さらには、Syntaxのハイライトもつくようになりました。この機能は去年まではありませんでした。</p>

<p><img src="/wp-content/uploads/2017/05/Console_Indent.png" alt="" width="400" class="aligncenter size-full wp-image-23575" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/Console_Indent.png 640w, /wp-content/uploads/2017/05/Console_Indent-300x154.png 300w, /wp-content/uploads/2017/05/Console_Indent-207x106.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>また<code>⌘</code>キー（<code>Ctrl</code>キー） + <code>D</code>キー で同一の引数を一挙に変更可能です。</p>

<p><img src="/wp-content/uploads/2017/05/command_d.png" alt="" width="600" class="aligncenter size-full wp-image-23585" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/command_d.png 640w, /wp-content/uploads/2017/05/command_d-300x92.png 300w, /wp-content/uploads/2017/05/command_d-207x64.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>非同期（Asynchronous）なJavaScriptのDebugに対応した新機能</h3>

<p>例えば、非同期処理のPromisesのDebugはとても難しかった。しかし現在では下の図のように、例えばCallStackには4つのCo-Frameがありそのうち2つは非同期の処理がある、ということを容易に把握することが可能です。ここで重要なのは、どのように動作したかを目で確認できることです。</p>

<p><img src="/wp-content/uploads/2017/05/promises.png" alt="" width="600" class="aligncenter size-full wp-image-23587" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/promises.png 640w, /wp-content/uploads/2017/05/promises-300x167.png 300w, /wp-content/uploads/2017/05/promises-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>ここでの例は非常に短いサンプルの紹介ですのでシンプルですが、実際のアプリではもっと複雑です。例えば下の図のような形です。</p>

<p><img src="/wp-content/uploads/2017/05/LongCallStack.png" alt="" width="550" class="aligncenter size-full wp-image-23589" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/LongCallStack.png 640w, /wp-content/uploads/2017/05/LongCallStack-300x219.png 300w, /wp-content/uploads/2017/05/LongCallStack-207x151.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>先程も述べた通りでここで重要なのは「どのように動作したかを目で確認できること」で、このように長いStackにおいても、どのように処理が流れになっていることがパッと見で分かります。</p>

<p>ブラウザのアプリの処理は<code>setTimeout()</code>、<code>requestAnimationFrame()</code>、<code>Promises</code>などの非同期処理が連なっている同期処理の塊によって成り立っている。例えば、つい最近新たに発表されたReact Fiberのアルゴリズムは大きな処理の塊を小さな塊に分割するように設計されています。</p>

<p>これがあるスクリプトの非同期処理の0.25秒間をどう動作したか表している図です。矢印が非同期処理の流れを示しています。非常に忙しいスクリプトです。</p>

<p><img src="/wp-content/uploads/2017/05/asyncdiagram_busy.png" alt="" width="550" class="aligncenter size-full wp-image-23591" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/asyncdiagram_busy.png 640w, /wp-content/uploads/2017/05/asyncdiagram_busy-300x191.png 300w, /wp-content/uploads/2017/05/asyncdiagram_busy-207x132.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>見ての通りDevToolsでは非同期処理から次に何が起こっているかを表示することも可能です。特定の呼び出しから、次はどこの処理に遷移したのかを知ることはとても重要です。</p>

<p>これを手動で調査するとなると、とても時間がかかりますが、DevToolsを使えば、この図を見るだけで把握が可能です。DevToolsでは全ての非同期の処理を記録しているので、ページロード時からの全ての非同期処理を追うことができています。</p>

<p>これによって、プログラムのどこのポイントにおいても非同期処理の履歴を完全に追うことが可能になり、どのように到達したのか、またなぜ到達したのかを知ることが可能になっています。</p>

<h3>AsyncのDebug</h3>

<p>BreakPointを1つ1つ使って進むDebugもよく行いますが、あまり効率的ではないです。これがリアルタイムにできるようになっています。</p>

<p>例えば、<code>console.log('Processing')</code>にBreakPointを置き、<code>⌘</code>キー（または<code>Ctrl</code>キー）を押すと次にジャンプできる箇所を青色でハイライトします（下図：左）。そしてそれらの1つをクリックすることでそこまで進めることができ、さらにそこでプログラムの動作は停止します。</p>

<p>もちろん、直前の<code>result</code>の内容も見ることができる（下図：右）。</p>

<p><img src="/wp-content/uploads/2017/05/awaitDebug-1.png" alt="" width="640" class="aligncenter size-full wp-image-23601" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/awaitDebug-1.png 640w, /wp-content/uploads/2017/05/awaitDebug-1-300x183.png 300w, /wp-content/uploads/2017/05/awaitDebug-1-207x126.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>PromisesのDebug</h3>

<p>Promiseの処理の中にインラインでBreakPointを置くことが可能になりました。<br />
14行目にBreakPointを置くと、<code>result</code>の値が何であったかの確認もすぐにできるようになっています。</p>

<p><img src="/wp-content/uploads/2017/05/Promise_breakpoint.png" alt="" width="640" class="aligncenter size-full wp-image-23603" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/Promise_breakpoint.png 640w, /wp-content/uploads/2017/05/Promise_breakpoint-300x195.png 300w, /wp-content/uploads/2017/05/Promise_breakpoint-207x135.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>さらに、これをもっと簡単に実現しています。<br />
先ほどと同じく<code>⌘</code>キー（または<code>Ctrl</code>キー）を押すと青いハイライトと緑色のハイライトが出てきました。「その行にジャンプできる」という意味では同じですが非同期処理であることを示しています。これをクリックすることで非同期処理の内側で処理を停止することが可能です。</p>

<p><img src="/wp-content/uploads/2017/05/BlueGreen.png" alt="" width="600" class="aligncenter size-full wp-image-23605" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/BlueGreen.png 640w, /wp-content/uploads/2017/05/BlueGreen-300x196.png 300w, /wp-content/uploads/2017/05/BlueGreen-207x135.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>Performance Panel</h3>

<p>パフォーマンスを測定するときは、Profiles Panel、Timeline Panel、Network Panelの3つもしくは組み合わせで使っていると思います。このように、ツールが分散しているのが現状ですが、実際のところはJavaScriptのダウンロードが終ってからいつメインスレッドでの動作につながるか、</p>

<p>つまりブラウザのパフォーマンスを見たいはずです。動作と動作の接続されている箇所、例えばJavaScriptの実行完了後、ブラウザはレイアウトを計算し表示するのがいつなのか見られるのがとても重要。ですので、これらを1つのタイムラインで並列に並べて1度に見られるPerformance Panelを作りました。</p>

<p><img src="/wp-content/uploads/2017/05/PerformancePanel.png" alt="" width="640" class="aligncenter size-full wp-image-23608" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/PerformancePanel.png 640w, /wp-content/uploads/2017/05/PerformancePanel-300x167.png 300w, /wp-content/uploads/2017/05/PerformancePanel-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Profile Panelを使ってJavaScriptの開発をしていた方は、Mainスレッドを広げることでどの時間に何が処理されているのか見ることが可能です。下のペインの&#8221;Bottom-Up&#8221;のタブが全ての処理でどれだけ時間がかかったかを表す&#8221;Self Time&#8221;の列でソートされて表示されます。</p>

<p><img src="/wp-content/uploads/2017/05/Profile_Pane.png" alt="" width="640" class="aligncenter size-full wp-image-23612" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/Profile_Pane.png 640w, /wp-content/uploads/2017/05/Profile_Pane-300x158.png 300w, /wp-content/uploads/2017/05/Profile_Pane-207x109.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>セッションではこの機能を実際にNestのホームページを使って紹介していますのでぜひご覧になってください。（<a href="https://youtu.be/PjjlwAvV8Jg?t=19m46s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Nestのホームページを使ったPerformance Panelの解説</a>）</p>

<p><a href="https://youtu.be/PjjlwAvV8Jg?t=19m46s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2017/05/YouTubeNest.png" alt="" width="640" class="aligncenter size-full wp-image-23609" style="border:1px solid #dddddd" /></a></p>

<h3>Coverage Profiler</h3>

<p>最も速いコードは実は動いていないコード、またそれより速いのはダウンロードすらされていないコード。そこで、何が実際に操作しているのかを何とかして提供することはできないかと考えた。そして実装したのがCoverage Profilerです。</p>

<p><img src="/wp-content/uploads/2017/05/CoverageProfiler00.png" alt="" width="640" class="aligncenter size-full wp-image-23615" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/CoverageProfiler00.png 640w, /wp-content/uploads/2017/05/CoverageProfiler00-300x174.png 300w, /wp-content/uploads/2017/05/CoverageProfiler00-207x120.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Coverage Panelはここから開きます（下図：左）。</p>

<p><img src="/wp-content/uploads/2017/05/CoveragePanel.png" alt="" width="640" class="aligncenter size-full wp-image-23616" style="border:1px solid #dddddd" /></p>

<p>CSSを見てみます（上図：右）。サイトで使われている部分は緑、使われていない部分は赤で表示される。赤はCSSもJavaScriptでも現在のページで使われていない部分なので、動作させることで青に、つまり動作した部分はリアルタイムに反映される。</p>

<p>ユーザにとっては赤色になるByteは不要なのでを送らないようにしましょうね。</p>

<h3>3rd Party Attribution</h3>

<p>Consoleで<code>⌘</code>キー（または<code>Ctrl</code>キー）+<code>Shift</code>キー+<code>p</code>キーを押し、<code>Show third party badges</code>と入力して、一度Enterをします（下図：右）。その後にNetwork Panel等を開くと、Networkリクエスト左側にバッジが表示されます。（下図：左）このバッジが 3rd Party Attribution です。このバッジ内の文字列は3rd Partyの名称のイニシャルです。例えば「GA」ならGoogle Analytics。</p>

<p><img src="/wp-content/uploads/2017/05/CommandShiftP.png" alt="" width="640" class="aligncenter size-full wp-image-23626" style="border:1px solid #dddddd" /></p>

<p>Consoleのエラー等の表示にもバッジが表示されるようになっているので、エラー、警告等のConsole出力がどこの誰のスクリプトに由来しているかをひと目で確認できるようになりました（下図：下）。また、Performance Panelのタイムラインでは3rd Partyはグループとしてまとめて表示されるようになっています（下図：上）。</p>

<p><img src="/wp-content/uploads/2017/05/3rdParty.png" alt="" width="600" class="aligncenter size-full wp-image-23632" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/3rdParty.png 559w, /wp-content/uploads/2017/05/3rdParty-262x300.png 262w, /wp-content/uploads/2017/05/3rdParty-181x207.png 181w" sizes="(max-width: 559px) 100vw, 559px" /></p>

<h3>Authoring</h3>

<h4>Cookie Edithing</h4>

<p>Cookieの編集がDevToolsで可能になりました。</p>

<p><img src="/wp-content/uploads/2017/05/CookieEditing.png" alt="" width="640" class="aligncenter size-full wp-image-23637" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/CookieEditing.png 640w, /wp-content/uploads/2017/05/CookieEditing-300x169.png 300w, /wp-content/uploads/2017/05/CookieEditing-207x117.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>Change Tracking</h4>

<p>DevTools上で変更した箇所をファイルごとにdiff（差分ファイル）として全ての変更を提供することが可能になりました。まだExperimentalです。（セッションでは月曜日、そらく5月22日の月曜日、って言ってるけどまだ使えないっぽい？）</p>

<p><img src="/wp-content/uploads/2017/05/ChangeTracking.png" alt="" width="640" class="aligncenter size-full wp-image-23638" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/ChangeTracking.png 640w, /wp-content/uploads/2017/05/ChangeTracking-300x167.png 300w, /wp-content/uploads/2017/05/ChangeTracking-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>Screenshot</h4>

<p>モバイルデバイスのフレームも入れたスクリーンショットも撮れるようになりました。</p>

<p><img src="/wp-content/uploads/2017/05/ScreenShot01.png" alt="" width="640" class="aligncenter size-full wp-image-23642" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/ScreenShot01.png 640w, /wp-content/uploads/2017/05/ScreenShot01-300x156.png 300w, /wp-content/uploads/2017/05/ScreenShot01-207x107.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>さらにフルサイズのスクリーンショットも撮れるようになりました。撮り方は<code>⌘</code>キー+<code>Shift</code>キー+<code>p</code>キーを入力し&#8221;Capture full size screenshot&#8221;と入力し<code>Enter</code>。（&#8221;Capture Screen Shot&#8221;はブラウザウインドウサイズの画像）</p>

<p><img src="/wp-content/uploads/2017/05/ScreenShot.png" alt="" width="640" class="aligncenter size-full wp-image-23640" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/ScreenShot.png 640w, /wp-content/uploads/2017/05/ScreenShot-300x66.png 300w, /wp-content/uploads/2017/05/ScreenShot-207x46.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>Breakpoint Resolving</h4>

<p>Breakpointを置いて、例えばそれより若い行に変更を加えた場合、Breakpointは消えてしまっていましたが、DevToolsではBreakpointを置いた行番号が動く変更がされたとしても、出来る限り追従することが可能になりました。</p>

<p>大きな変更が入った場合は恐らく追従できません。Best Effortでの追従ですのでご了承ください。</p>

<h4>Auditing</h4>

<p>LightHouseはChrome Extention、コマンドライン、Node.jsのモジュールで提供されているwebページの質の向上を上げる、サイトのインサイトを見るためのツールです。私はこのプロジェクトにいます。
多くの形式で提供されていますが、DevToolsから実行はできませんでした。これがDevToolsに組み込まれたらとてもよいです。ということで実装しました。</p>

<p>DevToolsを開き、Audiotsのタブを表示します。すると、ここでLighthouseが実行できるようになっています。Nexus5Xをエミュレートして、ネットワークの速度、CPUの速度の調節して計測しています。ページのロードのパフォーマンス、その他にも多くの計測を行ったり、PWAのアプリとしてどうかという計測等を行って結果を出します。</p>

<p>DevToolsですので、Lighthouseで表示結果の中で、指摘された場所をダイレクトに示すことができる。LightHouseとDevToolsの連携したことでwebサイトのインサイトを見る強力なツールになっています。</p>

<p><img src="/wp-content/uploads/2017/05/LightHouseTool.png" alt="" width="600" class="aligncenter size-full wp-image-23646" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/LightHouseTool.png 640w, /wp-content/uploads/2017/05/LightHouseTool-300x210.png 300w, /wp-content/uploads/2017/05/LightHouseTool-207x145.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>セッションでは実際に<a href="https://www.chromeexperiments.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chrome Experiments</a>を使ってデモをしていますのでぜひ御覧になってください。
（<a href="https://youtu.be/PjjlwAvV8Jg?t=33m" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Chrome Experimentsのページを使ったDevToolsに統合されたLightHouseのデモ</a>）</p>

<p><a href="https://youtu.be/PjjlwAvV8Jg?t=33m" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2017/05/LightHouseIntegration.png" alt="" width="640" class="aligncenter size-full wp-image-23644" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/LightHouseIntegration.png 640w, /wp-content/uploads/2017/05/LightHouseIntegration-300x170.png 300w, /wp-content/uploads/2017/05/LightHouseIntegration-207x117.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h3>Headless Chrome</h3>

<p>画面を表示しない（Headless）C
hromeを使うことで、異なった複数のセッティングでの自動検査を行うツール等を作ることができる。例えば、テキスト抽出、スクリーンショット、PDF生成、リグレッションテスト、ユニットテスト、インテグレーションテスト、セキュリティテスト、サーバサイドでのレンダリングなどの検査です。</p>

<p>Chromeチームではそういったシナリオを実現させたかったので現在使えるようになっています。Linux、macOS、Windows（60で対応）で動作可能です。Seleniumへも対応中です。<br />
現状は低レイヤーのAPIしかありませんが、今後高レイヤーのAPIも実装されます。</p>

<p><a href="https://developers.google.com/web/updates/2017/04/headless-chrome" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Eric BidelmanがHeadless Chromeについて書いたブログポスト</a>（<a href="https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">日本語版</a>）がありますのでそちらもご確認ください。</p>

<p><img src="/wp-content/uploads/2017/05/headless_Chrome.png" alt="" width="640" class="aligncenter size-full wp-image-23654" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/headless_Chrome.png 640w, /wp-content/uploads/2017/05/headless_Chrome-300x131.png 300w, /wp-content/uploads/2017/05/headless_Chrome-207x90.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>Node.js</h4>

<p>去年Node.jsもDevToolsでDebug、Profileを出来るようになりました。ブラウザとNode.jsに多くの時間を使うのでとてもよいことです。ここ2年で進化したNode.jsを、私がLightHouseのプロジェクトで行っているDebug方法で実際にお見せします。</p>

<p>セッションでの実際のデモへのリンクです。併せてご覧になると分かりやすいと思います。</p>

<p><a href="https://youtu.be/PjjlwAvV8Jg?t=37m27s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">デモ動画</a>
<a href="https://youtu.be/PjjlwAvV8Jg?t=37m27s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2017/05/NodeYouTube.png" alt="" width="640" class="aligncenter size-full wp-image-23658" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/NodeYouTube.png 640w, /wp-content/uploads/2017/05/NodeYouTube-300x203.png 300w, /wp-content/uploads/2017/05/NodeYouTube-207x140.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>以下のコマンドをTerminalから入力して始めますが重要なのは<code>--inspect-brk</code>の部分です。次に出力されるURLをコピーして表示することも可能ですが、よりよい方法があります。</p>

<p><code>
$ node --inspect-brk lighthouse-cli --pref http://example.com;/
</code></p>

<p>Chromeのアドレスバーに<code>about:inspect</code>と入力して &#8220;Open decicated DevTols for Node&#8221; のリンクをクリックします。するとNode.jsにのみ接続されている専用のDevToolsのウィンドウが表示されます。もちろんこのウィンドウ内でもDevToolsの全ての機能が利用可能です。</p>

<p>このNode.js専用DevToolsを開くもう1つのよりよい方法です。<br />
DevToolsを開いておき先ほどと同じコマンドを入力します。</p>

<p>そして、DevToolsを見るとInspect ElementのアイコンのとなりにNode.jsのアイコンが現れます。このアイコンをクリックすることで先ほどと同じNode.js専用DevToolsを表示することが可能です。このNode.js専用DevToolsの良いところは、Debugをして再起動したとしても、Node.js専用DevToolsを再起動する必要がないところ。</p>

<p><img src="/wp-content/uploads/2017/05/node_debug.png" alt="" width="640" height="304" class="aligncenter size-full wp-image-23657" style="border:1px solid #dddddd" srcset="/wp-content/uploads/2017/05/node_debug.png 640w, /wp-content/uploads/2017/05/node_debug-300x143.png 300w, /wp-content/uploads/2017/05/node_debug-207x98.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h1>まとめ</h1>

<p>たくさんの新しい機能を説明してきました。<br />
Twitter、定期的に更新しているドキュメント、バグの報告＆フィードバック＆機能追加のリクエストを行うリンクは以下になります。</p>

<ul>
<li>Twitter: <a href="https://twitter.com/ChromeDevTools" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@ChromeDevTools</a></li>
<li>Docs: <a href="https://devtools.chrome.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">devtools.chrome.com</a></li>
<li>File bugs &amp; give feedback: <a href="https://new.crbug.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">new.crbug.com</a></li>
</ul>

<p>ありがとうございました！</p>

<h1>おわりに</h1>

<p>今回も開発者視点で欲しい機能がたくさん追加されました。ブラウザであるはずのChromeですが、DevToolsだけに注目すると「ブラウザっていうか、どちらかというと開発ツールだよね？」と思う（もちろん良い意味で）ことも少なくありません。今までに磨きをかけて更にwebの開発をまたスピードアップできるのではないでしょうか？</p>

<p>セッションの中でPaul Irishは「ユーザからの声が多かった◯◯の機能」「◯◯の開発の手順（ワークフロー）を考えるとこの機能は重要で…」というように常に開発者視点に立った上で機能の追加を行ってくださっていますので、</p>

<ul>
<li>こんなツールがDevToolsに欲しい</li>
<li>こういった開発の手順を考えるとこの機能はDevToolsに欲しい</li>
</ul>

<p>などをフィードバックすることで、もしかしたらその機能が本当に実装されるかもしれませんので、要望のある方はぜひ上記のURLよりフィードバック、バグ報告等を行ってください!</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2017特集]]></series:name>
	</item>
		<item>
		<title>Progressive Web Appで実現する動画アプリの最新テクニック ──Google I/O 2017 セッションレポート</title>
		<link>/ryoyakawai/23440/</link>
		<pubDate>Wed, 31 May 2017 01:00:16 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O 2017]]></category>
		<category><![CDATA[Progressive Web Apps]]></category>

		<guid isPermaLink="false">/?p=23440</guid>
		<description><![CDATA[連載： Google I/O 2017特集 (1)この記事は2017年5月17、18、19日に米国カリフォルニア州マウンテンビューにあるAmphitheatreで行われたGoogleの開発者向けカンファレンスGoogle...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google-io-2017/" class="series-450" title="Google I/O 2017特集" data-wpel-link="internal">Google I/O 2017特集</a> (1)</div><p>この記事は2017年5月17、18、19日に米国カリフォルニア州マウンテンビューにあるAmphitheatreで行われたGoogleの開発者向けカンファレンスGoogle I/Oの3日目に「The Future of Audio and Video on the Web」というタイトルのセッションの内容です。</p>

<h1>はじめに</h1>

<p>タイトルをパッと見て、例えばWeb Audioの話も絡むのか！？と思いきや、内容はビデオでしたが、2000年からwebのみならずリビングにあるテレビ（動画）から、YouTube、SNSでの動画も含めて歴史を追った説明、デモをまじえ動画を中心としたwebサイトの現在できる最高のExperience、そして見えかけている未来のwebでの動画の拡がり、とwebで動画という切り口から幅広く説明をした中身の濃いセッションでした。</p>

<p>登壇したのはこのお二方。Product ManagerのJohn Pallettと、Developer Programs EngineerのFrancois Beaufortです。</p>

<p><img src="/wp-content/uploads/2017/05/John_Francois.png" alt="" width="640" height="230" class="aligncenter size-full wp-image-23451" srcset="/wp-content/uploads/2017/05/John_Francois.png 640w, /wp-content/uploads/2017/05/John_Francois-300x108.png 300w, /wp-content/uploads/2017/05/John_Francois-207x74.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>それでは内容を見ていきましょう。</p>

<h1>動画が机、リビングから手の上に乗り外に向けて歩き出す</h1>

<p>2000年から10年はほとんど変わらなかった。
2000年は私(John Pallett)がHDのテレビを買った最初の年。この当時はHD動画を録画する機器すらなかったが、直後にHD録画機器も出始めSkypeも同じ頃に登場。2005年にYouTube、2007年にはAmazonのPrimeビデオ、Netflixがストリーミングサービスを開始。しかし、この頃は机、リビングで見るのが主でした。
<img src="/wp-content/uploads/2017/05/tv_living.png" alt="" width="640" height="364" class="aligncenter size-full wp-image-23453" srcset="/wp-content/uploads/2017/05/tv_living.png 640w, /wp-content/uploads/2017/05/tv_living-300x171.png 300w, /wp-content/uploads/2017/05/tv_living-207x118.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>2010年からは私の娘を軸に見ていきます。
2010年はタブレットが出始めた年。娘はこの頃から場所を選ばず受動的に動画、音楽を聞いたり、一方で能動的に録画、録音するようになっていました。</p>

<p>ちょうどその頃にはFaceTimeが登場し、ビデオチャットが気軽にできるようになり、2011年にはTwitchでゲーム動画の配信、2013年にはSnapchat、2014年にmusical.lyで若者が音楽ビデオを録り、さらにそれを友達同士で配信するようになった。さらに過去数年では、VR、AR、360度動画が出てきたりと、イノベーションがここ数年の動画の進化を加速。</p>

<p><img src="/wp-content/uploads/2017/05/tv_mobile.png" alt="" width="640" height="384" class="aligncenter size-full wp-image-23456" srcset="/wp-content/uploads/2017/05/tv_mobile.png 640w, /wp-content/uploads/2017/05/tv_mobile-300x180.png 300w, /wp-content/uploads/2017/05/tv_mobile-207x124.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>この進化を裏付けるように、現在のインターネットのトラフィックの70%が映像（ビデオ）で、Cisco社は2020年までにこれが80%まで伸びるだろうと予測しています。</p>

<p><img src="/wp-content/uploads/2017/05/badMovie4.png" alt="" width="640" height="107" class="aligncenter size-full wp-image-23461" srcset="/wp-content/uploads/2017/05/badMovie4.png 640w, /wp-content/uploads/2017/05/badMovie4-300x50.png 300w, /wp-content/uploads/2017/05/badMovie4-207x35.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h1>モバイルwebでの動画の過去と未来</h1>

<p>先程挙げた、Twitch、Snapchat、musical.ly、これらのサイトに行くと実はアプリ（Android, iOS）のインストールを求められます。</p>

<p>しかし、モバイルwebでこれらのアプリを作ればアプリのインストールは不要、そしてすぐにやりたいことができるはずなのに、なぜそうなっていないのでしょう？少し奇妙です。</p>

<p>理由を考えると実はそれにはいくつかの問題、課題がありました。一言でいうと、モバイルwebは動画が得意ではなかったのです。その問題点を見ていきます。</p>

<h3>Buffering</h3>

<p>動画の提供側はFlashを第一に、第二にHTML5に向けて公開するという時代が続いていて、モバイルwebは眼中の外でした。なぜならモバイルwebで動画にアクセスすると動画のダウンロードに時間がかかり、再生までにかなりの時間がかかっていたからです。</p>

<h3>映像のクオリティの低さ</h3>

<p>「ダウンロードに時間がかかるのなら、映像のクオリティを落とし、ファイルサイズを小さくしよう！」となりますが、小さくすればするほど映像のクオリティは低下します。</p>

<h3>いけてないレイアウト</h3>

<p>動画の提供側はモバイルwebは眼中の外だったので、サイト全体のデザイン、レイアウトはデスクトップに最適化されていて、モバイルwebでは動画の一部しか表示されていなかったりした。しかし、この現象は防ぐためのAPIがなかったことが大きい要因で、対策はできなかったかもしれないというのも事実。</p>

<h3>オフラインでは利用不可</h3>

<p>オフラインでの利用はできなかった。もちろんChromeではOffline時には恐竜ゲームはできて楽しいけど、動画を観たいのに恐竜ゲームを例えば飛行機に乗って数時間するのは現実的ではありません。</p>

<p>では現在のモバイルwebでどうなっているかを紹介します。</p>

<p>デモアプリとしてDeveloper Relations TeamのPaul Lewisが書いたアプリを例に紹介します。アプリの名前は「<strong>Biograf</strong>」で、アプリとソースコードは以下のURLにあります。</p>

<ul>
<li><strong>アプリ</strong> <a href="http://bit.ly/pwa-media" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">bit.ly/pwa-media</a></li></li>
<li><strong>ソースコード</strong> <a href="http://bit.ly/pwa-media-code" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">bit.ly/pwa-media-code-media</a></li>
</ul>

<p><img src="/wp-content/uploads/2017/05/biograf.png" alt="" width="640" height="386" class="aligncenter size-full wp-image-23472" srcset="/wp-content/uploads/2017/05/biograf.png 640w, /wp-content/uploads/2017/05/biograf-300x181.png 300w, /wp-content/uploads/2017/05/biograf-207x125.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>（セッションではここで実際にデモを行います。併せてご覧になると分かりやすいと思います。<a href="https://youtu.be/z9unKFzAj1w?t=4m51s" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">デモの動画</a>）</p>

<p><a href="https://youtu.be/z9unKFzAj1w?t=4m51s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2017/05/demo1.png" alt="" width="640" height="470" class="aligncenter size-full wp-image-23471" srcset="/wp-content/uploads/2017/05/demo1.png 640w, /wp-content/uploads/2017/05/demo1-300x220.png 300w, /wp-content/uploads/2017/05/demo1-207x152.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a>
（クリックでデモ部分の動画が再生可能です）</p>

<p>特徴は以下です。これはwebアプリですよ！</p>

<ul>
<li>Progressive Web App</li>
<li>Nativeアプリのようにホーム画面からアイコンをタップして起動可能</li>
<li>起動アニメーション（Splash）が表示できる</li>
<li>Chrome（ブラウザ）の枠はなく、全画面でアプリ全体を表示</li>
<li>スクロールも非常にスムース</li>
<li>動画は再生をタップしてから一瞬で開始</li>
<li>デバイスを横にするとフルスクリーンでも動画の表示が可能</li>
<li>タイムラインをスクロールすると、サムネイルも表示可能</li>
<li>フルスクリーン中にタップすると、「再生、停止、コマ送り・戻し」のコントロール画面が表示可能</li>
<li>通知エリアにもコントロールを表示することが可能</li>
<li>動画のダウンロード機能もあり、ダウンロードした動画はプラウザを閉じても、機内モードでも再生可能（Background Fetch）</li>
<li>ロック画面からのコントロールも可能</li>
<li>ロック画面で動画のサムネイルを背景としても表示可能</li>
<li>制限付き動画でもライセンスをハンドルして再生可能</li>
</ul>

<p>これらのExperienceは動画の再生時「ページのロードが遅いとユーザはサイトから離脱してしまう」事実を元に考えると非常に重要な機能でもあります。Akamai社の調査では2秒で表示されないとサイトからの離脱が始まり、また動画の再生に関しては6秒以内に再生されないとユーザは再生開始を待たず離脱してしまうという調査結果を出しています。</p>

<p>では、このアプリを例にExperienceを1つ1つ見ていきましょう。</p>

<p><img src="/wp-content/uploads/2017/05/experience.png" alt="" width="640" height="362" class="aligncenter size-full wp-image-23476" srcset="/wp-content/uploads/2017/05/experience.png 640w, /wp-content/uploads/2017/05/experience-300x170.png 300w, /wp-content/uploads/2017/05/experience-207x117.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>反応の速い再生(Fast Playback)</h3>

<p>これはAdaptive Bitrate Streamingで実現しています。動画を再生するには動画のダウンロードは必須だが、モバイル環境下ではダウンロードするデバイスがトンネルを通ったり、帯域を失ったりする。Adaptive Bitrate Streamingがこれらのネットワークがコンスタントでない部分を解決します。</p>

<p>再生するビデオは複数のBitrateでエンコードして、それらがさらにある時間間隔で断片化して保存する。断片化されたファイルをダウンロードするアプリ側で低域等の状況に合わせてBitrateと断片の組み合わせの最適化を施すことで、反応の速い再生を可能にします。</p>

<p>これを実装したのがOpen Sourceの<a href="http://github.com/google/shaka-player" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shaka Player</a>です。</p>

<p>また、再生ボタンをクリック/タップしてからの再生の反応に関しては、Service Workersで動画をPre-Cacheすることで速くしている。これが実装されているのが<a href="https://www.theoplayer.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">THEOPlayer</a>です。Biografにも実装されているが、動画の説明等も一緒に、事前にキャッシュ（Pre-Cache）することで再生までの時間を短縮している。またService Workersを使うとサイト自体のスピードもアップすることが可能です。</p>

<p>VIACOM18の<a href="https://www.voot.com/public_html/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Voot</a>という動画サイト（5月25日現在、インドでの提供のみ）ではページロード時間が5倍速くなり、これによってユーザがが77%増加、日々に動画を再生するユーザは15％増加したという結果もあります。</p>

<h3>Offline</h3>

<p>Offlilneは例えば飛行機に乗っている時など、インターネットアクセスがない場所では非常に重要な機能。BiografではService Workersを使って、ページに表示する動画の説明、また動画に関してはリーズナブルなBitrateで事前にダウンロードしキャッシュとしてブラウザ側に保存することでどこでも再生できるようにしています。このBitrateは開発者側からService Workersのロジックの中で、またはユーザ側が例えばダウンロード開始時に選択することが可能。</p>

<p><img src="/wp-content/uploads/2017/05/Offline.png" alt="" width="640" height="358" class="aligncenter size-full wp-image-23479" srcset="/wp-content/uploads/2017/05/Offline.png 640w, /wp-content/uploads/2017/05/Offline-300x168.png 300w, /wp-content/uploads/2017/05/Offline-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
Offlineはオーディオにも適応可能です。例えばオーディオブックを考えると、Service Workersを使って事前にブック内のプレイリストのオーディオを事前にキャッシュしておくことで、Offlineでも再生が可能になる。</p>

<p>Biografでは動画をキャッシュするためにBackground FetchというAPIを使っていますが、この機能は現在開発中でExperimental Web Platform features（Chromeのアドレスバーに<code>chrome://flags/#enable-experimental-web-platform-features</code>を入力すると変更可能です）をEnableにすることで利用が可能になります。このAPIに関するフィードバックをお待ちしています。</p>

<h3>VP9</h3>

<p>コーデックに関してです。クオリティを落とさずに2倍のコンテンツを保存できたらよいですよね。VP9は一般的なコーデックに比べると50％程圧縮率が高いので、質を落とさずにファイルサイズを50％減らすことができます。既に20億のデバイスがサポートされている状態なのでとてもよい選択肢。例えばYouTubeではVP9を使うことで他のコーデックで配信したときよりも再生までの時間を15〜80％縮めることができています。</p>

<h3>User Experience</h3>

<h4>Media Session API</h4>

<p>ロック画面、通知エリアでサムネイルをバックグラウンドに表示していたのと、コントロールボタンを表示していたのがこのAPI。ウェアラブル側にも表示されます。</p>

<p><img src="/wp-content/uploads/2017/05/SessionOrientationAPI.png" alt="" width="640" height="375" class="aligncenter size-full wp-image-23483" srcset="/wp-content/uploads/2017/05/SessionOrientationAPI.png 640w, /wp-content/uploads/2017/05/SessionOrientationAPI-300x176.png 300w, /wp-content/uploads/2017/05/SessionOrientationAPI-207x121.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
実装は簡単でMetadataとしてタイトル、アーティスト、アルバム名、表示する画像を指定をし、コントロール（再生、ストップ等）のボタンが押された時のHandlerをそれぞれ書くことで実装が可能です。</p>

<h4>Session Orientation API</h4>

<p>デバイスを回転させたときの動作を指定できるAPI。Biografでは横にした場合に全画面表示にしている。縦、横になった場合のHandlerを書くことで実装が可能。
<img src="/wp-content/uploads/2017/05/MediaSessionAPI.png" alt="" width="640" height="376" class="aligncenter size-full wp-image-23482" srcset="/wp-content/uploads/2017/05/MediaSessionAPI.png 640w, /wp-content/uploads/2017/05/MediaSessionAPI-300x176.png 300w, /wp-content/uploads/2017/05/MediaSessionAPI-207x122.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>webでの動画の未来</h2>

<p>タイトル通りの未来のお話をします。映像周辺の仕様の進化はディスプレイをよりリアルな表現の表示に近づけてくれます。</p>

<h4>Wide Color Gamut</h4>

<p>まずは色からお話します。現在のテレビ（4Kや8K）で実現されている色がモバイル、デスクトップのwebで表現できるようになります。</p>

<p>現在のディスプレイで表現できている色は目で見えているよりも色の表現は乏しい。その色は存在する色が外側の枠だとすると、最も内側にある三角枠が現在のディスプレイ（SRGB）の守備範囲。これがBT2020になると真ん中の三角枠まで表現できるようになります。</p>

<p><img src="/wp-content/uploads/2017/05/WideColorGamut.png" alt="" width="300" class="aligncenter size-full wp-image-23484" srcset="/wp-content/uploads/2017/05/WideColorGamut.png 598w, /wp-content/uploads/2017/05/WideColorGamut-280x300.png 280w, /wp-content/uploads/2017/05/WideColorGamut-193x207.png 193w" sizes="(max-width: 598px) 100vw, 598px" /></p>

<p>僕の履いている靴、実はこのディスプレイ（登壇者の背面にある）では正しい色で表示されていない。けども4K、8Kではより近い色が出てるはず。<br />
（独り言：もしや登壇者のJohn Pallettさん、このために靴を新調したのかな？）
<img src="/wp-content/uploads/2017/05/Screen-Shot-2017-05-25-at-9.52.00-PM.png" alt="" width="640" height="364" class="aligncenter size-full wp-image-23486" srcset="/wp-content/uploads/2017/05/Screen-Shot-2017-05-25-at-9.52.00-PM.png 640w, /wp-content/uploads/2017/05/Screen-Shot-2017-05-25-at-9.52.00-PM-300x171.png 300w, /wp-content/uploads/2017/05/Screen-Shot-2017-05-25-at-9.52.00-PM-207x118.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>High Dynamic Range (Brightness)</h4>

<p>いままでよりも明るいものは明るく、暗いものは暗く表示できるようになる仕様です。現在の一般的なディスプレイではSDR（Standard Dynamic Range）しか表現できません。これは現実の世界の明るさからするとかなりの差があります。</p>

<p>HDR(High Dynamic Range)をサポートしたディスプレイがこれから市場に出てきます。これはOTF（electric Optical Function、またはガンマFunctionともいう）を変えます。デジタルの数字からディスプレイでどれだけの明るさで表示するかのFunctionのことで、それが変更されるので映像・画像を扱う方はどのディスプレイが何をサポートしているか、またそのディスプレイの特性を知った上で選択する必要が出てくるということです。
<img src="/wp-content/uploads/2017/05/sdr-hdr.png" alt="" width="640" height="350" class="aligncenter size-full wp-image-23487" srcset="/wp-content/uploads/2017/05/sdr-hdr.png 640w, /wp-content/uploads/2017/05/sdr-hdr-300x164.png 300w, /wp-content/uploads/2017/05/sdr-hdr-207x113.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Wide Color GamutとHigh Dynamic Rangeのコードは以下です。上部についてです。CSS Media Query Level4で可能になります。現在のChromeではcolor-gamutがサポートされていますが、デバイスでどの色が使えるかをクエリすることが可能で、それによって決定することが可能です。</p>

<p>また下部のコードではVP9がHDRとOTFでどの色で表示できるかをクエリによって決定することができます。</p>

<p><img src="/wp-content/uploads/2017/05/CSSL4.png" alt="" width="640" height="348" class="aligncenter size-full wp-image-23490" srcset="/wp-content/uploads/2017/05/CSSL4.png 640w, /wp-content/uploads/2017/05/CSSL4-300x163.png 300w, /wp-content/uploads/2017/05/CSSL4-207x113.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>Alliance for Open Media(AOM)</h4>

<p>アライアンスです。このアライアンスはYouTube、Google、Amazon、Twitch、Netflix、Microsoft、Mozilla、Hulu、BBCが参加していて、Open SourceでRoyalty-Freeの新しいCodecを作ろうとしています。</p>

<p>HDRだけでなく、Wide Color Gamut、また8K、4K、360どビデオも低いBitrateでも届けることができるようなCodecを考えています。なぜなら世界で皆が同じレベルのネットワークを使えるわけではないから。</p>

<p>このアライアンスではAV1という名前のCodecを開発している。数週間前はまだ開発も終えていないし、使えるフォーマットではなかったが、NetflixがVP9よりも20％高い圧縮率のフォーマットを実現することができたとの報告を受けている。</p>

<p>恐らく疑問に思うのは「AV1がどれだけのデバイスでサポートされているのか？」というところだと思います。ここがwebのユニークで面白いところ。1GHzと3GHzのデバイスでは再生のされ方が違う。ではそこをどうするか、VP9を例にコードを見てみます。Media Capabilities APIを使うことで以下のようにいろいろな値を指定することが可能です。</p>

<p><img src="/wp-content/uploads/2017/05/VP9query.png" alt="" width="640" height="358" class="aligncenter size-full wp-image-23492" srcset="/wp-content/uploads/2017/05/VP9query.png 640w, /wp-content/uploads/2017/05/VP9query-300x168.png 300w, /wp-content/uploads/2017/05/VP9query-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>APIにResolution、Bitrate、再生したいCodecを渡すと、指定した形式をサポートしているか、指定した形式でスムースにつまらずに再生できるか、バッテリパワー的に効率的かを返してくれるので、この情報をどのタイプで再生するかのみならず、どのResolutionで再生するか等、ユーザに最適なExperienceを提供することができるようになる。</p>

<h2>録音・録画とシェアとSNS</h2>

<p>ここ数年、映像とオーディオに関してここ数年で飛躍的に前進している。私の娘がモバイルで音楽の制作、映像の撮影をしている。顔に飾り物をディスプレイ上でつけたりカスタマイズして、そのまま友達とSNSでシェアしてる。これは5、6年前では考えられなかったことです。SNSでは即座に撮影してシェアすることがキーになります。これはwebにはとても得意ところ。なので、ここでSNSやコミィニケーションについて話をします。</p>

<p>WebRTCはあたらしい技術ではないが、ここ数年で急速にブラウザベンダとアプリケーションプラットフォームとしての両方に適応されてきました。そしてWebRTCを使えばLiveStreamingもすることが可能です。</p>

<p>そしてユーザがシェアする動画・音楽の制作に関して、簡単に探せて、簡単に見ることができ、さらにそれを見た友達が動画・音楽の制作ができ…となれば、とてもよいサイクルが生まれます。
<img src="/wp-content/uploads/2017/05/Creation.png" alt="" width="640" height="369" class="aligncenter size-full wp-image-23494" srcset="/wp-content/uploads/2017/05/Creation.png 640w, /wp-content/uploads/2017/05/Creation-300x173.png 300w, /wp-content/uploads/2017/05/Creation-207x119.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>このサイクルの実現はwebでなら難しくはありません。それではこのサイクルがwebで実現できるかどうかを、デモを交えてフランソワから紹介してもらいます。</p>

<h1>Mustache（髭）</h1>

<p>映像とシェアに関わる部分で現在のwebでできることを盛り込んだデモをご紹介します。アプリは「Mustache」という名前です。</p>

<p><img src="/wp-content/uploads/2017/05/Mustache01-1.png" alt="" width="640" height="548" class="aligncenter size-full wp-image-23504" srcset="/wp-content/uploads/2017/05/Mustache01-1.png 640w, /wp-content/uploads/2017/05/Mustache01-1-300x257.png 300w, /wp-content/uploads/2017/05/Mustache01-1-207x177.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Progressive Web Appになっています。ホーム画面のアイコンから起動すると、起動アニメーション（Splash）が表示されます。このExperienceですと、既にwebアプリだと認識するのが難しいと思います。顔には髭、頭には帽子をかぶっています。動かしても映像はとてもスムーズです。動画の撮影も可能で、それをシェアすることももちろん可能です（上の画像の右側）。</p>

<h3>Mustacheが利用しているAPI</h3>

<h4>映像を扱う(getUserMedia())</h4>

<p>カメラを扱い、画面に表示するコードが以下になります。
<img src="/wp-content/uploads/2017/05/getusermedia-2.png" alt="" width="640" height="354" class="aligncenter size-full wp-image-23505" srcset="/wp-content/uploads/2017/05/getusermedia-2.png 640w, /wp-content/uploads/2017/05/getusermedia-2-300x166.png 300w, /wp-content/uploads/2017/05/getusermedia-2-207x114.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><code>getUserMeida()</code>でカメラの映像と音声を取得します。Mustacheの場合は映像のみを利用します。その他の条件として利用するカメラ（前面、背面）、Framerate、サイズをしています。そして下部のコードで取得した映像を画面に表示しています。</p>

<h4>形状の検知（Shape Detection API）</h4>

<p>現在、実験中のAPIであるShape Detection APIを使っています。動いている顔へ髭、そして頭に帽子をと、このAPIが重ねる正しい場所を検知することを可能にしています。つい先週完成したばかりのAPIです。</p>

<p>コードは以下のようになります。とてもシンプルです。<code>FaceDetector()</code>に顔を取得するか、また、顔を最大いくつ検知するかの数を指定するだけです。ブラウザ側のAPIなのでインターネットへの接続は不要です。</p>

<p>このShape Detection APIはBarcode、QR Codeを検知するAPIと同時に9月にはChrome安定版でテスト利用という目的で利用可能になります。また、現在でも「Experimental Web Platform features」をEnableにすることで利用可能です。もし要望、バグがあったら知らせてください。</p>

<p><img src="/wp-content/uploads/2017/05/shapedetectionapi.png" alt="" width="640" height="354" class="aligncenter size-full wp-image-23507" srcset="/wp-content/uploads/2017/05/shapedetectionapi.png 640w, /wp-content/uploads/2017/05/shapedetectionapi-300x166.png 300w, /wp-content/uploads/2017/05/shapedetectionapi-207x114.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>映像の録画（Media Recording API）</h4>

<p>Mustacheでは、以下のようにMedia Recording APIを使っています。<code>MediaRecorder()</code>へCodecをVP9と指定して、映像を受け取ったら処理をするHandler、また録画を停止した時のHandlerを書いている。Chromeに公開されて1年になるのでAPIは安定しています。</p>

<p><img src="/wp-content/uploads/2017/05/mediarecording.png" alt="" width="640" height="358" class="aligncenter size-full wp-image-23509" srcset="/wp-content/uploads/2017/05/mediarecording.png 640w, /wp-content/uploads/2017/05/mediarecording-300x168.png 300w, /wp-content/uploads/2017/05/mediarecording-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h4>シェア機能（Web Share API）</h4>

<p>シェアボタンを押したときにAndroidのNativeのシェア選択画面が出てきていましたよね。自然過ぎてわからなかったかもしれませんが…。これはWeb Share APIを使っています。<br />
コードは以下です。<code>share()</code>にタイトル、テキストと映像のURLを指定します。このAPIは今年末には利用できるようになるでしょう。
<img src="/wp-content/uploads/2017/05/webshare.png" alt="" width="640" height="347" class="aligncenter size-full wp-image-23510" srcset="/wp-content/uploads/2017/05/webshare.png 640w, /wp-content/uploads/2017/05/webshare-300x163.png 300w, /wp-content/uploads/2017/05/webshare-207x112.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Mustacheは以下のURLで公開しています。<br />
Chrome for AndroidのCanaryを使い、Experimental Web Platform featuresのEnableにして利用してください。</p>

<ul>
<li><a href="bit.ly/mustaches-io" data-wpel-link="internal">Mustache</a></li>
</ul>

<p><img src="/wp-content/uploads/2017/05/MustacheURL.png" alt="" width="640" height="356" class="aligncenter size-full wp-image-23512" srcset="/wp-content/uploads/2017/05/MustacheURL.png 640w, /wp-content/uploads/2017/05/MustacheURL-300x167.png 300w, /wp-content/uploads/2017/05/MustacheURL-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>全てのAPIを1つのノードとしてみるとwebではPlug-inなしでこれらノード同士を無限につなげることができます。例えば、Media Streamを使えばカメラからCanvasに描画、アップロード、またマイクからWeb Audioそして、WebRTCのRTCPeerConnectionへと、たくさんのAPIと接続して利用することが可能です。</p>

<h1>まとめ</h1>

<p>デモに交えてたくさんのAPIを話しました。多くが現在でも利用可能なAPIです。</p>

<p>Biografでは、Service Workers、Media Session API、Full Screen API、Screen Orientation APIなどを使っています。フランソワが<a href="bit.ly/mobile-web-video-playback" data-wpel-link="internal">こちらに記事として</a>まとめてくれていますので詳しくはそちらを参照してください。</p>

<p>映像の再生等に関わるProgressive Web Appを書く場合は<a href="bit.ly/pwa-media-code" data-wpel-link="internal">Biografのコード</a>を参考にするとよりよいExperienceを提供できるでしょう。<br />
そしてMustacheで使っているMediaStream Recording API、Media Capture API、Media Streams APIは現在でも利用可能です。</p>

<p>最後に、以下の3つは特にFeedbackをお待ちしています。</p>

<ul>
<li><a href="http://wicg.github.io/background-fetch" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Background Fetch</a></li>
<li><a href="http://wicg.github.io/shape-detection-api" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Shape Detection API</a></li>
<li><a href="http://wicg.github.io/web-share" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Share API</a></li>
</ul>

<p>ありがとうございました！</p>

<h1>おわりに</h1>

<p>個人的に数年前から年に数回はFacebookをモバイルwebから使う儀式をしています。写真や動画を撮ってシェアしたりするのが特にですが不自由な点がありました。</p>

<p>また、QRコードの読み取りも必ずモバイルのNativeアプリ、またはインターネットへの接続が必須とされていました。それを元に考えると近年のWebブラウザの進化には目を見張るところがあり、また同時にその進化を肌で実感できるエキサイティングなプラットフォームの1つだと思います。</p>

<p>今後も映像のみならず、他の分野でのWebブラウザの発展、拡張も期待できそうですし、その進化から目が離せないですね。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2017特集]]></series:name>
	</item>
		<item>
		<title>Webの最先端では何が起こっているか、今Googleが取り組んでいることは？──Google I/O 2016セッションレポート【後編】</title>
		<link>/ryoyakawai/19461/</link>
		<pubDate>Wed, 15 Jun 2016 00:00:15 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[I/O 2016]]></category>
		<category><![CDATA[MIDI]]></category>

		<guid isPermaLink="false">/?p=19461</guid>
		<description><![CDATA[Google I/O 2016のセッション「What&#8217;s new for the web?」についてのレポート後編です。（前編はこちら） 前編では、既に導入済みの機能、API、またこれから導入される機能が怒涛...]]></description>
				<content:encoded><![CDATA[<p>Google I/O 2016のセッション「What&#8217;s new for the web?」についてのレポート後編です。（前編は<a href="https://html5experts.jp/ryoyakawai/19335" target="_blank" data-wpel-link="internal">こちら</a>）
前編では、既に導入済みの機能、API、またこれから導入される機能が怒涛のごとく紹介してきました。後編では、Web Platformをより先に進めるためにGoogleが取り組んでいること、そしてWeb BluetoothやPhysical Webについて解説していきます。</p>

<h2>Google loves the web</h2>

<p>ChromeチームWeb Platformをより先に進めるために、ここ1～2年取り組んでいるアプローチの紹介です。</p>

<p><img src="/wp-content/uploads/2016/06/GoogleLovetheWeb1.png" alt="GoogleLovetheWeb" width="640" height="356" class="aligncenter size-full wp-image-19479" srcset="/wp-content/uploads/2016/06/GoogleLovetheWeb1.png 640w, /wp-content/uploads/2016/06/GoogleLovetheWeb1-300x167.png 300w, /wp-content/uploads/2016/06/GoogleLovetheWeb1-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>まず、前提としてGoogleはWebが大好きです。Googleの同僚は皆、Webが大好きです。そしてChrome Teamには「Webをより先に進める」という重要なMissonがあります。ここで私がWebと言っているのはChrome Webということではなく、全てのWebのことを指していて、それら全てのWebが素晴らしくなってほしいと思っています。</p>

<p>よって、Interoperability（相互運用性）を保ちモダンブラウザの全てにShipされるまでが我々の使命です。なぜならInteroperabilityが保たれずShipしてしまったら、誰でも・いつでも・どこでも利用できるというWebの最も大きく重要な利点の1つが失われてしまうからです。Vender Prefixを廃止したのもそういった理由です。</p>

<p>Chromeにおいては、Web Platformをより先に進めるために4つのアプローチをを持ち取り組んでいます。</p>

<h4>Chromeチームが取り組んできたこと</h4>

<ul>
<li><b>複数のチャネルを持つ</b>（Stable, Dev, Canary、Beta）</li>
<li><b>実験的な機能にはExperimental flagを設けONにしないと動かなくしている</b>(chrome://flags のことでWeb Bluetoothもこの1つ)</li>
<li><b>Original Trials</b>：実装したAPIをそのままExperimental flagとして提供してしまうと、いつの間にかデファクトになってしまう可能性があります。APIの仕様・実装を吟味してからShipすることがよりよいWebを作るのには必要不可欠です。よって、Feedbackをすることに同意したDeveloperのみ利用を可能にすることで、利用するユーザー数を絞り、さらに期間を区切ることでデファクトすることを防ぎ、実験のIterationのスピードを上げることを目的としています。さらに多くのDeveloperが使い始めた場合は自動的に利用を停止する機能も入っています。</li>
<li><b>Incubation of substantial new feature</b>(<a href="https://html5experts.jp//wicg.io" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">wicg.io</a>)：Web Incubator Community GroupをW3Cでにて行っています。標準化のProposalの議論をライトウェイトに行うグループです。チャーター（W3Cで議論を進める場合には必ず作成します）を作ったりすることに全ての時間は費やさないものの、正しく管理されるし、Contributionも受け付けることが可能です。もし新しい機能を提案したい場合は是非このグループに提案してください。</li>
</ul>

<p><img src="/wp-content/uploads/2016/06/wicg.png" alt="wicg" width="640" height="355" class="aligncenter size-full wp-image-19467" srcset="/wp-content/uploads/2016/06/wicg.png 640w, /wp-content/uploads/2016/06/wicg-300x166.png 300w, /wp-content/uploads/2016/06/wicg-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>しかし、機能を追加するだけではWeb Platformを健康に保つことはできません。よって、機能の削除も行います。削除の理由には、他のAPIとの入替えや、実験的に作ったが上手くいかなかった、というものがあったりします。3つ前までで削除された機能のリストがこちら(<a href="https://html5experts.jp//goo.gl/5gq1Im" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">goo.gl/5gq1Im</a>)です。今後、requestAutoCompleteだったり、HTML5 App Cacheのような影響の大きな機能も削除しようとしています。まだ使われている機能、APIをいきなり削除しないというようなポリシーもありますので安心してください。</p>

<h4>これまでの成功の紹介</h4>

<p>それでは、ここ数年での成功を紹介します。私がここに立っている、ということは何のことだか分かる方も多いかも知れませんが、そうですWeb MIDIです。</p>

<p>MIDIは知ってる方もそうでない方もいると思います。仕様ができてから30年以上にもなる楽器のキーボード、シンセサイザー等、電子楽器同士、またはコンピュータとを接続する標準化されたプロトコルです。数年前Web Audioで遊んでいたときに「これを楽器のキーボードから操作したい」と思い立ったW3Cにて標準化を始め、Chromeでは去年Shipされました。</p>

<p>ChromeでのShip以降、多くの楽器メーカがユーザー体験を提供するプラットフォームとしてWebを使い始めました。Yamahaはrefaceという新しいシンセサイザーのラインナップに対してSoundmondoという音色のエディタ、ライブラリアンを提供するWeb MIDIを使ったサービスを展開しています。NovationのCircuit Groove BoxはWebに接続して新しいサンプルをダウンロードします。これらの作業においてソフトウェアを新たにインストール必要はないのです。</p>

<p>そして、間違いなくスゴイことはフランスのEDMアーティストであるMadeonがWeb Audioで作られたRemixBoardをWebサイトで公開したことです。ファンに向けられて作られたサイトで、彼のアルバムの中の音をRemixして遊ぶことができるのです。もちろんMIDIデバイスも接続してプレイすることができるようになっているのです。<br>
（デモ（パフォーマンス？）が始まります。実際の動画を御覧ください）</p>

<p><figure class="aligncenter">
<a href="https://youtu.be/bK6Ah68jEX8?t=28m25s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">
<img src="/wp-content/uploads/2016/06/chris_madeon.png" alt="chris_madeon" width="640" height="359" class="aligncenter size-full wp-image-19477" srcset="/wp-content/uploads/2016/06/chris_madeon.png 640w, /wp-content/uploads/2016/06/chris_madeon-300x168.png 300w, /wp-content/uploads/2016/06/chris_madeon-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a>
<figcaption>何が起きたかは<a href="https://youtu.be/bK6Ah68jEX8?t=28m25s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ここ</a>または画像をクリックして動画を御覧ください！</figcaption>
</figure></p>

<p>デモアプリのURLはこちら<a href="https://html5experts.jp//www.madeon.fr/adventuremachine" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">www.madeon.fr/adventuremachine</a>です。</p>

<p>「これスゴイでしょ？！」と言いたいのですが、本質はそこではなくて「ハードウェアがブラウザにアクセスできる」ということが大きな可能性を生んだ、ということを伝えたいのです。ちょうど加速度センサから素晴らしいユーザー体験（UX）が生まれ、モバイル・デバイスが大きな可能性を持ったのと同じようにです。他にも接続できることで大きな可能性が生まれるデバイスはたくさんあると思います。我々は、そこにある可能性を積極的に解き放っていきたいと考えています。</p>

<p>（ここでChris氏からFrançois氏に交代）</p>

<h2>これから何が起こるのか</h2>

<h4>Web Bluetooth</h4>

<p>Bluetoothの名称の由来の説明から始まります。（詳しくはWikipediaの<a href="https://goo.gl/s7nIAG" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Bluetooth </a>「名称の由来」をどうぞ）
<img src="/wp-content/uploads/2016/06/bluetooth.png" alt="bluetooth" width="640" height="358" class="aligncenter size-full wp-image-19486" srcset="/wp-content/uploads/2016/06/bluetooth.png 640w, /wp-content/uploads/2016/06/bluetooth-300x168.png 300w, /wp-content/uploads/2016/06/bluetooth-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Bluetoothはいろいろなバージョンで20年成長してきた技術で、最新はBluetooth Low Energy（BLE）が導入されたVersion 4でリリースされてから6年経過しています。Wi-Fi、Ethernetのスピードは継続的に上がっていますが、Bluetoothはちょっと様子が違っています。</p>

<p><img src="/wp-content/uploads/2016/06/blespeed.png" alt="blespeed" width="640" height="358" class="aligncenter size-full wp-image-19488" srcset="/wp-content/uploads/2016/06/blespeed.png 640w, /wp-content/uploads/2016/06/blespeed-300x168.png 300w, /wp-content/uploads/2016/06/blespeed-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>なぜなら、今まで接続されていなかった多くのデバイスに搭載できるようにバッテリの消費量を最小限にできるようにデザインされているからです。例えば小型のデバイスが使うバッテリは、通常CR2032です。（2032の20は直径、32は厚さを表すそうです！）なので、転送速度はとっても遅いのです。ですが、BLEはそもそも転送速度が遅くても大丈夫なデバイスをターゲットにしているので問題はありません。</p>

<p>それでは、デモをしてみます。デモはPlaybulb Candleという電球のOn/Off、色をBluetooth通信にて変更できるデバイスをWebアプリから操作します。（映像には全体が映っていませんでしたが、会場ではこんな感じでデモが行われていました）</p>

<p><img src="/wp-content/uploads/2016/06/playbulbcandle.jpg" alt="playbulbcandle" width="640" height="426" class="aligncenter size-full wp-image-19491" srcset="/wp-content/uploads/2016/06/playbulbcandle.jpg 640w, /wp-content/uploads/2016/06/playbulbcandle-300x200.jpg 300w, /wp-content/uploads/2016/06/playbulbcandle-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Bluetooth SIG(Bluetoothの規格の策定、技術利用に対する認証を行う団体)は、これから先2年で96%の電話、タブレットにBLEが搭載されると予想している。そこからも、いろいろな場所でBLEが存在するであろうことがお分かりになると思います。</p>

<p>Web BluetoothのAPIを説明する前に、一度BLEの動作を復習してみます。Bletoothには、以下の2つの機能があります。</p>

<ul>
<li><b>Central</b>：近隣のデバイスを探索する（電話、ラップトップPCの等）</li>
<li><b>Peripheral</b>：周囲に向けて継続的に自らの情報を格納したアドバタイジング・パケットをBroadcastする。（心拍センサ、ビーコン、冷蔵庫等）</li>
</ul>

<p>PeripheralがCentralに接続（ペアリング）されると、Peripheralはアドバタイジング・パケットのBroadcastを停止し、CentralがPeriferalで動作するGATTサーバと通信を開始する。通信に関しては、デフォルトで用意されているバッテリ、心拍のようなサービスも存在していますが、もちろん独自にサービスを作ることも可能になっています。それぞれのサービスにはそれぞれのCharastristicに属性を持っていて、読込み（バッテリーレベルの取得等）、書込み（設定の変更等）、また更新時に通知（心拍数のリアルタイム監視）してもらうことも可能です。Web Bluetooth APIを使って書いたサンプルを説明していきます。</p>

<h4>値の読込み</h4>

<p><img src="/wp-content/uploads/2016/06/bluetooth_getValue.png" alt="bluetooth_getValue" width="640" height="358" class="aligncenter size-full wp-image-19498" srcset="/wp-content/uploads/2016/06/bluetooth_getValue.png 640w, /wp-content/uploads/2016/06/bluetooth_getValue-300x168.png 300w, /wp-content/uploads/2016/06/bluetooth_getValue-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>コードはラップトップがCentral、何かしらのデバイスがPeripheralとなっていることを想定しています。まず、Centralのラップトップがnavigator.bluetooth.requestDevice(option)をCallして近隣のデバイスを探索します。optionにデバイスが山ほど列挙されないためにどの種類でフィルタするかを記述します。コードではバッテリのサービスは標準化されているので「batttery_service」と文字列で指定していますが、アドバタイジングパケットにはカスタマイズした値も書込むことが可能です。</p>

<p>navigator.bluetooth.requestDevice(option)をCallすることで探索が開始され、それと同時にアドレスバーの直下に該当するデバイスを列挙するポップアップが出てきます。ユーザがリストからデバイスを選択すると、JavaScript側ではそのデバイスのデバイス名、利用可能なサービスが格納されているオブジェクトにアクセスが可能になります。</p>

<p>ここでセキュリティに関する注意点。<br>
navigator.bluetooth.requestDevice(option)はユーザのインタラクションにて初めて動作します。デモではボタンクリックで開始していました。Localhost以外のホストでWeb Bluetoothを使う場合は、HTTPSでコンテンツがServeされたことを要求している。</p>

<p>device.get.connect()をCallしてGATTサーバと接続をします。その後に、server.getPrimaryService(&#8216;battery_service&#8217;)でバッテリサービスを取得、service.getCharacteristic(&#8216;battery_level&#8217;)で読込みたいCharacteristicを指定して取得、最後にcharacteristic.getValue()をCallすることで、バッテリのレベルの読込み（取得）をすることができます。</p>

<h4>値の書込み</h4>

<p><img src="/wp-content/uploads/2016/06/bluetoothapi_lookslike.png" alt="bluetoothapi_lookslike" width="640" height="360" class="aligncenter size-full wp-image-19496" srcset="/wp-content/uploads/2016/06/bluetoothapi_lookslike.png 640w, /wp-content/uploads/2016/06/bluetoothapi_lookslike-300x169.png 300w, /wp-content/uploads/2016/06/bluetoothapi_lookslike-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>先ほどとは違い、心拍センサをPeripheralとしています。その他、ハイライトされた部分が違います。charctristic.writeValue()にUint8Arrayにて、1バイトを引数に渡すことで書込みを行っています。</p>

<h4>更新の受取り</h4>

<p><img src="/wp-content/uploads/2016/06/bluetooth_notify.png" alt="bluetooth_notify" width="640" height="359" class="aligncenter size-full wp-image-19499" srcset="/wp-content/uploads/2016/06/bluetooth_notify.png 640w, /wp-content/uploads/2016/06/bluetooth_notify-300x168.png 300w, /wp-content/uploads/2016/06/bluetooth_notify-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>この例でも、心拍センサをPeripheralとしています。この例でも、ハイライトされた部分が違います。characteristicにcharacteristicvaluechangedのイベント名でEventハンドラを設定し、beepという関数をCallbackとして指定しています。characteristic.startNotifications()で、更新の受け取りを開始します。これで、更新がある度にbeepが実行されます。</p>

<p>続いて、心拍センサを動作させるデモです。私（François氏）は心拍センサをつけています。リアルタイムに値を受け取ることができますので、ちょっと見てみましょう。通常私の心拍数は60-80ですが、今はどうでしょう？</p>

<p><img src="/wp-content/uploads/2016/06/francis_heartrate.png" alt="francis_heartrate" width="640" height="361" class="aligncenter size-full wp-image-19504" srcset="/wp-content/uploads/2016/06/francis_heartrate.png 640w, /wp-content/uploads/2016/06/francis_heartrate-300x169.png 300w, /wp-content/uploads/2016/06/francis_heartrate-207x117.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>（普段の倍近くの心拍数が表示されChris氏も会場も爆笑）<br>
次に実際にリアルタイムに心拍数を受け取っていることを証明するために腕立て伏せをしてみます。（前編の最後に掲載さいた画像はここでの1シーンです）<br>（が、ペアリングが切断されたのか動作せず……そして、今度はChris氏も会場も大爆笑！失敗するということは、デモがリアルタイムに行われている証拠です！）</p>

<p>私以外にも、Web Bluetoothで遊んでいる同僚たちもいます。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2016/06/bletoy00.png" alt="bletoy00" width="640" height="361" class="aligncenter size-full wp-image-19505" srcset="/wp-content/uploads/2016/06/bletoy00.png 640w, /wp-content/uploads/2016/06/bletoy00-300x169.png 300w, /wp-content/uploads/2016/06/bletoy00-207x117.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Web Bluetoothでラジコンカーをコントロール</figcaption>
</figure></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2016/06/bletoy01.png" alt="bletoy01" width="640" height="359" class="aligncenter size-full wp-image-19506" srcset="/wp-content/uploads/2016/06/bletoy01.png 640w, /wp-content/uploads/2016/06/bletoy01-300x168.png 300w, /wp-content/uploads/2016/06/bletoy01-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Web Bluetoothでプリンタをコントロール</figcaption>
</figure></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2016/06/bletoy02.png" alt="bletoy02" width="640" height="359" class="aligncenter size-full wp-image-19507" srcset="/wp-content/uploads/2016/06/bletoy02.png 640w, /wp-content/uploads/2016/06/bletoy02-300x168.png 300w, /wp-content/uploads/2016/06/bletoy02-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Web BluetoothでBB-8をコントロール</figcaption>
</figure></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2016/06/bletoy03.png" alt="bletoy03" width="640" height="359" class="aligncenter size-full wp-image-19508" srcset="/wp-content/uploads/2016/06/bletoy03.png 640w, /wp-content/uploads/2016/06/bletoy03-300x168.png 300w, /wp-content/uploads/2016/06/bletoy03-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Web BluetoothでLEDをコントロール</figcaption>
</figure></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2016/06/Screen-Shot-2016-06-05-at-1.20.56-AM.png" alt="Screen Shot 2016-06-05 at 1.20.56 AM" width="640" height="359" class="aligncenter size-full wp-image-19509" srcset="/wp-content/uploads/2016/06/Screen-Shot-2016-06-05-at-1.20.56-AM.png 640w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-05-at-1.20.56-AM-300x168.png 300w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-05-at-1.20.56-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Web Bluetoothで空飛ぶ猫をコントロール</figcaption>
</figure></p>

<p>Bluetoothのパケット通信の中身を見るときはAndroidを使うのが最も簡単な方法です。AndroidのDeveloper Optionにある「Bluetooth HCI snoop log」を有効にしてください。（詳しくは<a href="http://wifimanager.hateblo.jp/entry/2016/06/02/204600" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">この辺り</a>を参照してみてください）</p>

<p><img src="/wp-content/uploads/2016/06/support_browser.png" alt="support_browser" width="640" height="358" class="aligncenter size-full wp-image-19511" srcset="/wp-content/uploads/2016/06/support_browser.png 640w, /wp-content/uploads/2016/06/support_browser-300x168.png 300w, /wp-content/uploads/2016/06/support_browser-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>現在Web BluetoothをサポートしているブラウザはOperaとChromeOS、マシュマロ上で動作しているChrome for Android、Chrome for LinuxでChromeでは chrome://flags/#enable-web-bluetooth （アドレスバーにコピー＆ペーストしてください）を有効にすることで利用することが可能です。Mac、WindowsのChromeへは現在実装中です。</p>

<p>開発の助けになるであろう以下の2つを紹介します。</p>

<ul>
<li>Get Start with Web Bluetooth (<a href="https://html5experts.jp//goo.gl/MLKzj2" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">goo.gl/MLKzj2</a>)：コードジェネレータ</li>
<li>Web Bluetooth Developer Studio Plugin (<a href="https://html5experts.jp//goo.gl/c2ype5" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">goo.gl/c2ype5</a>)：Bluetooth SIGが提供している<a href="https://www.bluetooth.com/~/media/developer-studio/index" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Bluetooth Developer Studio</a>向けのPlug-in</li>
</ul>

<p>WebアプリからでもNativeアプリと同じように、Bluetoothでデバイスを操作できるようになりました。また、Webアプリですので、URLをシェアすることで、誰でもスグにアプリを利用できるようになります。当たり前のことかもしれませんが、これがWeb Platformの大きな強みです。</p>

<h4>Physical Webとの連携</h4>

<p>URLを載せたBluetoothのパケットをビーコンからブロードキャストするPhysical Webですが、これがもしBluetoothのアプリからブロードキャストできたらどうでしょう？</p>

<p>URLをPhysical Web経由で受け取り、そのURLにアクセスするとBluetoothデバイスをコントロールするアプリが表示され、Bluetoothデバイスとのペアリングが完了したら、その直後からBluetoothの利用が可能になりますよね。今までのアプリを検索してインストールする等の作業が一切必要がなくなり、通知エリア(Notification Area)に通知されたURLにアクセスするだけでペアリングも含め、Bluetoothデバイスを利用する準備が整うことになります。</p>

<p>今後、Web BluetoothはPhysical Webの機能を組み込み、前述の動作を一気通貫でJavaScriptで実装できるような機能を追加する予定です。</p>

<p>Codelabも<a href="https://codelabs.developers.google.com/codelabs/candle-bluetooth/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Control a PLAYBULB candle with Web Bluetooth</a>と<a href="https://codelabs.developers.google.com/codelabs/polymer-bluetooth/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Interactive with Bluetooth devices on the web with Polymer</a>もありますので、是非挑戦してみてください。</p>

<p>（再びChris氏）</p>

<h4>Web USB</h4>

<p>Web USBは現存する全てのUSBデバイスに接続しようと考えているわけではなくて、Firmwareへのアクセスを許可されているような新しい種類のデバイスに適用されます。</p>

<h2>まとめ</h2>

<p>ここではカバーしきれなかった、まだまだ多くの以下の様な機能が進行中です。</p>

<p><img src="/wp-content/uploads/2016/06/note_covered.png" alt="note_covered" width="640" height="358" class="aligncenter size-full wp-image-19515" srcset="/wp-content/uploads/2016/06/note_covered.png 640w, /wp-content/uploads/2016/06/note_covered-300x168.png 300w, /wp-content/uploads/2016/06/note_covered-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>さらに、まだデザインも始めていないPersistent Storageとか、Web Intents v2もあります。</p>

<p>そろそろ時間です。我々がWeb Platformの未来にワクワクしているのと同じくらいに、皆さんもワクワクしていることを期待しています。</p>

<p><a href="https://html5experts.jp//developers.google.com/web/updates/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">developers.google.com/web/updates/</a> にさらなる情報がありますので、お時間がありましたらご覧ください。</p>

<p>（というところで、セッションは終了しました）</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2016/06/IMG_34891.jpg" alt="IMG_3489" width="640" height="443" class="aligncenter size-full wp-image-19360" srcset="/wp-content/uploads/2016/06/IMG_34891.jpg 640w, /wp-content/uploads/2016/06/IMG_34891-300x208.jpg 300w, /wp-content/uploads/2016/06/IMG_34891-207x143.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>セッション終了後の素敵な笑みを浮かべるChris氏とガッツポーズのFrançois氏</figcaption>
</figure></p>

<p>ありがとうございました＆お疲れ様でしたっ！！！</p>
]]></content:encoded>
			</item>
		<item>
		<title>今、Webの最先端では何が起こっているのか？──最新機能目白押し！Google I/O 2016セッションレポート【前編】</title>
		<link>/ryoyakawai/19335/</link>
		<pubDate>Tue, 14 Jun 2016 00:00:22 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[I/0 2016]]></category>
		<category><![CDATA[Stream]]></category>

		<guid isPermaLink="false">/?p=19335</guid>
		<description><![CDATA[2016年5月18日〜20日、Googleさんの本社Googleplexの横にあるShoreline Amphitheatre（ショアライン アンフィシアター）で行われたGoogle I/0 2016のセッション「Wha...]]></description>
				<content:encoded><![CDATA[<p>2016年5月18日〜20日、Googleさんの本社Googleplexの横にあるShoreline Amphitheatre（ショアライン アンフィシアター）で行われたGoogle I/0 2016のセッション「What&#8217;s new for the web?」についてのレポート前編です。前編では、Webの最先端として、既に導入済みの機能やAPI、またこれから導入される機能を怒涛のごとく紹介します！</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2016/06/beforesession.jpg" alt="beforesession" width="640" height="427" class="aligncenter size-full wp-image-19421" srcset="/wp-content/uploads/2016/06/beforesession.jpg 640w, /wp-content/uploads/2016/06/beforesession-300x200.jpg 300w, /wp-content/uploads/2016/06/beforesession-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>セッション開始前の会場入口</figcaption>
</figure></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2016/06/IMG_3404.jpg" alt="IMG_3404" width="640" height="213" class="aligncenter size-full wp-image-19422" srcset="/wp-content/uploads/2016/06/IMG_3404.jpg 640w, /wp-content/uploads/2016/06/IMG_3404-300x100.jpg 300w, /wp-content/uploads/2016/06/IMG_3404-207x69.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>登壇者：左：Chris Wilson氏、右：François Beaufort氏</figcaption>
</figure></p>

<h1>今現在Webで起こっていること</h1>

<h3>Progressive Web App (<a href="https://html5experts.jp//goo.gl/WR7yJ3" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">goo.gl/WR7yJ3</a>)</h3>

<p>Service Worker、Add to Home Screen、App Manifest、Background Sync等を使い、NativeアプリのようなUXを提供するWebアプリを指す言葉です。
Chris氏いわく、23年間Webをやってきているけど、やっと理想だと思っていた世界、ユーザーとのエンゲージ率が高いUXを持つサイトがWebというPlatformのみで制作することが可能になっている。（作り方等の詳細は<a href="https://www.youtube.com/watch?v=0SSI8liELJU" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">こちら</a>「The Mobile Web: State of the Union」でとのこと）</p>

<p>けど、ここで話すのは既に利用可能なCutting Edgeな話ではなくて、「New Shiny」と呼んでるWeb PlatformのBleeding Edgeな話をします。なので、まだリリースされていない機能だったりCross-Browser、Cross-Deviceで動かない機能、Experimentalフラグの変更を必要とする機能も含まれます。</p>

<p>ただここではカバーしない機能もあり、その代表的なものの一覧はこちらです。</p>

<p><img src="/wp-content/uploads/2016/06/02.png" alt="not coverd" width="640" height="357" class="aligncenter size-full wp-image-19354" srcset="/wp-content/uploads/2016/06/02.png 640w, /wp-content/uploads/2016/06/02-300x167.png 300w, /wp-content/uploads/2016/06/02-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h2>New Shiny（Bleeding Edge）</h2>

<h3>開発をより簡単に速くするための機能(導入済み)</h3>

<h4>Promise</h4>

<p>非同期のAPIの記述を一貫性のあるパターンで書く方法です。Callbackのように混乱しやすかったり、散らかりやすくなく、同期APIをブロックすることもなくなります。Web開発はブロッキングをなくすようなデザインをするように考え方を変える必要があります。なのでPromiseは新たなWebのAPIをデザインするときには一般的な方法になっていて、以下はPromiseを使うAPIとしてデザインされている代表的なものです。</p>

<ul>
<li>HTMLMediaElement.play()：Promiseに書き換えられました</li>
<li>Web Bluetooth</li>
<li>Web USB</li>
<li>Web MIDI</li>
</ul>

<p><a href="https://www.chromestatus.com/feature/5681726336532480" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>Fetch</h4>

<p>FetchもPromiseを使っています。FetchはXMLHTTPRequest(XHR)と似ていてNetworkリクエストを行います。XHRとの違いはPromiseを使って可読性が上がっているところ。Fetchで何をしているか分からなくても、見たら何となく内容を理解できるところです。Callback地獄からの脱却、XHRの複雑な部分から開放してくれる。例えば、直接JSONや他のデータ・タイプを扱うことも可能です。</p>

<p>左がFetch、右がXHR。パッと見、XHRとも悪くないけど、Stateのチェックとかしてないから悪くないのであって、本来はもっと長くゴチャゴチャするのでご注意してください。</p>

<p><img src="/wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.27.41-PM1.png" alt="Screen Shot 2016-06-03 at 10.27.41 PM" width="640" height="222" class="aligncenter size-full wp-image-19362" srcset="/wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.27.41-PM1.png 640w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.27.41-PM1-300x104.png 300w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.27.41-PM1-207x72.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>そしてES6のアロー・ファンクションを使うと、さらにこんなにもキレイになります。</p>

<p><img src="/wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.45.55-PM.png" alt="Screen Shot 2016-06-03 at 10.45.55 PM" width="640" height="358" class="aligncenter size-full wp-image-19365" srcset="/wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.45.55-PM.png 640w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.45.55-PM-300x168.png 300w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.45.55-PM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>ただ、さらなるチャレンジ。問題はこのままだとデータを完全に取得してからでないとJSONとしてParseができないところ。つまりAtomicで割り込みができない。そこで実装中なのが、このFetchやその他のAPIの本当の能力を引き出す機能、それがStreamです。
<br>
<a href="https://www.chromestatus.com/feature/4531143755956224" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>Stream</h4>

<p>Streamは基本的な要素で、その使い道はいろいろあると思います。Jakeはこんなことを言ってます。「Streamは2016年の大きな1つの機能になるだろう」と。なぜならStreamはProgressiveなデータ転送を可能にするからです。全てのデータを受け取っていない状態でも、受け取った順に処理することができる。つまり、Progressiveなレンダリングだったり処理が可能になるのです。App Shellアーキテクチャを使う場合等は1度に複数の場所からデータを取得するので、とても重要な要素になります。</p>

<p>画像は左側の「Fetch」の全てが終わらないと真ん中の「Process」に進めない、それに引きづられて最終的な「Render」も遅くなってしまう、を表した図。</p>

<p><img src="/wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.58.02-PM.png" alt="Screen Shot 2016-06-03 at 10.58.02 PM" width="640" height="358" class="aligncenter size-full wp-image-19367" srcset="/wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.58.02-PM.png 640w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.58.02-PM-300x168.png 300w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-03-at-10.58.02-PM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>Jakeが作成したOffline Wikipediaのサイトで、Streamを使うとどれくらい差がでるかを比較したデモ動画です。左からServer Render、Service Worker Client Render、Service Worker Client+Hacks Render、一番右がStreamを使ったService　Worker Client Renerです。（画像が小さくてすみません。セッションでのビデオ再生は<a href="https://youtu.be/bK6Ah68jEX8?t=7m18s" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ココ</a>から見られます）</p>

<p><img src="/wp-content/uploads/2016/06/wikipedia_loop.gif" alt="wikipedia_loop" width="420" height="273" class="aligncenter size-full wp-image-19436" /></p>

<p>初期のレンダリングは一番左のServer Renderが他よりも8倍くらい遅い、しかしレンダリング完了までだとnon Streamの真ん中の2つよりも速い。この理由は、真ん中の2つは全てのデータを取得するのを待ち、それから処理を始め、その後最終的にレンダリングされるからです。せっかくのハイパフォーマンスなProgressiveなWebアプリなサイトであるのに、表示が遅くては致命的とも言えるでしょう。実際に、現況ではApp Shellアーキテクチャのがコストが高い（時間がかかる）場合もあります。
<br>
<a href="https://www.chromestatus.com/feature/6605041225957376" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<p>さらにパフォーマンスをテーマに話を続けます。ハイパフォーマンスなWebサイトを作るために実装しているエキサイティングなその他の機能を紹介します。</p>

<h4>RequestIdleCallback</h4>

<p>多くのWebアプリ、サイト上では多くのスクリプトが動いていることと思います。しかし全てのスクリプトがユーザーが見ている画面に直接関係のあるスクリプトではなかったりしますよね。例えば、Analyticsデータの送信です。スクロール中に動いてしまうとスクロールがロックしたりユーザー体験（UX）の質は下がります。そこで、そういったユーザーが見ている画面に直接影響を及ぼさない処理を空いている時間に走らせよう、という機能がRequestIdleCallbackです。</p>

<p>RequestAnimationFrameはできるだけ60fpsで表示ができるようその処理をスケジュールしています。そして、RequestIdleCallbackはRequestAnimationFrameと一緒に動作しています。レンダリングに関係しない処理を、レンダリング処理が空いているところにスケジュールしてくれる、という動きです。</p>

<p><img src="/wp-content/uploads/2016/06/Screen-Shot-2016-06-04-at-12.03.01-AM.png" alt="Screen Shot 2016-06-04 at 12.03.01 AM" width="640" height="359" class="aligncenter size-full wp-image-19387" srcset="/wp-content/uploads/2016/06/Screen-Shot-2016-06-04-at-12.03.01-AM.png 640w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-04-at-12.03.01-AM-300x168.png 300w, /wp-content/uploads/2016/06/Screen-Shot-2016-06-04-at-12.03.01-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>実装は難しくないけど、ここで動かしたいタスク（処理）の1つ1つはリーズナブルな時間で終わるように分割されている必要があります。時間がかかるタスクは今まで通りWeb Workerで動作させることをおすすめします。ちなみにNetflex、Facebookはこの機能を既に導入しています。
<br>
<a href="https://www.chromestatus.com/feature/5572795866021888" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>PassiveEventListener</h4>

<p>新しいDOMの機能でChrome 51でShipされます(I/O後の2026年5月下旬にリリースされました)が、ユーザーによりよいスクロール機能を提供するための機能です。導入はすごく簡単。</p>

<p>スムーズなスクロールの機能はWebにとって、特にタッチデバイスでのWebにとってはとても重要です。モダンなブラウザは高コストなJavaScriptがUIスレッドで走っていたとしても、スクロールを別スレッドでハンドリングする機能を持っています。</p>

<p>なのですが、問題はそれがタッチやスクロールeventハンドラを持っていると、最適化で負けてしまうところです。なぜならそれらのハンドラは.preventDefaultをCallすることでスクロールを完全にブロックしてしまうからです。eventハンドリング中に.preventDefaultがCallされるかどうかは分からないので、高コストなJavaScriptの処理が完了するまで待つ必要が出てきてしまうのです。</p>

<p>そこでPassiveEventListenerでは、.preventDefaultをCallしないと宣言し、スクロールがeventによってブロックされないようにするのです。</p>

<p>Chrome for Androidではその80%のTouchEventがブロックされる必要はないのにブロックされている。その10％がスクロール開始までに最低100ms待ち時間が生じた。さらに、その1％は500msの待ち時間がスクロール開始までに生じている。</p>

<p>CNNのサイトで導入したのと、していないのとで比較をしてみます。（ビデオは<a href="https://youtu.be/bK6Ah68jEX8?t=11m26s" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>から：preventdefaultをcallしてないのに遅くなっているのとPassiveEventListenerを使った場合の比較ビデオ）</p>

<p>この違いを生むための実装は、たったこれだけです。</p>

<p><img src="/wp-content/uploads/2016/06/PassiveEvent.png" alt="PassiveEvent" width="640" height="360" class="aligncenter size-full wp-image-19393" srcset="/wp-content/uploads/2016/06/PassiveEvent.png 640w, /wp-content/uploads/2016/06/PassiveEvent-300x169.png 300w, /wp-content/uploads/2016/06/PassiveEvent-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p><a href="https://www.chromestatus.com/feature/5745543795965952" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>Intersection Observer</h4>

<p>特定のDOM Elementが画面内に入っているかどうかを見る、またその場所も簡単に得ることができるのがこのAPI。今までも実装は可能だったけど、効率的ではなかったし問題もいろいろあった。では、Intersection Observerのコードを見てみましょう。</p>

<p><img src="/wp-content/uploads/2016/06/code_intersectionobserver.png" alt="code_intersectionobserver" width="640" height="363" class="aligncenter size-full wp-image-19403" srcset="/wp-content/uploads/2016/06/code_intersectionobserver.png 640w, /wp-content/uploads/2016/06/code_intersectionobserver-300x170.png 300w, /wp-content/uploads/2016/06/code_intersectionobserver-207x117.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>画面内に入ったかを監視したいターゲットとなるElementを決めましょう。そしてIntersectionObserverのオブジェクトの生成時します。生成時には画面内に入った場合の動作についてのCallbackも渡します。最後に生成したオブジェクトでどのElementを監視するかを指定します。（デモページ：<a href="https://html5experts.jp//goo.gl/mNdYRv" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">goo.gl/mNdYRv</a>、Chrome 51以降で御覧ください）</p>

<p>デモページはとてもスムーズで超速な無限のスクロールを提供しています。コンテンツ表示はネットワークの遅さをシュミレートしているかのように遅れていますが、Service Workerを使ってキャッシュすると解決します。例えば、たくさんの画像を表示するページ等には持ってこいですね。
<br>
<a href="https://www.chromestatus.com/feature/5695342691483648" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>&lt;link rel=&#8221;preload&#8221;&gt;</h4>

<p>Chrome 50でShip済みで、リソースのPreload（事前読み込み）を行います。遷移先のページを事前取得する&lt;link rel=&#8221;prefetch&#8221;&gt;とは違い、現在のページ内のリソースを読み込む優先順位を指定ができる属性です。
<br>
<a href="https://www.chromestatus.com/feature/5757468554559488" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>HTTP Clients Hints</h4>

<p>HTTPヘッダにつけることで取得するコンテンツの種類を事前ネゴシエーションすることができる。ネゴシエーションの要求を出すことで、ユーザーのデバイス、環境によってサーバ側が提供されるコンテンツを差替えてServeすることが可能です。サーバ側に実装されるものであって、クライアント側のコードで指定するものではありませんが、以下の様な要求ができるように用意されています。</p>

<ul>
<li>DevicePixelRatio(DPR)</li>
<li>Preferred widt</li>
<li>viewport-width</li>
<li>save-data: サーバにデータ転送を節約していることを知らせることができる</li>
</ul>

<h4>Canvas.toBlob</h4>

<p>Chrome 50でShip済みで、クライアント側でCanvasをそのままBlobにすることができます。一説によるとこの機能が実現するまでに6年かかったそうです。.toDataURL()から得られるBase64の文字列を操作することなく、画像としてそのままサーバにアップロードしたり、IndexDBに保存したりできるので、より簡単に再利用することが可能になります。
<br>
<a href="https://www.chromestatus.com/feature/4562033294966784" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>ImageBitmap</h4>

<p>Chrome50でShip済みで、ImageBlobを他のCanvasにそのまま描くことも可能になっています。Canvasに描くために画像をデコードするのはとても一般的ですが、画像のデコードにCPUリソースをとても多く使ってしまうという問題点があります。しかし、Base64とデータの間での処理をすることなく扱えるようになったのです。そうすることで、例えば他の画像、エレメント、ビデオ等をCanvasに描くときと同じように扱えるようになりました。
<br>
<a href="https://www.chromestatus.com/feature/5684964708319232" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>Unified Media Pipeline</h4>

<p>クライアントではなくてChrome自体のコードの話です。デスクトップ版でもモバイル版でも全く同じ処理がされるようなMediaようにPipelineを持つようにしました。Chrome for AndroidにおいてもOSが持つAndroid Media Stackでの処理は行わないようにしました。これによりCross-Platformでも一貫した処理（例えばキャッシュ、エンコード、デコード）を行うようになっています。よって、Cross-Platformでのデバッグをより簡単にしています。</p>

<h4>MediaRecorder</h4>

<p>ビデオ、オーディオをキャプチャするだけでなく、エンコードして保存をすることが可能になりました。例えば、取得したオーディオをMP3にクライアント側で変換してサーバにアップロードすることが可能です。
（デモページ：<a href="https://html5experts.jp//simpl.info/mediarecorder" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">simpl.info/mediarecorder</a>、Chrome 49以降でご覧ください）</p>

<p><img src="/wp-content/uploads/2016/06/mediarecorder.png" alt="mediarecorder" width="640" height="358" class="aligncenter size-full wp-image-19416" srcset="/wp-content/uploads/2016/06/mediarecorder.png 640w, /wp-content/uploads/2016/06/mediarecorder-300x168.png 300w, /wp-content/uploads/2016/06/mediarecorder-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<p>コードはこんな感じです。MediaRecorderのオブジェクトをOptionを渡して作成して、データを取得したときのCallbackを.ondataavailableに指定します。Callbackにはどう扱うかを書くのだけど、ほとんどの場合取得したデータ（Blob）をくっつけるだけです。そして、最後にどれだけの長さの動画を作るかを指定して完了です。サーバにアップロードする、ローカルに保存する等ができるようになります。Web Audioでの質問として何度か受けていますが、まさにこれがその解です。
<br>
<a href="https://www.chromestatus.com/feature/5929649028726784" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>Media Session</h4>

<p>Mediaの動作を操作のカスタマイズ、例えばラップトップのオーディオように用意されたキーを特定の機能に割り当てることができたり、モバイルでは通知エリア(Notification Area)、ロック画面にMedia操作用のUIを出すことができるAPI。もしMediaに関するアプリを作っている開発者であれば一度見てもらいたい。
<br>
<a href="https://www.chromestatus.com/feature/5639924124483584" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>CSS Variables</h4>

<p>正確にはCSS Custom Propertyとも言いますがChrome 49でShipされています。例えば、同じ属性を何度も繰り返し書くことの削減してくれたり、また色・見た目等のテーマの変更にもとても有効です。
<br>
<a href="https://www.chromestatus.com/feature/6401356696911872" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>CSS Containment</h4>

<p>CSSを隔離してパフォーマンスを最適化してくれる機能です。例えば、3rd Partyのウィジットを使った場合、そのウィジットのCSSを隔離することで自サイトのパフォーマンスに影響が出ないように最適化してくれます。
<br>
<a href="https://www.chromestatus.com/features/6522186978295808" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<h4>CSS Font Loading API</h4>

<p>最初に実装されたのはChrome 35でそこそこ前なんですが、Font LoadingのInterfaceはChrome 48でShipされたばかりです。1つ1つのFont Faceのチェック、またそれらのダウンロード状況を確認できるようになりました。これによりFontが実際にどれくらいダウンロードされたか、どんなFontであるかを知ることができるようになりました。
<br>
<a href="https://www.chromestatus.com/feature/4594172182921216" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[実装状況]</a></p>

<p>Progressiveに速いスピードで短い説明で新しい機能を紹介しまくって、後で調べてね、と言っている感があるように聞こえるかもしれないですので、少し休憩というようなお話をしますね。</p>

<p>（後編の予告など）<br>
ということで、この辺りで前編は終了です。後編はWeb Platformをより先に進めるためにここ1～2年Chromeチームが取り組んでいるアプローチ、Chris氏の大好きなアレ、そしてWeb Bluetoothについてお伝えします。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2016/06/IMG_3473.jpg" alt="pushup" width="640" height="427" class="aligncenter size-full wp-image-19458" srcset="/wp-content/uploads/2016/06/IMG_3473.jpg 640w, /wp-content/uploads/2016/06/IMG_3473-300x200.jpg 300w, /wp-content/uploads/2016/06/IMG_3473-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" /><figcaption>Bluetoothの説明中の一幕。詳しくは後編で！</figcaption>
</figure></p>
]]></content:encoded>
			</item>
		<item>
		<title>Web Music Developer Meetup@札幌レポート</title>
		<link>/ryoyakawai/17532/</link>
		<pubDate>Fri, 25 Dec 2015 00:00:02 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[MIDI]]></category>
		<category><![CDATA[TPAC]]></category>
		<category><![CDATA[W3C]]></category>
		<category><![CDATA[Web Music]]></category>

		<guid isPermaLink="false">/?p=17532</guid>
		<description><![CDATA[本記事は2015年10月25日に札幌で行われたWeb Music Developer Meetup@札幌のレポートです。 Meetupを「札幌」で行うキッカケ 2015年10月末はなぜか札幌でのイベントが多かったと思いま...]]></description>
				<content:encoded><![CDATA[<p>本記事は2015年10月25日に札幌で行われたWeb Music Developer Meetup@札幌のレポートです。<br />
<img src="/wp-content/uploads/2015/11/sapporo01.jpg" alt="sapporo00" width="480" class="aligncenter size-large wp-image-17539" /></p>

<h1>Meetupを「札幌」で行うキッカケ</h1>

<p>2015年10月末はなぜか札幌でのイベントが多かったと思いますが、これ実はW3C Technical Plenary / Advisory Committee(通称：TPAC、てぃーぱっく)というMeetingが札幌で行われたからなのです。</p>

<p>詳細は<a href="https://html5experts.jp/yusuke-naka/16710/" data-wpel-link="internal">Web技術の最新動向と未来を知る！〜Leading the way to W3C TPAC 2015〜【TPAC紹介編】</a>にも書かれていますが、ここでも軽くご説明します。TPACとはWebの標準化団体であるW3Cが年に1回行う全体会合で、通常10月最終週の5日間で北米、ヨーロッパ、アジアのどこかで開催されます。</p>

<p><strong>全体会合</strong>とはいえ、5日間通して全体会議をしている訳ではなくて、実際に全体で集まるのはたいて中間日のTechnical Plenary Dayと呼ばれる日。この日だけはアンカンファレンス形式で進められ、当日の朝に話したい内容がある人が場所を確保して分科会(Breakout Session)を行う、という流れになっています。
<figure>
<img src="/wp-content/uploads/2015/11/breakout00.jpg" alt="breakout00" width="640" class="aligncenter size-medium wp-image-17535" srcset="/wp-content/uploads/2015/11/breakout00.jpg 640w, /wp-content/uploads/2015/11/breakout00-300x200.jpg 300w, /wp-content/uploads/2015/11/breakout00-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption class="aligncenter">分科会の場所を確保する様子</figcaption>
</figure></p>

<p>この日以外は、W3Cにある43のワーキング・グループ（2015年11月6日現在）からそれぞれが議論したい内容、メンバーのスケジュールから日程設定してFace to Faceでのミーティングを行っています。たいていの場合メンバーは世界各国に散らばっているため、普段は電話での会議をしているので顔を合わせてミーティングを行うのは、非常に貴重な時間となっています。</p>

<p>前段が長くなりましたが、ここから本題です。Web Audio API、Web MIDI API（Web Music）の仕様を策定しているのはW3Cのオーディオ・ワーキンググループ(Audio WG)。今回のTPACでは26日、27日にミーティングを行うことになりましたので、せっかくのこの機会に「Audio WGのメンバーとイベントやろう！」と思い立ったのが、今回のMeetupのキッカケです。</p>

<h1>「札幌」でWeb Musicは初めて</h1>

<p>今まで日本で開催されたWeb Music関連イベントは、東京と京都でのハッカソンとMeetup1回だったので、北海道では初めて。そこで、Meetupにして「Web Musicとはなんぞ？」を中心に伝えられるように、以下の方々に登壇していただきました。</p>

<ul>
<li><a href="https://html5experts.jp//twitter.com/ryoyakawai" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">かわい りょうや</a>（開発者、私です）</li>
<li><a href="https://html5experts.jp//twitter.com/cwilso" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Chris Wilson 氏</a> (Web Audio/MIDI 仕様の編集者)</li>
<li><a href="https://html5experts.jp//twitter.com/aike1000" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">藍 圭介 氏</a>（開発者）</li>
<li><a href="https://html5experts.jp//twitter.com/toyoshim" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">豊島 隆志 氏</a>（ChromiumコミッターでWeb MIDI APIの実装者）</li>
<li><a href="https://html5experts.jp//twitter.com/joeberkovitz" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Joe Berkovitz 氏</a> (Audio WGの共同議長)</li>
<li><a href="https://html5experts.jp//twitter.com/sascacci" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">渡邊 正和 氏</a>（開発者：VJアプリを主に開発）</li>
</ul>

<h1>セッションの内容</h1>

<h3>かわい りょうや</h3>

<p>Web Audio、Web MIDIとは何か、何ができるのか、どのブラウザで使えるのかを中心に話をしました<a href="https://html5experts.jp/ryoyakawai/12569/" data-wpel-link="internal">ブラウザで電子楽器を作ってみよう！</a>でご紹介したWeb Audioで作ったアナログ・シンセ、FMシンセの紹介とデモを行い、基本的な使い方とできることの説明、またそれに加えて今回はServiceworkerを使ったオフラインでの動作のデモ、またデスクトップからアプリを起動できるWebApp Manifestのデモも実施。モバイル上でもWebアプリは進化していてNativeアプリに近づいていることの説明を行いました。<br />
▶ <a href="https://www.slideshare.net/ryoyakawai/web-musicdevelopersmeetupsapporo" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><strong>スライド</strong></a></p>

<h3>Chris Wilson 氏</h3>

<p><img src="/wp-content/uploads/2015/11/cwilso-300x200.jpg" alt="cwilso" width="300" height="200" class="aligncenter size-medium wp-image-17597" srcset="/wp-content/uploads/2015/11/cwilso-300x200.jpg 300w, /wp-content/uploads/2015/11/cwilso.jpg 640w, /wp-content/uploads/2015/11/cwilso-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" />
<strong>Making the Web Rock</strong>というタイトルで<a href="http://webaudiodemos.appspot.com/MIDIDrums/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Drum Machine</a>、<a href="https://webaudiodemos.appspot.com/Vocoder/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ボコーダー</a>、<a href="https://webaudiodemos.appspot.com/input/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Audio Input Effect</a>、<a href="http://webaudiodemos.appspot.com/wubwubwub/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">DJ</a>と次々にデモを披露していただき、「Web Audio API、Web MIDI APIを使うとWebブラウザ上でここまでできます」という点を幅広く説明してくれました。また「この<a href="https://aerotwist.com/blog/guitar-tuner/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Webアプリのチューナ</a>ができたおかげでOSネイティブなチューナーアプリ（iOSやAndroidのアプリ）は全部消した」という実話も披露していただきました。チューナーとは音の周波数（音程）を正しく調整する為に使う器具のことです。<br />
▶ <a href="http://webaudiodemos.appspot.com/slides/index.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><strong>スライド</strong></a></p>

<p>ここでChris氏の発表の中から「Webアプリのチューナ以外のOSネイティブなチューナーアプリを削除できた」という点について、旬な話題ですので少しだけご紹介します。</p>

<p><strong>どのようにWebアプリのチューナーが実装されているか</strong><br />
チューナーは例えばギターの弦1本1本を正しく調整（チューニング）する為に、1本の弦を弾いた時に発せられる音声を入力して周波数を正しく表示します。この表示に従って、弦毎にあるべき周波数にチューニングをすることで常に正しい音で演奏しています。このチューニングは演奏する間に必ず行うので、自宅のみならず、あらゆる場所で動作することが求められます。ここでまとめるとチューナーという器具には最低限以下の2つの要件を満足することが求められます。</p>

<ul>
<li>入力した音声の周波数を正しく表示する</li>
<li>携帯性に優れている</li>
</ul>

<p>モバイル・デバイスのアプリ（iOSアプリケ、androidアプリ；以後「モバイルアプリ」と略します）で製作したチューナーはこれらの2つの要件を満足します。チューニングに関してはマイクから入力した音の周波数を正しく表示するよく知られたアルゴリズムがありますし、携帯性に関してもチューナーアプリを一度ダウンロードしてインストールしてしまえばネットワークへの接続に左右されることなく携帯端末上で動作することが可能ですので、  場所を選ばずどこでも動作します。<br />
前置きが長くなりましたが、ここからがこの2つの要件をどうやってWebアプリとして再現するのか？という点です。1つ目の「入力した音声の周波数を正しく表示する」に関しては、getUserMedia()を使いマイク入力をWeb Audio APIを使って周波数を割り出せばなんとか出来そうだと、とお気づきになると思います。しかしながら「携帯性に優れている」の点はいかがでしょうか？ネットワーク接続なしにどうやってWebアプリを動作させるのでしょうか？<br />
その解決には <em>Service Worker</em> を使います。Webアプリを最初に起動した時に、アプリ全体をキャッシュしてしネットワーク接続のに場合はそのキャッシュを利用してアプリを動かすのです。WebアプリのチューナのService Workerの実装は<a href="https://guitar-tuner.appspot.com/sw.js" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ココ</a>にされています。詳しい解説はここでは割愛しますが、Servive Workerインストール時（最初にサイトを表示した時と考えていただいて問題ありません）に、以下の部分でWebアプリのチューナーに必要なファイルをキャッシュしていることが分かります。</p>

<p></p><pre class="crayon-plain-tag">self.oninstall = function(event) {

  var urls = [

    '/',
    '/images/chrome-touch-icon-192x192.png',

    '/scripts/guitartuner-core.js',

    '/elements/audio-processor/audio-processor.html',
    '/elements/audio-visualizer/audio-visualizer.html',
    '/elements/tuning-instructions/tuning-instructions.html',
    '/elements/tuning-instructions/tick.svg',
    '/elements/tuning-instructions/up-down.svg',

    '/third_party/polymer.html',
    '/third_party/webcomponents-lite.min.js',

    '/third_party/Roboto/Roboto-100.woff2',
    '/third_party/Roboto/Roboto-300.woff2',
    '/third_party/Roboto/Roboto-400.woff2',

    '/favicon.ico',
    '/manifest.json'

  ];

  urls = urls.map(function(url) {
    return new Request(url, {credentials: 'include'});
  });

  event.waitUntil(
    caches
      .open(CACHE_NAME + '-v' + CACHE_VERSION)
      .then(function(cache) {
        return cache.addAll(urls);
      })
  );

};</pre><p></p>

<p>もう1点は起動に関してです。Webアプリとして再現できたのに、起動がブラウザのブックマークからだったり、URLバーが表示されていては少しガッカリです。androidであれば、Webアプリであっても、ホーム画面のアイコンから起動し、URLバーを表示しないことが可能です。また起動時のデバイスの向き、スプラッシュ画面（起動処理中に表示する画像）を設定することも可能です。これを <em>Web App Manifest</em> と呼ばれる機能になります。Webアプリのチューナでは<a href="https://guitar-tuner.appspot.com/manifest.json" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ココ</a>に実装されています。</p>

<p></p><pre class="crayon-plain-tag">{
  "short_name": "Guitar Tuner",
  "name": "Guitar Tuner",
  "start_url": "./?utm_source=web_app_manifest",
  "icons": [
    {
      "src": "/images/chrome-touch-icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    }
  ],
  "display": "standalone",
  "orientation": "portrait"
}</pre><p> 
この数行のJSONを設置して、メインとなるHTMLには以下の1行を追加して読み込ませたらモバイルアプリと同じユーザー体験（ホーム画面からの起動）を提供することが可能になります。
</p><pre class="crayon-plain-tag">&lt;link rel="manifest" href="/manifest.json"&gt;</pre><p></p>

<p>詳細な説明は割愛してしまいましたが、こういった技術を使ってProgressive Web Appsを作ってみてはいかがでしょうか？</p>

<h3>藍 圭介 氏</h3>

<p><img src="/wp-content/uploads/2015/11/aike-300x200.jpg" alt="aike" width="300" height="200" class="aligncenter size-medium wp-image-17599" srcset="/wp-content/uploads/2015/11/aike-300x200.jpg 300w, /wp-content/uploads/2015/11/aike.jpg 640w, /wp-content/uploads/2015/11/aike-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" />
<strong>Web Audio API Creative Coding</strong>というタイトルで、moogのアナログシンセのWeb版の<a href="http://aikelab.net/websynth/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">2D版</a>、<a href="http://aikelab.net/websynthv2/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">3D版</a>、それ以外にもセンサーを使うことで<a href="http://aikelab.net/iphonewah/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Wahペダル</a>だったり、<a href="http://aikelab.net/sw/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ライトセーバー</a>のような動きに反応するアプリケーションも作ることが可能というデモを実施。Web Audio/MIDI以外のAPIとの親和性も高く、手軽に使えることから「Web Audio/MIDIは音楽のためのみならず、表現メディアのプラットフォームになり得る」という点をご説明してくださいました。<br />
▶ <a href="http://aikelab.net/wmmu/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><strong>スライド</strong></a></p>

<h3>豊島 隆志 氏</h3>

<p><img src="/wp-content/uploads/2015/11/toyoshim-300x200.jpg" alt="toyoshim" width="300" height="200" class="aligncenter size-medium wp-image-17600" srcset="/wp-content/uploads/2015/11/toyoshim-300x200.jpg 300w, /wp-content/uploads/2015/11/toyoshim.jpg 640w, /wp-content/uploads/2015/11/toyoshim-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" />
<strong>Chrome Web MIDI 2015</strong>というタイトルで発表。実際にChromeに実装をしているので、今までのWeb MIDIの実装の歴史、AndroidのWeb ViewでもOperaでもElectronでもChromeと同じようにWeb MIDIが使えるようになっていること、Firefoxでの実装状況、Web MIDI APIの使われる頻度等、APIを実装するという視点から発表をしてくれました。<br />
▶ <a href="http://www.slideshare.net/toyoshim/chrome-web-midi-2015-54372357" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><strong>スライド</strong></a></p>

<h3>Joe Berkovitz 氏</h3>

<p><img src="/wp-content/uploads/2015/11/joe-300x200.jpg" alt="joe" width="300" height="200" class="aligncenter size-medium wp-image-17601" srcset="/wp-content/uploads/2015/11/joe-300x200.jpg 300w, /wp-content/uploads/2015/11/joe.jpg 640w, /wp-content/uploads/2015/11/joe-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" />
<strong>Music Notation and W3C:
Framing the Future</strong>というタイトルでの発表。Audio WGの共同議長でもあり、また2015年7月にW3CでMusic Notation Community Group(楽譜に関するグループ)の立ち上げも行っており、普段はnoteflight Inc.にてブラウザ上で楽譜を表示、演奏するアプリケーションを開発しています。今回の発表では、Noteflightが実際に楽譜表示を軸にどういった機能を実装しているのか、またWeb上で表示できるようになるとどう変わるのかをデモを交えながらの発表でした。<br />
▶ <a href="https://html5experts.jp/wp-content/uploads/2015/11/MusicNotationNext.pdf" data-wpel-link="internal"><strong>スライド(PDF)</strong></a></p>

<h3>渡邊 正和 氏</h3>

<p><img src="/wp-content/uploads/2015/11/watanabe-300x200.jpg" alt="watanabe" width="300" height="200" class="aligncenter size-medium wp-image-17602" srcset="/wp-content/uploads/2015/11/watanabe-300x200.jpg 300w, /wp-content/uploads/2015/11/watanabe.jpg 640w, /wp-content/uploads/2015/11/watanabe-207x138.jpg 207w" sizes="(max-width: 300px) 100vw, 300px" />
<strong>ライブパフォーマンス、その他（例えば教育）でのWeb Audio/MIDIの活用事例</strong>を紹介。Audio/MIDIがWeb上で使えることで拡がった、音楽の世界を語ってくれました。<a href="https://dl.dropboxusercontent.com/u/50143793/app/lissajous_float.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">リサジューのデモ</a>も披露。</p>

<ul>
<li><a href="http://sascacci-blog.tumblr.com/post/126325315693/takashi-mori-x-masakazu-watanabe" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Takashi Moriさんの演奏とのコラボ</a></li>
<li><a href="http://sascacci-blog.tumblr.com/post/132239501178/networks" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">NETWORKSとのコラボ</a></li>
<li><a href="http://sascacci-blog.tumblr.com/post/127920844973/%E3%82%A8%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AD%E3%83%9C%E3%82%A4%E3%82%B9%E3%81%A8%E3%83%93%E3%82%B8%E3%83%A5%E3%82%A2%E3%83%AB%E3%82%A2%E3%83%BC%E3%83%88" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">エレクトロボイスとビジュアルアート</a></li>
</ul>

<h1>Lightning Talk</h1>

<p>3名、1団体からの発表がありました。</p>

<ul>
<li><a href="https://twitter.com/aklaswad" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@aklaswad</a>さん:
wani[WebAudio N Interface]の<a href="http://aklaswad.github.io/wani/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">デモ</a></li>
<li><a href="https://twitter.com/edy555" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">高橋さん</a>：<a href="https://github.com/ttrftech/threejs-spectrum" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ワンセグチューナーから電波を拾ってthree.jsで電波を表示するデモ</a></li>
<li><a href="https://twitter.com/plusadd" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">小池さん</a>：楽譜アプリのpiaScoreの説明とPlasaddがスタッフ募集している件、</li>
<li><a href="http://jp.yamaha.com/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ヤマハ株式会社</a>：MIDI、音楽系でよく使われるOSC(OpenSound Control)と、Web Socketをごちゃ混ぜのシステムでも簡単に構築できるRaspberry Piで作ったシステムの紹介がありました。</li>
</ul>

<h1>Meetupを終えて</h1>

<p>今回Audio WGでコアに動いている方のほとんどがMeetupに足を運んでくれたこともあって、日本の皆さんにはもとより、Audio WGの皆様には「こういう使われ方もしている」という現状を見ていただけて、とてもよい機会になったと思っています。今後もこういう機会があったら企画したいと考えています。<br />
▶ <a href="https://plus.google.com/u/0/events/coke57atppv4rvgkiueu5mco7tg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer"><strong>写真等</strong></a></p>

<h1>おまけ：Web Audio、Web MIDIの進捗に関して</h1>

<p>W3Cが定める仕様策定までの5段階のうち、Web Audio/MIDI共に、現在は1つ目の段階（WD:Working Draft）です。しかし、Web Audioは次の段階（LC:Last Call）へと進む気配があります。早くて年内、遅くとも来年4月（<a href="http://webaudio.gatech.edu/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web Audio Conference 2016があります</a>）ではないでしょうか。またWeb MIDIに関してもFirefoxに実装が進んでいてMac OSでは動いているとのことですので、こちらも次の段階へ進むことへの期待ができるでしょう。</p>

<p><figure>
<img src="/wp-content/uploads/2015/11/audiowg-640x427.jpg" alt="audiowg" width="640" height="427" class="aligncenter size-large wp-image-17579" srcset="/wp-content/uploads/2015/11/audiowg.jpg 640w, /wp-content/uploads/2015/11/audiowg-300x200.jpg 300w, /wp-content/uploads/2015/11/audiowg-207x138.jpg 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption class="aligncenter">Audio WGのミーティングの様子</figcaption>
</figure></p>

<p>それでは、今後もWeb Musicをよろしくお願いします！</p>
]]></content:encoded>
			</item>
		<item>
		<title>MIDIデバイスの準備不要！お手軽な『MIDIアプリ』実装法</title>
		<link>/ryoyakawai/17337/</link>
		<pubDate>Fri, 27 Nov 2015 00:00:53 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Web MIDI API]]></category>

		<guid isPermaLink="false">/?p=17337</guid>
		<description><![CDATA[連載： MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！ (2)この記事は、Web MIDI APIを題材にした連載の第二回目です。（第一回目はこちら） 第一回目はWeb MIDI APIでMIDI...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/webmidi-2015/" class="series-347" title="MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！" data-wpel-link="internal">MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！</a> (2)</div><p>この記事は、Web MIDI APIを題材にした連載の第二回目です。（第一回目は<a href="https://html5experts.jp/ryoyakawai/16787/" data-wpel-link="internal">こちら</a>）</p>

<p>第一回目はWeb MIDI APIでMIDI Inputデバイス、Outputデバイスを列挙し、利用する実装方法を説明してきましたが、詳細の実装の説明までできていませんでした。第二回ではx-webmidiというPolymer Elementを使い、第一回で実装した部分、また実装ができていなかったHotplugを含めて、お手軽に実装してしまう方法をご説明します。</p>

<p>前回に引き続き、今回もMIDIデバイスの準備は不要な内容になっていますので、最後までお試しいただけると嬉しいです。</p>

<h1>Polymerとは？</h1>

<p>「Web Componentsを簡単・便利にするライブラリ」です。Polymerを使うと簡単にWeb ComponentsのElementを作成することが可能です。本サイトHTML5Expert.jpでも連載記事がありますので、ぜひご覧ください。</p>

<ul>
<li><a href="https://html5experts.jp/series/web-components-2/" data-wpel-link="internal">基礎からわかる Web Components 徹底解説</a>  </li>
</ul>

<p>そして今回は、Web MIDI APIをPolymer Element化したx-webmidiを使って、以下の2つのアプリの実装をしていきます。</p>

<ol>
 <li>InputからOutputにMIDIメッセージを中継するアプリ</li>
 <li>SMF（Standard MIDI File）を再生するアプリ</li>
</ol>

<h1>x-webmidiとは？</h1>

<p>Web MIDI APIは、外部のMIDIデバイスとUSB-MIDIで接続するAPIです。API自体には<strong>「デバイスをリストする」</strong>、<strong>「デバイスへMIDIメッセージを送信する」</strong>、<strong>「デバイスからのMIDIメッセージを受信を行う」</strong>、また、接続に関しては<strong>「Hotplug」</strong>が、それぞれサポートされています。</p>

<p>しかし、これらを実装するのは少し手間がかかります。自分自身の体験としては、複数アプリケーションを書いていると「アイデアをアプリケーションに落としこむ時、MIDIデバイスの制御の部分に労力をかけるのは極力抑えたい」と思うようになりました。そこで考えついたのが、Polymerを使って基本的な操作はElementにしてしまう方法です。そして生まれたのが<strong>「x-webmidi 」</strong>です。</p>

<h1>さっそく実装してみよう</h1>

<h3>環境整備</h3>

<p><a href="https://html5experts.jp/ryoyakawai/16787/" data-wpel-link="internal">連載第一回目の環境整備</a>と同じです。ここでは手短に説明します。<br />
Polymer本体、今回利用するx-webmidiをそれぞれダウンロードします。</p>

<ul>
 <li><a href="http://zipper.bowerarchiver.appspot.com/archive?polymer=Polymer/polymer%231.0.0" target="blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a></li>
 <li><a href="https://github.com/ryoyakawai/x-webmidi/archive/0.10.23.zip" target="blank" data-wpel-link="external" rel="follow external noopener noreferrer">x-webmidi</a></li>
</ul>

<p>開発するディレクトリを作成して、ダウンロードした2つのファイルを解凍し、以下の構成になるように配置してください。その後、同一ディレクトリにindex.htmlを作成します。</p>

<p><img src="/wp-content/uploads/2015/10/xwebmidi-directory-02.png" alt="Directory Structure" width="300" class="aligncenter size-full wp-image-17346" srcset="/wp-content/uploads/2015/10/xwebmidi-directory-02.png 535w, /wp-content/uploads/2015/10/xwebmidi-directory-02-300x183.png 300w, /wp-content/uploads/2015/10/xwebmidi-directory-02-207x126.png 207w" sizes="(max-width: 535px) 100vw, 535px" /></p>

<p>以上で環境整備は完了です。</p>

<p>では、実際に実際に開発を行っていきましょう。</p>

<h3>InputからOutputにMIDIメッセージを中継するアプリ</h3>

<p>作成する index.html のコード全体は<a href="https://github.com/ryoyakawai/x-webmidi/blob/gh-pages/src/hx_webmidi_02.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>になります。それでは順に説明していきます。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.js"&gt;&lt;/script&gt;
&lt;link rel="import" href="bower_components/x-webmidi/x-webmidirequestaccess.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-webmidilink/wm-webmidilink.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-pckeyboard/wm-pckeyboard.html"&gt;
&lt;x-webmidirequestaccess input output&gt;&lt;/x-webmidirequestaccess&gt;

&lt;wm-webmidilink id="wmlink"&gt;&lt;/wm-webmidilink&gt;
&lt;wm-pckeyboard id="pckeyboard"&gt;&lt;/wm-pckeyboard&gt;</pre><p></p>

<ul>
<li>1行目：Web ComponentsのPolyfillを読み込み</li>
<li>2〜4行目：Web MIDI API（x-webmidi）、仮想MIDI Outputデバイス(wm-webmidilink)、仮想のInputデバイス(wm-pckeyboard)のPolymer ElementをImport  </li>
<li>5行目：x-webmidiをアクティベート</li>
</ul>

<p>x-webmidiの属性は以下の通りです。</p>

<ul>
 <li><b>input</b>： MIDI Inputデバイスを利用する場合に追加</li>
 <li><b>output</b>： MIDI Outputデバイスを利用する場合に追加</li>
 <li><b>sysex</b>： System Exclusive メッセージを使う場合に追加</li>
</ul>

<p>今回、System Exclusive メッセージは使わないので、inputとoutputのみを記述します。</p>

<ul>
<li>7行目：wm-webmidilinkをアクティベート</li>
<li>8行目：wm-pckeyboardをアクティベート</li>
</ul>

<p>以上で準備は完了です。次にMIDIデバイスのリスト表示を行います。</p>

<p></p><pre class="crayon-plain-tag">input: &lt;x-webmidiinput id="midi-input" additionalid="pckeyboard" autoselect="PC-Keyboard" autoreselect&gt;&lt;/x-webmidiinput&gt;&lt;br&gt;
output: &lt;x-webmidioutput id="midi-output" additionalid="wmlink" autoselect="GMPlayer(WebMIDILink)" autoreselect&gt;&lt;/x-webmidioutput&gt;
&lt;br&gt;</pre><p> 
x-webmidiinputとx-webmidioutputの属性は以下の通りです。</p>

<ul>
 <li><b>additionalid</b>： 仮想のデバイスを追加する場合、そのタグのIDで指定します</li>
 <li><b>autoselect </b>： 自動選択して欲しMIDIデバイス名を指定します</li>
 <li><b>autoreselect </b>： 現在指定しているデバイスが切断され再接続した場合に自動選択します</li>
</ul>

<p>今回は仮想のデバイスを追加するため、属性 additionalid に、input側はpckeyboard(wm-pckeyboardタグのID名)、output側はwmlink(wm-webmidilinkタグのID名)をそれぞれ指定しています。最後に入力されたMIDIメッセージを表示する場所を作ります。
</p><pre class="crayon-plain-tag">&lt;div id="msg" style="margin:30px;"&gt;&lt;/div&gt;</pre><p></p>

<p>Inputから受け取ったMIDIメッセージを中継するためのJavaScriptを記述していきます。
</p><pre class="crayon-plain-tag">var output=document.getElementById("midi-output");
    window.addEventListener("midiin-event:midi-input", function(event){
        for(var i=0, out=[]; i&lt;event.detail.data.length; i++) out.push(("00"+event.detail.data[i].toString(16)).substr(-2));
        var div_msg=document.getElementById("msg");
        var ex_msg=div_msg.innerHTML.split("&lt;br&gt;");
        while(ex_msg.length&gt;19) ex_msg.pop();
        div_msg.innerHTML=out.join(" ")+"&lt;br&gt;" + ex_msg.join("&lt;br&gt;");
        if(output.checkOutputIdx()!="false") {
            output.sendRawMessage(event.detail.data);
        }
    });</pre><p></p>

<ul>
<li>1行目：MIDI OutputのObjectを取得</li>
<li>2行目：MIDI InputからのメッセージはEventとして飛んできますので、EventListenerをつける。Event名は&#8221;midiin-event:&#8221;に続き x-webmidiinput タグで指定したIDになる。MIDI Inputデバイスから入力したMIDIメッセージは event.detail.data。  </li>
<li>3行目：「MIDIメッセージを表示する場所」に表示して、分かりやすいように16進数の文字列にキャスト </li>
<li>4行目：「MIDIメッセージを表示する場所」のElementを取得</li>
<li>5, 6行目：「MIDIメッセージを表示する場所」の表示を新しいメッセージから順に並べるのと同時に表示する行数を絞る</li>
<li>7行目：MIDIメッセージを「MIDIメッセージを表示する場所」に表示</li>
<li>8〜10行目：Outputデバイスが選択されていたら、選択されているデバイスに対してInputから入力されたMIDIメッセージを送信。  </li>
</ul>

<p>これで、InputからOutputにMIDIメッセージを中継することができました。</p>

<h3>SMF（Standard MIDI File）を再生するアプリ</h3>

<p>次にMIDIというと必ず出てくるであろうSMF（Standard MIDI File）の再生です。</p>

<p>SMFはMIDIメッセージ1つ1つに時間情報を付加して、規定のフォーマットにまとめたバイナリファイルです。ここで付加された時間通りにMIDIメッセージを音源モジュールに送ることで、自動演奏ができる仕組みになっています。</p>

<p>SMFをWebブラウザ上で再生するには、SMFのバイナリを読み解いて（パース）、付加されている時間通りにMIDIメッセージを音源モジュールに送信する、という手順になります。しかし、このバイナリファイルをパースするためにはSMFのフォーマットを勉強しないといけません。この問題を解決するべく、SMFのバイナリをパースする部分を、<strong>「wm-smfplayer」</strong>というPolymerのElementにしてみました。このElemetでSMFを再生するアプリを作ってみます。</p>

<p>作成する index.html のコード全体は<a href="https://github.com/ryoyakawai/x-webmidi/blob/gh-pages/src/smfplayer.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>になります。それでは順に説明していきます。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.js"&gt;&lt;/script&gt;
&lt;link rel="import" href="bower_components/x-webmidi/x-webmidirequestaccess.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-webmidilink/wm-webmidilink.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-smfplayer/wm-smfplayer.html"&gt;
&lt;x-webmidirequestaccess input output sysex&gt;&lt;/x-webmidirequestaccess&gt;</pre><p></p>

<ul>
<li>1〜3行目：「InputからOutputにMIDIメッセージを中継するアプリ」と同じ</li>
<li>4行目：SMFをパースするElementを読み込む。SMFの中にはSystem Exclusiveが入っている場合があるので属性を書いています。  </li>
</ul>

<p></p><pre class="crayon-plain-tag">&lt;wm-webmidilink id="wmlink"&gt;&lt;/wm-webmidilink&gt;
&lt;wm-smfplayer id="smfplayer" midifile="contents/ys2_op_gm.mid" latency="1200"&gt;&lt;/wm-smfplayer&gt;</pre><p> 
続いて、wm-webmidilinkタグを記述して仮想のOutputデバイスをアクティベートし、SFMをパースする wm-smfplayer タグを記述しています。wm-smfplayerの属性は以下の通りです。</p>

<ul>
 <li><b>midifile</b>： SMFのURL（パス）</li>
 <li><b>latency </b>： MIDIメッセージをバッファする時間</li>
</ul>

<p>Latencyを指定してMIDIメッセージをバッファリングすることで、より時間に正確な再生が可能になります。<br>
次に、MIDI Outputデバイスのリスト表示、SMFの再生制御のためのボタンを追加します。
</p><pre class="crayon-plain-tag">output: &lt;x-webmidioutput id="midi-output" additionalid="wmlink" autoselect="GMPlayer(WebMIDILink)" autoreselect&gt;&lt;/x-webmidioutput&gt;
&lt;br&gt;

&lt;button id="startPlay" disabled&gt;Start&lt;/button&gt;
&lt;button id="stopPlay" disabled&gt;Stop&lt;/button&gt; &lt;br&gt;
&lt;button id="allSoundOff" disabled&gt;All Sound Off&lt;/button&gt;</pre><p></p>

<p>最後に、SMF再生中に取得したMIDIメッセージを、選択されたMIDI Outputデバイスに送信するためのJavaScriptを記述していきます。</p>

<p></p><pre class="crayon-plain-tag">var out_elem=document.getElementById("midi-output")
var output=null;
out_elem.addEventListener("midioutput-updated:midi-output", function(event){
    output=out_elem.getOutputDevice();
    document.getElementById("startPlay").removeAttribute("disabled");
    document.getElementById("stopPlay").removeAttribute("disabled");
    document.getElementById("allSoundOff").removeAttribute("disabled");
}, false);
var smfPlayer=document.getElementById("smfplayer");
document.getElementById("startPlay").addEventListener("mousedown", function(){
    if(output!=null) smfPlayer.startPlay(output);
});
document.getElementById("stopPlay").addEventListener("mousedown", function(){
    smfPlayer.stopPlay();
});
document.getElementById("allSoundOff").addEventListener("mousedown", function(){
    var output=document.getElementById("midi-output").getOutputDevice();
    smfPlayer.allSoundOff();
});</pre><p></p>

<p>各行での処理の内容は以下の通りです。</p>

<ul>
<li>1行目：MIDI OutputのElementのObjectを取得  </li>
<li>2行目：変数outputの初期化  </li>
<li>3〜8行目：MIDI Outputがユーザに選択したObjectの取得、再生制御のボタンの有効化  </li>
<li>9行目：wm-smfplaymerのElementのObjectを取得  </li>
<li>10-19行目：それぞれの再生制御ボタンが押された時の動作</li>
</ul>

<p>以上で、実装完了です。</p>

<h1>おわりに</h1>

<p>今回はWeb MIDI APIをPolymerのElementにしたx-webmidiを使用して、2つのアプリケーションを作りました。そして、第一回目と比べるとコードの量が減るとともに、その多くがJavaScriptによる手続き型の実装ではなく、HTMLによる宣言型の実装になりました。宣言型で書くことで見通しがよく、手軽に実装できるようになります。</p>

<p>ここで「手軽になった」ということは、「アイデアを具現化するまでの道のりが短くなった」ということを示していて、実際に開発を行う際は、考えついたアイデアの実現のみに集中してすることができるようになります。</p>

<p>次回は、MIDIはMusical Instrument Digital Interfaceの略称ではありますが、文字通りの音楽という枠を超えて別の分野でも利用可能、という実例をご紹介しようと思います。</p>

<p>お楽しみに！</p>
]]></content:encoded>
		
		<series:name><![CDATA[MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！]]></series:name>
	</item>
		<item>
		<title>MIDIデバイスの準備不要、Web MIDI APIの基礎</title>
		<link>/ryoyakawai/16787/</link>
		<pubDate>Tue, 13 Oct 2015 02:00:51 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[プログラミング]]></category>
		<category><![CDATA[Web MIDI API]]></category>

		<guid isPermaLink="false">/?p=16787</guid>
		<description><![CDATA[連載： MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！ (1)この記事は、Web MIDI APIを題材にした連載の第一回目です。 Web MIDI APIはWebブラウザのAPIですが、Webブ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/webmidi-2015/" class="series-347" title="MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！" data-wpel-link="internal">MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！</a> (1)</div><p>この記事は、Web MIDI APIを題材にした連載の第一回目です。</p>

<p>Web MIDI APIはWebブラウザのAPIですが、Webブラウザの中で完結はしません。Webブラウザと外部のMIDIデバイスとの間でMIDIによる通信を行うためのAPIなのです。Webブラウザと外部デバイスとのやりとりでというとGamepad APIを想像される方もいらっしゃると思いますが、Gamepad APIはGame PadからWebブラウザへの一方通行の通信を行うのに対し、Web MIDI APIはWebブラウザと外部MIDIデバイスとの間で、双方向の通信が可能です。</p>

<p><img src="/wp-content/uploads/2015/08/Screen-Shot-2015-08-27-at-2.55.56-PM.png" alt="Screen Shot 2015-08-27 at 2.55.56 PM" width="60%" class="aligncenter wp-image-16791" srcset="/wp-content/uploads/2015/08/Screen-Shot-2015-08-27-at-2.55.56-PM.png 640w, /wp-content/uploads/2015/08/Screen-Shot-2015-08-27-at-2.55.56-PM-300x130.png 300w, /wp-content/uploads/2015/08/Screen-Shot-2015-08-27-at-2.55.56-PM-207x90.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h1>昔ホームページで鳴っていたやつ</h1>

<p>ところで、<strong>MIDI</strong>ってご存じですか？ MIDIと聞くと、<strong>「昔ホームページで鳴っていたやつ」</strong> を思い出される方が多いと思います。そもそもMIDIとは、「電子楽器の演奏データを機器間でデジタル転送する」ための物理的な回路・インターフェイス、通信プロトコル、ファイルフォーマット等の複数の規格から成り立っている規格の総称です。そして、Web MIDIを語る上で重要になるのが、「MIDIプロトコル」と「物理的な回路・インターフェイス」というキーワードです。</p>

<p>冒頭の<strong>「昔ホームページで鳴っていたやつ」</strong> ですが、あれはMIDIの中のファイルフォーマット（Standard MIDI File）を、OSが持つ音源を使って再生したモノとなります。「つまりどういうこと？」という方もいらっしゃると思いますが、この後、解説する、MIDIプロトコルの説明をご覧いただければ理解できるはずです。</p>

<p>まず最初は「MIDIプロトコル」から解説していきます。</p>

<h1>MIDIプロトコル</h1>

<p>MIDIとは先述した通り、「電子楽器の演奏データを機器間でデジタル転送する」ための規格でした。まず、演奏データ、つまり「音楽」とはどういうモノで成り立っているか、誰もが小学生で触ったであろうリコーダー（縦笛）を例に考えてみまます。</p>

<p>リコーダーは口にくわえて息を吹き込むことで音が出ます。強く吹けば力強い音が出るし、弱く吹けば優しい音が出る、つまり息の強さで <strong>音の強弱が表現</strong> できます。それから、押さえる穴の数を変えれば高い音階の音が鳴ったり、低い音階の音が鳴ったりする、つまり穴の数を変えることで <strong>音程の変化</strong> をさせているのです。これら <strong>音の強弱が表現</strong> 、 <strong>音程の変化</strong> の2つの情報があれば、音を再現できそうですよね。実はMIDIプロトコルで音を鳴らす部分は、この2つの情報を1つのメッセージとして扱うことで「機器間での演奏データの転送」を実現しています。さらに、MIDIには <strong>チャンネル</strong> というものがあり、これを使い分けることで16個の独立したメッセージを扱うことが可能になります。</p>

<p>それでは、実際にMIDIメッセージを見てみましょう。「音を出す」、「音を停止」する場合は、このように16進数でに3バイトを1つのMIDIメッセージとして指定します。</p>

<h3>音を出す(noteOn)</h3>

<p><img src="/wp-content/uploads/2015/08/MIDI_noteOn.png" alt="MIDI_noteOn" width="640" height="77" class="aligncenter size-full wp-image-16903" srcset="/wp-content/uploads/2015/08/MIDI_noteOn.png 640w, /wp-content/uploads/2015/08/MIDI_noteOn-300x36.png 300w, /wp-content/uploads/2015/08/MIDI_noteOn-207x25.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></p>

<h3>音を止める(noteOff)</h3>

<p><img src="/wp-content/uploads/2015/08/MIDI_noteOff.png" alt="MIDI_noteOff" width="640" height="77" class="aligncenter size-full wp-image-16904" /></p>

<ul>
 <li><b>チャンネル</b>: 0〜15を16進数で指定</li>
 <li><b>音階</b>： 21(最も低いラ：27.5Hz)〜108(最も高いド：4186Hz)を16進数で指定</li>
 <li><b>音の強さ</b>： 0〜127を16進数で指定（音を停止の場合、機器によって解釈が違う場合もある）</li>
</ul>

<p>MIDIメッセージの特徴の1つは、このように <strong>「何を」</strong> 、 <strong>「どのくらい」</strong>、 <strong>「どうする」</strong> の3つの内容が1組になっているところです。この2つのメッセージが分かれば音が出せるので、早速実装してみましょう。</p>

<h1>Web MIDI APIを使って実装する</h1>

<p><a href="http://webaudio.github.io/web-midi-api/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">Web MIDI APIの仕様</a>に中で、実装に必要な処理は以下の4つです。</p>

<ol>
 <li>コンピュータに接続されているMIDI Input/Outputの機器を列挙</li>
 <li>利用したい、MIDI機器を選択</li>
 <li>MIDI Input機器からの入力はEventで上がってくるので、EventListenerで処理を書く</li>
 <li>MIDI Output機器にMIDIメッセージを送信する</li>
</ol>

<p>今回は単純に、MIDI Input機器からの出力をブラウザで中継して、MIDI Output機器に送信するプログラムを書いてみたいと思います。まずは<a href="http://ryoyakawai.github.io/x-webmidi/src/hx_webmidi_01.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ライブデモ</a>を御覧ください。
<div id="attachment" style="width: 650px" class="wp-caption aligncenter"><a href="http://ryoyakawai.github.io/x-webmidi/src/hx_webmidi_01.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/09/deviceselect.png" alt="deviceselect" width="480" class="aligncenter size-full wp-image-17203" srcset="/wp-content/uploads/2015/09/deviceselect.png 640w, /wp-content/uploads/2015/09/deviceselect-300x114.png 300w, /wp-content/uploads/2015/09/deviceselect-207x79.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">inputのリストから「PC-Keyboard」をoutputのリストから「GMPlayer(WebMIDILink)」を選択してください。</p></div></p>

<p><div id="attachment_17033" style="width: 650px" class="wp-caption aligncenter"><a href="http://ryoyakawai.github.io/x-webmidi/src/hx_webmidi_01.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/09/livedemo01.png" alt="livedemo01" width="640" height="210" class="aligncenter size-full wp-image-17033" srcset="/wp-content/uploads/2015/09/livedemo01.png 640w, /wp-content/uploads/2015/09/livedemo01-300x98.png 300w, /wp-content/uploads/2015/09/livedemo01-207x68.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a><p class="wp-caption-text">左：inputのリストから「PC-Keyboard」を選択し、横に表示される鍵盤のアイコンをクリックした図、<br />右：outputのリストから「GMPlayer(WebMIDILink)」を選択し、横に表示されるMIDI端子のアイコンをクリックした図</p></div>
「PC-Keyboard」と「GMPlayer(WebMIDILink)」は、MIDI機器がなくても動かせるように、PCのキーボードで鍵盤、また、MIDIメッセージで発音するWeb Audioで作った音源モジュールをPolymerで仮想のデバイスにしています。（「GMPlayer(WebMIDILink)」は<a href="http://twitter.com/g200kg" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">@g200kg</a>さんが開発した音源です）</p>

<h3>環境の整備</h3>

<p>今回は、PolymerとPolymerのElement(x-webmidiというElementのExtraのElement)を使いますので、ダウンロードしてきます。</p>

<ul>
 <li> <a href="http://zipper.bowerarchiver.appspot.com/archive?polymer=Polymer/polymer%231.0.0" target="blank" data-wpel-link="external" rel="follow external noopener noreferrer">Polymer</a></li>
 <li><a href="https://github.com/ryoyakawai/x-webmidi/archive/0.10.23.zip" target="blank" data-wpel-link="external" rel="follow external noopener noreferrer">x-webmidi</a></li>
</ul>

<p>例えば、 <strong>hx_webmidi_01</strong> ディレクトリを作成して、その下に <strong>bower_components</strong> ディレクトリを作成し、リンクからダウンロードしたファイルを保存してください。(x-webmidiは解凍するとファイル名にバージョン番号が付いてしまいますので削除してください)<br />
そして、これからコードを追加していく <strong>index.html</strong> を作成します。</p>

<p><img src="/wp-content/uploads/2015/10/xwebmidi-directory-01.png" alt="directory_structure" width="300" class="aligncenter size-medium wp-image-17012" /></p>

<p>以上で環境整備は完了です。</p>

<h3>Polymerのコードを実装</h3>

<p>では、次に実装するコードを見てみましょう。今回作成する index.html のコード全体は<a href="https://github.com/ryoyakawai/x-webmidi/blob/gh-pages/src/hx_webmidi_01.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">こちら</a>になります。早速、HTML部分を上から説明していきます。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="bower_components/webcomponentsjs/webcomponents.js"&gt;&lt;/script&gt;
&lt;link rel="import" href="bower_components/polymer/polymer.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-webmidilink/wm-webmidilink.html"&gt;
&lt;link rel="import" href="bower_components/x-webmidi/extras/wm-pckeyboard/wm-pckeyboard.html"&gt;

&lt;wm-webmidilink id="wmlink"&gt;&lt;/wm-webmidilink&gt;
&lt;wm-pckeyboard id="pckeyboard"&gt;&lt;/wm-pckeyboard&gt;

input: &lt;select id="midi-input"&gt;&lt;option&gt;SelectOne&lt;/option&gt;&lt;/select&gt;&lt;span id="virtual-input"&gt;&lt;/span&gt;&lt;br&gt;&lt;br&gt;
output: &lt;select id="midi-output"&gt;&lt;option&gt;SelectOne&lt;/option&gt;&lt;/select&gt;&lt;span id="virtual-output"&gt;&lt;/span&gt;&lt;br&gt;
&lt;br&gt;

&lt;div id="msg" style="margin:30px;"&gt;&lt;/div&gt;</pre><p></p>

<p>Web MIDI APIで列挙したMIDIデバイスを選択するためのSelectタグを書いておきます（9行目、10行目）。また、MIDI Inputデバイスから受けたMIDIメッセージを表示するエリアもつけています(12行目)。尚、今回は、MIDIデバイスがなくても楽しめるようにPolymerを使っています（1行目から7行目）が、ここでは深く触れません。Selectタグの直後の&lt;span&gt;&lt;/span&gt;も同様にPolymerに関連する記載のためここでは触れません。</p>

<h3>MIDIデバイスの列挙</h3>

<p>続いてWeb MIDI APIを使った実際の処理の説明です。
</p><pre class="crayon-plain-tag">navigator.requestMIDIAccess({sysex:false}).then(successCallback, errorCallback);
function successCallback(access) {
  (後ほど詳しく)
}
function errorCallback(msg) {
  console.log("[ERROR] ", msg);
}</pre><p> 
requestMIDIAccessはPromiseの形になっていますので、まずは「システムエクスクルーシブ(sysex)」を使用するか・使用しないかを設定し、実行します。成功すればsuccessCallbackへ、失敗すればerrorCallbackへと処理が遷移します。ここで「システムエクスクルーシブ」とはMIDIメッセージの1つで、電子楽器機器固有の機能を制御するために使われます。電子楽器内のデータのバックアップで使うことも多いため、Web MIDI APIではセキュリティの観点から、ユーザの許可（ダイアログを表示）を得ることが利用する条件となっています。</p>

<p>Promiseが成功し、successCallbackへ遷移した場合の説明です。</p>

<p></p><pre class="crayon-plain-tag">// MIDI Inputデバイスの配列を作成
var inputIterator = access.inputs.values();
for (var o = inputIterator.next(); !o.done; o = inputIterator.next()) {
    midi.inputs.push(o.value);
}
// 仮想のMIDI Inputデバイスを追加
midi.inputs.push((document.querySelector("#pckeyboard")).getInput());

// MIDI Outputデバイスの配列を作成
var outputIterator = access.outputs.values();
for (var o = outputIterator.next(); !o.done; o = outputIterator.next()) {
    midi.outputs.push(o.value);
}
// 仮想のMIDI Outputデバイスを追加
midi.outputs.push((document.querySelector("#wmlink")).getOutput());</pre><p> 
Prmiseが成功すると、コンピュータに接続されているMIDIデバイスの情報を引数で渡されます。MIDI Inputデバイスの場合access.outputs.values() 、MIDI Output デバイスの場合はaccess.outputs.values()を実行することで、それぞれのデバイスのリストをIteratorの形で取得できます。ここでは機器情報の配列 midi.inputs、midi.outputsを作成します。最後に仮想のデバイスを取得して追加しています。</p>

<h3>MIDI Outputデバイスのリスト表示と選択時の処理</h3>

<p></p><pre class="crayon-plain-tag">// MIDI Outputデバイスのリスト表示と選択時の処理
var osel=document.querySelector("#midi-output");                                                                                            
for(var i=0; i&lt;midi.outputs.length; i++) {                                                                                                  
    osel.appendChild((new Option(midi.outputs[i]["name"], i)));                                                                             
}
osel.addEventListener("change", function(event){
    outputSelIdx=event.target.value;                                                                                                        
    // 仮想のMIDI Outputデバイスが選択された時の処理
    if(parseInt(outputSelIdx)&gt;=0 &amp;&amp; midi.outputs[outputSelIdx].virtual==true) {
        document.querySelector("#virtual-output").appendChild(document.querySelector("#wmlink").getElement());                              
    } else {
        document.querySelector("#virtual-output").innerHTML=""
    }
});</pre><p> 
先ほど作成したMIDI Inputデバイスの配列の要素を、リストとして表示するためにselectタグにoptionとして追加します。（2行目〜5行目）
リストの選択の変化に対してEventListenerを設定します。（6行目～14行目）ここで行っているのは、選択された機器に割り振られたIDを記憶（7行目）、続いて、もし仮想デバイスの場合はリストの横にアイコンを追加（9行目～13行目）を行っています。</p>

<h3>MIDI Inputデバイスのリスト表示と選択時の処理</h3>

<p></p><pre class="crayon-plain-tag">// MIDI Inputデバイスのリスト表示と選択時の処理
var isel=document.querySelector("#midi-input");                                                                                             
for(var i=0; i&lt;midi.inputs.length; i++) {                                                                                                   
    isel.appendChild(new Option(midi.inputs[i]["name"], i));                                                                                
}
isel.addEventListener("change", function(event){
    if(inputSelIdx!=null) {
        midi.inputs[inputSelIdx].onmidimessage=null;                                                                                        
    }
    inputSelIdx=event.target.value;                                                                                                         
    midi.inputs[event.target.value].onmidimessage=eventOut;                                                                                 
    // 仮想のMIDI Inputデバイスが選択された時の処理
    if(parseInt(inputSelIdx)&gt;=0 &amp;&amp; midi.inputs[inputSelIdx].virtual==true) {
        document.querySelector("#virtual-input").appendChild(document.querySelector("#pckeyboard").getElement());                           
    } else {
        document.querySelector("#virtual-input").innerHTML=""
    }
});</pre><p> 
先ほど作成したMIDI Inputデバイスの配列の要素をリストとして表示するために、selectタグにoptionとして追加します。（2行目～5行目）リストの選択の変化に対してEventListenerを設定します。（6行目〜18行目）ここで行っているのは、選択された機器に割り振られたIDを記憶（10行目）、MIDI Inputデバイスからの入力を受ける為の関数をonmidimessageに指定(7行目〜11行目)、もし既MIDI Inputデバイスからの入力を受ける機器が指定されていたらonmidimessageも解除（7行目〜9行目）、続いて、もし仮想デバイスの場合はリストの横にアイコンを追加（8行目～12行目）を行っています。</p>

<h3>MIDI Inputデバイスからの入力を受けた時の処理</h3>

<p>ここでは、MIDI Inputデバイスから取得したMIDIメッセージを、もしMIDI Outputデバイスが指定されていたら加工はせずにそのまま送信しますので、以下のようになります（7行目～9行目）。MIDI InputからのMIDIメッセージはevent.dataで取得することが可能で、MIDIメッセージは画面表示します（4行目、5行目）。
</p><pre class="crayon-plain-tag">function eventOut(event) {
// MIDIメッセージを表示
for(var i=0, out=[]; i&lt;event.data.length; i++) out.push((&quot;00&quot;+event.data[i].toString(16)).substr(-2));
    var div_msg=document.getElementById(&quot;msg&quot;);
    var ex_msg=div_msg.innerHTML.split(&quot;<br>");
    while(ex_msg.length&gt;19) ex_msg.pop();
    div_msg.innerHTML=out.join(" ")+"<br>" + ex_msg.join("<br>");

    if(parseInt(outputSelIdx)&gt;=0) {
        midi.outputs[outputSelIdx].send(event.data);
    }
}</pre><p></p>

<p>以上で、接続されたMIDI Inputデバイスから、指定したMIDI Outputデバイスへメッセージを送信するWebアプリケーションが作成されました。PCのキーボードで演奏ができるようになったはずです。</p>

<p>もし電子ピアノ等の電子楽器をお手持ちの場合はUSB端子がついてないかご確認ください。そして、もしUSBで接続可能であれば接続し、作成したWebアプリをリロードしてみてください。inputもしくはoutputのどちらかに接続したデバイスがリストされるはずです。（ポケットミク、eVY1シールドも操作できます）</p>

<p>また、MIDIメッセージは単なるメッセージですので、音以外に割り当てたり、鍵盤に複数のMIDIメッセージを割り当ててフレーズを再生する等、アイデア次第で様々なモノのコントローラとして活用することができます。今回は、花火をモチーフに（季節外れですが…）こんな<a href="http://ryoyakawai.github.io/x-webmidi/src/fireworks.html" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">アプリケーション</a>を作ってみました。鍵盤を弾くと、音とともに花火の打ち上がります。この音はもちろんMIDIメッセージで音源モジュールを鳴らしています。</p>

<p><a href="http://ryoyakawai.github.io/x-webmidi/src/fireworks.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/09/fireworks-640x432.png" alt="fireworks" width="640" height="432" class="aligncenter size-large wp-image-17216" srcset="/wp-content/uploads/2015/09/fireworks.png 640w, /wp-content/uploads/2015/09/fireworks-300x203.png 300w, /wp-content/uploads/2015/09/fireworks-207x140.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<h3>おわりに</h3>

<p>いかがでしたでしょうか？Web MIDIはそんなに難しくない、いやむしろ簡単であることをお分かりいただけたと思います。普段Webの開発をしていると「外部デバイスと接続して何かをする」という発想はなかったかもしれませんが、Web MIDIを使うとそういった実装もWebだけでできるようになります。「何かを作る」場合に選択の1つに是非Web MIDIを加えてみてください。</p>

<p>さて、今回は「MIDIとは何か？」というところから「Web MIDI APIの実装」、そして「MIDIを別の用途に応用してみる」というところを紹介してきました。しかし「難しくはないけど、少し準備が長い」と感じたりしていませんか？</p>

<p>実はWeb MIDIにはHotPlugの機能もありますが、今回の実装ではそこまで紹介しきれていないのです。そこで次回は、今回の記事にも少し登場した、Web MIDIと仮想デバイスの実装が一瞬でできてしまうx-webmidiというPolymerのElementについて、さらに具体的に紹介する予定です。</p>

<p>お楽しみに！</p>
]]></content:encoded>
		
		<series:name><![CDATA[MIDIデバイスの準備不要 ！Web MIDI APIを使いこなそう！]]></series:name>
	</item>
		<item>
		<title>Polymer 1.0最新情報！（後編）ーGoogle I/O Web Appの作り方、Polymer Starter Kitで始めるMaterial Design、etc.</title>
		<link>/ryoyakawai/15883/</link>
		<pubDate>Wed, 01 Jul 2015 00:00:39 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O]]></category>
		<category><![CDATA[Polymer]]></category>

		<guid isPermaLink="false">/?p=15883</guid>
		<description><![CDATA[連載： Google I/O 2015 特集 (6) 本記事は、「Polymer 1.0最新情報」の後編になります（前編はこちらから）。Google I/OでPolymer 1.0が取り上げられた「Polymer and...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google_io_2015/" class="series-313" title="Google I/O 2015 特集" data-wpel-link="internal">Google I/O 2015 特集</a> (6)</div><p><style>.post-detail-contents p{text-indent:0; overflow:hidden}</style></p>

<p>本記事は、「Polymer 1.0最新情報」の後編になります（前編は<a href="https://html5experts.jp/ryoyakawai/15885/" target="_blank" data-wpel-link="internal">こちら</a>から）。Google I/OでPolymer 1.0が取り上げられた「Polymer and modern web APIs: In production at Google scale」のセッションをレポートします。Polymerの最新情報や活用事例、Polymer Catalog、Polymer Starter Kitなど、盛りだくさんのこのセッションの翻訳と解説を前後編に分けてお伝えします。</p>

<p>後編となる本記事では、「ライブサイトへの適用例（後半）」、「Polymer Starter Kitとは」を解説します。</p>

<h2>ライブサイトへの適用例（後半）</h2>

<p>前編に引き続き、Polymerのライブサイトへの適用例の後半です。コードを交えながら具体的に解説していきます。</p>

<h3>Google I/O Web App</h3>

<p>このアプリは社内ではIOWA（アイオワ）と呼んでいる。IOWAはModen Web Platformでの良い実装例で、デスクトップでもモバイルでも動作して、コンテンツが最初に読込まれるときマテリアルデザインのエフェクトと共に表示され、ページとコンテントの間の表示での大きなエフェクトついているし、デスクトップでもモバイルでもビデオをクリックすると全画面になる。Webアプリでここまでネイティブアプリ感が出せている。</p>

<p>そのIOWAには想像できる新しいWeb APIのほとんど全てが使われている。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-22-at-11.09.12-PM.png" alt="NewAPIs_IOWA" width="640" height="357" class="alignnone size-full wp-image-15600" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-22-at-11.09.12-PM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-22-at-11.09.12-PM-300x167.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-22-at-11.09.12-PM-207x115.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>使っているAPIたち</figcaption>
</figure></p>

<p>ここからIOWAのポイントは以下です。</p>

<ul>
<li><strong>バックエンド</strong>：広範囲に渡ってAppEngine上でGoを使用</li>
<li><strong>Material Designの実装に関して</strong>：Web Animation、Promiseで各種エフェクトを実現</li>
<li><strong>開発したチーム</strong>：ソフトウェア エンジニアではなく、Developer Relationsチーム</li>
<li><strong>ツール</strong>：誰でも使うことのできる3rdパーティ製のツールを使い、Googleの特別なツールは使っていない</li>
</ul>

<p>ここから実装方法に関しての説明になります。</p>

<h4>Templateを使ったSPA（シングル・ページ・アプリケーション）の実現</h4>

<p>Google Santa Tracker 2014ではURLルーティングを行うことでSPAを実現していましたが、IOWAではTemplateとHTML Importsを使って動的にコンテンツを読み込でいるそうです。</p>

<ol>
<li>異なるid属性を付けた複数のTemplateを1つのページに配置</li>
<li>ref属性を持ったTemplateタグを配置</li>
<li>ref属性に予め埋め込んだTemplateのidどれかを指定</li>
</ol>

<p>すると、指定したidのTemplateのコンテンツがTemplateの中に差し込まれます。IOWAは予め複数ファイルでページをTemplateとして用意して、必要に応じてそれらのファイルを動的に読み込む（HTML Imports）ことでSPAが実現されている、とのことでした。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Untitled1.gif" alt="template" width="640" height="357" class="alignnone size-full wp-image-15618" />
<figcaption>TemplateとHTML Importsを使った動的なコンテンツを読み込み</figcaption>
</figure></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-12.53.20-AM.png" alt="import_Pomyler1.0" width="640" height="358" class="alignnone size-full wp-image-15622" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-12.53.20-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-12.53.20-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-12.53.20-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer 1.0でTemplateとHTML Importsを使ったSPAを実現させるコード</figcaption>
</figure></p>

<h4>Material Designの実現</h4>

<p>ビデオ等は遅延ゼロの理想状態でMaterial Desginの動きは説明されているが、Webアプリではそうはいかないので工夫が必要です。IOWAではWeb Animation、Promiseを使い、ロジカルなアニメーションのシーケンスを作ることで実現しているそうです。</p>

<ol>
<li>Promiseが&#8221;page-transition-start&#8221;のEventを発行し、ページトップ部分の色を変更するのと同時にコンテンツをページ表示領域から外側にスライドしフェードアウトさせる</li>
<li>Import Page Method（TemplateとHTML Importを使ったSPA実現方法）を使ってページのコンテンツをAjaxで取得する</li>
<li>コンテンツの準備が完了したら、ページ全体のアニメーションを実行する。このアニメーションは基本的にコンテンツを200ms以下の時間でページにスライドさせていて、パララックスのエフェクトもかけている</li>
<li>動的なページ読み込みとアニメーションが完了した時点で、例えばJavaScriptの実行のようなページを構成するために必要な処理が実行できるようになる</li>
</ol>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-1.02.04-AM.png" alt="webanimation_promises" width="640" height="358" class="alignnone size-full wp-image-15626" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-1.02.04-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-1.02.04-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-1.02.04-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Material Designを実現しているAnimation flowのコード</figcaption>
</figure></p>

<p>このように、PromiseとWeb Animation APIをWrapして利用することでCSSのアニメーションが動いたり、ネットワーク接続が発生したりと非同期な処理が起こっている状態でも、ロジカルな同期が可能です。</p>

<h4>オフライン ファーストの実現</h4>

<p>IOWAで注目すべき機能で、Service Workersを使って実現している。Service WorkersのおかげでWeb開発者が実現できることの代表例は以下です。</p>

<ul>
<li>ページキャッシュ</li>
<li>プッシュ通知（Push Notification）</li>
<li>バックグラウンド・シンク</li>
<li>ネットワークリクエストの横取り</li>
</ul>

<p>IOWAではこれらの機能を使い、アクセス解析を行うGoogle Analyticsへのリクエストをオンライン時はリアルタイムに、オフライン時は横取りをして一旦IndexDBに蓄積。オンラインになった段階で再現をしてオフライン時のアクセス解析を可能にしています。一般的にも、こうすることで重要なインサイトを逃さず見ることができるでしょう。</p>

<h4>オフライン時の動作の実装で注意した点</h4>

<p>Webサイトがオフラインでも動作することはユーザは体験したことがないので、例えばオフラインになったときにアプリケーションを終了されてしまうことを防いだりします。またオフライン動作することに驚かれないために、IOWAでは「オンラインからオフライン」に遷移した時にアプリケーション側で何が起こっているかユーザが把握できるよう、トースト（自動的に消える小さなお知らせエリア）で状態を知らせることができるように注意して実装してます。</p>

<p>実際に以下のリストのような事象が起こった場合にトーストを出しています。</p>

<ul>
<li><strong>初回アクセス時</strong>：次回からは最初からオフラインで動作します</li>
<li><strong>オフライン時の情報情報更新</strong>：オンラインになった時に情報をサーバに通知します</li>
</ul>

<p>オフラインとは電波（Wi-Fi、3G、4G等）の状況が悪いとき、Airplaneモード等でインターネットにつながらなくなった状態のことを指しています。</p>

<h4>プッシュ通知(Push Notifications)</h4>

<p>プッシュ通知はNativeなアプリでは当たり前になっている機能ですが、Webの世界では真新しい機能になります。もちろん、アプリが開いていない状態でも通知を受けることが可能です。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-2.12.31-AM.png" alt="pushnotification" width="640" height="337" class="alignnone size-full wp-image-15644" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-2.12.31-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-2.12.31-AM-300x158.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-23-at-2.12.31-AM-207x109.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>プッシュ通知を表示させた例</figcaption>
</figure></p>

<p>プッシュ通知も新しい機能なので、オフライン時の動作と同じく状況をトーストで通知しています。このプッシュ通知を動作させるためには、ユーザが通知を受ける/受けないを選択することに加えて、通知を受け取る許可をユーザがブラウザに対して行う必要があります。</p>

<p>プッシュ通知を行う目的はWebサイト/アプリへの再訪にあります。IOWAではその効果測定のためにプッシュ通知からどれだけユーザが実際にサイト/アプリに再訪してくれたかをAnalyticsを利用して計測しています。</p>

<p>プッシュ通知の送信は一見難しそうですが、Elementがあるので心配しないでください。実際にはこのような形で実装することができます。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Untitled2.gif" alt="PushNotification" width="640" height="358" class="alignnone size-full wp-image-15725" />
<figcaption>プッシュ通知の送信</figcaption>
</figure></p>

<p>プッシュ通知を使う目的はWebサイト/アプリへの再訪です。なのでIOWAではプッシュ通知からどれだけユーザが実際にサイト/アプリに再訪してくれたかの計測をAnalytics利用して行っています。</p>

<p>ここまでお話してきた、オフライン動作の実現、Service Workers、プッシュ通知に関してもElementが存在していて、Platinum Elementsに実装しています。</p>

<p><a href="https://elements.polymer-project.org/browse?package=platinum-elements" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Platinum Elements（英語）</a></p></p>

<p>最後に「6ヶ月の出来事のお話しだったので、駆け足の説明で盛りだくさんになってしまった。紹介した2つはライブサイトも動作しているし、ソースコードも公開しているので、詳しくはそちらをご覧ください」と結びました。</p>

<p>(Speaker: Eric Bidelman)</p>

<p>リンク：Google I/O web app <a href="https://html5experts.jp//events.google.com/io2015" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[ライブサイト]</a> <a href="https://html5experts.jp//github.com/GoogleChrome/ioweb2015/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[コード]</a></p>

<h2>Polymer Starter Kitとは</h2>

<p>「PolymerのDeveloper Toolを担当しているAddy Osmaniです」と自己紹介から始まりました。</p>

<p>そして間髪入れず、最近の出来事からの例えを交えて「物事の筋道にはステップを踏まないと思い通りのモノは作れない」ということの説明が始まりました。</p>

<p>Addyの友達に赤ちゃんが生まれたそうで、赤ちゃんのスケッチしてプレゼントしようと考えたそうです。そしてスケッチ方法をGoogle.comで検索をすると「まずは丸を書くことが最初のステップ（Step1）」という結果だったそうです。「実現可能性を確信したけど、次のステップを探した結果がStep2でした。このStep1からStep2への飛躍は非常に大きく、これを目標に続けると最終的にはStep1.5のようになることも少なくない」と続きます。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Untitled3.gif" alt="draw_baby" width="640" height="358" class="alignnone size-full wp-image-15738" />
<figcaption>赤ちゃんの顔のスケッチ：Step1、Step2、Step1.5</figcaption>
</figure></p>

<p>Polymerはまさに例に挙げたStep1からStep2へ移行しようとしている段階なので、これを避けるべくPolymer Teamは「Polymer Starter Kit」で、この状況の回避を行うとのこと。「Polymer Starter Kit」は、過去1年間でPolymerを使ったプロジェクトGoogle I/O App、Web Starter Kit、Google Santa Trackerを見返して、そこから得られた知見を1つにまとめた結果です。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-12.16.13-AM.png" alt="PolymerStarterKit" width="640" height="315" class="alignnone size-full wp-image-15744" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-12.16.13-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-12.16.13-AM-300x148.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-12.16.13-AM-207x102.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer Starter Kit</figcaption>
</figure></p>

<p>ここから「Polymer Starter Kitがどのようなものなのか？」の説明に入ります。</p>

<h3>Material Design</h3>

<p>非常に高いレベルでMaterial Designをサポートしています。Toolbar，Header-Panelのようなモバイルアプリを開発するときに必ず必要になるパーツ、URLルーティングや複数の画面サイズにフィットするような仕組みもサポートしている。CSS Custom Propertyを使って、アプリ全体のテーマカラーを数行のコードで変更する可能で、非常にパワフル。</p>

<p>モバイルWebアプリ開発ではテーマカラーの変更、クロスデバイス（Android、iOS、Windows Phone）でホーム画面へのアイコンリンクの準備も最初からできているので、再訪へとつなげられる。</p>

<h3>Adaptive UI</h3>

<p>今回のI/OでMaterial Design Teamが発表したガイドライン。これはデバイスによってインタラクションをどう作り込むのがよいのかのガイドラインですが、Polymer Starter Kitはこれらを全てを含んでいる。あくまでもこれらは1つの例でしかないので、必要に応じてカスタマイズすることも可能。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-27-at-8.07.25-PM.png" alt="adaptiveui" width="640" height="358" class="alignnone size-full wp-image-15980" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-27-at-8.07.25-PM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-27-at-8.07.25-PM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-27-at-8.07.25-PM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Adaptive UI</figcaption>
</figure>
<a href="http://www.google.com/design/spec/layout/adaptive-ui.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Adaptive UI（英語）</a></p>

<h3>App Template</h3>

<p>Navigation Card Layout、住所録のようなアプリに最適なNavigation List Detail Layout、List Card Over Layout(Wider Card View Layout)などが用意されていて、すぐに利用できるLayoutのセットとなっている。</p>

<h3>Offline-first (in your app)</h3>

<p>Ericもオフラインの重要性を訴えた通りで、またRob Dodsonも「2015年は、もしアプリがオフラインをサポートしていないのであれば、それは本当の意味でのモバイルWebエクスピリエンスを提供できていない、という考え方が現実になるだろう」と言っています。良いことにPolymer Starter Kitはデフォルトでオフライン ファーストになっているので何の設定をすることもなくAirplaneモードや、オフラインになったときにもアプリに含まれる全てのページにアクセスすることが可能。</p>

<h3>Service Workers</h3>

<p>素晴らしい機能だけど、導入するには多くの設定が必要です。ですが、</p>

<p>&gt; There is an element for that!</p>

<p>で、Polymer CatalogにあるPlatinum Elementsを使えば、Service Workersを使ったキャッシュ機能を簡単に実装することができます。</p>

<p>Service Workersのセット・アップの例です。Service Workersの登録し、キャッシュのストラテジを数行で設定している。例では「Network First」をキャッシュのストラテジとして、キャッシュしたいファイル名を予め宣言しています。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.15.19-AM.png" alt="Platinum Element" width="640" height="358" class="alignnone size-full wp-image-15754" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.15.19-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.15.19-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.15.19-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Plutinum Elementsを使ったオフラインキャッシュのコード</figcaption>
</figure>
<a href="https://elements.polymer-project.org/browse?package=platinum-elements" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Platinum Elements（英語）</a></p>

<h3>Production-ising Cache</h3>

<p>ユーザにできるだけ小さく、できるだけ速いアプリを提供するという意味ではビルドプロセスはとても重要。Polymer TeamはストリーミングビルドシステムのGulpが大好きなので、Polymer　Starter Kitに採用している。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.27.47-AM.png" alt="BuildByGulp" width="640" height="360" class="alignnone size-full wp-image-15757" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.27.47-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.27.47-AM-300x169.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-1.27.47-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Gulpを使ったビルドシステム</figcaption>
</figure></p>

<p>web-component-testerなどのクオリティテスト、Vulcanize等のミニフィケーション等が可能。Browser Syncを使っているので、アプリに変更を加えるとその変更はクロスデバイスで伝搬され（クリック/タップ、スクロールも含む）全てのデバイスで一度に確認することも可能。</p>

<p>実際に「Polymer Starter Kit」を適応して「Paper Reader」という名のRSSリーダアプリを作ったお話は変わります。</p>

<p>使った技術の一覧で、これらの1つ1つにElementが存在しています。</p>

<ul>
<li>記事をGoogle Feedから取得（RSS、Atom、Media RSS feedに対応）</li>
<li>既読/未読の管理にはFirebaseを利用</li>
<li>オフラインでの動作</li>
<li>新着のプッシュ通知</li>
</ul>

<p>まとめると、Polymer Starter Kitは大きく分けて、以下の4つを含んでいる。</p>

<ul>
<li>Components</li>
<li>Layout</li>
<li>Theming</li>
<li>Build tools</li>
</ul>

<p>「これらのElementやPolymer Starter Kitを使って、何を作るかはあなた次第です」</p>

<p>と最後に結び、Matthew McNultyに戻ります。</p>

<p>(Speaker: Addy Osmani)</p>

<p><a href="https://html5experts.jp//developers.google.com/web/tools/polymer-starter-kit/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Polymer Starter Kit（英語）</a></p>

<h2>まとめ</h2>

<p>ここ2年間で、Polymerが約束をして実現したことは以下の通り。</p>

<ul>
<li>Web Components</li>
<li>Interoperability</li>
<li>宣言的な書き方ができること</li>
</ul>

<p>ChromeではWeb Componentsがリリースされて1年、またProductionに耐えられるPolymer 1.0がリリースされた。</p>

<p>Salesforde、Vaadin、Atabistなどの3rdパーティも、PolymerをProduction用に使っている。Google Santa Tracker、Google I/O web appはオフラインで動作します、Polymer Starter Kitも今日から使えるし、今後は1.0には入れられなかった新しい機能、Elementを早いペースで次々に追加する予定です。</p>

<p>Polymerについての情報の取得等のリンクは以下。</p>

<ul>
<li>最新情報：<a href="https://html5experts.jp//polymer-project.org" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">polymer-project.org</a></li>
<li>Polymer Teamと直接会話：<a href="https://html5experts.jp//polymer-slack.herokuapp.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Slackチャンネル</a></li>
</ul>

<p>そして、Polymer単独のカンファレンスの告知がありました。</p>

<p>「2015年9月15日にアムステルダムにて、PolymerだけのカンファレンスPolymer Summitを開催します。1日中、Polymerを、また最先端のWeb開発を学びにくてください」とのことです！</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.21.54-AM.png" alt="Polymer Summit" width="640" height="359" class="alignnone size-full wp-image-15761" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.21.54-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.21.54-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.21.54-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer Summit@アムステルダム 2015/09/15</figcaption>
</figure></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.26.35-AM.png" alt="PolymerTeam" width="640" height="359" class="alignnone size-full wp-image-15763" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.26.35-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.26.35-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-24-at-2.26.35-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer Teamの皆さん</figcaption>
</figure></p>

<p>最後に「バグも見つけてね」でセッションは終了でした。</p>

<p>(Speaker: Matthew McNulty)</p>

<h2>あとがき</h2>

<p>個人的にはPolymerを最初に触ったのが2013年頃で、そのキッカケは楽器系のアプリを作った時に必ず使いたくなるリッチなノブ、スライダ、スイッチ、鍵盤を簡単に配置できる世界を夢見た<a href="https://github.com/g200kg/webaudio-controls" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">webaudio-controls</a>が開発され始め、それに乗っかって一緒にはじめたことでした。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/webaudio-controls.png" alt="webaudio-controls" width="350" class="alignnonewp-image-15858" srcset="/wp-content/uploads/2015/06/webaudio-controls.png 555w, /wp-content/uploads/2015/06/webaudio-controls-300x153.png 300w, /wp-content/uploads/2015/06/webaudio-controls-207x106.png 207w" sizes="(max-width: 555px) 100vw, 555px" />
<figcaption>webaudio-controls</figcaption>
</figure>
</p></p>

<p>今回のセッションに参加して、その中で何度もリピートされていた言葉、
&#8220;<q>There is an element for that!</q>&#8220;（それ、エレメントあるよ！）をwebaudio-controlsを作ってから、実際に自分自身が言っていたことに気が付きました。</p>

<p>また、ブラウザにMIDI機器を接続して遊べるWebアプリを、簡単に作ることができる世界を夢見て<a href="https://github.com/ryoyakawai/x-webmidi/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">x-webmidi</a>というElementも作りました。これを作った理由は「ゼロから書くのはちょっと…という理由で手が出しずらい、という印象を少しでも和らげたい」からでした。</p>

<p>この「手軽に使えること」だったり「ゼロから書くのはちょっと…という理由で手が出しずらい、という印象を少しでも和らげたい」という想いがさらに一般に拡がりElementが量産されたのであれば、その未来はブラウザにはよりプリミティブなAPIが実装されるようになり、ブラウザのAPIをより使いやすくする、APIを組合せることで新たな枠組みを作るためのWeb Componentsが「ブラウザのAPIとWebアプリの中間に新たなクリエイティブな層」を創り出して、Web開発がExtensible Webな時代へ突入するのかな？なんて、Webの未来をモヤモヤ考えさせられる2015年のPolymerのセッションでした。</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2015 特集]]></series:name>
	</item>
		<item>
		<title>Polymer 1.0最新情報！（前編）ーPolymer 1.0とPolymer Catalog、活用事例の徹底解説</title>
		<link>/ryoyakawai/15885/</link>
		<pubDate>Tue, 30 Jun 2015 06:00:23 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Google I/O]]></category>
		<category><![CDATA[Polymer]]></category>

		<guid isPermaLink="false">/?p=15885</guid>
		<description><![CDATA[連載： Google I/O 2015 特集 (5) Polymerは、Google I/O 2015にて1.0が正式リリースとしてアナウンスされました。本記事は、Google I/OでPolymerが取り上げられた「P...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/google_io_2015/" class="series-313" title="Google I/O 2015 特集" data-wpel-link="internal">Google I/O 2015 特集</a> (5)</div><p><style>.post-detail-contents p{text-indent:0; overflow:hidden}</style></p>

<p><img src="/wp-content/uploads/2015/06/POLYMER-1.0.png" alt="POLYMER 1.0" width="300" class="wp-image-15439" align="left" srcset="/wp-content/uploads/2015/06/POLYMER-1.0.png 599w, /wp-content/uploads/2015/06/POLYMER-1.0-300x209.png 300w, /wp-content/uploads/2015/06/POLYMER-1.0-207x144.png 207w" sizes="(max-width: 599px) 100vw, 599px" />
Polymerは、Google I/O 2015にて1.0が正式リリースとしてアナウンスされました。本記事は、Google I/OでPolymerが取り上げられた「Polymer and modern web APIs: In production at Google scale」のセッションをレポートします。Polymerの最新情報や活用事例、Polymer Catalog、Polymer Starter Kitなど
盛りだくさんのこのセッションの翻訳と解説を前後編に分けてお伝えします。</p>

<p>前編となる本記事では、「Polymer1.0の特徴」、「Polymer Catalogとすぐに使えるElements」、「ライブサイトへの適用例（前半）」を解説します。</p>

<h2>Polymer1.0の特徴</h2>

<p>Polymerが全体的にどう変わったのか、その特徴をまとめて説明してくれました。Polymer1.0の特徴を全て紹介しきれていないとのことですが、セッションで特に紹介されていたのは以下の通りです。</p>

<ul>
<li><strong>高速化(0.5と比較)</strong>：Chromeでは3倍、モバイルSafariでは4倍高速化した</li>
<li><strong>軽量化(0.5と比較)</strong>：以前より35％コード量減らしPolyfillも含めてgzipをすると19kb-42kb</li>
<li><strong>Shady DOMの採用</strong>：スピードを重視したShadow DOMのPolyfillで100％互換ではない</li>
<li><strong>CSS Custom プロパティ</strong>：プロパティの変更だけでテーマやスタイルの変更を可能に</li>
</ul>

<p>「PolymerはWeb標準技術であるWeb Componentsのライブラリであって、そのElementを作ることができます。なので、結果的にそれらのElementはWeb標準技術の上に作られたのと同意である。他のブラウザ上でも動作するし、AngularやReactといったFrameworkの中に一緒に共存させることもできる、というところが最大の特徴であり利点でもあります」</p>

<p>セッションでは、これらの説明をコンテナを運ぶ物流システムに例え「標準化を元に作られたコンテナ（Polymer Element）だからこそ、標準化されたボート・電車・トラックで効率的に運ぶことだってできる（ブラウザのInteroperabolity）」という形で説明をしていました。この例えは、Polymer TeamはSan Franciscoのオフィスにいて、普段の会話の中に湾を行き交う輸送船について話すことが多いことに由来しているそうです。</p>

<p>(Speaker: Matthew McNulty)</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-12.39.14-AM.png" alt="SF_Bay" width="640" height="358" class="alignnone size-full wp-image-15430" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-12.39.14-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-12.39.14-AM-300x168.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-12.39.14-AM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>サンフランシスコ オフィスからの眺め</figcaption>
</figure></p>

<h2>Polymer Element Catalogとすぐに使えるElements</h2>

<p>ここからPolymerを使ってWebアプリを作るときのElementについて話に変わります。</p>

<p>「Polymer Teamは全ての開発者にPolymerを使って高品質なアプリを簡単に作ってもらうことを目標にしています。そして、アプリはElementによって出来が左右されるので、高品質なアプリを作るには高品位なElementが不可欠です。なのでGoogleでは高品質なElementを提供します」</p>

<p>という導入があり、続いて具体的にElementの説明です。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-11.20.41-PM.png" alt="PolymerCatalog" width="640" height="360" class="alignnone size-full wp-image-15480" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-11.20.41-PM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-11.20.41-PM-300x169.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-17-at-11.20.41-PM-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>Polymer Catalogに用意されているElementのセット一覧 (2015年5月末の状態)</figcaption>
</figure></p>

<p>まずは去年から公開されていたElementとして、Iron Element、Paper Elementが紹介されています。そして、新しく追加されたElementとして、Google Web Components、Platinum Elements、Gold Elementsがあります。</p>

<ul>
<li><b style="background-color:#81c784;padding:5px">Iron Element (Fe)</b><br>新しく聞こえますが、Core Elementから名称を変更しました。内容は以前と変わらずElementの基本となり、どのアプリケーションにも使うようなエレメントのセット。</li>
<li><b style="background-color:#efefef;padding:5px">Paper Element (Md)</b><br> Material DesignのリファレンスになるElementのセット。</li>
<li><b style="background-color:#64b5f6;padding:5px">Google Web Components (Go)</b><br> Google SDKとも言えるようなElementでGoogleのServiceやAPI（GCP、Drive、Map、Hangout、Calendar、Analytics、YouTube、Docs、Chrome Web Store、アドレス帳など）を利用する際に利用するElementのセット。</li>
<li><b style="background-color:#cfd8dc;padding:5px">Platinum Elements (Pt)</b><br> オフライン・キャッシング、ServiceWorkers、Push Notificationのようなとてもパワフルな機能を最も簡単に利用することのできるElementのセット。このElementを使うことで、半年前には夢だと思っていたような機能が簡単に実装可能。</li>
<li><b style="background-color:#ffbb4d;padding:5px">Gold Elements (Au)</b><br> モバイルでの高品質な決済のチェックアウト遷移を作成できるElementのセット。日付、カード番号等の自動Validationが可能。</li>
</ul>

<p>これらのうち、新しく追加された3つのElementは、Web開発者が特定の問題を解決するために用意しているものとのことです。このPolymer Catalogについては次のように説明しています。</p>

<p>「このサイトの目的は、解決したい問題がある場合は解決策を見つければいいのだけど、例えば、何かに触発されたかったり、思ったこともないようなデザインを見つけたかったり・眺めたかったり、考えたこともないようなアプリケーションを考えたいという場合もあります。この2つ「解決策を見つける」、「インスピレーションを得たい」を実現させる為に、Elementをブラウスでき、デモを動作可能で、ドキュメントも読むことができるのがPoymer Catalogです」</p>

<p><a href="https://elements.polymer-project.org/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Polymer Catalog（英語）</a></p>

<h3>Polymerを使ってアプリを実装、公開している3rdパーティとそのアプリの紹介</h3>

<p>「Polymer TeamではWeb開発者が「実装したい」と考えるであろう機能は、&#8221;<q>There is an element for that!</q>&#8220;（それ、Elementであるよ！）
と言えるようにりたいと思っていますが、我々の以外でも同じことを想っている方々は多くいます。そこで、ここでは出版関連を行っているAtabist、Enterprise向けのJavaアプリ用のFrameworkを作っているVaadin、そしてSalesforceの3つの事例を紹介します」</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-12.51.47-AM.png" alt="3rdparty" width="640" height="361" class="alignnone size-full wp-image-15792" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-12.51.47-AM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-12.51.47-AM-300x169.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-12.51.47-AM-207x117.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>PolymerでElementを作り公開している3rd Partyの紹介</figcaption>
</figure></p>

<h4>Atabist</h4>

<p>出版関連を行っている会社で、Web上に本を作るPlatformをリリース。Webは音声、映像、画像、地図、ブラフを一緒に配置して1つにまとめるにはとてもよい媒体で、これらの1つ1つをPolymerのElementにして自由に配置できるようにしたのがこのPlatform。</p>

<p><a href="https://atavist.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：Atabist（英語）</a></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.20.47-PM.png" alt="vaadin" width="640" height="420" class="alignnone size-full wp-image-15903" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.20.47-PM.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.20.47-PM-300x197.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.20.47-PM-207x136.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>インタラクティブにSoundCloudをページ上に配置している例</figcaption>
</figure></p>

<h4>Vaadin</h4>

<p>Enterprise向けのアプリを書くためのFrameworkを作っている有名な会社の1つで、Front-endのComponentsはPolymer Elementを使って実装している。特に大量のデータを表示することに重きを置き開発されていて、例えば、v-gridというElementを作っていて、これを使うとアドレス帳のようなモノを表示、LazyLoading、行または列の複数選択の機能もElementを実装することができる。グラフを描くElementも作っていてタグ名を変えるだけで、グラフの種類を変更することができる。</p>

<p><a href="http://vaadin.github.io/components-examples/v-grid/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">リンク：v-grid（英語）</a></p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-26-at-10.13.22-PM.png" alt="vaadin" width="640" height="359" class="alignnone size-full wp-image-15596" />
<figcaption>アドレス帳のElementの例</figcaption>
</figure></p>

<h4>Salesforce</h4>

<p>Salesforceは彼らのPlatform上でそのデータを表示するアプリケーションを作るためのSDK、APIを公開している。このアプリケーション開発をより簡単にしたいということで、Polymer Elementでの提供を行っている。</p>

<p><a href="https://sfdc-designer.herokuapp.com/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ：デザイナ（英語）</a></p>

<h4>Google社内でのPolymerの実用例</h4>

<p>最後にGoogle社内でのPolymerの実用例の紹介です。Polymer Teamは「GoogleさんはLiveサイトでPolymerを使っているの？」とよく聞かれるそうですが「もちろん使っている」とのことで、そのうち3つを紹介してくれました。</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/Translate.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/Translate-150x150.png" alt="Translate" width="120" height="120" class="alignleft size-thumbnail wp-image-15908" /></a>
<strong>Translate</strong>：Translation TeamはTranslateの質を上げるためにコミュニティのメンバーが参加して作り上げることのできるシステムを新しく作った。サイト全体がPaper Elementを使ったMaterial Designを採用している。このプロダクトはFront-endエンジニア2人で2～3ヶ月の開発期間で完成させることができたとのこと。Paper Elementを使っているので、開発者はどうやってMaterial Desiginを実装するかということは気にせず、アプリケーションの本質部分に集中して開発を進めらたそうです。</p>

<p><a href="https://translate.google.com/community" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ（英語）</a></p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/PlayMusic.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/PlayMusic-150x150.png" alt="PlayMusic" width="120" height="120" class="alignright size-thumbnail wp-image-15905" /></a>
<strong>Play Music</strong>：Play TeamもPaper Elementを使ってMaterial Designを採用しているので、アプリケーションの本質部分に集中して開発を進めることができたとのことです。Play Musicは現在はPolymer Elementの組合せで作られていて、同じような音楽再生用WebサイトにElementを再利用することも可能です。（日本からはアクセスできません）</p>

<p><a href="https://html5experts.jp/wp-content/uploads/2015/06/youtube_web.png" data-wpel-link="internal"><img src="/wp-content/uploads/2015/06/youtube_web-150x150.png" alt="youtube_web" width="120" height="120" class="alignleft size-thumbnail wp-image-15906" /></a>
<strong>YouTubeのモバイルWebサイト</strong>：多くのPolymerを使ったサイトはまだGoogle社内にしか公開されていないのですが、その中の1つ、それがYouTubeのモバイルのFront-End。これも全てがPolymer Elementで作られています。キビキビ動き、アニメーション、トランジションもついていて、とてもよいUIに仕上がっている。またビデオを画面の角にドラッグして動かすというWebでは実現が可能とは予想していなかったであろう動作も実現できている。このようにWebでもNativeのような最高の動作をPolymer Elementで作ることができる。</p>

<p>「Elementはとても素晴らしく、紹介したような素晴らしいElementを作ることができます。Polymer Teamは引続き素晴らしいElementを開発していきます。そして、コミュニティからもっと素晴らしいElementが出てくることを楽しみにしています」</p>

<p>と結び、次のライブサイトへの適用例の説明に移りました。</p>

<p>(Speaker: Taylor Savage)</p>

<h2>ライブサイトへの適用例（前半）</h2>

<p>ここからはEric Bidelmanにバトンタッチです。彼の3年間を振り返ってのお話からです。</p>

<p>Polymer Teamにいて「これはどうやってWeb Componentsで実現するの？」ということを開発者と話してきて、そこでよく質問にあがる具体例が「どうやってSPA（Single Page Application）をWeb Componentsでどう実装するのか？」、「他言語化やLazyLoad、またURLルーティングはど実現するのか？」というような「Polymerを使ってどう実現したいモノを実装するか？」という部分です。それに対してPolymer Teamはこう答えているそうです。</p>

<p>&gt; There is an element for that!</p>

<p>という掴みがあり、続いてEric Bidelmanが前回のI/Oから数多くの実験を実際に行い、Google.com上のアプリを作りそれらを公開して、実際に使えるのかを試してみた、というストーリで実例を2つ紹介してくれました。</p>

<p>「これらの事例ではPolymer1.0ではなく、ちょっと遅いけどGoogle.comで公開されているのは0.5。なんだけど、1.0と書き方が少し違うだけで本質的なPolymerの部分は同じなので、これからお話をする事例には影響は特にないのです」</p>

<p>と捕捉があって、Google Santa Tracker 2014とGoogle I/O Web Appの説明が始まります。</p>

<h3>Google Santa Tracker 2014</h3>

<p>このアプリは12月に公開されたアプリで、サンタ村を訪れることができ、12月中は毎日新しいゲームを提供したりしているAdvent Calendarのアプリ。日々提供されるゲームだったり、そのSceneのことを社内ではLaunchと呼んでいて、それらの全部がElementになっていて、Web AudioだったりWeb GLだったりを使っているものもある。クリスマスイブには今どこでサンタがプレゼントを配っているかも見ることができる。もちろんそれもElementになっている。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-20-at-8.06.39-PM.png" alt="SantaTracker" width="636" height="539" class="alignnone size-full wp-image-15586" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-20-at-8.06.39-PM.png 636w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-20-at-8.06.39-PM-300x254.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-20-at-8.06.39-PM-207x175.png 207w" sizes="(max-width: 636px) 100vw, 636px" />
<figcaption>Google Santa Tracker 2014</figcaption>
</figure></p>

<p>コード的な説明です。&lt;santa-app&gt; が全体をオーケストレーションするElementで、Google Analyticsに、また音楽の再生・停止をするEventの発火を行う。&lt;santa-app&gt; の内部にはさらにElementが入っている。URLルーティングもElementを作って対応していて、LazyLoadingのElementとを結びつけ、ユーザがSceneを選択したときにJavaScript、CSSが動的に読み込まれるような仕組みになっている。このプロジェクト全体的にElementはDeclarativeにしていて、各Sceneのプログレスバー、背景色、背景画像もそのおかげでHTMLのAttributeでの設定が可能になっている。</p>

<p><figure class="aligncenter">
<img src="/wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-10.55.33-AM1.png" alt="SantaTracker2014" width="640" height="360" class="alignnone size-full wp-image-15818" srcset="/wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-10.55.33-AM1.png 640w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-10.55.33-AM1-300x169.png 300w, /wp-content/uploads/2015/06/Screen-Shot-2015-06-25-at-10.55.33-AM1-207x116.png 207w" sizes="(max-width: 640px) 100vw, 640px" />
<figcaption>&lt;santa-app&gt;のElement</figcaption>
</figure>
  </li>
</ul></p>

<p>Google Santa Tracker 2014の説明は以上でした。</p>

<p>リンク：Google Santa Tracker <a href="https://html5experts.jp//santatracker.google.com" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[ライブサイト]</a> <a href="https://html5experts.jp//github.com/google/santa-tracker-web" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">[コード]</a></p>

<p>（後編に続きます）</p>
]]></content:encoded>
		
		<series:name><![CDATA[Google I/O 2015 特集]]></series:name>
	</item>
		<item>
		<title>【Web Audio API + Web MIDI API】ブラウザで電子楽器を作ってみよう！</title>
		<link>/ryoyakawai/12569/</link>
		<pubDate>Mon, 23 Mar 2015 04:01:41 +0000</pubDate>
		<dc:creator><![CDATA[河合良哉]]></dc:creator>
				<category><![CDATA[最新動向]]></category>
		<category><![CDATA[Web Audio API]]></category>
		<category><![CDATA[Web MIDI API]]></category>
		<category><![CDATA[ブラウザ]]></category>

		<guid isPermaLink="false">/?p=12569</guid>
		<description><![CDATA[連載： HTML5 Conference 2015 特集 (3)ブラウザ上で音を扱うというと、直接音を加工できるWeb Audio API、ブラウザから直接MIDIデバイスと接続できるWeb MIDI APIの2つがここ...]]></description>
				<content:encoded><![CDATA[<div class="seriesmeta">連載： <a href="https://html5experts.jp/series/h5conf2015/" class="series-257" title="HTML5 Conference 2015 特集" data-wpel-link="internal">HTML5 Conference 2015 特集</a> (3)</div><p>ブラウザ上で音を扱うというと、直接音を加工できるWeb Audio API、ブラウザから直接MIDIデバイスと接続できるWeb MIDI APIの2つがここ数年の間に利用可能になり、実際のWebサイトでも使われるようになりました。<br>
今回は「ハンズオンだともっとよかった」というお声をいただきましたHTML5 Conference 2015での講演内容を元に、2つのAPIの説明と、実際にブラウザ上に電子楽器の1つであるシンセサイザーを作ってしまうという記事です。</p>

<p>記事中のサンプルは<a href="https://github.com/ryoyakawai/html5conference2015" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">GitHub</a>に公開していますので、そちらも合わせてご参照ください。</p>

<h2>利用するAPIの説明</h2>

<h3>Web Audio API</h3>

<p style="margin-bottom:8px">短く一言で説明すると<b>「ブラウザ上で音を直接作ったり、いじったりすることのできるAPI」</b>です。もう少し難しく言うと「ブラウザ上で波形処理を可能にしたAPI」となります。<br>
Web Audio APIの理解を深めるためにまず「音」とは何かを考えてみたいと思います。Wikipediaには以下のように書かれています。
</p>

<div style="border:solid 1px #cccccc;margin-bottom:8px">
<blockquote>
<ul style="margin-left:20px;margin:10px 0px 10px 20px">
 <li style="margin-top:2px">物の<b>響き</b>や人や鳥獣の声</li>
 <li style="margin-top:2px">（物体の振動が空気などの<b>振動</b>（音波）として伝わって起す）聴覚の内容</li>
 <li style="margin-top:2px">またはそのもととなる<b>音波</b></li>
</ul>
</blockquote>
<div style="margin:10px 0px 10px 80px;border-left:3px solid #aaaaaa;padding-left:10px">
「引用」『フリー百科事典　ウィキペディア日本語版』より。<br>
2015年3月16日 8:30 UTC<br>
<a href="http://ja.wikipedia.org/wiki/%E9%9F%B3" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">http://ja.wikipedia.org/wiki/%E9%9F%B3</a><br>
</div>
</div>

<p>
<b>響き</b>、<b>振動</b>、<b>音波</b>と出てきました。実は、音を目に見える形にすると<b>波</b>になるのです。Web Audio APIも原理は同じで、波を与えて音として出力しています。そして、その波の形（波形）をいじる（処理）して様々な音を作り出すとご理解いただけばよいと思います。</p>

<p style="margin-bottom:8px">原理の説明はここまでにして、最初に声を取得して、その声をWeb Audioでピッチシフト（音を高くしたり、低くしたりする効果）、Delay（音を遅らせる効果）の加工を行うデモをご紹介いたします。（できるだけマイクとヘッドホンをご用意ください）<a href="http://ryoyakawai.github.io/html5conference2015/audio/" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">ピッチシフト＆Delayのライブデモ</a></p>

<div class="aligncenter" style="clear:both;width:568px">
<div style="float:left;width:283px"><a href="http://ryoyakawai.github.io/html5conference2015/audio/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/Screen-Shot-2015-02-15-at-9.54.14-AM.png" alt="PitchShift&amp;Delay" width="281" height="289" class="alignnone size-full wp-image-12827" srcset="/wp-content/uploads/2015/02/Screen-Shot-2015-02-15-at-9.54.14-AM.png 281w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-15-at-9.54.14-AM-201x207.png 201w" sizes="(max-width: 281px) 100vw, 281px" /></a></div>
<div style="float:left;width:283px">
 <div style="text-align:left;padding:40px 0px 0px 20px">
  <p style="margin-bottom:2px;font-weight:bold">ノブとボタンの説明▼</p>
  <div style="padding:4px">
   <p style="margin-bottom:2px"><b>(1)</b> PitchShift ON/OFF</p>
   <p style="margin-bottom:2px"><b>(2)</b> Shiftの種類：(上:高い、下：低い)</p>
   <p style="margin-bottom:2px"><b>(3)</b> Delay ON/OFF</p>
   <p style="margin-bottom:2px"><b>(4)</b> Delayの種類：並列/直列</p>
   <p style="margin-bottom:2px"><b>(5)</b> Feedback量</p>
   <p style="margin-bottom:2px"><b>(6)</b> Delay時間</p>
  </div>
 </div>
</div>
</div>

<div style="clear:both"></div>

<p><br></p>

<div class="aligncenter">
<img src="/wp-content/uploads/2015/02/delay-parallel.png" alt="delay-parallel" width="70%" class="alignnone wp-image-12849" srcset="/wp-content/uploads/2015/02/delay-parallel.png 631w, /wp-content/uploads/2015/02/delay-parallel-300x85.png 300w, /wp-content/uploads/2015/02/delay-parallel-207x59.png 207w" sizes="(max-width: 631px) 100vw, 631px" /></div>

<p><br>
ノードグラフ（Web Audioでは処理をする1つ1つをノードと呼び、それらをつなぎ合わせて1つのグラフにします）は上図のようになっています。ピッチシフト＆DelayのライブデモのDelayをONにして、種類を直列にする（（4）のスイッチを下にする）と<a href="https://html5experts.jp/wp-content/uploads/2015/02/delay-direct.png" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">このような接続</a>になります。直列につなげると、マイクで拾った音が(6)Delay時間だけ遅れてスピーカから出るようになります。<br>
このノードグラフをWeb Audio APIで書くとこうなります。（ピッチシフト部分、Delay部分をObjectにしてまとめている関係上、ゼロから書くともう少し長く、複雑になります）（<a href="http://ryoyakawai.github.io/html5conference2015/audio/sample01.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>）</p>
<pre class="crayon-plain-tag">var ctx=new AudioContext();
var mic;
var psin=ctx.createGain(), psout=ctx.createGain();
var delayin=ctx.createGain(), delayout=ctx.createGain();

navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
navigator.getUserMedia({audio : true}, successCallback, errorCallback);
function successCallback(stream) {
    mic = ctx.createMediaStreamSource(stream);
    mic.connect(psin);
}
function errorCallback(msg) {
    console.log(msg);
}
var pshift=new pitchShift(ctx);
psin.connect(pshift.getSrc());
pshift.connect(psout);

var delay=new delayProcess(ctx);
delayin.connect(delay.getSrc());
delay.connect(delayout);

psout.connect(delayin);
delayout.connect(ctx.destination);</pre></p>

<p>このように、Web Audio APIを使うと、今まではプラグインを使う以外に方法がなかったWebブラウザ上でのリアルタイムな波形処理を、比較的簡単に行うことが可能です。</p>

<h3>Web MIDI API</h3>

<p>短く一言で説明すると<b>「ブラウザとデバイス間でMIDIメッセージを送受信するためのAPI 」</b>です。MIDIとは <b>M</b>usical <b>I</b>nstrument <b>D</b>igital <b>I</b>nterface の略で、電子楽器の演奏データをデバイス間でデジタル転送するための世界共通規格であり、物理的な送受信回路・インタフェース、通信プロトコル、ファイルフォーマットなど複数の規定からなっています。Web MIDI APIは特にこの中の通信プロトコルをWebブラウザへの実装したAPIです。</p>

<p style="margin-bottom: 8px">Web MIDI APIの特徴は外付けのMIDIデバイス<a href="#footnote0" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※0</a>とWebブラウザが直接接続できるところです。ですのでWeb Audio APIのようにそれ単体で音が鳴ったりする訳ではなく、MIDIデバイスからWebブラウザで動くアプリケーションをコントロールしたり、またWebブラウザからMIDIデバイスコントロールするために利用します。よって本記事では最初にWeb Audio APIを使った電子楽器アプリケーションを作り、それをWeb MIDI APIを使って外付けのMIDIデバイスからコントロールするというシナリオで進めさせていただきます。</p>

<div style="border:solid 1px #cccccc;margin-bottom:25px">
  <a name="footnote0" data-wpel-link="internal"></a>
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <a name="footnote0" data-wpel-link="internal"></a>
    <span style="vertical-align: top;color: red;font-size:10px">※0</span> <b>MIDIデバイス</b>： 楽器関連では鍵盤をはじめ、ドラムパッド、スライダー、ノブ等があり、楽器以外ですと、ステージ上のセットを楽器等と一緒にMIDIでコントロールしてしまおうという発想で照明機器、その他噴水、爆破、炎の制御に使われていることもあります。<br>
  </div>
</div>

<p>なお、やや長い記事になってしまいましたので、ソースコードの量の少なさを体感していただき、その解釈は後回しにしてデモを触っていただくのがよいと思います。「電子楽器を実装する」というと難しそうに聞こえるかもしれませんが、そこまで難しくもありませんので実装に挑戦していただけるとうれしいです。</p>

<h2>Web Audio API で電子楽器を実装する</h2>

<p>電子楽器と言ってもその種類は複数あります。今回はその中からアナログシンセサイザーとFMシンセサイザーを実装してみます。</p>

<h3>Web Audio API でアナログ・シンセサイザー</h3>

<p>アナログ・シンセザイザーはアナログ回路を用いて信号処理を行うことで音を出す方式のシンセサイザーです。そのアナログ回路をWeb Audio APIを使って実装していきます。まずはどんな音が出るか<a href="http://ryoyakawai.github.io/html5conference2015/analog/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>で試してみてください。
</p>

<p><a href="http://ryoyakawai.github.io/html5conference2015/analog/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/Screen-Shot-2015-02-19-at-12.49.31-AM.png" alt="AnalogSynthApp" width="60%" class="aligncenter size-full wp-image-12998" srcset="/wp-content/uploads/2015/02/Screen-Shot-2015-02-19-at-12.49.31-AM.png 640w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-19-at-12.49.31-AM-300x248.png 300w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-19-at-12.49.31-AM-207x171.png 207w" sizes="(max-width: 640px) 100vw, 640px" /></a></p>

<p>
画面上にある２つのスライダを動かすと音色を大きく変化させることができると思います。それでは原理を見てみましょう。
</p>

<p style="margin-bottom:8px">
このシンセサイザーは以下の3つの部品を使っています。
</p>

<ul style="margin-bottom:14px">
  <li style="margin-bottom:2px">基本の信号・波形を作り出す発振機<a href="#footnote1" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※1</a> （VCO0、VCO1）</li>
  <li style="margin-bottom:2px">波形を加工するフィルタ（VCF）</li>
  <li style="margin-bottom:2px">低い周波数の制御信号を発振機から発生させて送ることで周期的な変化を与える（LFO）</li>
</ul>

<p>
これらを接続して下図のノードグラフを作ります。
<img src="/wp-content/uploads/2015/02/analogsynth.png" alt="AnalogSynthNodeGraph" width="60%" class="aligncenter size-full wp-image-13003" srcset="/wp-content/uploads/2015/02/analogsynth.png 527w, /wp-content/uploads/2015/02/analogsynth-300x225.png 300w, /wp-content/uploads/2015/02/analogsynth-207x155.png 207w" sizes="(max-width: 527px) 100vw, 527px" />


<div style="border:solid 1px #cccccc;margin-bottom:8px">
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <a name="footnote1" data-wpel-link="internal"></a>
    <span style="vertical-align: top;color: red;font-size:10px">※1</span> <b>発振機</b>： 波を発生させる部品で、オシレータ（Oscillator）とも呼びます。<br>
  </div>
</div>



</p>

<p>ソースコードは以下のようになります。（<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample02.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>、<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample02.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</p>

<p></p><pre class="crayon-plain-tag">var ctx=new AudioContext();
var vco0, vco1, lfo, vcf;

vco0=ctx.createOscillator();   // VCO0を作成
vco1=ctx.createOscillator();   // VCO1を作成
lfo=ctx.createOscillator();    // LFOを作成
vcf=ctx.createBiquadFilter();  // VCFを作成

vco0.connect(vcf);             // (1)の接続
vco1.connect(vcf);             // (2)の接続
lfo.connect(vco0.frequency);   // (3)の接続
lfo.connect(vco1.frequency);   // (4)の接続
lfo.connect(vcf.detune);       // (5)の接続
vcf.connect(ctx.destination);  // (6)の接続

// 値を変更
//vco0.type="sawtooth";
//vco1.detune.value=-35;
//lfo.frequency.value=2;
//vcf.frequency.value=10000;

// Oscillator（発振機）を動作させて発音
vco0.start(0);
vco1.start(0);
lfo.start(0);

// 音階を変える
vco0.frequency.value=440;
vco0.frequency.value=440;</pre><p></p>

<p style="margin-bottom:12px">これで発音されます。が、このままですとそのままの音が出るだけですので面白くありません。そこで、それぞれのノードのパラメータを変更してみます。コメント化していた「値を変更」の以下4行を生かしてみます。（<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample03.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>、<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample03.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）<br>
先程より音色が明るくなったと思います。<a href="http://ryoyakawai.github.io/html5conference2015/analog/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>のVCFのスライダを右に動かしたのと同様な値の変更を行いました。VCFは設定値より低い周波数を通す（ローパス）フィルタになっていて、そのパラメータを大きくしてより多くの明るい部分を通して明るい音色を出しています。</p>

<p>さらにシンセサイザーっぽい音にするべく、音量や音高などを時間で変化させる<a href="http://ja.wikipedia.org/wiki/ADSR" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ADSR</a><a href="#footnote2" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※2</a> と呼ばれてるエンベロープ<a href="#footnote3" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※3</a> の機能実装します。ここではこのエンベロープを発振機（Oscillator）の音量（VCO0、VCO1）に適応しますので音量を調節するGainNodeを(1)、(2)へ追加します。そのソースコードは以下のようになります。（ノード作成、接続部分のみ抜粋）

<div style="border:solid 1px #cccccc;margin-bottom:8px">
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <a name="footnote2" data-wpel-link="internal"></a>
    <span style="vertical-align: top;color: red;font-size:10px">※2</span> <b>ADSR</b>：下図のように波形を処理する場合のそれぞれも部分を指しています。<br>
<img src="/wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-12.14.23-AM.png" alt="ADSR-DIAGRAM" width="60%" class="aligncenter size-full wp-image-13025" srcset="/wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-12.14.23-AM.png 473w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-12.14.23-AM-300x157.png 300w, /wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-12.14.23-AM-207x108.png 207w" sizes="(max-width: 473px) 100vw, 473px" />
    <ul style="margin-bottom:14px;padding-left:5px">
      <li style="margin-bottom:2px"><b style="color:#ff0303">A</b> (Attack) :音の出始め（例えば鍵盤を押した瞬間）から最大音量に到達する時間</li>
      <li style="margin-bottom:2px"><b style="color:#3c78d8">D</b> (Decay) : Attackで到達した音量最大からSustainに到達するまでの時間</li>
      <li style="margin-bottom:2px"><b style="color:#6aa84f">S</b> (Sustain) : Decayから音が出続けている間保つ音量</li>
      <li style="margin-bottom:2px"><b style="color:#ffd966">R</b> (Release) : 演奏終了（例えば鍵盤を離した瞬間）から音量ゼロまで到達する時間</li>
    </ul>

  </div>

    <a name="footnote3" data-wpel-link="internal"></a>
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <span style="vertical-align: top;color: red;font-size:10px">※3</span> <b>エンベロープ</b>： ピーク（最大値）を描いた曲線。特にここでは音量のピークを描く曲線のことを指しています。<br>
  </div>


</div>
</p>

<p></p><pre class="crayon-plain-tag">var ctx=new AudioContext();
var vco0, vco1, lfo, vcf;

vco0=ctx.createOscillator();
vco1=ctx.createOscillator();
lfo=ctx.createOscillator();
vcf=ctx.createBiquadFilter();

// GainNodeを追加
vco0gain=ctx.createGain();
vco1gain=ctx.createGain();

vco0.connect(vco0gain); // vco0の接続先を変更
vco1.connect(vco1gain); // vco1の接続先を変更
vco0gain.connect(vcf);  // vco0gainからvcfへ接続
vco1gain.connect(vcf);  // vco1gainからvcfへ接続
lfo.connect(vco0.frequency);
lfo.connect(vco1.frequency);
lfo.connect(vcf.detune);
vcf.connect(ctx.destination);

// Oscillator（発振機）を動作させて発音
vco0.start(0);
vco1.start(0);
lfo.start(0);</pre><p></p>

<p>続いて、実際にエンベロープを適応していきます。Web Audioには今回のエンベロープのような時間と目標値を指定して、その間を連続的に値を変化させるオートメーションの機能も提供されており、非常に簡単に実装することが可能です。今回は「指定した値まで直線的に連続して値を変化させる」linearRampToValueAtTime()を使いオートメーションを行います。
ソースコードは以下になります。（エンベロープ部分のみ抜粋）
</p><pre class="crayon-plain-tag">var now=ctx.currentTime;
var attack=0.5, decay=0.5, sustain=0.5, release=0.5;

var rootValue0=0.8; // Attackの目標値を0.8
vco0gain.gain.cancelScheduledValues(0);  // スケジュールを全て解除
vco0gain.gain.setValueAtTime(0.0, now);  // 今時点を音の出始めとする
vco0gain.gain.linearRampToValueAtTime(rootValue0, now + attack);  
// ▲ rootValue0までattack秒かけて直線的に変化
vco0gain.gain.linearRampToValueAtTime(sustain * rootValue0, now + attack + decay);
// ▲ sustain * rootValue0までattack+decay秒かけて直線的に変化

var rootValue1=0.8;
vco1gain.gain.cancelScheduledValues(0);
vco1gain.gain.setValueAtTime(0.0, now);
vco1gain.gain.linearRampToValueAtTime(rootValue0, now + attack);
vco1gain.gain.linearRampToValueAtTime(sustain * rootValue0, now + attack + decay);</pre><p>
<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample03.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">1つ前のライブデモ</a>にエンベロープを適応させた<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample04.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモはこちら</a>になります。（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample04.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）
</p>

<p>以上でアナログ・シンセサイザーの骨格が完成しました。楽器にするためには、パラメータをコントロールするスライダー、ノブ、VCOの周波数を変えて音階決める鍵盤を取り付ける作業を残すのみとなります。より個性的な音を作る場合、例えばノードグラフにVCOをもう1つ並列に追加したりすることで、更に多彩な音色を作ることが可能になりますので試してみてはいかがでしょうか。</p>

<p>ちなみに<a href="http://ryoyakawai.github.io/html5conference2015/analog/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>で使っているノブ、鍵盤は楽器、Audio系のアプリケーションには欠かせないカッコイイノブが簡単に取り付けられるスゴク便利なツール<a href="https://github.com/g200kg/webaudio-controls" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">webaudio-controls</a>というPolymerエレメント（<a href="https://html5experts.jp/1000ch/11905/" target="_blank" data-wpel-link="internal">詳しくはこちらをご覧ください</a>）を利用して実装しています。</p>

<p>アナログ・シンセサイザーの実装の説明は以上になります。</p>

<h3>Web Audio API でFMシンセサイザー</h3>

<p>FMシンセサイザーのFMはFrequency Modulationの頭文字を取っていて、その名の通り周波数を変調して音を作り出す方法で、周波数変調と呼んでいます。（しかしながら、Web Audio APIに用意されている発振機では周波数変調ができません。よって、ここでは複数の波を掛け合わせFMシンセサイザーっぽい音を作っていることにご注意ください。本当のFMシンセサイザーを作るためには周波数変調可能な発振機の作成が必要です）<br>
それでは、どんな音が出るか<a href="http://ryoyakawai.github.io/html5conference2015/fm/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>を試してみてください。
<a href="http://ryoyakawai.github.io/html5conference2015/fm/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer"><img src="/wp-content/uploads/2015/02/Screen-Shot-2015-02-20-at-1.23.53-AM.png" alt="AnalogSynthApp" width="60%" class="aligncenter size-full wp-image-12998" /></a>
</p>

<p>
アナログ・シンセサイザーよりももう少し金属音的な音が出ていると思います。画面右上のプルダウンメニューにて音色も変更することができるようになっていますので、ぜひお試しください。
</p>

<p>
さて、実装に関してですが複数の発振機（Oscillator）を接続していきます。ここで、掛け合わせる側の発振機（Oscillator）をモジュレータ、その影響を受けて掛け合わされる側の発振機（Oscillator）をキャリアと呼びます。今回の実装はモジュレータとキャリアを1つづつ直列に接続し、更にモジュレータを自身にFeedbackしするような接続にします。ノードグラフに表すと以下のようになります。
<img src="/wp-content/uploads/2015/02/fmsynth00.png" alt="fmsynthnodegraph" width="60%" class="aligncenter size-full wp-image-13095" />
少し余談ですが、モジュレータの数が増やすと接続の組み合わせによって複数の接続方法が考えられます。その接続方法の1つ1つをアルゴリズムと呼んでいます。
</p>

<p>ソースコードをみてみましょう。（<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample05.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>、<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample05.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</p>

<p></p><pre class="crayon-plain-tag">var ctx=new AudioContext();
var modulator, carrier;
var modulatorGain, carrierGain, feedbackGain;

modulator=ctx.createOscillator();  // モジュレータを作成
carrier=ctx.createOscillator();    // キャリアを作成
modulatorGain=ctx.createGain();    // モジュレータの振幅を制御するためのGainの作成 (1)の途中にある
carrierGain=ctx.createGain();      // キャリアの振幅を制御するためのGainの作成 (2)の途中にある
feedbackGain=ctx.createGain();     // フィードバックの振幅を制御するためのGainの作成

// 接続
modulator.connect(modulatorGain);          // モジュレータとモジュレータGainの接続
modulatorGain.connect(carrier.frequency);  // モジュレータGainとキャリアの接続
carrier.connect(carrierGain);              // キャリアとキャリアGainの接続
carrierGain.connect(ctx.destination);      // キャリアGainとDestinationの接続
modulator.connect(feedbackGain);           // モジュレータとフィードバックGainの接続
feedbackGain.connect(modulator.frequency); // フィードバックGainとモジュレータの接続

carrier.frequency.value=440;

// 値を変更
//var presetList={ "name":"Elec.Piano1", "freqRatio":[1,9], "feedback":"0", "outRatio":[99,55]};
//var freq=540;
//modulator.frequency.value=presetList.freqRatio[1]*freq;
//carrier.frequency.value=presetList.freqRatio[0]*freq; // 音階を変える
//feedbackGain.gain.value=presetList.feedback;
//modulatorGain.gain.value=(presetList.outRatio[1]/100)*1024;
//carrierGain.gain.value=(presetList.outRatio[0]/100);

// 発振機（Oscillator）を動作させて発音
modulator.start(0);
carrier.start(0);</pre><p></p>

<p>これで発音されます。が、アナログ・シンセサイザーの時と同様にそのままの音が出るだけで面白くないので、ここでもパラメータを変更してみます。コメント化されている「値を変更」の以下7行を生かしてみます。（<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample06.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>、<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample06.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）<br>
なんと、音がキラキラしてきました。さて、ではアナログ・シンセサイザーのときと同じようにエンベロープを適応してみます。ソースコードは以下になります。（エンベロープ部分のみ抜粋）
</p><pre class="crayon-plain-tag">var now=ctx.currentTime;
var m_attack=0, m_decay=0.5, m_sustain=0.3, m_release=0.5;
var c_attack=0.4, c_decay=0.3, c_sustain=0.7, c_release=0.4;

var modulatorRootValue=modulatorGain.gain.value;  // Attackの目標値をセット
modulatorGain.gain.cancelScheduledValues(0);      // スケジュールを全て解除
modulatorGain.gain.setValueAtTime(0.0, now);      // 今時点を音の出始めとする
modulatorGain.gain.linearRampToValueAtTime(modulatorRootValue, now + m_attack);
// ▲ rootValue0までm_attack秒かけて直線的に変化
modulatorGain.gain.linearRampToValueAtTime(m_sustain * modulatorRootValue, now + m_attack + m_decay);
// ▲ m_sustain * modulatorRootValueまでm_attack+m_decay秒かけて直線的に変化

var carrierRootValue=carrierGain.gain.value;      // Attackの目標値をセット
carrierGain.gain.cancelScheduledValues(0);        // スケジュールを全て解除
carrierGain.gain.setValueAtTime(0.0, now);        // 今時点を音の出始めとする
carrierGain.gain.linearRampToValueAtTime(carrierRootValue, now + c_attack);
// ▲ rootValue0までc_attack秒かけて直線的に変化
carrierGain.gain.linearRampToValueAtTime(c_sustain * carrierRootValue, now + c_attack + c_decay);
// ▲ c_sustain * carrierRootValueまでc_attack+c_decay秒かけて直線的に変化</pre><p>
<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample06.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">1つ前のライブデモ</a>にエンベロープを適応させた<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample07.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモはこちら</a>になります。（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample07.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）
</p>

<p>FMシンセサイザーの骨格もこれで完成しました。<a href="http://ryoyakawai.github.io/html5conference2015/fm/" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">完成形のデモ</a>ではパラメータの集合に音色名をつけて選択できるようにしていますが、アナログ・シンセサイザーのときのように、ノブやスライダでパラメータをコントロールするという方法も実現可能ですので、いろいろとお試しいただくと楽しいと思います。</p>

<p>アナログ・シンセサイザーとFMシンセサイザーの実装を通して「Web Audio APIで電子楽器を作ってみる」をやってきましたが、印象はどうでしょう。「Web Audio APIって簡単で楽しいな〜」と感じていただけているととても嬉しいのです！</p>

<p>さて、それでは次のセクションでは作成した電子楽器を本物の楽器のように鍵盤から演奏できるように、MIDIの接続を説明します。</p>

<h2>Web MIDI APIを使う</h2>

<p>
先ほど少しだけMIDIとWeb MIDI APIについてご説明させていただきました。さらに理解したいという方はDTM界隈で著名な藤本健さんの&#8221;DTMステーション&#8221;に<a href="http://www.dtmstation.com/archives/51930656.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">「今さら聞けない、「MIDIって何？」「MIDIって古いの？」」</a>というMIDIを理解するのにドンピシャな記事が公開されましたので、詳細はそちらにお任せするとしてここでは粛々と実装を行っていきたいと思います。</p>

<p>ちなみに2015年3月現在でWeb MIDI APIが動作するブラウザは<a href="https://www.google.co.jp/chrome/browser/desktop/index.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Google Chrome</a>だけとなっています。また、その使用には<a href="https://plus.google.com/u/0/+RyoyaKAWAI/posts/8QeU6ss4dHM" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">フラグの変更（Web MIDI APIを有効にする方法）</a>が必要ですので、お試しになる前にフラグの変更を忘れないようにお願い致します。（MIDIデバイスがお手元になく、Macをお使いの場合は<a href="https://itunes.apple.com/jp/app/easy-midi-free-turn-your-mac/id614043075?l=en&amp;mt=12" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Easy MIDI Free</a>をお使いいただくと演奏できるはずです）
</p>

<p>
コンピュータに接続されているMIDIデバイスをブラウザで取得するには以下のコードを書き、MIDI InputとOutputのデバイスリストを取得します。
</p>

<p></p><pre class="crayon-plain-tag">var inputs, outputs;
navigator.requestMIDIAccess.then({sysex:true})(successCallback, errorCallback);
function successCallback(midiAccess) {
  var inputIterator=midiAccess.inputs.values();
  for(var o=inputIterator.next(); !o.done; o = inputIterator.next()) {
    inputs.push(o.value);
  }
  var outputIterator=midiAccess.outputs.values();
  for(var o=outputIterator.next(); !o.done; o = outputIterator.next()) {
    outputs.push(o.value);
  }
}</pre><p></p>

<p>
MIDI Inputを使う場合、例えば使いたいMIDI Inputデバイスがinputsの先頭にリストされた（index=0）とします。その場合は以下のようにイベントハンドラをつけてあげます。
</p><pre class="crayon-plain-tag">inputs[0]=function(event) {
  console.log("[MIDI Message] " + event.data + " [Timestamp] " + event.timestamp);
}</pre><p>
こうすることで、inputsの先頭にリストされている外部MIDIデバイスからMIDIメッセージが飛んできた場合にMIDIメッセージとタイムスタンプをコンソールに出力するようになります。
</p>

<p>
MIDI Outputを使う場合、例えば使いたいMIDI Outputデバイスがoutputsの先頭にリストされた（index=0）にあったとします。
</p><pre class="crayon-plain-tag">outputs[0].send([0x90, 0x45, 0x3f], performance.now()+0);</pre><p>
とすると、outputsの先頭にリストされたMIDIデバイスに対して0x90, 0x45, 0x3fというMIDIメッセージを今すぐ(第２引数)送信します。MIDIメッセージ0x90, 0x45, 0x3fは、A4の音（0x45）を、50%の音量（0x3f）でチャンネル1を音を鳴らしなさい(0x90)、です。
</p>

<p>といっても、MIDIに慣れ親しんでいない場合は実装のハードルが高いと思っています。そこでWeb MIDI APIの実装を簡単にするPolymerエレメントを公開しています。それが、 <a href="https://github.com/ryoyakawai/x-webmidi" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">x-webmidi</a>です。x-webmidiを使うとHTMLタグを5つ追加する（そのうち1つはWeb ComponentsのPolyfill）だけで、コンピュータに接続されているMIDIデバイスを取得して、セレクトボックスを生成して表示する、までを行ってくれます。MIDI InputデバイスからのメッセージはEventハンドラを、またMIDI Outputデバイスへのメッセージの送信は.sendRawMessage()を使い生のMIDIメッセージを、.sendHRMessage()を使いMIDIに慣れていない方でも分かるようにメッセージを送信できるようになっています。コードにするとこうなります。</p>

<p></p><pre class="crayon-plain-tag">&lt;script src="path/to/webcomponents.js"&gt;&lt;/script&gt;
&lt;link rel="import" href="x-webmidirequestaccess.html"&gt;
&lt;x-webmidirequestaccess sysex="true" input="true" output="true"&gt;&lt;/x-webmidirequestaccess&gt;
&lt;x-webmidiinput id="midi-input"&gt;&lt;/x-webmidiinput&gt; 　　// MIDI Inputデバイスのセレクトボックスを表示 
&lt;x-webmidioutput id="midi-output"&gt;&lt;/x-webmidioutput&gt; // MIDI Inputデバイスのセレクトボックスを表示

// MIDIメッセージを受信する
window.addEventListener("midiin-event:midi-input", function(event){
    // MIDIノートナンバーと、対応する周波数をConsoleに出力
    console.log("[noteNumber] "+event.property.noteNumber+" [frequency] "+event.property.frequency);
});

// outputsの先頭にリストされたデバイスにMIDIメッセージを送信する
var outputs=documenet.getElementById("midi-output");
outputs[0].sendHRMessage("noteon", 0, ["d4", 127], performance.now()+0);</pre><p></p>

<p>それでは、Web Audio APIで作ったシンセサイザーを、MIDIデバイスから操作できるように実装していきます。演奏するためには、音階を変えるのですが、そのためには発振機（Oscillator）の周波数を変更する必要があります。MIDIの鍵盤は1つ1つに連番の番号がついていてこれを<a href="http://ja.wikipedia.org/wiki/MIDI" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">MIDIノートナンバー（ノートナンバーでページ内を検索）</a>と言いますが、そのMIDIノートナンバーから周波数に変換する必要がありますが、それをコードにすると以下のようになります。
</p>

<p></p><pre class="crayon-plain-tag">var freq=440.0 * Math.pow(2.0, (noteNo - 69.0) / 12.0); // noteNoはMIDI鍵盤の鍵盤番号</pre><p></p>

<p style="margin-bottom:8px">しかし、x-webmidiを使うとEventの引数として演奏した鍵盤の番号とそれに対応する周波数が取得することができるので、MIDIノートナンバーから周波数の変更をする必要はありません。これらをアナログ・シンセサイザーとFMシンセサイザーに実装をするとこのように実装できます。</p>

<ul>
<li style="margin-bottom:2px">（単音）アナログ・シンセサイザー：<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample08.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample08.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</li>
<li style="margin-bottom:2px">（単音）FMシンセサイザー：<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample09.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample09.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</li>
</ul>

<p style="margin-bottom:8px">
でもこのままだと単音しか出なくて楽しくないので、和音も出せるようにしちゃいます。そうするとこうなります。
</p>

<ul style="margin-bottom:14px">
  <li style="margin-bottom:2px">（和音可）アナログ・シンセサイザー：<a href="http://ryoyakawai.github.io/html5conference2015/analog/sample10.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/analog/sample10.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</li>
  <li style="margin-bottom:2px">（和音可）FMシンセサイザー：<a href="http://ryoyakawai.github.io/html5conference2015/fm/sample11.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ライブデモ</a>（<a href="https://github.com/ryoyakawai/html5conference2015/tree/master/fm/sample11.html" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">ソースコード</a>）</li>
</ul>

<p>自作した楽器を両手で演奏できちゃいますよね。立派な楽器のできあがりです！「Web Audio APIとWeb MIDI APIを接続するのって簡単で楽しいな～」と感じていただけているととても嬉しいのです！</p>

<h2>番外編</h2>

<p style="margin-bottom:8px">2015年3月13日（金）にWeb MIDI APIはGoogle Chromeにおいて実験的APIから標準のAPIとなることが承認されました。これによって、フラグを変更することなく（これが不要になる ▶ <a href="https://plus.google.com/u/0/+RyoyaKAWAI/posts/8QeU6ss4dHM" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Web MIDI APIを有効にする方法</a>）、Web MIDI APIを利用することが可能になります。この変更がChromeに適応されるまでにはもう少し時間がかかりますが、実現するとWeb MIDI APIがChrome APPsでの利用も可能になります。（<a href="https://developer.chrome.com/apps/about_apps" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Chrome Appsとは：英語</a>）Chrome Appsにしてしまえばオフラインでも利用可能<a href="#footnote4" style="vertical-align: top;color: red;font-size:10px" data-wpel-link="internal">※4</a>になります。ですので、ユースケースとして例えばライブでWeb Audio API、Web MIDI APIを使った自作楽器でパフォーマンスを行いたい、という場合に活躍してくれることでしょう。</p>

<p style="margin-bottom:8px">そこで、今回ご紹介した2つのシンセサイザーをChrome Appsにして公開してみました。（Web MIDI API部分の動作はしません：2015年3月14日現在）</p>

<ul style="margin-bottom:14px">
  <li style="margin-bottom:2px"><a href="https://chrome.google.com/webstore/detail/analog-synthesizer2-oscil/fpgbjodpjjmmjmoeiddbbmlkonmkjnhf" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">アナログ・シンセサイザー</a></li>
  <li style="margin-bottom:2px"><a href="https://chrome.google.com/webstore/detail/fm-synthesizer1-operator/okaomknpndkkiieohhibkfkbiniijpoe?utm_source=chrome-ntp-icon" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">FMシンセサイザー</a></li>
</ul>

<p style="margin-bottom:8px">細かいところですが、Chrome AppsはCSP（Contents Security Policy）によってスクリプト（JavaScript等）をHTMLファイルへインラインで書くことが禁止されていますが、これら2つのアプリにはPolymerエレメントを使っています（インラインJavaScirptが書かれたHTMLファイルです）のでちょっと困ったことになります。それを解決してくれるBuildツールに<a href="https://github.com/polymer/vulcanize" data-wpel-link="external" target="_blank" rel="follow external noopener noreferrer">vulcanize</a>があります。&#8221;csp&#8221;オプションをつけてツールを実行することでHTML部分ととスクリプトを分けてくれますので、ソースコードの変更なしにCSPに合致したソースコードを生成することが可能なのです。
</p>

<p><code>
$ vulcanize --csp -o build.html index.html
</code></p>

<p style="margin-bottom:8px">Google Chromeのフラグの変更なしにWeb MIDI APIの利用が可能になることで、Web Audio API、Web MIDI APIを使ったブラウザで作った電子楽器の使えるシーンがより拡大されることを期待しています。manifest.jsonとバックグランドで動作させるJavaScriptの2つのファイルを用意することで簡単に実現できますので、ぜひ試してみてください。</p>

<div style="border:solid 1px #cccccc;margin-bottom:25px">
  <div style="margin:10px 5px 10px 10px;border-left:3px solid #aaaaaa;padding-left:10px">
    <a name="footnote4" data-wpel-link="internal"></a>
    <span style="vertical-align: top;color: red;font-size:10px">※4</span> <b>オフラインでも利用可能</b>：Webアプリは大きく分けて以下の2つの種類があります。<br>
    <ul style="margin-bottom:14px;padding-left:5px">
      <li style="margin-bottom:2px"><b>Hosted App</b>: HTML、CSS、JavaScript等の全てのリソースファイルがWebサーバに保存されているWebアプリのことです。URLにアクセスしてアプリを起動する所謂従来からよく知られているWebアプリです。</li>
      <li style="margin-bottom:2px"><b>Packaged App</b>: Hosted Appとは違い、HTML、CSS、JavaScript等のリソースファイルがzip等で1つになっており、Webブラウザにインストールします。Webブラウザにインストールされたリソースから起動します。そのため、オフラインでも動作が可能になっています。Chrome Appsはこの方式のWebアプリです。</li>
    </ul>
  </div>
</div>

<h2>おわりに</h2>

<p>いかがでしたでしょうか？Web Audio APIで用意されている発振機（Oscillator）は正弦波、ノコギリ波、矩形波、三角波の基本的な波形しかなく、それ単体では単調な音しか出なかったのが、少し波形処理をしてあげることで楽器らしい音にすることができたと思います。さらにはWebブラウザに鍵盤をつなげると、和音まで演奏できるようになってしまいました。
</p>

<p>さて、自作で楽器が開発ができるのはWebブラウザが初めてでしょうか？いえ、そんなことはありません。Windows、Mac、Android、iOS等の所謂Nativeな環境でも開発することは可能でした。では、Webブラウザで開発できるようになった利点はなんでしょう。それは楽器を開発するということに対するハードルが一段と低くなったところです。WebアプリケーションはWeb標準言語で開発します。Web標準言語の開発はブラウザとテキストエディタで行います。ですのでコンピュータを買ってきたその日から開発が可能です。さらにご説明させていただいた通り、こんなにも簡単に楽器を開発することができるのです。</p>

<p>今までは難しそうなイメージがあった音楽を使ったアプリケーション。しかしWeb Audio APIを使うと音を作ることができます。またWeb MIDI APIを使うと外部のMIDIデバイスとの双方向の操作が可能です。開発するWebアプリケーションに音を鳴らす要素を追加してみる、または遊び心でMIDIデバイスからWebアプリケーションを操作してみる等、ほんの少しの遊び心があなたのWebアプリケーションをより面白くする可能性があります。これを機会にいろいろなとことで試してみてはいかがでしょうか？
</p>

<h2>セッションの資料と動画</h2>

<p>2015年1月25日に行われたHTML5 Conference 2015の当日の資料と動画へのリンクです。こちらも合わせて御覧ください。</p>

<h3>動画</h3>

<div class="aligncenter">
<iframe width="315" height="177" src="https://www.youtube.com/embed/sRHhclavETY?feature=oembed&#038;wmode=opaque" frameborder="0" allowfullscreen></iframe>
</div>

<h3>スライド</h3>

<div class="aligncenter">
<iframe src="https://www.slideshare.net/slideshow/embed_code/key/6s8QuVndYhqe7U" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/ryoyakawai/web-audi-oapi-web-midi-api-2015-html5-conference" title="Web Audio API, Web MIDI API - 2015 html5 conference" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Web Audio API, Web MIDI API &#8211; 2015 html5 conference</a> </strong> from <strong><a href="http://www.slideshare.net/ryoyakawai" target="_blank" data-wpel-link="external" rel="follow external noopener noreferrer">Kawai Ryoya</a></strong> </div>
</div>
]]></content:encoded>
		
		<series:name><![CDATA[HTML5 Conference 2015 特集]]></series:name>
	</item>
	</channel>
</rss>
