零細企業経営にはほとんどの意見が参考にならなかった話

IT 系パッケージメーカーの零細企業経営者場合

いつか書こうと思っていたので雑に書いていく。

要約

基本的に人の意見は参考にならない、聞く必要ない。自分の考えを信じたほうがいい。

ただし、IT 系の企業経営者で信頼できるなら人が身近にいるのであれば、意見交換はしたほうがいい。最近全く会えてないが、ヴェルクの田向さんSigfoss の森さんから頂いた意見はとても役に立った。

社外の人間の意見は参考にはならない

自分が起業したときに苦労したので、書いておくが、この記事も参考にならないと思ったほうがいい。

思い立ってすぐに起業したので、ほとんど知識がなかった。いろいろな人の意見を聞いてみたが、実際に経営してみると全く参考にならなかった。

助成金の話ばかりする人

これは最初に契約した税理士が良くなかっただけかもしれないが、基本的に助成金の話しかしてこない。助成金の仲介手数料が目当てなんだろう。

ちなみに助成金に関しては社員時代に一度助成金を使った事業のお手伝いをして本当に最悪な経験をしたので二度と関わるまいと決めていたので、助成金関連の事業には可能な限り関わらないようにしている。

ちなみに今の税理士は「高いサーバ買えば助成金が出る場合もあります」以外のことは一切言ってこない。よくわかっている。

カスタマイズしない自社製品なんて儲からないからやめろと言ってくる人

これはよく言われた。カスタマイズしたほうが儲かると。「別に儲ける必要はないんですよ」って言うと小バカにされた。

人は成功体験にしがみつくということを学んだ。

海外に目を向けろと言ってくる人

自分は英語がさっぱりできないので、日本国内だけでビジネスをやっているが「日本はオワコンなので、海外に打って出ないとダメ」と言われたた。

海外とビジネスするというのは自分には全く想像できないし、リスクしかないように思える。

正直、日本語ですらうまくやりとりができない日本の企業がいるのに海外とか無理だなと思っている。

資金調達しろといってくる人

なにをやるにしても「資金調達」ありきの話をしてくる。色々提案してくるが「そんなお金はない」っていっても「お金を稼ぐ時間なんて無駄だ、調達して攻めるべき」と言われた。

そもそも人とうまくやれないという、社会人不適合者ということで起業してるのに、調達して色々意見言われる時点で無理。

調達している人の意見は正直環境が違いすぎて何の参考にもならない。普通に世界線が違うので関わらないほうがいい。

銀行から借りろといってくる人

「無借金はだめ、お金を借りていることは大事」というのは年配の方に多かったが、お金借りる予定もないし銀行嫌いなので、受け入れられないという話をした。

「銀行は困った時に助けてくれる」と言われたが、むしろ困った時に厳しい話しか今まで聞いていないのなにを言ってるのかわからなかった。

あと別に IT 系は投資がほぼいらないのでそもそも借り入れ自体が不要。

営業を雇えと言ってくる人

自社製品が売れていないときに言われた。売れないのは営業を雇わないからだ。まず売り込みをしないとダメだと言われたが、「誰にでも売りたい製品」ではない時点で営業は別にいらないという説明をしたが「そんな甘い考えじゃ失敗する」と言われた。

ウェブサイト / Twitter / Discord / Gist で宣伝して売るという考えは受け入れられなかった。

人を増やせと言ってくる人

自分が結構忙しく働いてる時に言われた。今も忙しいが「人を増やすとコミュニケーションコストが高くなる」といっても理解してもらえなかった。

時雨堂は「ほっといてもなんかする人」だけを雇っているため管理コストがほぼ0なのだが、マネージャーを雇えと言われた。

実際、起業して見ると「売上を上げる=人を雇う」という考えの人がとても多いことに驚いた。皆、ほっといて売れるような製品をつくりたくはないらしい。

社会に還元しろと言ってくる人

一番めんどくさかった。一社だけで儲けるのはやめろといいながら、打ち合わせしようとしてきたりするし、自分に都合のいい話ばかりする人たち。

結局何がしたかったのかわからなかった。いい反面教師になった。

