2018年12月19日水曜日

2018 できたこと・できなかったこと

今年の反省と来年の豊富も込めて
細かいことまで書くと書ききれないのでブレークスルーっぽいやつだけ
Podcast は来年も続けたいかなー

できたこと

時系列

その他

  • ブログ執筆数: 251 (11/10 時点)
  • Podcast エピソード数: 18
  • 資産運用を開始

できなかったこと

  • Youtube Live 環境は構築したが一度もライブ放送をできなかった
  • 後半の iOS アプリ開発の失速感
  • 3D ゲームへの挑戦
  • 熱中できることの模索、やってることが分散しすぎた
  • コンフォートゾーンのぶち抜け

来年の豊富

  • 熱中できることを探すはやりたい
  • ブログは週1 ペースでいいので書きたい、最低でも月1

2018年12月1日土曜日

ラーメン花月嵐の壺ニラという最強のつまみ

作り方を紹介します
と言っても cookpad さんで紹介されているレシピをパクっただけです
分量とか手順とか材料とか毎回忘れるので備忘録として残しておきます

材料

  • にんにくチューブ (できれば生にんにく)
  • ごま油
  • 一味唐辛子
  • 豆板醤 (チューブじゃなくても OK)
  • ウェイバー (他の中華風調味料でも OK、鶏ガラでも代用できるっぽい)

tsubonira1.jpg

ニラを切る

今回ニラは 3 束ほど使います
後で紹介する各種調味料の量は 3 束を目安に入れているので 1 束の場合は 1/3 してください
ニラは 1/4 で OK です
tsubonira2.jpg

もっと細かくしたい人は細かくしても OK です
揉むと水分が出て小さくなるので 1/4 くらいがオススメです
ちゃんと水洗いしてあげましょう
tsubonira3.jpg

塩もみ

先に塩もみを軽くしましょう
塩はスプーン 1 杯くらいで良いと思います
tsubonira4.jpg

先にやる理由はさっぱりわかりません
面倒くさい人は他の調味料と一緒に混ぜちゃって大丈夫だと思います
また混ぜるときはビニール手袋をすると気持ちよく混ぜられると思います
tsubonira5.jpg

各種調味料を入れていく

以下順番は関係ないです
また写真では毎回混ぜている感じですが先に調味料を全部入れてあとで一気に混ぜ合わせれば OK です

にんにくチューブです
自分はにんにくが好きなので結構多めに入れています
ちなみにあとでこれの倍くらい追加しています
量で言うとチューブの半分くらいは入れていたかもしれません
tsubonira6.jpg

ごま油です
スプーン 3 杯入れたのですが 2 杯くらいで良いと思います
自分はごま油少なめのほうが好きです
tsubonira7.jpg

味覇です
スプーンで適当にすくったのを 2 杯入れました (これも 1 杯でも良いかも)
味覇は固形になっているので混ぜるときにちゃんと崩してあげるようにしましょう
tsubonira8.jpg

一味唐辛子です
全体が見えなくなるくらい入れました
ここで辛さを調整できるので辛いのが好きな人はもっと入れていいと思います
自分はこのあとビン一本分全部入れました
tsubonira9.jpg

豆板醤です
こんくらいかなと
ここでも辛さを調整できます
中華っぽい辛さ?が好みな人は一味を減らして豆板醤多めにすると良いと思います
tsubonira10.jpg

混ぜる

まんべんなく混ざるようにしましょう
固形のやつは残らないように注意してください
tsubonira11.jpg

混ぜ終わったら上からラップを押し蓋的にします
tsubonira12.jpg

一日冷蔵庫で保存

一日おいたほうが味が馴染んでおいしくなると思います
自分は置くのをオススメします
また一日置くと水分がだいぶ出るので吸い取って上げると良いと思います

食す

おいしいです
食べ過ぎると胃もたれするのでほどほどに
tsubonira13.JPG

2018年11月26日月曜日

Podcast 音源の編集方法

概要

配信環境については記事をまとめましたが編集方法についてまとめていなかったのでまとめました
Apple 純正のソフトウェアだけで編集しています

2018/11/26 時点での配信環境についてはこちらに記載しています

環境

  • macOS 10.14.1
  • GarageBand 10.3.1
  • iMovie 10.1.10
  • iTunes 12.9.0.164

GarageBand でノーマライズする

ノーマライズとは「音量正規化」で適切な音量に変更します
毎回そうなのですが自分の声が大きくゲストの方の声が小さいので GarageBand の音量バーを左右に調整して同じような音量になるようにしています
podcast_sound_edit1.png

使っているマイクのせいもあるのですが、これが近距離でないと音をうまく拾ってくれません
自分はそれを意識してかなりマイクを近づけているのですがゲストの方はそうもいかないのでこんな感じなってしまいます
本来であれば LXR マイクなどを使ってハードウェアミキサで調整するのですがケチって USB コンデンサマイクを購入してしまったので、そんな感じになってしまいました

あとは対処法としてソフトウェアミキサを使う方法があるのですが音源がダメダメだと限界があるのでやはりマイクを変えないと何ともかなと思います

とりあえず現状は GarageBand の機能の範囲でノーマライズしています
また GarageBand はデフォルトだと音量バーの設定を無視して自動でノーマライズしてくれるので設定から自動ノーマライズの設定をオフにする必要があります
podcast_sound_edit2.png

GarageBand で mp3 に書き出し

共有 -> 曲をディスクに書き出すで mp3 出力します
podcast_sound_edit6.png

あとは書き出す際のオプションを選択します
音質は「低音質 (64kbps)」を選択します
最終的には AAC にして更に圧縮しますが Podcast の音源は 64kbps で十分です
podcast_sound_edit7.png

iMovie でホワイトノイズを削除する

出力した mp3 を元に次はホワイトノイズを削除します

自分の環境の場合ばっちりホワイトノイズが入ってしまうのでソフトウェアである程度削除しています
ノイズもハードウェアなど環境によってそもそも入らないようにすることもできるのでノイズ削除の作業は必須ではありません

ホワイトノイズの削除は「iMovie」を使います

右上のイコライザタグを選択し「背景ノイズを軽減」にチェックします
あとはパーセンテージを選択するだけです
基本は 50% でやっています
podcast_sound_edit3.png

iMovie で mp3 で書き出し

背景ノイズを削除した版を mp3 で書き出します
右上の共有ボタンから「ファイル」を選択します
podcast_sound_edit4.png

あとはメタ情報を編集して出力します
フォーマットは「オーディオのみ」にしています
podcast_sound_edit5.png

せっかく 64kbps のステレオサイズで出力したのですが iMovie の場合、動画形式して出力されてしまうのでサイズが大きくなるのはあきらめます

iTunes で AAC に圧縮する

大きくなったファイルを iTunes を使って AAC に変換します

まず「環境設定」->「一般」->「読み込み設定」から AAC で書き出す場合のフォーマットを選択します
podcast_sound_edit8.png

iMovie で出力した mp3 を iTunes にドラッグアンドドロップして開いてファイルを選択します
そして「ファイル」から「変換」->「AAC バージョンを作成」で AAC 版が作成されます
podcast_sound_edit9.png

これで iTunes の所定のパスに AAC バージョンのファイルが書き出されるので必要に応じてコピーなどすれば OK です
パスは書き出された AAC 版のファイルを右クリックして「曲の情報」を選択すれば確認できます

ここで出力された AAC ファイルが現在公開している音源ファイルの最終版になります

最後に

かなり面倒くさいやり方ですがこんな感じでやっています
なぜこんな面倒くさい方法になっているかというとホワイトノイズを削除したいためにこうなっています
録音環境が良ければこんなことは不要です
GarageBand でチャネルごとに収録してノーマライズすれば完了です

