きょこみのーと

技術に関係ないほうのブログ

2016年振り返り

主にTwitterの全ツイート履歴を見て振り返る。

振り返り

半分くらいは業務コードと思われる.

f:id:kyokomi:20170101122503p:plain

開発合宿とかPC持っていく旅行

結構同じメンバー何回も開発合宿行ってて、会社が別になっても気軽に集まれる関係なのがいいなと思いました。 来年も行きましょう!!!

各月のサマリー

2〜7月: ひたすらAndroidして退職

  • Droidkaigiに行った
  • 業務でAndroidエンジニアが居なくて困っていたので、Androidエンジニアにコンバートした
  • ひたすらAndroid書いてた。とにかく仕様バグとかクラッシュを削りながらな日々
  • twitter.com
  • 去っていた人のコードを当時いた人の気持ちになってリーディングするサイコメトリーをマスターする
  • twitter.com
  • twitter.com
  • Androidそこそこできるようになったので、Androidエンジニアの採用を頑張っていた
  • 制約と誓約を意識して、Goを書かないで全ステータスをAndroidに振っていた
  • 7月一杯でGunosyを退職

8月〜9月

10月〜12月

その他

麻雀

2016年は10回くらい打った気がする。役満は1回。 メンツは結構バラバラだったけど、トータル勝ち越した気がする。

twitter.com

関係者各位また定期的にやりましょう!!!

個人開発

  • GAE/Goでちょっとしたキュレーションシステム
  • Androidアプリ2つ(キュレーションのクライアントと、Twitterの画像をひたすら表示するやつ)
  • 放置ゲーのAPIサーバーをGAE/Go -> ECSに移行
  • 放置ゲーのクライアントをUnityでプロトタイプ作成

相変わらずエターなってるけど、作ったものを自分では使っているのでそこそこ満足している。

まとめ

  • 2016年は発表とかブログとかアウトプット少なめで本を読んだり技術検証したりでインプット多めだった気がする
  • 温泉行って開発合宿すると疲労を回復しながら、開発が捗るので2017年もやっていきたい
  • 2017年はリリースもあるので、Tipsとか開発フローとかについてとか発表したり、ブログでの情報発信とかもしっかりやっていくぞ

werckerでprivate repositoryを含むglide installする方法

手順

  1. glide.ymlでsshのURLを指定する
  2. wercker上でApplication Environmentか Organization settings Environmentで + Generate SSH Keys してssh keyを環境変数に登録する
  3. 「2.」で登録したssh keyをgithub上の Settingsの SSH keys で登録する
  4. wercker.ymlに add-ssh-keyadd-to-known_hosts を記載する

glide.ymlとwercker.yml

gist.github.com

fingerprintはこちらを参考に入力しましょう。

What are GitHub's SSH key fingerprints? - User Documentation

wercker Generate SSH Keys

Application Environment

f:id:kyokomi:20161218150924p:plain

Organization settings Environment

こっちで指定すると全部のアプリケーションで使いまわせます。

f:id:kyokomi:20161218150826p:plain

Webラジオのm3u8をdownloadしてffmpegでmp3に変換するツールをGoで書いた

2016/12/15 23:06 追記:

ちなみにffmpegでm3u8 -> mp3変換はできますが、実行時間が20分以上かかって待ってられなかったのでBulkDownloadが含まれてます。

あとm3u8のURLが推測難しく、いちいちブラウザ開いてplaylistをダウンロードして中身のmedia playlistのm3u8のURLを確認して〜がだるかったのでScrapingしてます。

Webラジオのm3u8をScrapingしてtsファイルをBulkDownloadしてffmpegでmp3に変換するツールをGoで書いた が正確なタイトルですかね。


今期は、ガーリッシュナンバーが結構お気に入りです。

www.tbs.co.jp

(ちーさまのダメ可愛さがなかなか癖になります)

f:id:kyokomi:20161215205231p:plain

(そして目玉焼きの服というセンス...圧倒的か...)

なんでこんな話から始まったかと言うと、面白いなーと思った作品のアニメのWebラジオとか結構聴くんですが、なんか専用のアプリがあって使いにくかったり、Webブラウザでしか再生できなかったりと中々不便なので結局ダウンロードすることにしてツールを作りました。

(たとえば、途中まで再生してブラウザ閉じたときに、続きから聴けない...とか)

sp.animatetimes.com


ここから本編