社員をもっと働かせろと言ってくる人

時雨堂が 6 時間労働になったあたりで言われた。社員は替えがきくとか意味がわからない事を言っていた。

たくさんの時間働いて成果をたくさん出せるのはそれは才能なので、誰もが真似できるものでもないと思っている。

うまくいくとなにも言われなくなる

面白いもので、時雨堂コトハジメとかである程度うまくいってることをオープンにするとなにも言われなくなる。

社員の意見はとても重要

基本的に自分で方針は決めるが、悩んでるときは必ず社員たちに相談することにしてる。自分の考えが良くないことも多々あった。相談できる社員を雇うことが大事。

まとめ

結構なにも考えず上からの意見がふってくるので聞かないほうがいい。成功経験に引っ張られている考えがほとんどだった。

自分の考えを信じたほうがいい。もちろん、この記事の意見も参考にするべきではない。

Erlang/OTP / 時雨堂 / WebRTC / E2EE

Erlang/OTP / 時雨堂 / WebRTC / E2EE

これは、こんな事がやれたら楽しそうだなという話でどうするかとかはまだ決まっておりません。

要約

  • Momo に WebAssembly Runtime を載せたい
  • WebAssembly でエンコード前とエンコード後の音声と映像を操作できるようにしたい

Momo は libwebrtc を利用した WebRTC クライアントです。様々な環境で動き、とても軽いのでいろいろなところで利用いただいています。

ただ課題として基本的に Momo が対応していないことをやろうとすると自分でカスタマイズする必要があります。これは体力のある企業でやる場合はいいと思うのですがスタートアップなどでは厳しいのが現状です。

たとえば …

  • Momo が配信する映像にぼかしフィルターをかけたい
  • Momo が投げてる SDP をカスタマイズしたい
  • Momo が受信したパケットの映像部分をダンプしたい
  • Momo の Sora シグナリング時に投げてる JSON を加工したい

これらをやるには必ず Momo のコードに手を入れ自前でビルドする必要があります。

これらをなんとかして Momo に手を入れないで利用できるようにできないかとずっと考えていましたが、思いついたのは LuaJIT を使ってフックポイントからフックして処理できるような感じにするかという OpenResty 的な思考でした。

ただ Lua はまぁ、良い言語で自分も好きなのですが残念ながら流行っているとは言い難いですし、書きたい人もそんなにいません。

実際 Erlang VM 上で動作する Luerl を使った商用システムを何個か作りましたが、刺さるところには刺さるくらいでした。

なんどか めるぽん に「C++ でプラグインの仕組みはやっぱりしんどい?」という相談をしたこともありますが、厳しそうなのでやめました。

WebAssembly

Momo とはあまり関係ないWebRTC における End to End Encryption をブラウザ上で実現するために Go で書いたコードを WebAssembly に出力して利用するというのを実装して、かなりうまく動いたという経験をしました。

このとき思ったのが、Momo に WebAssembly Runtime を載せて WebAssembly 用のフックポイントを Momo に用意して、誰もが気軽に Momo のプラグイン的なものを WebAssembly…


定期的にやるやつ。前書いたのが 2020–06なので 5ヶ月でどうなったか。

Erlang/OTP

設計やリリース、調整などであまり Erlang/OTP は書かなかった。OTP 23.1 になった。なにより Erlang/OTP に AsmJit による JIT が OTP 24 で入ることになった。最大 40% の高速化が見込めるとのことで期待。

また、顧客から Erlang/OTP を利用した自社製品の性能検証報告をいただき信じられない性能がでており、衝撃を受けた。自分が作りたいものは今後も Erlang/OTP でいけると確信した。

Go

Wasm 向けの Go と自社サービス向けの Gin を利用した Go の両方を書いた。自分にとっては Go はミドルウェアよりもライブラリやウェブサービスに適してそう。

zerolog や sqlx や squirrel といった便利ライブラリはありがたい。

WebAssembly (Wasm)

Go から初めて利用したがとても便利だった。ただ自分が Wasm を利用する言語を増やしたくはないので Rust や AssemblyScript には手を出さず Go 一本に絞りたいと考えている。なので適用範囲はとても狭いという認識。

