新・日々の暮らしに疲れてない?

一人バンド、火頭工房

TensorFlow.jsで来客人数予想。

少し前から学習しているTensorFlow.jsですが、そろそろ何か使えるものが作りたい。

 

学習しながら漠然と考えていた作成予定のモノ。

1、画像認識を使って自動販売機を作る
2、クローム拡張機能にtensorflowを取り入れた何か
3、店の来客人数予想

 

1はまだ学習不足なのと実際に動かすには物理的な工作が必要になる、そっちの知識が皆無。


2はニュースサイトなどで邪魔な記事を消す機能を作りたい。文字、文章を理解させる構造を作るのが大変そう。文字をテンソルとして扱うのはどうするんだろう?

 

というわけで今回は3に取り組みました。

 

私、実は自分で作った加工品などを某店舗で販売して頂いているのですが、販売スペースも限られているので、どれくらい納品するべきか、どれくらい売れるか、というのはやはり気になるわけです。

 

数年やってりゃ7月はこんな感じ、とか11月はこれくらい、など分かりますし、
前年の記録を見て決める、など当たり前のやり方をしています。

 

とはいえ、来客人数を決める要因は季節(月)の他、曜日、日付、天気、温度などがあるでしょうし、祝日があるか、地域に観光バスが来るかどうか、など色々考えられます。

 

これらをtensorflow.jsで予想してもらいます。

 

まず、データを用意することが大事。

表計算ソフトでデータを用意し、csvファイルとして保存、それをjson形式に変換し、
javascriptで操作するようにしましょう。

 

今回作るのは簡易版として、用意する項目は...

 

月、曜日、最高気温、天気、祝日、閉店、来客数


ということにしましょう。日付も大事かと思いましたが、2月5日だから人が多い・少ない、というよりも曜日の要素の方が強いかな、と思いまして。

 

↓こんな感じ。

f:id:hiatama:20180730144907p:plain

 

月は1~12で入力していますが、tensorflowに渡す時は0.01~0.12のような小数点以下の形で渡します。
曜日は1~7で月~日曜日までを表します、やはり小数点以下の形に直して計算させます。
天気は0~4で、晴れ、くもり、雨~などを表します。
祝日、閉店は0か1かで渡します。閉店は年末年始など営業していない日です。

 

これを2016年までさかのぼって用意します。

 

天気、最高気温はこういうサイトで確認できます。
https://www.data.jma.go.jp/obd/stats/etrn/index.php
ただ天気に関してはあまり正確ではなさそう、アメダスとかで検索した方が良いかも。

 

一番困るのは実際の来客数なんですよねぇ。これはお店の人に教えてもらうしかないのですが、私がコミュ症なのと、なんのために1000件以上になるであろうデータを使うのか、など聞かれるわけで...


まさか夏休みの自由研究に、とも言えないわけで、小学40年生じゃあるまいし。


とりあえず、それらしい人数をでっちあげて入力しておきましょう。

この入力作業、2016年1月1日~2018年7月末現在までですから、結構大変です。

 

んで、このファイルをCSVという形式で保存します。
それを変換できるサイト調べてJSONの形に直してもらいます。

 

そうしましたらば、

