作成者別アーカイブ: todkm.admin

When Your Android Phone App Doesn’t Work, Just Install GApps Again

If you unlock your Android phone and install custom ROM and some basic Google apps don’t work properly, just reinstall GApps in recovery mode.

The Open GApps Project

In my case Google standard phone app can make a call but cannot hang up because the calling mode screen doesn’t appear, so the only choice is restarting phone. In addition, it cannot answer any call because the screen doesn’t switch to answering mode.

So I reboot to TWRP recovery, wipe nothing and just reinstall GApps stock version. After rebooting, everything OK. No need to set up Google account or other Android settings.

Google Chromeのディベロッパーツールをカスタマイズする方法のメモ

Google ChromeでWindowsのディベロッパーツールに独自のタブ(パネル)を追加できると最近知ったので備忘のために書いておく。

Google Chrome拡張機能として作成する。

最低限のmanifest.jsonファイルは以下のとおり。permissionは、この拡張機能を実行させたいWebサイトのURLを指定する。

{
	"manifest_version": 2,
	"name": "Hoge Hoge",
	"version": "1.0",
	"devtools_page": "devtools.html",
	"permissions": [
		"https://hogehoge.com/*"
	],
	"icons" : {
		"128": "icon.png"
	}
}

ポイントはdevtools_pageにHTMLファイルを指定すること。このHTMLファイルはmanifest.json他のファイルを同じフォルダに、テキストエディタでいいので新規作成する。ファイル名は何でもいい。ここでは分かりやすくdevtools.htmlという名前にした。

そしてそのdevtools.htmlの中身は以下のとおり。

<!doctype html>
<html>
  <head>
    <script src="./devtools.js"></script>
  </head>
  <body>
  </body>
</html>

何もしていない。ただ同じフォルダにあるdevtools.jsというJavaScriptを呼び出しているだけ。名前はdevtools.jsでなくてもいいが分かりやすいようにこうしておく。

そのdevtools.jsの中身で、パネルを作成することになる。

chrome.devtools.panels.create(  
	"HogeHogePanel",
	"", // icon画像を指定できる
	"./panel.html",
	(panel) => {} // callback
);

このJavaScriptはGoogleディベロッパーツールのElements、Console、Sources、Network等々のタブ(パネル)に、自分の好きなパネルを追加している。

chrome.devtoolsというのはGoogleが提供しているGoogleディベロッパーツールAPIで、Google拡張機能からはすでに存在するオブジェクトとしていつでも呼び出せる。

ここではchrome.devtools.panelsのcreateメソッドを呼び出して、Elements、Console、Sources、Network等々のパネルに、もう1枚パネルを新規作成している。

1つ目の引数がパネルのタイトル。ElementsパネルならElements、ConsoleパネルならConsoleにあたる名前。好きな名前をつければいい。ここではHogeHogePanelという名前にした。
2つ目はアイコンを指定できるが、なくていい。
3つ目がポイント。この拡張機能のフォルダ内に、テキストエディタでも何でも良いのでpanel.htmlというHTMLファイルを作成して指定すればいい。ファイル名はpanel.htmlでなくても何でもいい。
4つ目はコールバック関数の指定だが、筆者は何に使うのか分からなかった。指定なしでもここから書くことは実現できる。

ではそのpanel.htmlには何を書けばいいか。

<!DOCTYPE html>  
<html>  
  <body>
    <div id="container"></div>
    <script src="./panel.js"></script>
  </body>
</html>

このHTMLも基本的にpanel.jsというJavaScriptを呼び出しているだけ。中身は用途によっていろいろだが、ここではpanel.jsの実行結果をこのHTMLに動的に表示させたいので、そのためのコンテナとしてdivタグでcontainerというidの容れ物を作っておくことにする。

ここまでで準備ができた。Googleディベロッパーツールに独自に追加したHogeHogePanelというパネルに、このpanel.htmlが表示され、panel.jsの実行結果をcontainerにJavaScriptで動的に書き込めば、panel.jsの実行結果を動的に確認できるパネルが出来上がる。

