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 すごい