var myJson = [
{
"month": 1,
"day": 5,
"temp": 11,
"weather": 0,
"holiday": 0,
"closed": 1,
"customers": 0
},
{
"month": 1,
"day": 6,
"temp": 13,
"weather": 0,
"holiday": 0,
"closed": 1,
"customers": 0
},
以下略

 

こんな感じでjavascriptでいじれるようになります。

これをテストデータ(xs)とラベルデータ(ys)に分けてリストにします。
for inループでも回して、xsとysのリストを作る。xsとysについては以前のエントリーを読んで頂ければ。

 

さきほど書いた通り、tensorflowさんは小数点以下の形がお好きなようで、適宜正規化します。
例えばxsは、[0.01, 0.5, 0.13, 0.1, 0, 0] このような形になり、

左から、[1月、金曜日、最高気温13度、くもり、祝日×、閉店×] という風に表します、最終的には違う正規化をすると思いますが、わかりやすくしておかないとテストがしにくいので。

 

ysは[0.033]で、来客数33人を表すなど。


xsの条件の時、ysの結果になりました、というのを様々な角度からtensorflow様に学習してもらうわけですね。

 

この2つのリストをtensorの形にして、tensorflowさんに渡し、計算方法などを指定すれば学習してくれます。

 

計算中のTensorflow様。

f:id:hiatama:20180730144700p:plain


表示されている数字ができるだけ低くなるよう、計算方法やオプティマイザーと呼ばれるものを選んだりします。件数がまぁまぁ多いようで、遅い。

 

計算終わり。早速、予想してもらいましょう。

多少のインターフェースを用意しました(こういうのが一番苦手)。

f:id:hiatama:20180730144821p:plain

 

条件: 3月の日曜日、最高気温23度、晴れ、祝日ではなく、店舗は営業日。


さていかに!

 

f:id:hiatama:20180730144941p:plain

 

ウーム、この数字が正しいのかは正直よくわかりませんな。

 

↓最高気温を5度とさむぅい一日にしてみた所、予想人数は減りましたので、
まぁまぁ学習している模様、もっと減っても良くない?笑

f:id:hiatama:20180730145033p:plain

 

その他、月曜日や雨の日は予想人数が少ないなど、一応用意したデータ通りの結果になっています。

 

一応テスト終了。

 

あとはお店にお願いして、正確な来客人数を入手し、入力。
より細かい天候データを入力。

日付を入れるとどうなるか、その他の要因が必要かどうか。
調整を繰り返し...

 

これでお店の来客数が予想できるわけですが!!!

「アッ アノッ ライキャクスウ クダサイ…」

...お店に行って怪しまれるの嫌だなぁ...

 

おしまい

【Chrome拡張機能】YouTube動画の音量をオートで調整くんに着手 その2

前回のエントリーからテストを重ね、わかったことなどを書きます。

 

まず作成中の拡張機能について。

YouTubeの動画を流す時、音量の平均値を計算し、それを元にスレッショルドしきい値)を設定し、スレッショルドを超える音量が来た場合に自動で抑えてくれる機能。

絶対的に規定以上の音量を抑えるのではなく、突発的な大きい音を軽減する目的。

 

問題1

スレッショルドを大きく超える値が連続して飛んできた場合、例えば動画途中からBGMがかかりスレッショルド超え続けた場合など、音量がスレッショルド以下にならなければ機能がトリガーされたままになってしまう。このような音量の増加は上記の「突発的な大きい音」には当らないので、なんとかして機能を外す方法が必要となる。

 

対策案1

機能の作動時間を秒数で決めてしまう。簡単な解決策だが機能が外れた時に大きな音量が継続している場合、またトリガーされてしまい音量は意味なく上下されることになり不快である。

 

対策案2

機能がホールドされている間、スレッショルドを少しずつ上げていく、いずれ音量を上回るので、機能が外れることになる。この時点でスレッショルドが十分に高くなっているので、平均値の再計算が邪魔されることなく機能が正常に作動する。

 

以上です、当然対策案の2を採用しました。そもそもユーザーがボリューム上げる可能性だってありましたもんね 笑 機能がホールドされるのを防ぐ処置は必須でした。

 

さて、これで調子良く動作したのですが...

YouTube用の拡張機能は中々クセモノで、以前から、YouTubeのトップページから動画試聴ページに移動する時に問題が発生しています。

 

今回の機能が作動して欲しいのは当然、動画試聴ページの方だけなのですが、そのためにマニフェストファイルというものに、URLを指定するのです。

 

こんな感じの書式になります。

"content_scripts": [
{
 "matches": ["https://*.youtube.com/*"],
 "js": [
  "content.js"
 ]
}
],

 