あとはpanel.jsにやりたいことをひたすらコーディングしていく。

たとえばブラウザで読み込んだページが、WebサーバにGETメソッドで要求しているデータのURLをすべて列挙する、ネットワークアナライザ的なことがやりたけれは、chrome.devtools.networkというオブジェクトのonRequestFinishedメッソドを使って以下のように書けばいいらしい。

chrome.devtools.network.onRequestFinished.addListener(
	function(request) {
		var geturl = request.request.url;
	}
);

処理はWebページを読み込みつつ非同期で実行されるので、Webサイトへのデータ要求が終わるたびに関数が呼び出されるように、addListenerでリスナーを追加、そのリスナーの中にonRequestFinished、つまりデータ要求が終わるごとに呼び出される関数を書く。

その関数にはデータ要求の結果、戻ってきたデータがrequestオブジェクトとして渡されるので、それを引数にして、無名関数として記述する。 function(request)の部分がそれにあたる。

あとはこのrequestオブジェクトにたくさんある属性の中から、取り出したいデータを取れば良い。

ここでは戻ってきたデータの中に含まれるURLリンクアドレスを取り出したいので、request.request.urlとし、アドレスの文字列をgetrulという変数に代入している。(geturlという変数名は適当に付けただけなので、何でもいい)

Google ChromeがWebサーバに要求しているURLを列挙して何がうれしいのかというと、Google ChromeでWebページを表示させた時に表面上見えているデータ以外に、裏側でそのWebページがWebサーバに要求しているデータのURLアドレスを取り出せるから。

WebページはWebサーバからもどってきたデータをそのまま表示せずに、いったんJavaScript等で加工してからWebページを組み立てて表示させていることがほとんどだが、裏側で要求しているデータを生のままつかまえたい場合は、この方法が役立つ。

panel.jsの中身を地道にコーディングして、処理結果をpanel.htmlに表示するようにできれば、あとは目的のWebページを開いて、かつGoogleディベロッパーツールの画面を、WindowsならCtrl+Shift+Iで表示させればいいだけ。

そうするといちばん右側に、自分の作った「HogeHogePanel」というタブでパネルが追加されている。そのパネルはpanel.htmlなので、そこに自分の欲しいデータが書き出される。

ただ、じゃあpanel.jsがうまく動いているかどうかは、どうやってデバッグすればいいの?という話になるが、それもGoogleディベロッパーツールを使えばいい。

自分が新規作成したHogeHogePanelの動作を確かめるために、そのパネルを表示させた状態で、再びCtrl+Shift+Iを押すと、もう一つGoogleディベロッパーツールが開く。

この2つ目のGoogleディベロッパーツールは、最初に開いたWebページではなく、自分が作ったHogeHogePanelに対するGoogleディベロッパーツールなので、panel.jsに何かエラーがあれば、こちらの2つ目のGoogleディベロッパーツールのConsoleタブにエラー表示される。

なので二重に開いた2つ目のGoogleディベロッパーツールのConsoleタブを見ながら、panel.jsをデバッグできる。

…といったことができるのを、つい最近知った。

VLC media player cannot play some URLs of YouTube movies

VLC media player forum provides a solution for this problem, that’s to copy an updated youtube.lua file to /VideoLAN/VLC/lua/playlist/. However, this doesn’t solve the problem any more in March 2018.

If you get the error message containing word “MRL”, the true solution is to change configurations of Windows firewall.

In case of Windows 7/10, go to advanced settings of Windows firewall and change both of Inbound rules and Outbound rules of all “VLC media player” profiles into “Enabled=Yes” and “Action=Allow”. This means every profile of VLC media player will be turned into green.

顔認識ウェブAPI「Face++」をPHPで使ってみる

無償で使える顔認識Webサービスがあることを最近知ったのでPHPの実装とともにメモ。

https://www.faceplusplus.com/

API KEY、API SECRETの取得方法はウェブで検索すれば見つかる。


define("REQUEST_URL", "https://api-us.faceplusplus.com/facepp/v3/detect");