来年は環境整えてやりたいなーという思いも込めて残しておきます

2018年11月20日火曜日

QBハウスガチャ

QB ハウスという 1000 円カットをご存知だろうか
ぼくは大好きだ




だいたい四半期に一度通うので年 4 回ほど利用させていただいている
年 4 回通っても 4,000 円で済むのである (正確には 4,320 円)
1,000円カットと言いつつ現在は 1,080 円になっている
更に来年の増税で 1,100 円になるとのこと
まぁそれはどうでも良いことなのだが

簡単に QB ハウスの仕組みを説明しておくとカット専門のヘアサロンで約 10 分で注文通りのヘアカットをしてくれる
値段と時間の割にクオリティも高く時間のない現代人にとっては最高のヘアサロンなのではないかと思っている
おそらくターゲット層も帰宅や外出中のサラリーマンを想定しており設置されているのも駅構内などが多く短い時間で気軽に通える感じになっている
料金の精算は券売機システムとなっており場所によっては Suica or Pasmo などの電子マネーでの精算も可能となっている

そんな QB ハウスに通い続けている自分であるが注文の仕方はいつも一緒で

1/3 残して 2/3 切ってください、耳は出して OK で、刈り上げ無しで」

とお願いするようにしている
後半の「耳は出して OK で、刈り上げ無しでお願いします」は決まり文句のようなもので、これを言わないと QB の店員さんに「耳は出しますか?」「刈り上げはしますか?」と聞かれるのであらかじめ答えておく感じである

で問題は前半の「1/3 残して 2/3切ってください」の部分である
ここがタイトルの「ガチャ」要素で人によってだいぶ長さが変わるのである
(QB ハウスは確かカットする人の指定も可能だがその人が出勤しているかまではわからないし指定すると待ちになる可能性が高いのかそのシステムを使っている人はみたことがないし自分も使ったことはない)

まぁ人によって差が出てしまうのは仕方ないことなので良いのだがどんな人が長く残しがちでどんな人が短くしてくれるのか勝手に分析してみた
ちなみに自分の意図としてはバッサリ切ってほしいので短ければ短いほど良いと思っている (それならいっそ坊主やスポーツ刈りにすれば良い話ではあるが)

長く残しがちな店員さん

  • 慎重そうな人
  • 切る前に霧吹き+クシで髪をとかしてから切ってくれる人
  • 女性の店員さんに多いイメージ

短くしてくれる店員さん

  • カットが早い人
  • 迷いがない人
  • 特にクシでとかすこともなくいきなりカットに入る人
  • ベテラン感のある男性店員さんに多いイメージ

といった分析結果だ
完全に独断と偏見なので参考程度に見ていただきたい
これも予想だが長めに切る人は短くしすぎて何か言われる可能性を考慮してとりあえず安牌ラインで少し長く残しているように感じる
QB ハウスの場合最後に鏡で後ろも確認して「こんな感じで良いですか?」と聞かれるのでそこで「あーもう少し短めに」とかお願いすればいいのだが自分は小心者なので言えない

あと正直あの鏡の確認だと本当に良い感じになっているかわからない
帰宅してお風呂で髪を洗ってみて鏡で見て触って初めて「あ、ちょっと長いわー」とか「あ、いい長さだわ」とわかる気がする (と自分は思っているがどうでしょうか?)
なのでガチャ結果はお風呂に入った後でないとわからないのが正直なところだ
(もしかすると見た目ではわからない微妙な誤差を勝手に自分の中でアタリだハズレだとか決めつけているだけで他の人からみればいつも通り髪を切っただけにしか見えないのかもしれないが)

あとは本当にたまに散切り頭になっている場合もある
「あれここだけ切り過ぎじゃー、、」みたいなのがたまにだがある
(が、まぁそんな細かいことはどうでもいいのだ、短くなればそれでいい、あとはワックスで何とかすればいいじゃないかということだ)

結局何が言いたかったのかというと「これからも QB ハウスを使いますのでよろしくお願いします」ということだ
QB ハウス最高です

2018年11月3日土曜日

ホームページを自動デプロイできるようにしてみました

概要

久しぶりのテックネタの投稿です
自分のホームページ https://kakakikikeke.com は Ruby で書かれており docker コンテナとして動作しています
https に対応しているのですが内部で nginx コンテナも動いておりそこで SSL を受け付けています

デプロイは git push 後にホストマシンに SSH ログインして docker-compose build -> up という王道の流れなのですがいちいち SSH ログインするのが面倒でした
まぁコマンドも 2, 3 ほどなのでそこまで面倒な作業でもないのですが今回はそのデプロイ作業を自動化してみました

仕組みとしては bitbucket の webhook 機能を使ってホストマシンで webhook を受け取るアプリを起動します
そして、そのアプリに今まで実行していたデプロイコマンドを実行してもらうという何のひねりもない仕組みです

環境

  • CentOS 7.5
  • docker 18.06.1-ce
  • Ruby 2.5.0p0
  • bitbucket

bitbucket webhook にエンドポイントを追加する

まずは webhook にエンドポイントを追加します
homepage_autodeploy1.png

各リポジトリごとにエンドポイントを追加できます
今回はホストマシンでデプロイ用のアプリも動かします
Sinatra を使うので 9292 ポートに対して webhook を投げてもらうようにエンドポイントを追加します
/webhook にしていますがここは好きなものに変更してもらって OK です

スクショだと Enable request history collection にチェックがありませんがどんな webhook が飛んだかあとから確認したい場合はここにチェックを入れておくと履歴が確認できます

IP を許可

bitbucket のホワイトリスト IP は以下の通りです
ファイアウォールなどに設定の許可を入れましょう

  • 104.192.136.0/21
  • 34.198.203.127
  • 34.198.178.64
  • 34.198.32.85

今回の場合であれば 9292 ポートへのアクセスだけを許可すれば OK です

ライブラリインストール

ではアプリを作っていきます

  • bundle init
  • vim Gemfile
gem "sinatra"
  • bundle install --path vendor

webhook 用のアプリ

  • vim config.rb
require './app'
run Webhook
  • vim app.rb
require 'sinatra'
require 'json'
require 'open3'

class Webhook < Sinatra::Base
  helpers do
    def deploy
      File.open("./deploy.txt", mode = "r"){ |f|
        f.each_line{ |line|
          o, e, s = Open3.capture3(line)
          halt 500, "missed: #{e}" unless s.success?
        }
      }
    end
  end
  post '/webhook' do
    body = JSON.parse request.body.read
    p body
    body['push']['changes'].each { |push|
      deploy if push.has_key? 'new'
    }
    'deployed'
  end
end
  • vim deploy.txt
cd /root/ruby-homepage && git pull
cd /root/ruby-homepage && docker-compose down
cd /root/ruby-homepage && docker rmi rubyhomepage_web
cd /root/ruby-homepage && docker-compose up -d

少し解説

特に解説は不要かなと思いますが一応

まず POST /webhook が bitbucket から送られてくる webhook を受け取る URI になります
ここは bitbucket に設定したエンドポイントと同じ URI にしてください
ボディに push 時のいろいろな情報が格納されてきます
コミットした人やコミット番号などがあります
詳しくは上記のリンクからサンプルリクエストなどが確認できるます

今回は特に条件はないですが、new という新規のコミットがある場合にデプロイを実行するようにしました
new がないケースとしてはブランチを削除した場合になります
デプロイ時の条件を厳密にしたい場合はここに条件を加えれば OK です

deploy は helpers を使って実現しています
デプロイコマンドを書き連ねた deploy.txt を読み込み open3 で逐一実行してるだけです
open3 であればコマンドの結果 (0 とか 127 とか) をチェックできるので、もし成功じゃない場合は halt でエラーを返却します