今回作ったツール

github.com

github.com

github.com

1つのツールにしても良かったんですが、用途考えると別々のほうが使いやすいかなと思って3つに分けました。

はじめに

今回必要なダウンロードの流れは以下になります。

流れ

  1. 指定したURLのWebページのCrawl
  2. CrawlしたHTMLから対象のURLをScrapingして抽出
  3. m3u8のPlaylistのURLを元にtsファイルをBulkDownload
  4. tsファイルをffmpegでつなぎ合わせてaacを作成
  5. aacffmpegを使ってmp3に変換

3〜5のあたり github.com/yyoshiki41/radigo こちらを参考にさせていただきました。

前提条件・事前準備

  • Macでしか試してません
  • 対象のWebページのURLを用意してださい
  • 対象のxpathを適当に調べておく(ChromeDeveloperToolとかで)
  • ffmpegをインストールしておく
  • Go環境用意しておく

インストールの仕方・それぞれの役割説明

インストール

go get github.com/kyokomi/xcrawl
go get github.com/kyokomi/m3u8go
go get github.com/kyokomi/ffmpego

役割

使い方

xcrawlのオプションで使えるconfig

スマートフォンサイトをCrawlしたいとかのときに使います。

headers:
  User-Agent: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Mobile Safari/537.36

実行例

xargsでつなぐと一発で実行できて便利です。

$ xcrawl -c <configファイルのパス> \
         -i '<ラジオ再生ボタンがあるWebページのURL>' \
         -x '<master playlistのURLが抽出できるxpath>' \
         | xargs m3u8go -i \
         | xargs ffmpego -o <出力するファイル名> -i

デモ

冒頭にもリンク貼りましたが最近ハマっている、ガーリッシュナンバーの「クズらじ」で試してみます。

www.animatetimes.com

$ xcrawl -c config.yaml \
            -i 'http://sp.animatetimes.com/radio/details.php?id=gn&a=10&m=a' \ 
            -x '//*[@id="main-contents"]/ul[1]/li[3]/div/div[1]/div/a[1]/@href' \
            | xargs m3u8go -i \
            | xargs ffmpego -o kuzu3.mp3 -i

f:id:kyokomi:20161215203950p:plain

これでひとまず満足... ^q^

かなり雑に実装したので、もし自分以外に使う方がいましたら、バグとかあればお気軽に〜(対応するかはわからないが...)

Amazon Lambdaにデフォルトでインストールされているライブラリを最新にして使う方法の1つ

業務でAmazonLambda上でPDFを画像に分割処理を実装したのですが、その時ghostscriptのVersionが古くて、 特定のPDF変換でエラーになるという現象でハマったのでその時調べたことと、 対応策を紹介したいと思います。

前提

  • Apex (Go)で動かしてます
  • ImageMagickがghostscriptを呼び出している
  • ghostscriptが古くてエラー

Apexについては前に書いた記事をご覧ください。

kyokomi.hatenablog.com

Lambdaのamiについて

Amazon Linux AMI 2014.09 Packages

ghostscript-8.70
ghostscript-fonts-5.50

フォーラムでの質問

https://forums.aws.amazon.com/message.jspa?messageID=611159

AWS Lambda doesn't provide a way for functions to update the Amazon Linux AMI. 
As has been suggested, you can include alternative versions of libraries, executables, 
and language runtimes in your function's ZIP file if the default ones available don't address your needs.

We'll also be looking at ways to make that process easier in the future through simplified deployment options. 
Until then, apologies for the inconvenience of having to copy this in with your code.
  • AWS LambdaではAMIをupdateする術を提供してない
  • もしversionを更新したいならzipに含んで頑張ってくれ

と解釈。/(^o^)\

解決策

functionの構成

pdf2images
├── bin
│   └── gs            // 上記のdownloadしたバイナリ
└── main.go

コード抜粋

func main() {
    apex.HandleFunc(func(event json.RawMessage, ctx *apex.Context) (interface{}, error) {
        os.Setenv("PATH", os.Getenv("LAMBDA_TASK_ROOT")+"/bin"+":"+os.Getenv("PATH"))
 
        // TODO: 〜 色々省略 〜

        outputLog, err := exec.Command("convert", "/tmp/input/hoge.pdf", "/tmp/output/hoge.png").CombinedOutput()
        if err != nil {
            return nil, err
        }
        log.Println(string(outputLog))

        return nil, nil
    })
}