// ローカルの画像をアップロードするためのパラメータに変換
$cfile = curl_file_create($local_imgpath, 'image/jpeg');

// return_attributesパラメータはカンマ区切りで複数指定できる。ここでは性別だけ。
// api_key, api_secretは自分で取得した文字列に置き換えること
$params = array(
'api_key' => 'xxxxxxxxxxxxxxxxxxxxxxxxxx',
'api_secret' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'image_file' => $cfile,
'return_attributes' => 'gender',
);

$curl = curl_init();
curl_setopt($curl, CURLOPT_POST, TRUE);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data'));
curl_setopt($curl, CURLOPT_URL, REQUEST_URL);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER , FALSE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER , TRUE);
curl_setopt($curl, CURLOPT_TIMEOUT , 15);

$res1 = curl_exec($curl);
$res2 = curl_getinfo($curl);
curl_close($curl);

$json = substr($res1, $res2['header_size']);

// PHPの場合はJSONを連想配列に変換するとやりやすい
$face_data = json_decode($json, TRUE);

// これが検出された複数の顔のデータ
$faces = $face_data["faces"];

// 検出されたときだけ顔データを1つずつ見てみる
if (isset($faces)) {
foreach ($faces as $face) {

$gender = $face["attributes"]["gender"]["value"]; // 性別
$width = $face["face_rectangle"]["width"]; // 幅
$height = $face["face_rectangle"]["height"]; // 高さ
$top = $face["face_rectangle"]["top"]; // 上端
$left = $face["face_rectangle"]["left"]; // 左端

// デバッグのために検出された顔データを表示してみる
echo "DETECTED [$gender] $width x $height ($top, $left) ";

}
}

OBS Studioでニコニコ生放送をするときマイクの音声にエフェクトをかける方法

自分のメモ代わりの記事。

OBS Studioを使ってPCの画面キャプチャと音声と、マイクからの音声入力をミックスして配信するとき、マイクからの入力音声にエフェクトをかける方法。

前提としてYAMAHAのミキサーAG03/AG06がセッティング済みとする。AG03/AG06のようなミキサーがなくても、PCのサウンドカードとは別モノとして認識される音声入力デバイスなら何でもよい。

OBS Studioでニコニコ生放送をするためのプラグインも導入済みとする。

OBS Studio公式サイト

OBS Studio ニコニコ生放送プラグインのインストール方法

次に、マイクからの入力音声を出力する先を「ライン(AG06/AG03)」ではなく、仮想オーディオデバイスにする必要があるので、何らかの仮想オーディオデバイス・ドライバをインストールする。

「NETDUETTO」というアプリケーションに付属する「Yamaha NETDUETTO Driver(WDM)」を利用する方法もあるが、わざわざ仮想オーディオデバイス・ドライバをインストールするだけのためにアプリを入れたくない、という人もいるはず。

なので純粋に仮想オーディオデバイス・ドライバだけをインストールする。

こちらの「VB-CABLE Virtual Audio Device」

英語サイトだが、DOWNLOADボタンをクリックしてZIPファイルをダウンロード、適当な場所に解凍。

32bit環境であればその中にある「VBCABLE_Setup.exe」を、Windows 10なら64bitなので「VBCABLE_Setup_x64.exe」を右クリックし「管理者として実行」をクリックし、インストールする。

「VB-Cable」というやや派手なインストーラー画面が出てくるが「Install」をクリックするだけ。PCの再起動が必要なので、再起動すると、仮想オーディオデバイスが有効になる。

Windowsのサウンド設定そのものは、再生、録音とも「ライン AG06/AG03」でよい。

ミキサーAG06/AG03上では「HEADSET」のマイク入力、ヘッドホン出力に、PC用のヘッドセットのマイク、ヘッドホンプラグをそれぞれ差しておく。(USBでPCと接続するヘッドセットは使えない)

同ミキサー上で「TO PC」は「INPUT MIX」にしておく。OBS StudioでPCの音声とAG06/03から入力されたマイクの音声がMIXされて配信されるので、ここで「LOOPBACK」にしてはいけない。