クソ簡単です

アプリ起動

  • bundle exec rackup config.ru -o 0.0.0.0 &

外部から受付できるように 0.0.0.0 で LISTEN します
また、バックグラウンドで動作させるようにします
tmux バッファ上でフォアグラウンドで動作させても良いと思います
もっとちゃんとやるならデーモン化させたり systemd 配下で動かすようにしても良いと思います
停止するときはプロセス番号を調べて kill してください

という感じで開発自体は完了です
あとは push して挙動を確認したりしてみてください

デメリット

今回の場合、直接ホストに対してコマンドを実行するのでコンテナで動かすとコンテナ内にコマンドを実行してしまいます
なのでホストマシンに ruby + bundler をインストールしなければいけません
これまですべて docker で動かしていた環境にいきなり謎の勢力のためにバイナリをインストールしなければいけないのは納得いかない点があるかなと思います

また git pull をするときに認証されないことを想定しています
git-credential を使ってホストマシンに認証情報を保存していることが前提になっています (もしくは .git/config に ID/PW が書かれていても OK)

代替策

今回は webhook + コマンドにしましたが他にもいろいろな方法があると思います
例えば Bitbucket Pipeline を使う方法です
ここにコマンドを記載できるので push 後にホストに SSH してコマンドを実行することでデプロイすることも可能です
これであれば web アプリを作る必要もありません

あとはどうしても webhook 用のアプリをコンテナで動かしたい場合はコンテナからホストに SSH ログインしてコマンドを実行するか sidekiq などを使ってコンテナからホストにデプロイの支持を渡してそこからホスト側の worker でデプロイするなどでしょうか
ただ、これもコンポーネントが 1 つ増えるので微妙です

エージェントを配置してエージェントに指示を送る方法でもいいですが、今回の webhook アプリ方式とあまり変わらないかなと思います

そもそもイメージをお腹に抱えてしまっているのでそれもあまりよくない気がします
docker build -> docker push でどこかのレポジトリにアップロードして、ホストマシン側では pull -> up だけする感じのほうが良いかなと思います
ただ、その場合でも結局ホストマシン側でコマンドを実行する仕組みは必要かなと思います 

k8s の Deployment と ReplicaSet を使えばローリングアップデートが使えるのでそれも手かもしれません
ただその場合は k8s 環境の構築から必要になりますが、、

今回の方法はリポジトリからの push 型なのでそうでなくホストマシンからの pull 型で良い感じに簡単にできる仕組みにすると良いのかなと思います
やはりコマンドをホストマシンで直接実行するのは何か微妙なやり方なような気がします

むしろ何か良い代替策があれば教えていただきたいです

参考サイト

2018年10月31日水曜日

NEOGEO mini を持っているなら Mayflash f300 も買おう

実は NEO GEO mini を持っています
公式からずっと出なかったアーケードコントローラですが Mayflash から NEO GEO mini 対応のアーケードコントローラが出ました

早速購入して使ってみたので使い方とか紹介します

購入したもの

まず f300 ですがこれです


Mayflash ジョイスティック F300 PS4/PS3/XBOX ONE/XBOX 360/PC/Android/Nintendo Switch/Neogeo mini対応 [日本正規品]

9,000 円くらいで購入しました
見ての通り NEOGEO mini にも対応しています
現在 Amazon で購入できるものはファームウェアのバージョンが v1.2 となっており、それであれば特に何もせず NEOGEO mini で使えます

もしすでに f300 を持っている場合でもファームウェアのアップデートをするだけで使えるようになるとかならないとか

あとは USB TypeA -> TypeC の変換器も購入しました
NEOGEO mini 側の端子が TypeC で f300 側の端子が TypeA なので変換が必須です

700 円くらいで購入しました
変換器に関しては何でも OK です
ただ一点注意が必要なのは NEOGEO mini 側の TypeC の端子がやや狭い点です
変換器の端子の部分が太いと接続できない可能性があるので注意してください
上記で紹介している自分が購入した変換器はギリギリ入りました

接続した様子

こんな感じです
neogeomini_with_mayflash1.jpg

f300 のケーブルの長さは 3m もあります

設定

f300 の左上にトグルスイッチ的なのがあります
これをいじって NEOGEO mini で動作するようにします
neogeomini_with_mayflash2.jpg

一番左は下の「DINPUT/PS3」にします
その隣は「DPAD」にします

これで OK です

動作確認

あとは接続してプレイするだけです
問題なく動作すると思います

スタート+セレクトでメニューセレクトにもいけます

最後に

NEOGEO mini は公式のパッドもありますがやはりアーケードコントローラでプレイするのがしっくり来ます
しかも NEOGEO mini に収録されているソフトに格闘ゲームが多いのでアーケードコントローラの方がやりやすいと思います

また f300 は NEOGEO mini 以外にも PC や PS4、任天堂スイッチにも対応しているのでそれらのハードでも使いまわしできます

ただ結構出費が痛いです

  • NEOGEO mini 本体・・・約 12,000 円
  • Mayflash f300・・・約 9,000 円
  • TypeA -> TypeC・・・約 700 円

合計 21,700 円なり
2 万円あれば別のハードを購入することもできるかなと、、
自分は KOF がアケコンでやりたかったので後悔してないです

2018年10月20日土曜日

エピソードの検索機能をレベルアップしました

これまでのエピソード検索機能は画面に見ている情報だけを使って検索していました
https://kakakikikeke.com/podcast
podcast_new_search1.png

仕組みとしては jQuery の filter を使っているだけなので DOM 内で情報を絞り込みしている感じです

さすがにこれだと検索対象の情報量が少ないので検索機能をレベルアップしてみました

新しい検索機能

https://kakakikikeke.com/mypage/search
で新しい検索機能なのですが「サポータ専用の機能」として提供しています
「おい!使えんのかい」という感じですが、まだ何もサポータ専用コンテンツがなかったのでちょうどいいかなと思いサポータ専用にしてみました

上記 URL にアクセスすると Patreon のログイン画面になるのでログインします
podcast_new_search2.png

そして OAuth のアクセス許可の画面になるので「Allow」を選択します
(画像は開発用の画面なので実際の文言とは多少異なります)
podcast_new_search3.png

すると検索画面になるのでここで好きなキーワードを入力して検索しましょう
podcast_new_search4.png

検索対象

これまでは DOM に表示されている情報だけでしたが今回の新しい検索機能は以下の情報を検索対象にしています

  • タイトル
  • 概要
  • Show note
  • 文字起こししたテキスト情報

先頭 3 つはもともと情報としては持っていたものですが今回は新たに文字起こしの情報を作成しました
具体的には Google Cloud Speech API を使って各エピソードの音声情報を文字に起こしています
それを検索対象とすることで Show note にも書かれれていない内容を検索することができます

やってみた所感

正直 Google Cloud Speech API の精度があまり良くないです
原因は不明ですが音質などが影響しているかもしれません
また検索方法も表記ゆれや AND/OR 検索などには対応しておらず単純な match による検索になります
なので正直微妙です

検索の仕組みとしては Google Cloud Speech API で得られるテキストファイルをただ検索しているだけなのでテキストファイルをブラッシュアップすれば精度はあがります
まだエピソードも少ないので今後エピソードが増えてから使ってみると便利な機能に化けている可能性はありそうです

文字起こしするタイミングもどうするか悩んでいます
いつも収録後に編集する作業があるのですが、今回の検索機能を入れたせいで文字起こしの作業も必要になってしまいました
これを編集作業にプラスして毎回やるとなると結構辛いです
(しかも Google Cloud Speech API も有料というものあります、、)
ちなみに今回の作業でかかった料金は $24.86 でした
podcast_new_search5.png