WASI はとても楽しみにしており、wasmtime-go も良さそう。

Vim

erlang-ls を設定してもらったので、大変快適。Erlang/OTP とドキュメントは Vim で書いている。erlang-ls も定期的にアップデートしている。

VSCode

Go を書くときは VSCode を利用している。Go についてはいたれりつくせり。Vim モードもいい感じ。

WebRTC

メインのお仕事。E2EE 向けのライブラリを Go で書いたりしていた。

やることが無限にでてきているが、機能追加というよりは改善がほとんどなので、気は楽。徹底的に良いものを作っていくという方針。

WebRTC 界隈は動きがそんなに無いが、やろうとしていることは巨大なので、プロトコルに絞って追いかけている。

QUIC / WebTransport

ちょっと調べては、まだ大丈夫の繰り返し。2021 年は本格的に取り組んでいきたい。

E2EE

たくさんの知識と経験を得た。今後も色々やっていきたい。自分がとても興味を持てる分野ということがわかった。

まとめ

分野的には WebRTC と E2EE の2つを中心に広げていきたいと考えてる。自分にとって興味の範囲を狭めるのは集中できている証拠なのでとても良い。

来年から QUIC / WebTrasnport に取り組みたい。この分野は先人がたくさんいるので苦労があまりなさそうで今から楽しみだ。


オンラインイベントで聞かれて、ツイッターにつぶやいたら思った以上に反響があったので、もう少し詳細に書いてみます。

思ったより反響があった
  • 信頼できる暗号ライブラリがある
  • 自分が TypeScript より Go のほうが書ける
  • Go の Wasm バイナリサイズを気にする必要がない

自社の WebRTC SFU において End to End Encryption (E2EE) をブラウザ上で実現するためにはいくつかの壁がありました。

一つは WebCrypto が提供していない暗号を利用したいというものです。

今回 E2EE を実装するにあたり採用した Signal プロトコルでは公開鍵暗号に Curve25519 を採用しています。残念ながら WebCrypto では Curve25519 に対応していません。この時点で「暗号ライブラリをどこからもってくる」というのが必要になりました。

一つ思いついたのが Emscripten を利用した何かしらの信頼できる暗号ライブラリを引っ張ってくるということです。libsodium あたりを利用するというのも一瞬考えましたが、Curve25519 を使うだけにしてはオーバキルだと判断しました。

ただそれはそれで JavaScript 側で Signal プロトコルを実装するということになり、しんどそうだなと判断しました。

そこで考えたのが Go です。Go の暗号ライブラリは Go で書かれています。一部 CPU 専用命令が有効になるのもあります、それを使わず Wasm 化は可能でした。

Go の暗号ライブラリは「標準」で用意されているもののため信頼性がとても高いです。そのためこのライブラリをそのまま Wasm 化できるのはとても大きいと判断しました。

どうでもいいですがプロトコル実装者には暗号ライブラリを自作するのは学習以外ではやってはならぬという鉄の掟が存在します。

Signal プロトコルを TypeScript で実装したくなかった

Go の暗号ライブラリを使うと判断したタイミングで Wasm 側で Signal プロトコルの状態管理までしたいと考えていました。

Signal プロトコルはシンプルではありますが、状態を管理するものが多いため、可能な限り Go で書いて、テストをガッツリ書いておきたいと考えたからです。

また自分が TypeScript で Signal プロトコルを実装できる能力がないと判断したというのもあります。

実際 Go で状態管理は思った以上によく書けました。テストもガッツリ書いたおかげでミスも減りました。

JavaScript と Go のグルー部分は自分ではなく JavaScript に慣れている社員に書いてもらいました。

Go の生成した Wasm バイナリサイズを気にする必要がない

WebRTC SFU で利用するため、2.6 MiB (圧縮して 700KiB) のバイナリは正直全く気にならないレベルです。E2EE 自体が CPU を食べますし、音声と映像を送受信するだけで 2.6MiB なんて一瞬です。

容量を気にする必要がないというのも大きな判断材料になりました。

雑感