matches の所に作動して欲しいページを指定、*.youtube.com/*から始るURLの時だけcontens.jsを動かしてね、ということなんですが、このままだとトップページでも作動してしまいます。

 

動画試聴ページのURLは 'youtube.com/watch?v=' こうなっていますので、そのように指定するのですが...ダメなんですよねぇ、トップページで作動しようとしてしまいます。

 

別に全ページで作動させればいいじゃん、って思うじゃないですか?

 

YouTubeではAjaxを利用してページの一部分だけ読み込みをし直す手法を取っているんです。一度エラーが出てしまうと無理をしない限りもう一度機能をトリガーさせられません。

 

そこでMutationObserver という機能でタイトルが変わった時を察知させようとしたり頑張ってるんですがねぇ...何故かトップページから動画試聴ページに始めて飛ぶ時だけが上手くいかないんです。動画ページでリロードすると以降はうまく作動するんですけど。

 

どうやら憎きクロスオリジン系のエラーが出ているそうです、狙った通りに作動するまで公開はお預けになりそうです。残念。

【Chrome拡張機能】YouTube動画の音量をオートで調整くんに着手

YouTubeなしではもう生きられません、火頭です。

それほどにYouTubeは私の生活に根付いております。

 

そう言った手前、文句を言うのははばかれるのですが、今回直したいことは以下。

 

動画を自動再生にして流していると、動画によって音量が違うので、たまに耳に痛かったりします。あとは動画の最中に盛り上がってワッと音量上がったり、うるさいジングルを採用していたり...イヤホンしていることが多いので、結構困るんですよね。

 

自作の拡張機能で、新しく動画を開いた時は音量を70%くらいに設定するようにしているのですが、動画の最中のうるさい瞬間に関してはそれでは対応できません。

 

ということで「動画の音量を監視して、一定より音量が上がった場合に自動で音量を抑えてくれる機能」を作りたい。

 

まず「音量を監視する」について。

 

いきなり難関です。結局はWeb Audio APIを採用することに。この機能、自分のサイトで使っているのですが、拡張機能では初めて、いやな予感しかしません。

 

ってか普通Web Audio APIは自分でシンセ的なものを作って音を出すか、ファイルを読み込んでそれを加工する目的で使われます。ブラウザ内で流れてる音をどうやってWeb Audio APIに繋げるのか、そこからして初めての試みです、でも拡張機能でEQ機能とかあるもんなぁ。

 

結局は<audio>とか<video>タグをgetElementして、それをWeb Audio APIに繋げると出来るらしい。なんと荒っぽいというか...ホンマに出来るんかいな、って試してみたら出来ました 笑。YouTubeは当然<video>タグの方でした。

 

とりあえず、ブラウザ内の音をWeb Audio APIでいじれるようになりました。

音量監視はAnalyserノードを使います。使い方をアレコレ調べて回ったのですが、そういえば自分のサイトですでに使ってました、音量を数値化して音楽に合わせて映像を出すビジュアライザーを自作したのでした。それをコピペしてとりあえず音量監視はクリア。

 

さて、これで動画を流したらsetInterval関数などで指定したタイミングで音量が取得できる。

 

「一定より音量が上がった場合」について。

 

一定より音量が上がった場合って何? ってことですよブラザー。

スレッショルドを決めてそれを上回った場合、ということですが、そのスレッショルドをどうやって決めましょう? 

 

ちなみに音量は数値でズラズラと流れてきます。30 32 38 40 43...といった感じでしょうか。

 

簡単なところでは、ある期間、音量を監視して、その平均を出す、それをその動画のその部分の平均的な音量として、その少し上くらいをスレッショルドとして設定し、スレッショルドは随時更新する。無音があったりする動画には弱そうですが、切捨てすれば良いでしょう。こんな所でいかがでしょう。

 

「自動で音量を抑えてくれる機能」の部分。

上記のスレッショルドを上回る音量が飛んで来たら、gainNodeでボリュームを下げる、これで良い、実際試してみたら動作確認できました。

 

で、次の課題。

・下げた音量はいつ戻すか

・音量はスムーズに下げたり上げたりしたい

 

下げた音量をいつ戻すか、について。

普通に考えてスレッショルドを下回るまで下げ続ける、という感じですが。ここで問題。gainNodeで音量を下げると当然、監視している音量に影響するんですよね。

 

動作の様子はこんな感じ ↓

 

スレッショルド = 50として

44 48 52 ←拡張機能作動! 48 41 37 33...

 

こうなるので、すぐにスレッショルドを下回るんですよね。

これで音量を戻してしまうと実際の動画ではまだうるさい部分の最中なわけです。

 

f:id:hiatama:20180704214201j:plain

 

どうしましょう? 

効果は一定時間にするか、それとも下げる前の音量を監視できるように調整するか?

後者のが良いですが、面倒です。とりあえず一定時間で。

 

というか実際はスレッショルドを越える時、数回そういう数値が飛んでくるので、何度も機能がトリガーされてしまいます。

 

音量の変化を繰り返さないよう、そこはフラグで対応するとして、トリガーされるたびに音量平均の計算を0の位置に戻してやれば、計算は最初からになり数秒かかります(そういう設定にしている)数秒間は音量が下がった状態が続きます、平均計算が終わった時に、音量を戻すように設定してやれば、大体良い感じに動作します。

 

元の音量を監視しているわけではないので、戻ればまたトリガーされる可能性のあるザル仕様ですが、とりあえずこれで。

 

音量をスムーズに上げ下げしたい。

結構苦労しました。gainNodeはループ回してちょっとずつ音量を下げても結果はドンと下がるだけ、まぁこれは予想通り。

 

再帰関数作ってはどうか。これもダメ、やっぱドンと下がるのみ。

setTimeoutとかsetIntevalか?と思い調べてみたところ。

 

var gainNode.gain.exponentialRampToValueAtTime

 

という謎メソッドがヒットしました。これでスムーズに狙った音量に、狙った時間をかけて移動できます。良いメソッドです、自分のサイトで採用してそうなもんだけど知らんかったなぁ。

 

これくらいで最低限の動作が確保されました。

 

気になるのは、analyserNodeによる音量の計算のところで、実際の音量というよりも音圧によって数値が上がってるなぁ、という印象。

BGMが入ったり、複数人数がしゃべってる時に音量の数値が高く計算される感じ、一人が大声出すより、二人がわいわいしてる方が数値が高いイメージ、もうちょいなんとかしたい。

 

あとはインターフェイス揃えて、エフェクターソフトのような使用感にするべきですね、そういうの面倒で嫌なんですけど。

 

でも、スレショルドの高さ、音量の押さえ具合、平均値の計算にかかる時間(現状ではこれがリリースのタイミング)など私が独断で決めてますからね、そりゃマズイです。

 

調整ができたら公開します。

あとそういえばWeb Audio APIにはコンプレッサー機能があるんですよね、今回の拡張機能はまさにコンプなので、最初からこちらを採用すれば良かったのでは?

 

f:id:hiatama:20180705204404p:plain

 

【Tensorflow.js】Tensorflowがjavascriptにやって来た。その2

前回のエントリーの続きですが、書いてすぐに例の素晴らしい動画主が新作をアップしてくれていて、ちょうど私がトライしたかった画像認識に通ずる「クラス分類」の導入を見ることが出来ました。

 

youtu.be

 

私がいくらドシロウトプログラマーだとして、さすがに適当な事ばかり書くのはよくないので、今回の動画から学んだことを記します。

 

まず以降でたくさん使うかも知れない「クラス分類」という言葉について。

↑英語でClassifierです、正確な日本語は知らん

 

例えば画像認識で「これは80%の確率で犬です」とか「これは98%の確率で猫です」と、こういうものがクラス分類です。で、どのようにTensorflow.jsが正解率を上げて行くかというと、大量の学習データが必要なわけです。

 

上の動画では、色をランダムにサイトに表示させ、ユーザーが「これは赤っぽい」とか「緑っぽい」とか選ぶように、協力を呼びかけています。

 

ユーザーがそのサイトに行って、ポチポチと色の判断をしていくわけですが、表示される色は赤、緑、青の度合い(0~255の数字)によって表現されていますので、赤さ、緑さ、青さの数値をデータベースに記録させていきます。

 

あとは表示された色が「赤っぽい」と感じたのか「緑っぽい」と感じたのか、答えとなる「ラベル」を記録。その他、イタズラを検知するための「ユーザーID」なども記録しています。

 

で、前回の私のエントリーと繋がるわけですが、ここでワンホット※です。

※[0,0,1] や[0,1,0]など1つだけ「1」があり、その他は「0」の形をいいます。

 

動画でワンホットは、答えとなる「ラベル」と合わせて登場します。

例えばユーザーが選べる答えが5種類しかないとして、

「赤っぽい」「青っぽい」「緑っぽい」「黒っぽい」「白っぽい」これがラベル。

上に習うなら、赤は [1, 0, 0, 0, 0] 黒は[0, 0, 0, 1, 0]という風にTensorflow.jsに学習してもらいたい、つまり答えを表す「ys」としてワンホットが登場します。

 

データベースにはラベルを「赤っぽい」「青っぽい」と記録しているわけですから、そのようなリストを作る。

 

const labelList = [

 '赤っぽい',

 '青っぽい',

............

]

 

んで、データベースからデータ引っ張ってきて、ユーザーが実際に選んだラベルが上のリストの何番目に当てはまるかループでも回して別のリストに記録していく。

 

var labels_users = [

 0,

 1,

 4,

 2

...

]

 

これでユーザーが選んだラベルの数値化が出来たので、これをワンホットにします。tf.oneHot() を使います。

引数にさきほどのリストとクラス分類の数(5色しか選べないなら5)を渡せば...

 

f:id:hiatama:20180705204404p:plain

 

まぁ何度かこんなんなりながらも...

labels_users で3だったものは、[0, 0, 0, 1, 0] このように表現されるはずです。

 

はぇ~、こうして ys を設定するべきだったのかぁ~なるほどよぉ~。

で、これでスマートに学習できるじゃん!行けそうじゃん!ってなるわけですが。

 

チョ、マテヨ。

ラベルの設定がスマートに行ったとして、結局tensorflow.jsが返してくれる答えは 

[0, 0, 0.88888888, 0,122222, 0] とこんな感じの、ようするにワンホットじゃあないわけです。

 

一番確率が高いものが分かったとして、それが何番目のインデックスで、それが答えのリストで何色を表していたのか、この辺はやっぱ自分で書くわけ?

 

で書いてると、ループ回しすぎてエラーが出て...

f:id:hiatama:20180704221619p:plain

こうなるわけです。

 

無事動作し、ラベルのお作法がわかったのは良いのですが、手間的には前回とあまり変わっていません。

 

というか、動画ではその辺を説明するのは次回以降なんですね。

あー待ち遠しい。

 

以上。

【Tensorflow.js】Tensorflowがjavascriptにやって来た。

えーっ!! Tensorflowがjavascriptに来たってぇ!?

そりゃめちゃくちゃホットです。

 

マシンラーニングはずっと気になっていた分野ですが、私は基本的にjavascriptしか使えないので泣く泣く保留していたのです、あとなんか難しそうだし。


以前2つ目のプログラミング言語を学習する気になった時、Pythonも候補だったのですが、Goを選んでしまったんですよね、その後Haskellも。←どっちも今全く触っていないので本当に判断ミスです。


ついに、人工知能ライブラリのTensorflowがjavascriptで使えるようになりました、と。これはもう逃げ道がありません、やるっきゃない!


環境構築はめちゃくちゃ嫌いなので、かなり気合を入れて公式ページを開き、導入の仕方を見ることに。さて何をインスコさせられ、パスを通させられるのやら...


実際は

<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@0.11.7"> </script>

これをhtmlファイルに貼るだけ。衝撃の手軽さです。


ウキウキになった所で、色んな人のブログを見て学習を始めたものの、すごく難しい、全くついていけん。


幸い私、英語がそこそこわかるので、Youtubeチュートリアル的なのを探した方がいいな、ということでいくつか物色したところ、この人の動画が一番自分に合っていました。教え方、しゃべり方、動画のクオリティも素晴らしい。

 

動画をなぞる形でとりあえず真似をする。

インプットを与えて、ラーニングさせて、アウトプットを出す。という流れは再現できました。


今回のインプットはただの数字、例えば


const xs = tf.tensor2d([     

  [0], 

  [0.5],   

  [1]

 ]);


tf.tensor2dの部分は、こうしてデータを渡さないとtensorflowが読んでくれないからこういう書式にする。そりゃテンソル(テンサー)フローですからね。


人工知能界隈ではテストデータを「xs」で表現するのが慣習な模様。

xsは例えばトランプのカードの画像。
それに対してysは「ラベル」と呼ばれ、xsと対になる「答え」のリスト。

 

例えば、xsの最初の画像(カード)は「ハートの5」次は「スペードのジャック」ですよ、などとtensorflowに教えてあげるわけですね。


答えは適当に

const ys = tf.tensor2d([     

  [1, 0, 0], 

  [0, 1, 0], 

  [0, 0, 1]

 ]);


とりあえずこんな感じに。

xsと合わせて見ると、[0]を渡した時、答えは[1,0,0]で、[0.5]を渡せば[0,1,0]ですよ、と学習させて行く感じ。tensorflowは自分で予測を立て、ミスを繰り返しながら予測の精度を高めて行く感じでしょうか。

 

学習パラメータや方法などを指定して実行してそれでお終い。このあたりは動画のコピーで簡単に終わりました。ただしっかり理解するのは難しい、ってか自分には無理な気がします。


学習が終わったモデルさんに、xsと同じような形でデータを用意して渡してあげれば...

[0]に対する答えは [0.988889, 0.122112, 0.122343] ←こんな感じで返ってきます。

[1, 0, 0]に近い形になり、一応これでインプットに対して予想を返す、ということが出来ました。


んー、でも数字の羅列が返って来てもよくわかんないよな...

ゆくゆく実践したい画像認識を意識して、

[0]を渡す → 「犬」だと思います。

[0.5]を渡す → 「猫」だと思います。

と数字じゃなく文字で返してもらうことにしよう。というわけで私は無意味な地獄にはまって行ったのです。

 

f:id:hiatama:20180704214201j:plain

 

以下、無意味な地獄の話。改善したこちらのエントリーもどうぞ。


tensorflowさんが返してくれる [0.988889, 0.122112, 0.122343] こういうやつをまずテンソルではなく、普通の数値に変換する。

dataSync() でOK、これで手軽にいじれます。


ysと同じ内容の答えリストを用意する

const answerList = [     

  [1, 0, 0], //dog     

  [0, 1, 0], //cat     

  [0, 0, 1]  //fox

]

それぞれどういう意味なのかを別のリストに書く。

const answerWords = ['dog', 'cat', 'fox'];


さて、返ってくるデータは半端な数字なので、なんというか四捨五入的なことをして、[1,0,0]みたいな形に直す。ちなみにこういう[1]が1つだけ、他は[0]というデータの形をワンホットと言うそうです。


そのワンホットのデータとanswerListとを比べて一致するものを調べ、answerWordsから同じインデックスのモノを取って来て表示。

 

さて、ブラウザで実行してみると、以下のように徐々に数字が減って行きます。これが間違い率みたいなもので、低いほど学習が進んでいます。

 

f:id:hiatama:20180704213556p:plain

 

トレーニングが終わったモデルさんがどう予測してくれるか、チェック。

入力と出力をお忘れでしょうからもう一度書きます。

xs = [0, 0.5, 1]

ys = [     

  [1, 0, 0],  ←「dog」を意味します     

  [0, 1, 0],  ←「cat」を意味します     

  [0, 0, 1]   ←「fox」を意味します     

]

例えば、[0.1]を渡したらtensorflowさんが「それ[1, 0, 0]に近いよね」とテンソルで結果を返してくれて、その結果を先述のワンホットがうんたらとかをまとめた自作のcheck()関数で翻訳「答えはdogっぽいですよ」。みたいな感じ。

 

では「1」を渡してみましょう。

f:id:hiatama:20180704213559p:plain

わかりにくいですが、チェック関数に[1]を渡すとtensorflowがテンソルを返してくれます、なんとなく[0, 0, 1]に近い形をしていますね。これをワンホットに直し、自作した答えリストと照らし合わせ、「fox」にマッチする、と答えを出してくれています。

 

もうちょっと曖昧な数値を渡すとどうでしょう?

f:id:hiatama:20180704213601p:plain

「0.4」を渡してみれば、[0,1,0]に近い形で返してくれました。これはxsの0.5に近い入力なので、これで正解ということになります。

 

以上。


ムキになってワンホットを自作したりしましたが、たぶん気軽にラベルを設定する方法とかあるはずなんですよね。


tensorflowで大事なことは、データ(例えば画像)をどのようにインプットとしてフォーマットし、テンソルとして渡すのか、ここのように思えます。画像ならピクセルの数をテンソルに合わせる模様、[28×28]など、なるほどぉ~。


あとはアウトプットの読み取り方もよくわかっていませんが、何か簡単なラベルの操作の仕方がありそうな気がします。


ゆくゆくはリアルタイムの映像認識を学習して、自動販売機を作りたい、と思ったのですが...お金の映像認識は結構危ないな、カ○ーコピーされたらたぶん認識しちゃってアウトだよね 笑。

 

書いてしまうとあっさりですが、ここまで死ぬほど苦労しました。

f:id:hiatama:20180704221619p:plain

↑ こうです。

Chrome拡張機能「YouTube Quality Adjuster」がいつの間にか動かなくなっていたのを復活させた話。

お久しぶりです、火頭です。

以前作成したクローム拡張機能YouTube Quality Adjuster」がクロームのアップデートの具合で、機能が効かなくなっていました。↓これ

 

YouTube Quality Adjuster」

YouTube Quality Adjuster - Chrome ウェブストア

 

実に1年くらいこの状態が続いており、海外でも似た機能を実装していた人達がアレコレと苦労していました。Youtubeが用意しているapiには速度調整や画面の大きさ変更等色々ありますが、apiが用意されているにも関わらず、なぜか画質調整機能だけが効かないという不思議な状況が続いていました。

 

そしてついに直りました!

 

ロームアップデートで機能が復活していないかな?と定期的にチェックしていたのですが、適当にYoutubeを開いてコンソールでチェックしていたら以前はなかった機能があることを発見。コレ↓

 

setPlaybackQualityRange();

 

なんやコレ? と思って試しに使ってみた所...

画質が変更されました、なんじゃそりゃ。

 

rangeとなっているので引数はなにを入れるんだろう?と悩んだものの、以前採用していたsetPlaybackQuality()と同じ使い方をしたところ、成功。

 

このメソッド調べても、公式に仕様が(というか存在自体)説明されていない謎メソッドです。

 

グーグルさん、お願いだからこのメソッド廃止にしたりしないでね。 

楽曲「Snow Covered Town」を公開。

楽曲「Snow Covered Town」を公開しました。

前回も冬に書きたくなる曲を投稿しましたが、その第二弾です。

 

soundcloud.com

 

完成してみればそれほど冬っぽくないな、と思いましたが、まぁインスピレーションをもらったということで。