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 型で良い感じに簡単にできる仕組みにすると良いのかなと思います
やはりコマンドをホストマシンで直接実行するのは何か微妙なやり方なような気がします

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

参考サイト