次にOBS Studioのメニューの「ファイル」>「設定」>「音声」の設定。

「デスクトップ音声デバイス」は「既定」、つまりWindowsの設定を同じにする。
「マイク音声デバイス」は「CABLE Output (VB-Audio Virtual Cable)」に変更する。ここがポイント。

そしてメニューの「編集」>「オーディオの詳細プロパティ」の設定。

「マイク」の「音声モニタリング」は、「モニターと出力」にしてはいけない。ここがポイント。

「モニターと出力」にすると、加工前と加工後のマイクからの入力音声が両方とも配信されてしまう。

加工前の音声だけで良ければ「モニターオフ」、加工後のマイクからの入力音声を確認したければ「モニターのみ(出力はミュート)」にする。

「デスクトップ音声」の「音声モニタリング」は「モニターオフ」。PC音声はAG06/AG03経由で戻ってくるので、ここでモニターする必要はない。

次に、マイクからの入力音声にエフェクトをかける任意のアプリの設定をする。

「録音デバイス(Input)」は「ライン (AG06/AG03)」にする。PCの音声ではなく、マイクからの入力音声「だけ」にエフェクトをかけたいからだ。ここでPCのサウンドカードを指定すると、PCの音声にエフェクトがかかってしまう。

「再生デバイス(Output)」は「CABLE Input (VB-Audio Virtual Cable)」に変更する。ここがポイント。

こうすれば、先ほどAG06/AG03上で「INPUT MIX」にしておいたので、AG06/AG03に接続されたマイクからの入力音声だけがエフェクト・アプリに入力される。AG06/AG03上で「LOOPBACK」にしてしまうと、PCの音声までエフェクト・アプリに入ってしまうので、マイク入力を含めたすべての音声にエフェクトがかかってしまってダメになる。

エフェクト・アプリの以上の設定で、エフェクトを・アプリの出力が、仮想オーディオデバイス「VB-Audio Virtual Cable」を通ってOBS Studioの「マイク音声デバイス」へ入っていくことになる。

つまり、物理的なマイクからOBS Studioの「マイク音声デバイス」に入るまでの経路は以下のとおり。

物理的なマイク
⇒ AG06/AG03 (INPUT MIXモード)
⇒ PCの「録音デバイス」の「ライン AG06/AG03」
⇒ エフェクト・アプリの「録音デバイス(Input)」の「ライン AG06/AG03」
⇒ エフェクト・アプリの「再生デバイス(Output)」の「CABLE Input (VB-Audio Virtual Cable)」
⇒ 仮想オーディオデバイス内部で「Input」から「Output」へ通過
⇒ OBS Studioの「マイク音声デバイス」の「CABLE Output (VB-Audio Virtual Cable)」

AG06/AG03のようなミキサーではなく、外付けのオーディオデバイスの場合も同じ流れ。

物理的なマイク
⇒ 外付けのオーディオデバイスの入力
⇒ PCの「録音デバイス」の外付けオーディオデバイス
⇒ エフェクト・アプリの「録音デバイス(Input)」の外付けオーディオデバイス
⇒ エフェクト・アプリの「再生デバイス(Output)」の「CABLE Input (VB-Audio Virtual Cable)」
⇒ 仮想オーディオデバイス内部で「Input」から「Output」へ通過
⇒ OBS Studioの「マイク音声デバイス」の「CABLE Output (VB-Audio Virtual Cable)」

どちらにしてもPCのサウンドカードから出力される音声で、最終的な出力は確認できないため、OBS Studioの録画機能で少し録画してみて、想定どおりにエフェクト付きマイク入力音声と、PC音声が出力されていることを確認する。

PC本体の音声はOBS Studio上で「デスクトップ音声デバイス」を「既定」にしてあるので、直接OBS Studioに入る。

以上で、PC本体の音声に、PC上のエフェクトアプリでエフェクトをかけて加工したマイクからの音声をMIXして、配信できる。