Lambda x Apexで、Goで書いたラムダ関数を楽に動かす

業務でAmazonLambdaを使う機会があり、Apex(Go)を試していい感じだったのでその紹介とハマりポイントを幾つか紹介しようかと。

github.com

導入

すごく簡単で、 https://github.com/apex/apex#installation に書いてある通りインストールして apex init で対話式でプロジェクト名とか入力するだけです。

ExampleのGo実装をそのままコピって apex deploy すれば速攻でdeployも出来ます。

exampleはこちら -> https://github.com/apex/apex/tree/master/_examples/go

package main

import (
    "encoding/json"

    "github.com/apex/go-apex"
)

type message struct {
    Hello string `json:"hello"`
}

func main() {
    apex.HandleFunc(func(event json.RawMessage, ctx *apex.Context) (interface{}, error) {
        var m message

        if err := json.Unmarshal(event, &m); err != nil {
            return nil, err
        }

        return m, nil
    })
}

かなりシンプルに書けて楽です。

概要・Tips

  • functions下がラムダ関数と1対1になります
    • 下記の例だと pdf2imagesresizeImage になります
  • GOPATH下にプロジェクトを置けば共通の実装とかをパッケージ化して使いまわせるので便利
    • 下記の例だと resize パッケージと aws パッケージ
  • glide使ってライブラリ固定もできます
  • ちゃんと調べてないんですが、 os.stdoutを呼び出すとNode.js側でエラーになるので fmt.Print ではなく log.Print を使いましょう
  • 外部ライブラリも exec.Commnad で呼び出せます
  • 環境変数の変更は os.Setenv() を使うと exex.Commandで呼び出すときにも反映されます
  • /tmp 下が書き込み可能になっているので、一時ファイル系の処理で積極的に使っていきましょう

プロジェクト構成例

example_lambda
├── functions
│   ├── pdf2images // PDFを画像に変換するラムダ関数
│   │   ├── main.go
│   └── resizeImage // 画像を元にサムネイルを作成するラムダ関数
│       └── main.go
├── glide.lock
├── glide.yaml
├── project.json
├── resize        // resizeする共通処理
│   └── resize.go
├── aws          // aws-sdk-go周りの共通処理
│   ├── aws.go
│   └── message.go
└── vendor   // vendoring

ISUCON6本戦初出場で敗退しました @ご注文はpoyoですか?

ISUCON参加は今年で3回目。毎年運営の方々はお疲れ様です。 今年は初の本戦出場が出来て本当に楽しかったです。

仕事とかでバタバタしてて、ブログ書くのが遅くなってしまった...

チームメンバーと役割

過去2年はk02というチームで出ていたのですが、メンバーの一人がセブ島にいるという体たらくで雑に集まったメンバーで参加しました。

実際、雑に集まった突貫チームだけど、前職で一緒に仕事してたこともあり、それぞれの得意分野とか性格とか把握してたので事前準備とか打ち合わせ無しでも特に問題がありませんでした。

f:id:kyokomi:20161103140723p:plain

※窓側の席でした

当日の準備

  • 無事に起床
  • 本戦参加者だけが貰えるネームカードをGETしてテンションが上がる
  • GitHubのRepositoryを作ってコラボレーターに招待
  • sshのPrivateKeyを共有したり
  • インスタンスで使うgithubアカウントの用意など

ちゃんと会社の宣伝してきました ^^

※右の写真のひきこもりTシャツ

地味に弊社を知っている人が居て驚きましたね。

今回のお題

  • フロントエンドサーバーとしてReact.jsを使ったnode.js
  • そこからリバースプロキシされる形でアプリが存在し、それには各言語の実装(Goを選択)
  • DBは、MySQL
  • すべて docker になっていて、 docker-compose で動いている
  • 5台あるけど1台で全部のdockerが動いてる状況

反省点

  • Dockerを捨てるかどうかの判断が遅かった(午前中くらい)
    • nginxをdocker-composeに混ぜるのでハマった
    • そもそもなんで docker-compose...頑張ってるんだ... ってなるまでに時間かかった
  • 5台インスタンスを使い切る前に時間切れ(時間配分)
    • ある程度チューニングしたら横に並べるつもりだったが時間配分ミス
  • Reactのフロントエンドサーバーは飾りだと思って、軽視してた
    • 一応、チラっと見たけど先にセオリー通りまずはサーバーを〜って優先度を雑に決めてしまった
  • 絵チャット掲示板的なやつという前情報でなんとなくわかったつもりになってしまった
    • あまりサービスそのものを触る時間を取らなかった
    • 触ってると、ここはAPI通信必要そうだな〜とかここは最適化できそうみたいなのが湧いてきて、本戦終了して改めて触ってると「なるほど、こうなってたのか〜」という感じだった