もしかするとエピソードを公開するタイミングと同時に文字起こしはせず、ある程度溜めてから文字起こしするかもしれません
まぁその辺りは気分でやりたいと思います

最後に

検索機能をレベルアップしてみたのでサポータの方は使ってみてください
サポータになっても良いですよという方は以下からよろしくお願いします
https://kakakikikeke.com/supporter

まだ検索機能しか専用コンテンツがないので今後も何か増やしていこうかなと思います

2018年10月19日金曜日

Podcast の音源を Google Speech API で文字起こししてみた

とりあえずコマンドだけメモ

  • gsutil cp gs://sound.kakakikikeke.com/ep15.m4a ep15.m4a
  • ffmpeg -i ep15.m4a -f flac -ac1 ep15.flac
  • gsutil cp ep15.flac gs://sound.kakakikikeke.com/
  • gcloud ml speech recognize-long-running 'gs://sound.kakakikikeke.com/ep15.flac' --language-code=ja-JP --async
  • gsutil rm gs://sound.kakakikikeke.com/ep15.flac

概要

現在 Podcast の検索はこのページ内の単語だけを対象に検索することができます
さすがにそれだと検索性が悪すぎるかなーと思い音声情報を文字起こししてそこからエピソードを検索できたらいいなと思いました
ということで Google Speech API を使って文字起こししてみました
なお今回の作業内容はお金が発生するので同じことをするのであれば承知の上作業してください (と行っても数円もかからないですが)

環境

  • macOS 10.14
  • gcloud 220.0.0

flac への変換

自分の podcast は m4a で配信しているのでそれを一旦 flac に変換します
変換してくれる便利なサイトがあるので今回はこれを使わせていただきます
https://online-audio-converter.com/ja/

今回はエピソード14 (Youtube Superchat Ads) の音源を使って文字起こししています

P.S ffmpeg でもできます

  • ffmpeg -i ep14.m4a -f flac ep14.flac

gcloud コマンドのインストール

  • brew cask install google-cloud-sdk

bq, docker-credential-gcloud, gcloud, git-credential-gcloud.sh, gsutil がインストールされます

  • gcloud init

で初期化します
ブラウザが立ち上がり OAuth の認証画面になるので自分の Google アカウントでログインしましょう
あとは使用するプロジェクトやデフォルトリージョンなどを設定します

  • gcloud info

でいろいろと情報を確認できます
詳しい手順はこちらが参考になると思います

文字起こししてみる

  • gcloud ml speech recognize-long-running 'gs://podcast-episodes/ep14.flac' --language-code=ja-JP --async

これで OK です
文章が 1 分以上を越える場合は非同期音声認識を使ったほうが良いみたいです

また音声が何語で話されているのか --language-code で指定する必要があります
日本語も普通に対応していました
サポートしている言語はかなり多いようです

リクエストすると OPERATION_ID が取得できるのでそれを使って進捗を確認することができます

{
  "name": "4268235842997122372"
}
  • gcloud ml speech operations describe 4268235842997122372
{
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.speech.v1.LongRunningRecognizeMetadata",
    "lastUpdateTime": "2018-10-16T03:31:31.157254Z",
    "progressPercent": 5,
    "startTime": "2018-10-16T03:30:28.318655Z"
  },
  "name": "4268235842997122372"
}

progressPercent が 100 になれば完了です

INVALID_ARGUMENT: Request payload size exceeds the limit: 10485760 bytes. 対策

ローカルからファイルをアップロードしてファイルを解析する場合は 10MB 以内でないとダメなようです
その場合はファイルをクラウドストレージに事前にアップロードしてそれを解析するように指定します

今回のファイルサイズは 385329211 bytes あったので全然オーバーしていました
なので Google Cloud Storage にバケットを作成してそこに音声データをアップロードしておきました
バケットは Nearline あたりでいいかなと思います

ちなみに Regionalus-west1 を選択すれば Always free の範囲であれば無料で使えます

INVALID_ARGUMENT: Invalid audio channel count

残念なことに Cloud Speech API はモノラル音源にしか対応していません
kakakikikeke's Podcast はステレオ音源なのでモノラルに変換しました

自分の場合は iTunes で行いました

  • 環境設定 -> 一般 -> 読み込み設定

で設定からカスタムを選択しチャネルを「モノラル」にすれば OK です
podcast_transcript1.png

あとは mp3 音源を選択し AAC で書き出せばモノラルになっています

結果を確認する

  • gcloud ml speech operations describe 4268235842997122372

でテキストが返ってきます
今回のように 60 分を越える音声の場合レスポンスの JSON もかなり長いです

一部抜粋ですが結果は unicode で送られてきます

{
  "alternatives": [
    {
      "confidence": 0.94057757,
      "transcript": "\u3061\u3087\u3063\u3068\u98a8\u90aa\u6c17\u5473\u306a\u3093\u3060\u3093\u307e\u58f0\u304c\u51fa\u306a\u3044\u304b\u3082\u3057\u3093\u306a\u3044\u3042\u306e\u6885\u539f\u5927\u543e\u3063\u3066\u77e5\u3063\u3066\u307e\u3059\u6885\u539f\u5927\u543e\u3055\u3093\u3066\u8ab0\u3067\u3059\u304b\u77e5\u3089\u306a\u3044\u3067\u3059\u304b\u3042\u306e\u30d7\u30ed\u30b2\u30fc\u30de\u30fc\u30d7\u30ed\u683c\u95d8\u5bb6\u30b2\u30fc\u30e0\u30b9\u30c8\u30ea\u30fc\u30c8\u30d5\u30a1\u30a4\u30bf\u30fc\u3068\u304b\u8a00\u3063\u3066\u308b\u3051\u3069\u77e5\u3089\u306a\u3044\u304b\u805e\u3044\u305f\u3053\u3068\u306a\u3044\u3088\u3046\u306a\u81ea\u5206\u7d50\u69cb\u597d\u304d\u3067\u306a\u3093\u304b\u5148\u306b\u30b9\u30dd\u30fc\u30c4\u3068\u304b\u3084\u3063\u3066\u308b\u3088\u306d\u306f\u3044\u306a\u3093\u304b\u3042\u306e\u95a2\u4fc2\u3067\u3042\u306e\u95a2\u4fc2\u3067\u306e\u304a\u83d3\u5b50\u3067\u3059\u672c\u5f53\u306b\u305d\u306e\u30d1\u30a4\u30aa\u30cb\u30a2\u7684\u5b58\u5728\u306e\u4eba\u3067\u30b2\u30fc\u30e0\u3067\u672c\u5f53\u306b\u304a\u91d1\u7a3c\u3044\u3067\u8cde\u91d1\u307f\u305f\u3044\u3067\u3059\u304b\u9577\u3044\u3067\u6709\u540d\u306a\u3084\u3064\u3060\u3068"
    }
  ]
}

Web 上でコンバートしてくれるサービスなどがあるのでそれに投げちゃうのが早いと思います
ちなみに上記の unicode を変換すると以下のようになりました

{
  "alternatives": [
    {
      "confidence": 0.94057757,
      "transcript": "ちょっと風邪気味なんだんま声が出ないかもしんないあの梅原大吾って知ってます梅原大吾さんて誰ですか知らなかあのプロゲーマープロ格闘家ゲームストリートファイターとか言ってるけど知らないか聞いたことないような自分結構好きでなんか先にツとかやってるよねはいなんかあの関係であの関係でのお菓子です本当にそのパイオニア的存在の人でゲームで本当にお金稼いで賞金みたか長いで有名なやつだと"
    }
  ]
}