信頼できる暗号ライブラリと慣れている言語での状態管理実装はとてもマッチしました。コード自体もとても短く書けて、テストも充実させられることができました。

今回のような暗号ライブラリの利用とプロトコルの詰め込みという天で WebAssembly を利用する場合は C/C++ か Rust が本命だと思いますが、今回は Go を採用したことで暗号ライブラリをサクッと利用でき、状態管理もさくっと実装できました。

今後は Wasm 側のテストも Go で chromedp を利用して書いていければと考えています。

今回は用途にピッタリハマったから良いと思いますが、Go での Wasm 生成は何かしら明確な理由がない限りは選択するのはおすすめできません。

適材適所です、ほんとに。

ちなみに Sora Labo にて WebAssembly を利用した E2EE のサンプル、E2EE (WebAssembly 版) マルチストリームが試せますのでもしよければどうぞ。

Twitter でツッコミいただいたので、せっかくだから TinyGo で試してみたらビルドはできました。動かすために wasm_exec.js を TinyGo のものに変更してみましたが、残念ながら “syscall/js.finalizeRef not implemented” というエラーがでて動きませんでした。どこかで追いかけようと思います。もしこれを読んでなにかヒント持ってる方は是非コメントください。

追記


Sora JavaScript SDK では正式リリース前に定期的に Canary リリースをはじめました。GitHub リポジトリのタグにも npm にも登録しています。

npm で canary というタグがセットできるのでそれを利用しています。

Image for post
Image for post

Sora デモ機能での利用と Sora Labo での利用が主な目的です。また新しい機能を試しやすくしたいというのもあります。

もしよければ使ってみてください。

Canary リリースと Lerna は Next.js から

今回 Canary リリースは Next.js を参考にさせていただきました。Next.js は積極的に Canary リリースをしていて、とても参考になります。色々自動化されているのも流石です。

Sora JavaScript SDK のリポジトリ構成も Next.js を参考にし Lerna を採用しました。E2EE ライブラリが入ってくるため、複雑になってしまうのをきれいにパッケージとして分割できるようにするためです。


WebRTC SFU の課題である録画ファイルの合成を簡単に実現する Hisui をリリースしました。

「なぜ開発しているのか」は別にまとめてあるのでどうぞ。

Hisui 2020.1 はとにかくシンプルに、最低限の機能を提供するというのを目的にリリースを行いました。

  • インプットもアウトプットも WebM に統一する
  • 映像コーデックは VP8/VP9 に統一する
  • 音声コーデックは Opus に統一する
  • 1 バイナリで利用可能にする
  • Docker 経由で利用可能にする
  • Ubuntu 20.04 固定する (Docker 経由なので気にする必要はない)

H.264 関連はすべてライセンスの扱いが存在するため今回は省きました。今後は対応していく予定です。MP4 対応は次のリリースで対応してく予定です。

Image for post
Image for post
合成した WebM

合成後の解像度は 320x240 に合わせています。今後は細かく指定可能にしていく予定です。

録画された WebM ファイルと recording.report で出力されるファイルを同じフォルダに置いて実行すればあとは処理が走ります。

まず動くものをということでリリースしました。Discord にてフィードバックをお待ちしております。

ヘルプ

こんな感じのヘルプです。

$ docker run ghcr.io/shiguredo/hisui:2020.1 hisui --help
hisui
Usage: /usr/local/bin/hisui [OPTIONS]
Options:
-h,--help Print this help message and exit
-f,--in-metadata-file Metadata filename (REQUIED)
--out-video-codec Video codec (VP8/VP9) default: VP9
--out-video-frame-rate Video frame rate (INTEGER/RATIONAL) default: 25)
--out-webm-file Output filename
--max-columns Max columns (POSITIVE INTEGER) default: 3
--libvpx-cq-level libvpx Constrained Quality level (NON NAGATIVE INTEGER) default: 10
--libvpx-min-q libvpx minimum (best) quantizer (NON NEGATIVE INTEGER) default: 3
--libvpx-max-q libvpx maximum (worst) quantizer (NON NEGATIVE INTEGER) default: 40
--verbose Verbose mode
--show-progress-bar Toggle to show progress bar. default: true