所感

本戦は初出場なんですが、予選と違って裁量がかなり多くてやることも多いけど一番効果的なものをやろうという感じで、今までの経験と頭をフルにつかって取り組む感じがめっちゃ楽しかったです。

結果は11位という形でやり残しもたくさんありますが、来年も開催されるだろうと思い腕を磨いて行きたいと思います。 来年も本戦出るぞ。来年こそ優勝だ !!!

ひきこもりを加速するクラスター株式会社に入社しました!!!

f:id:kyokomi:20161003205936p:plain

2016年7月一杯で約1年半働いた株式会社Gunosyを退職し、2ヶ月ほどフリーランスという形で数社のお仕事を手伝っていました。 クラスター株式会社はその中の一社であり、Founder & CEOの加藤さんとは4年ほど?前にCocos2d-xで個人ゲーム開発をしていたときにTwitterや勉強会でお世話になっていた経緯で退職したという話をしたらちょっと遊びに来ません?という流れから今に至ります。

人のつながりというのは本当に大事ですねと実感します。

約2ヶ月フリーランスをやった話について

がっつりフリーランスで稼いでいくぞ〜というよりは、色々な会社を回って自分に合っている&やりたいことをできそうな会社を探したかったのが目的でフリーランスをやっていました。 (もちろん、契約させていただいた各社様には予め長期的に働くというよりは短期的に〜ということで了承を頂いていました)

※知人で似たような形でフリーランスをやっていた人がいたので参考にさせていただきました。感謝!

細かい話をするとキリがないのですが、雑に学びがあったことを箇条書きするとこんな感じです。

  • 市場の金額感
  • 各社エンジニアリングやチームビルディングなど
  • 色々な会社の制度や働き方
  • 日本の納税義務や税務署、開業届など
  • マネーフォワード便利すぎるのでは?とか
  • クレジットカードやオートチャージSuicaは個人事業主用につくっておくと捗る!とか
  • 交通費は税抜きでした

Clusterの紹介と入社の決めてついて

cluster.mu

軽く紹介

サービス内容は↑に書いてあるとおりで、 ひきこもりを加速する ― クラスターは家から出たくないすべてのクリエイターのためのバーチャル集会アプリ ですね。 現在は、Oculus RiftMac/Windowsしか対応していませんが、HTC Vive等の対応も行っている最中ですので今後にご期待ください。

VR空間でイベントを開催したりイベントに参加したりできるので、距離の問題や収容人数の問題とかを解決できてハッピーになります。

入社の決めてとか

自分は、たぶん5人目の社員です。ちなみに約2ヶ月間フリーランスとして週3日くらい働いて以下を肌で感じて判断しました。

  • サービス
    • VRサービスの将来性を感じた
    • 最初に話を聞いたときにもめっちゃ面白そうと思った
    • チームの雰囲気も近すぎず遠すぎずでバランス良い
    • 将来的にリモートワークも視野にいれている雰囲気
    • アジャイルな開発フローも自分に合っている気がした
    • 開発速度・品質のバランス感
  • 技術
    • 技術選定のモダン感や尖りすぎず枯れすぎず柔軟な感じ
    • サーバーサイドがGoで、今までのAPI開発経験が役に立ちそう
    • Unityでの開発は前々から興味あったけどソシャゲ以外でやれそうなので

まだ数名ですが社員募集中

募集要項はたぶん以下みたいな感じです(近いうちにcluster.募集要項が更新されるはず...!?)

  • DDDやTeam Geekアジャイルサムライに書いてあるようなことに理解がある
  • 業務経験等でGoでAPI or Unityでクライアントがしっかり開発できる
  • VR開発に興味がある
  • サーバーとクライアント両方やっていきたい

ほしいものリスト

www.amazon.co.jp

一応貼っておきますが...

退職時にたくさん門出を祝ってのプレゼントを頂いたので、すでに送っている方はお気持ちだけで結構ですので!!!! (さすがに、恐縮しちゃいます... (^_^;)