うーん、何とも絶妙な感じですね、、、
感覚的には confidence が 1.0 から 0.9 の間で更に分解能がある感じで 097 くらいいかないと精度は高くないなーといった印象です

どうやってエピソードを検索するか

やり方はいろいろとあると思います

  • 形態素解析などをして単語に分割し単語検索させる
  • 文章を結合して MySQL などに突っ込んで LIKE 検索させる
  • 検索エンジン (Solr) などを使う

検索機能をどこまで提供するかかなと思います
AND 検索や OR 検索までやりたいのであればデータベースに使うのは必然ですし高速な全文検索をするのであれば検索エンジンを使うでしょう

自分の場合とりあえずある単語を含むエピソードを検索できればいいかなーと思ったのでそのままファイルをメモリ上に展開し正規表現で検索しようかなと思います

require 'json'

def check(keyword)
  json_data = open('./log_jp') do |io|
    JSON.load(io)
  end
  json_data['response']['results'].each { |ret|
    ret['alternatives'].each { |alt|
      return true unless alt['transcript'].match(/#{keyword}/i).nil?
    }
  }
  return false
end

1 エピソード分でしか試してないですが速度も申し分なかったです
これの主なデメリットとしては複雑な検索ができない点ですが、まぁ十分かなと思います
エピソードが増えるとファイルが増えるので検索速度は落ちますが、そこは問題になったら別の仕組みを検討しようと思います

とりあえずこの方法でエピソードを検索できるようにしてみようと思います

おまけ: 今回の作業でおいくらかかったか

今回お金が発生するのは Google Cloud Storage のデータ料金と 60 分以上の音声データを解析した分の料金になります
後日請求が確定したのでコンソール画面で確認したら $0.4 でした
podcast_transcript2.png

podcast_transcript3.png

これまでの全 14 エピソードを文字起こしすると $0.4 * 14 = $5.6 なので激安ですね、、、
それでもお金掛けたくない場合は 60 分未満は無料なので無理やり分割すれば無料でいけるかと思います (Cloud Storage 代はかかると思いますが)

最後に

Podcast の音源を文字起こししてみました
Google Speech API は料金もかなりお安いのでこれで全話文字起こししてみようかなと思います
あとはこのテキスト情報を元に検索できる機能でも実装してみようかなと思います
もしかしたらサポータ限定プログラムにしちゃうかもしれませんが、、
https://kakakikikeke.com/supporter

2018年10月6日土曜日

1 日ひとつだけ強くなる。備忘録

梅原大吾さんの「1 日ひとつだけ強くなる。」を読んだので心に残った言葉や感想、所感を備忘録として残しておきます
なお書籍自体は読んでいることを想定しているので詳しい内容などには触れません
一応 GAME01 から GAME06 の 6 章構成になっているのでその構成に沿って記載します
また文章はかなり長いのでご承知おきください

GAME01 視点を高くする

ポイントを捉える

センスというか工夫みたいなことも必要になってくると思った
全体を俯瞰的に捉えて何がポイントかを人より早く見つけることができる人は確かに優秀な人が多い印象がある

何事もまずは試してみることが大事

日々進化する世界ではわからないことが多い、だからまず試すというスタイルは自分も好きだ
技術の世界でもそういった場面は多い
議論ばかりしないで「まずは作ってみよう」というスタイルがそれに当たるかなと思った

場面ではなく視点

この書籍で終始この言葉が出てきた気がする
出てこない場面でも結局「視点」を持っているか持っていないかの差が大きいというニュアンスが含まれていた気がする
自分が理解した場面と視点は言い換えれば「点」と「線」かなーと思った
瞬間瞬間の場面 (点) ではなく未来を見据えて如何に考え行動するか (線) の違いな気がする

言い方は悪いが過程なんてどうでもよく最終的に勝者になっていれば良いのである
そういう視点を持って行動すると自然と過程も良い方向に進むんだなーと思う

この辺りの熱い思い、理論は正直読まないと伝わらない気がする

コピーされない武器

確かにそれを持っている人は少なくかつ優れている人な気がする 

GAME02 感情を支配する

ジャスティン

自分も梅原さんを本格的に知ったのはこの動画かも知れない
それまでは名前は聞いたことがあるくらいしか知らなかった気がする
そして書籍内で本人は「この試合はそんなに重要じゃない」的なことをおっしゃっていたのでまたそれもおそろしい

感情を殺す

という表現は書籍内ではしていないが、必要な場面で感情を殺すコントロールができるようになることが重要だと理解した
常に感情的な人よりも常に冷静に物事を捉える人のほうが優れていると
「心は熱く頭は冷静に」という言葉があるがどんな場面でも、それをコントロールできるようになればどんな場面も切り抜けられると
確かにそんな気がする、非常に難しいことだと思った

雀士

全然重要なことではないが一時期真剣にプロ雀士を目指していたという記載があった
個人的にはかなりビックリした
麻雀の勝負感も実は人生に役立っていたりするのかも

どうにもならないことを受け入れる

書籍内では「自然現象として捉えれば OK」というニュアンスの記載があった
確かにそうだとは思う、がこれも難しいと思う
またそれでもダメな場合にはゲーム感覚で攻略してみるという紹介もあった
さすがにこの表現は梅原さんにしかできないなと思った

嫌なヤツには自分から心を開いてみる、その上で相手の出方を伺う
耳が痛い部分もあるが自分のそんな風になれたらいいなと思う

目先の損得の誘惑に負けてはいけない

大事なのは自分のペース、スタイルを崩さないということ
崩してまで損得を掴みにいっていけない、そうすると必ずその先で崩れてしまうから
書籍内では麻雀のオーラスを例に上げていたが、いざ自分がその状況になったことを考えると果たして本当にできるのだろうか
自信はない

GAME03 成長とは変わること

成長することは義務ではない

別に成長することを強要しているわけではない、が単純に成長を感じで生きるほうが楽しいに決まっている
成長することをそこまで望まない人は変化もそこまで望まないんだと思う
逆も言えて変化を望む人は成長も望んでいるんだと思う
自分は変化することが好きな方だと思う、これまでも自分なりにいろいろ変化して挑戦してきたと思う

そもそも「変化」が人それぞれの感覚でだいぶ違うと思う
自分が思う変化は「今もしくは過去に経験、挑戦したことがないこと」だと思っている
それにも大小はあるだろうが少なくともそんな感じのものだと思って変化を取り入れるようにしている
そして変化はリスクでもあると思う

そう考えるとリスクを避ける傾向にある人は実は成長するペースも遅いのかもしれない
まぁリスクを好んで受け入れる人はいないと思うが

人のアドバイスはまず 100% 信じてみる

これは正直自分は真逆の発想だった
人のアドバイスはまず 100% 疑うことからしてしまう
疑いつつ慎重に試してみて結果採用するという流れが多い
試すという行動は必ずするようにしている

なぜか、たぶん性格的な問題だと思う
どちらかというと慎重タイプなんだと思う、だから上記のような流れになる
ウメハラさん的には最悪なんだろうけど個人的には良い場合もあるんじゃないかと思っている
というのも人のアドバイスが 100% 成功する保証はどこにもない
それよりかはこれまで自分の経験や直感を信じたほうが成功する可能性が高いと思っている (思ってしまっているのが問題かもしれないが、、)
自分の目で見たものだけを信じるように意識しているからかもしれない

少し前の節で「行動力」「見る力」「聞く力」と言う 3 つのパワーを全部持っている人は強い人だという説明をしているところがあるのだが、おそらく自分は「聞く力」のない人間だと思う

個性

正しい鍛錬の積み重ねの先に他の人と差が生まれたものが個性なのだと
自分にはまだ個性はない

GAME04 飽きても続ける

体調管理

自分がどれくらい疲れているかしっかりと把握することは非常に難しいことだと思う
意外と無理をしてしまうということは結構あると思う (特に仕事が絡んだときは)
かつそのときにしっかりと休むことも重要だと思う
「しっかり休む」というのが重要で実や休めたと思っていても案外休めていないことが多い
自分が本当に「しっかり休む」方法を見つけることも実は非常に難しいことなんじゃないかと思っている
もし他人に「あなたがしっかり休める方法はなんですか?」と聞かれてはっきり「これです!」と自信を持って答えられる人は実は少ないんじゃないかなと

モチベーション

仕事でも遊びでもモチベーションを維持することは非常に大事だと思う
ウメハラさんは「自分の成長の実感」がモチベーションにつながっていると述べていた
正直これを見たいときに自分も全く同じ印象を覚えてた
特に自分が大事だなと思ったのは「メモする」というところ
成長などは特に目に見えないものかなーと思う
それをちゃんと形に残し、より実感しやすくすることでモチベーションにつなげるということは非常に素晴らしいと感じた

一日一個というハードルも非常に良いなと感じた
これなら続けられるというレベルのハードルにすることは良いことだと思う
そしてそのハードルの高さを守り続けることも大事だと思う
自分も同じようなハードルで毎日続けられていることがあるので、この節に関しては非常に共感することができた

本書内では「成長のループ」という表現でまとめられていた

同じ姿勢で走り続ける

プロはそうあるべきだと述べていた
プロじゃなくてもそうであるほうが良いかなと感じた

燃え尽き症候群ではないが一つのことに集中して努力し続ける姿勢も嫌いではない
ただ大事なのは燃え尽きたあとにすぐに切り替えて次に行けるかどうか
これができないと、ただただ疲弊するだけの人生になってしまいそうな気がする

たぶんそういうのも考えると一喜一憂するような姿勢ではなく淡々と、それこそ成長のループを続けていくような姿勢で走り続けることが重要なんだなと感じた

GAME05 ここ一番で勝つ

勝つ根拠

試合前に必ず考えてから勝負に挑むという
そしてその根拠 (仮定) が正しかったのかを検証するという
それ自身がすごい学びになるという

何事もトライする前にちゃんと仮定を立てると、立てないよりも何倍の経験が得られるんだと思う
自分もこれからは仮定を意識してトライしてみることにしよう

研究する

対象がわかっているのであればとことん研究してみることも大事だという
研究し検証を重ね万全の体制を作ることで自信にもつながる
更にそういった場合は負けときにもとんでもない経験や学びがあるという

そもそもそこまで研究する「大一番」にまだ自分は遭遇していないのかもしれないが

GAME06 才能を越える

才能はそんなに関係ない

何かを始めるのに才能は関係ないからそんなの気にしないでまずはやってみることが大事
大事というよりか「やってみたい」という気持ちがあるかが重要
やってみたいのであればとりあえず挑戦してみる、その結果伸びることもあるし伸びないこともある
けど、それよりもやってみたことが大きな経験になるんじゃないかと思う

食わず嫌いしない

これも上と同じだが食わず嫌いしてやらないのはもったないと思う
自分は結構食わず嫌いしがちだけど、そういう項目はメモしておいて心に余裕があるときにやってみるようにしている
少し義務的な感じも覚えるが、やってみて後悔したことはほとんどない
むしろそれを経験できなかった方が後悔すると思う

食わず嫌いばかりすると実は自分にとってのチャンスを逃しているかもしれない
あとは書籍内で述べられている「不得意」を作らないことにもつながると思う
ゲームの世界だけではなくいろんなことを知っていたほうが、いろんな場面、場所で役に立つと思っている

ただそれで自分の場合は薄く広くなりすぎていろんなことが中途半端になってしまってはいるが、まぁそれもそれもありだと思っている

普通への取り組み

不自然な態度や怯えた感情が少しでも出る人にすごい人はいないと
常に堂々と自然な態度を取り続ける人が実はすごい人であるケースが多い
確かにそんな気がする
普通の自分の常に出せている人はどこか凄みを感じる
そしてそういう人は普通を意識しているわけではなく自信とか経験から自然にそうなっているんだと思う
普通を意識的に装うことはできないんだと思う

最後に

ただただおもしろかった
T さんと呼んでいた師匠的な存在の方が気になる
モチベーションのところ一番共感できた
他の書籍も読んでみたくなった
TheBeast すごい

2018年9月17日月曜日

Airpods のススメ

先日 (9.12) に Apple のスペシャルイベントがありました
そこで iPhone と Watch の新作の発表がありました

個人的に期待していたのは Mac mini と Airpods だったのですが全くかすることもなく終了してしまいました
本当はイベントで Airpods の新作が発表されそれを購入する予定だったのですが出なかったので我慢できず Airpods を購入しました

1 週間くらいしか使ってないですが、使ってみていろいろと感じることがあったので紹介します
Good, Bad で紹介しています
「ってか Bad 多いじゃん!」って感じなのですが基本は Good なので大丈夫です

Good

「線」がないという素晴らしさ

そもそも紐がなく、プラプラもしていないので耳への負担が少ないです
持ち運びするときも線が絡んだりどこかに引っかかる心配もありません
イヤホンジャックに接続するという手間もないです (ケースから取り出すという手間はありますが)

とにかく今まで線でイライラしていたことがすべて解消されます
この UX を得られるだけでも購入する価値はあると思います

耳の着脱で bluetooth の接続/切断ができる

ケースから取り出し耳に着けるだけで Mac なり iPhone と Bluetooth 接続されます (もちろんペアリングしたあとからです)

片耳だけ外すと停止することができます (できるアプリとできないアプリがある)
両耳を外すと Bluetooth を切断します
なので停止ができないアプリなどはいきなりスピーカーに切り替わったりして恥ずかしい感じになる可能性があるので事前にアプリを停止しておくことをおすすめします

この着脱の UX もやってみると素晴らしいと分かります
いちいち Bluetooth の設定画面にいって接続するみたいな作業はやはり面倒です

デザイン

最近のイヤホンは「カナル型」と「インナーイヤー型」に大別できるかなと思います
Airpods は「インナーイヤー型」になります
自分は耳があまり丈夫でないためカナル型を使うと耳がすぐに痛くなります
また酷いときは頭痛などに発展します

カナル型の完全ワイヤレスイヤホンは結構たくさんあるのですが、このインナーイヤー型の完全ワイヤレスイヤホンはたぶん Airpods 以外ないと思います
Airpods のパクリみたいなやつが一時期登場して噂になりましたが、おそらく耳に着脱した際の自動接続やあとで紹介するダブルタップの機能などはないと思います
というかそういうのは買わないでちゃんとしたのを買いましょう

ちなみに Airpods の本物は以下で

当時噂になった偽物 (i7s) は以下です

ええほとんど同じです
そして偽物はなんと 800 円くらいで購入できます
確かに価格だけみたら非常に魅力ですが、まぁ安かろう悪かろうってやつです

でデザイン的にインナーイヤー型の完全ワイヤレスイヤホンが Airpods しかなかったというもの購入の理由の一つかなと思います
発売当時は「耳からうどん」というフレーズが流行りましたが、それも今やほとんど聞かなくなったかなと思います
むしろ今は Airpods している方が「どや」できるかなーって気もしています。

iCloud に登録してあるデバイスは勝手に接続できる

同一の Apple ID でログインしている端末同士は特にペアリングを行わなくても接続できました
ただ、デバイスを切り替える場合は手動で作業が必要で例えば Mac から iPhone に切り替える場合は iPhone の Bluetooth の設定メニューから Airpods に接続しないといけません

もしかすると Mac 側がスリープになっていれば iPhone を優先してくれるかもしれません
また同一 Apple ID 外で管理しているデバイスも同然ですが手動でペアリングする必要があると思います

充電もそこそこ持つ

Airpods の充電方式は少し特殊でバッテリーはイヤホンとケース側にも実はあります
要するにケースにしまっている間はケース側のバッテリーを使ってイヤホンを充電することができるのです
ケースがモバイルバッテリーになっているイメージです

フル充電で連続可動 5 時間が公式の情報です
そしてもしイヤホンのバッテリーがなくなっても 15 分ケースに入れておけば再度 3 時間連続再生できるという謎の急速充電機能もあります

ケース側の充電さえ怠らなければバッテリー切れの心配はないと思います
肝心のケース側の充電は自分の場合 3, 4 日に 1 回実施するペースです
ちなみにバッテリーの充電中はイヤホンは出しても入れてもどっちでも大丈夫です

クラムシェルとの相性がいい

普段 Mac Book Air をクラムシェルで作業することが多いのですが、その際に Earpods だと線が短くて使えませんでした
しかもクラムシェルの場合モニタにスピーカーがあるとそっちにいってしまうため音楽とかは流せませんでした

Airpods があればクラムシェルの状態でも直接 Mac の音を聞くことができます
また線の短さも考えなくていいので結構距離が離れているクラムシェル環境でも問題なく使えます

Android でも使える

これは少しビックリしたのですが Android でも使えました
Airpods のケースの裏側に白いボタンがあり、蓋をあけて少し長押しすると LED ランプが白色で点滅します
これがペアリング待ちの状態なのでその状態で普通に Android の設定画面から Bluetooth 接続でデバイス検索して接続すれば使えます

使えるんですが Airpods のありがたみを味わうことができません
耳の着脱の自動接続やダブルタップ時のアクションは設定できません
また充電情報などもデフォルトでは確認できず Android 版の Airpods 用のアプリがいろいろと出回っているので、どれかダウンロードしてそれを使う必要があります
とりあえず完全ワイヤレスイヤホンとしては使えますがやはり本来の力を発揮するのであれば Apple 製品で使ったほうがいいでしょう

Bad

ダブルタップ難しい

先程から話しに少し出てきているのですが Airpods の機能にダブルタップの機能があります
イヤホンの側面を「ポンポン」と叩くと Siri を呼び出したり音楽の再生/停止を行うことができます

がこのダブルタップが初めまったく動作しませんでした
自分の場合原因はやり方に問題があり耳が弱いせいなのか少しかばって優しく触れるような感じのタップをしていました
それだとまったく反応してくれなく少し (というか結構強め) でポンポンと叩いたら反応してくれるようになりました

仕組みを考えれば当然と言えば当然で W1 チップはダブルタップの振動で検知してアクションを実行します
優しくタップするだけだと振動を検知することができなかったのだと思います

このタップの強さが個人的にはかなり耳への負担を大きくしています
もう少し優しくタップしても反応するようにしてもらえると助かるのですが、現状耳への負担が大きいため使っていません
なので再生/停止、次のトラック、Siri 呼び出しは全部 Mac および iPhone で直接行っています

そして別にそれでも全く支障がありません
というもの先程紹介したように再生/停止はできないアプリもあります
なので結局本体側で停止しなければいけないケースがあるので、結局そっちに倒したという感じです
あとは音量の上げ下げを Airpods でするには Siri にお願いしなければいけません
これが面倒くさすぎるので本体側でやってしまってるというのもあります

どちらにしろ個人的にダブルタップは改良されない限り使うことはないと思います
一番いいのは自分で作った Swift のコードや最悪 Apple Script で作ったコードをアクションに設定できるようになりダブルタップで、そのスクリプトが実行できるようになるともっと使うかなと思います

少しお高め

だいたい日本円だと 18,000 円くらいです
イヤホンにしてはかなり高額だと思います

最近だと完全ワイヤレスではないですが後ろだけワイヤーで接続されているタイプのワイヤレスイヤホンがかなりお安く購入できます

なのでそれでも良いという人はわざわざ Airpods を購入する必要はないと思います
もしくは他の完全ワイヤレスイヤホン (Earin など) を持っている方はそれで十分だと思います (Earin なども十分高額ですが、、)

Apple 製品が好きとか、まだ完全ワイヤレスイヤホンを持っていなくて周りのデバイスやガジェットが Apple 製品が多いという人には Airpods を勧めます
そうでない場合には、まぁ正直デフォルトの Earpods でも何とかなるし音質も全く変わらないので無理して購入する必要は全くないかなと思います

紛失しそう

これも散々言われてきたことかなと思います
自分が初めて装着したときに紛失について感じたのは「動いただけでは絶対に落ちない」という感想でした
つまり普通に生活している分にはまず落とすことはないと思います

ただ自分が紛失しそうだと思ったのは耳から外したときにケースなりどこかに保存しておかなければいけない状況で、どこに置いたのか忘れちゃいそうだなと思いました
ケースに常に入れるクセが習慣があれば良いのですが正直それは面倒です
本当に少しの時間だけ外す場合などはそのままポケットに突っ込んだほうが楽です
またそのまま耳に戻せば Bluetooth 接続も再開されるので楽です

ですが、たぶんそれを続けていると近い将来必ず紛失するなーと思いました
これは完全に経験則というか勘ですが、それで慣れちゃうと結構危ないなーと思っています

それを解決するガジェットなども売られているくらいです

Airpods にワイヤーを付けて首から下げる感じにすることができるのですが「いやこれ本末転倒じゃ、、」と思う次第です
ですが、確かにこれがないと紛失リスクも高いなと思うところでもあります

自分はしばらくはそのまま使おうと思いますが外出先などで危ないなーと思った場合は積極的に採用しようと思っています

あとは単純に耳から誰かに強奪されないか心配です
正直都会の人混みの中さっと取られたらわからないかなと思います
ただ、そんな場合のために公式で Find my Airpods という機能があるので見つかるとは思いますが遠くに行かれたらさすがにどうしようもないかなと思っています

Siri さんの声がおかしい?

ダブルタップから Siri を呼び出すとスピーカーが切り替わるのか声の音質がだいぶ落ちた感じで聞こえます
調べてみても同じ症状の方の情報が見つからなかったのでもしかすると自分の環境だけかもしれませんが、何かへんな感じがします

「何かへんな感じ」というのが文章で非常に伝えづらいのですが、例えば Podcast を聞いているときにダブルタップで Siri を起動すると、その Podcast の声とは違う声で Siri さんが聞こえる感じです

まぁ今のところはダブルタップを使う予定はないので特に問題ないとは思いますが、一応気になったので記載しておきます

お掃除が少し面倒

これは Earpods でも同じです
Airpods は形はほぼ Earpods と同じなのでお掃除も同じくらい面倒です
また Airpods の場合ケース側もお手入れもしなければいけません
ケースの蓋の部分が磁石になっているため鉄製のゴミが付着しやすいです

一番面倒なのはメッシュになっている部分の凹凸であそこに耳垢やゴミなどが溜まりやすいなと思います
掃除の仕方も調べるといろいろ出てくるようですが、なんかどれもいまいちな感じがして決定打にはかけるかなーといった印象です

自分は毛先の細かいブラシである程度のゴミを掻き出したあとに掃除機で吸い取っています
あまり強くゴミを書き出すような掃除の方法だとメッシュの中にゴミが入って取れなくなるリスクがあるようなので、吸い取るほうを充填的にやっています
ただ、それも何かあんまり良くないなーとは思っています
何かいい方法があれば教えていただきたい、というか公式が動画とか出してほしい、、

最後に

Airpods を購入したので思ったところを書いてみました
いろいろ書きましたが購入して良かったです
少なくとも Earpods よりかは良いです

この記事がこれから購入を検討している人の手助けになれば幸いかなと
ただあの経験は正直購入して使ってみてからではないと伝わらないと思うので余裕があれば迷わず購入して使ってみることをオススメします

2018年9月7日金曜日

今更 Firefox のアドオンを Quantum に対応してみた

XML と JS で UI を作る XUL の仕組みが廃止となり JS のみでアドオンを開発するようになりました
古いアドオンは使えなくなってしまったので新たに Quantum 対応版に書き換えてみました
感覚的には Chrome の Extension を作るときと同じかなと思います

https://github.com/kakakikikeke/all-reload

以下ではハマりポイントを紹介します

感覚だけつかみたいならとりあえず Getting Started をやってみる

とりあえずこれをやってみましょう

matches は * だけではだめ

すべてのサイトに対応したいと言って以下のように記載するとアドオンのインストール時にエラーになります

"matches": ["*"]

以下のように記載しましょう

"matches": ["*://*/*"],

There was an error during installation: Extension is invalid

アドオンをテストで Firefox にインストールする際によく見かけると思います
これが出る場合は大抵の場合は manifest.json の記述に誤りがあります

console.log でデバッグするには

バックグラウンドモードで起動する必要があります

"background": {
  "scripts": ["main.js"]
}

browser.i18n.getMessage について

_locales/en/message/messages.json を作成してメッセージを定義しておきます

{
  "menuItemRemoveMe": {
    "message": "hoge",
    "description": "fuga"
  }
}

また manifest.json にデフォルトで使用する locale を指定する必要があります

"default_locale": "en"

公式のドキュメントはあてにならない

公式は割と古い情報が多いので Github にある数々のサンプルが一番参考になります
https://github.com/mdn/webextensions-examples/blob/master/menu-demo/

tab を操作する場合は permissions が必要

"permissions": [
  "tabs"
]

accessKey を作成するには

accessKey はコンテキストメニューを表示したときにクリックするのではなく特定のキーボードのボタンを押すことでコンテキストメニューを実行するための機能です
要するにショートカットみたいなものです

どうやら WebExtension では accessKey の機能自体はないようでコンテキストメニューのタイトルの先頭に該当のキーを表示することで対応できるようです
例えば「z」キーに割り当てる場合は以下のようにします

{
  "menuItemReload": {
    "message": "Z) all tabs reload",
    "description": "Reload all tabs when clicked."
  }
}

パッケージにする

公開するには zip ファイルを作成するだけです
xpi ファイルなどは不要になりました

  • zip -r -FS ../all-reload.zip *

ID は変えちゃダメ

install.rdf で指定していた em:id は manifest.json の applications.gecko.id で指定します
この値は同じでないと既存のアドオンに対して更新することはできません

<em:id>all_reload@kakakikikeke.blogspot.com</em:id>

2018年9月6日木曜日

Blogger が https + カスタムドメインに対応したのでやってみました

https://blog.kakakikikeke.com

でアクセスできるようになっていると思います
昔のアドレス https://kakakikikeke.blogspot.com/ にアクセスするとリダイレクトされると思います

設定は簡単で管理ページから「設定」->「基本」でカスタムドメインのアドレスを設定し、その少し下にある「HTTPS の使用」を「はい」にするだけです
blogger_https1.png

カスタムドメインにするのは DNS サーバ側の CNAME の伝播に少し時間がかかるので、それが反映されるまで待つ必要があります
DNS の伝播が完了した時点で http でカスタムドメインでアクセスできるようになります
またこの段階で古いアドレスへのアクセスはすべてリダイレクトされるのでアクセスできなくなります

更に https にしたい場合は「HTTPS の使用」を有効にします
この作業に少し時間がかかります
自分は 15 分ほどで完了しました
これを有効にしている間は完全にブログサイトにアクセスできなくなるので注意してください

なぜなら

  1. 既存の xxx.blogspot.com へのアクセスはカスタムドメインにリダイレクトする
  2. http のカスタムドメインにアクセスしようとする
  3. http -> https のリダイレクトが走る
  4. https が有効になっていないのでエラーになる

という感じです
まぁ仕方ないという感じです

で https 適用後に証明書を確認したら Let's Encrypt の証明書でした
blogger_https2.png

おそらく更新作業などは勝手にやってくれるはずです、、
証明書の更新間隔は 3 ヶ月になっています
たぶんですが更新時に証明書の入れ替えが発生するのでその間はサイトにアクセスできないか証明書のエラーが表示されるはずです
一瞬だと思うのでほぼ見れないと思いますが
もしくは Google 先生のことなのでそうならないように対策してくれているかもしれません

何にせよこれが無料で使えるのは、さすが Google 先生かなと思います

おまけ

StackEdit はカスタムドメイン設定後も問題なく使えました

2018年8月29日水曜日

Patron になろう

概要

Patreon は個人で活動している人を支援することができるサービスです
少し言いすぎかもしれませんがプライベートで始められるクラウドファウンディングみたいな感じです
実際に Patron になってみたので方法を紹介します
ちなみにサービス名は「Patreon」で支援する人のことを「Patron」と呼びます

環境

  • Pateron (2018/08/17 時点)

Patreon のアカウントを取得する

Patron になるには Patreon のアカウントが必要です
Patron になる途中でもアカウント作成できるます
すでに取得している場合はそのアカウントをご利用ください

支援したい人 (または組織) のページにアクセスする

まずは支援したい人のページに行きます
become_a_patron1.png

そのページ内に「Become a Patron」のボタンがあるのでここから Patron になります

支援するタイプ (tier (ティア)) を選択する

Patreon には支援するタイプが複数あります
タイプごとに金額や報酬などが異なります
今回は 1 つの tier しかないのでこれを選択します
become_a_patron2.png

1 ヶ月に $1 で支援する tier になります
「Continue」を選択します

アカウントを登録する

すでにログインしている場合このページは表示されません
まだアカウントがない場合は登録しましょう
become_a_patron3.png

カード情報 (または Paypal) を登録する

Patreon での支払いはクレジットカード or Paypal になります
Paypal にアカウントがある場合は Paypal を選択したほうが簡単です
become_a_patron4.png

クレジットカードの場合「Postal Code (郵便番号)」も必要になるのでハイフンなしで入力してください
クレカに紐付いている住所の郵便番号を入力すれば OK です

ちなみに登録したクレジットカードは「Settings」->「Payment Methods」から確認できます

Patron になった

あとは「Pay with Card」をクリックすれば OK です
Patron になれれば Thanks メッセージが表示されます
become_a_patron5.png

登録したメールアドレスにも Patron になった確認メールが来ると思います

解除するには

「Your Memberships」のページから「Edit」で「Edit or Cancel Payment」でいつでもキャンセルできます
become_a_patron6.png

参考 -> https://patreon.zendesk.com/hc/en-us/articles/360005502572-How-do-I-cancel-my-membership-

最後に

Patreon でユーザを支援する方法を紹介しました
Patreon アカウントとクレジットカードがあれば簡単に登録できました

ということで Patreon 始めたのでよろしくお願いします
https://www.patreon.com/kakakikikeke

サイトに専用のページも用意したのでこちらからでも可能です
https://kakakikikeke.com/supporter

基本は Podcast の機材や場所確保などに当てたいと思っています
今のところ特典はありませんが、ステッカーなどグッズを作成してプレゼントしようかなと思ったりしています