在宅勤務2週間と延長決定
新型コロナウイルス感染症のアレコレで、1/27から2週間ほど在宅勤務を続けている。
外に出るのもマスクしたいけれど店頭在庫はほぼ皆無。家のストックも少なくなってきた・・という感じなのでありがたいことです。 まぁ、もともと人混み苦手(即売会とか気分悪くなっちゃう)だし、出不精だし、ということで特段「外に出られないのでストレスがー」みたいなのはとくにない。
そして鎮静化しないため、在宅勤務の期間が延長・終了時期未定になった。なので、予想以上に長期戦となりそうだ。ここまでの生活を振り返り、より健康に過ごせるようにしたい。
デメリット?
とはいえ、生活スタイルが変わったら気になるのは体調面。 平日外出することはほぼなくなるので、1日の歩数は7000程度 -> 1500程度と大幅に減少した。(Mi Smart Band 4 による計測)えげつない減少でワリと引く。
メリット?
昼食は外食の必要がなく、家族でゆったり取れるのも大変良い。 また通勤時間がなくなるため、毎日1時間半程度の可処分時間が増えていろいろな事ができる。 これによって1日の作業が前倒しになるので、就寝時間がどんどん前倒しされて自然と早寝になっていった。
生活の変化
- 通常勤務
- 勤務時間 : 11:00 ~ 20:00
- 夕飯 : 21時から
- 運動
- エアロバイク25分(アニメとか見ながら) : 週1
- リングフィットアドベンチャー30分 : 週2
- 在宅勤務
意識して運動を増やしてみたのと、食事の時間が早い時間にズレた。 勤務時間はフレックスなのでお決まりではなく、自然と早まったもの。
結果
体調悪化・体重増量の防止ができれば良いな程度で運動量を増やしてみたが、結果は除脂肪体重は変わらないまま体重が0.8kg減、ウエストも1cm減を達成。
心配をよそに、より健康になってしまっていた。わはは。
ご飯を食べる時間・ご飯後の血糖値が上がったタイミングでどう過ごすのか。腰痛や下半身むくみの予防のため如何に血流をよくするか。これらが思いの外大事なのだろうなぁ・・というのが教訓。ご安全に。
Raspberry Pi 4 で MPEG-2 TS の動画を H.264 へハードウェアエンコードする際の負荷をみる
前回の記事で録画サーバを構築、MPEG-2 TS で保存できるようになった。
ということで今回は、Raspberry Pi 4 のエンコードの実力をみていく。
エンコード動作時
ffmpeg -i src.m2ts -vcodec h264_omx desc.mp4
上記コマンドで雑に mp4 へ変換してみる。オプションで -vcodec h264_omx
を指定しハードウェアエンコーディングすることで、CPU利用率 140%
(4core なので max 400%)で速度は 1.47x
を叩き出しているし、熱もファンを動かしているので 53°C
と余裕だ。-b:v 8000k
オプションでビットレートを指定することで、画質を変更できる。
これは私がメインで利用している MacBook Pro (15-inch, 2016) の CPU エンコードと同等のスピードだし、1倍以上なのでリアルタイムエンコードできちゃいそうな余裕を感じる。
録画・エンコード同時動作時
余裕がありそうだったので録画・エンコードを同時に動作させてみた。
録画のCPU利用は Mirakurun node recdvb で 40%
程度で、速度は 1.4x
drop した frame も無し、CPU温度も 53°C
で変わらないため、全く問題なさそうだ。
ハードウェアエンコード以外の速度など
-vcodec libx264
は 0.4x
程度の速度。 -vcodec libx265
は 0.1x
程度で -vcodec vp9
は 0.02x
程、 -vcodec libaom
はプリンストールされている ffmpeg version 4.1.4-1+rpt1~deb10u1
ではエンコード不可だ。
ということで、ハードウェアエンコード以外は Raspberry Pi 4 にはちょっと荷が重そうだなという印象。 h264 の画の眠たさを少しでも回避するために、下記のように 2pass で処理してあげるのが良さそうだなぁと思ってる。
ffmpeg -i src.m2ts -pass 1 -an -codec:v h264_omx -strict -2 -passlogfile encoded/log -f rawvideo -x264opts frameref=15:fast_pskip=0 -y /dev/null && \ ffmpeg -i src.m2ts -pass 2 -codec:v h264_omx -strict -2 -passlogfile encoded/log -b 6000k -x264opts frameref=15:fast_pskip=0 -y desc.mp4
が、ファイルの容量を抑えたいなら libx265 までギリ有りなラインかな・・。 この場合、コマンドは以下の感じかなぁ
ffmpeg -i src.m2ts -t 300 -codec:v libx265 -preset veryfast -vf pp=ac -x264opts frameref=15:fast_pskip=0 -y desc.mp4
感想など
Raspberry Pi 4 が想像以上に高性能で驚いている。これなら録画中でも気にすることなく様々な処理(Steam Linkとか、アプリのビルドとか)を雑にぶん投げても良さそうだ。 私の環境ではTVチューナーは1chだけなのでこんな結果だが、複数ch録画したい人は Raspberry Pi 4 + px-q1ud で十二分に幸せになれると思う。
Raspberry Pi 4 と NAS で録画環境を整える
ウチは今まで nasne を使って楽チン運用をしてきたのだけど、 生産も終わってサービス停止もそう遠くない将来にきてしまう 。 容量1TBの運用も窮屈に感じてきたし、元々運用していたNAS(8TB)を利用できる録画サーバーを作ることにした。 先人の多くの記録があったので「わたしでもできるっしょ、やってみっか」となった。感謝。
- Raspberry Pi 3+Chinachuで地デジ録画サーバー構築 - Qiita
- Raspberry Pi でTVを見る録る! - Qiita
- 「PX-S1UD V2.0」Linuxでも使える定番TVチューナー | 秋葉原ぶらり | ページ 2
重複する箇所は多々あるが、私の環境構築に必要なコマンドは全て記述しておく。
使ったハード
- 元々持っていたもの
- 新たに購入したもの
割り当てIPについて
私の自宅環境ではこんな感じ。
192.168.10.1 # ルーター 192.168.10.2 # NAS 192.168.10.128 # Raspberry Pi を今回割り当てる
作業
Raspberry Pi をセットアップ
TVに映像出力(Steam Link)もしたかったので、GUIを含んだパッケージの Raspbian Buster with desktop をインストール。 副次的効果として、言語・キーボード・タイムゾーン・wifi 設定もGUIのウィザードで終わるので楽だった。
Raspberry Pi に SSH 接続するために
慣れた端末(Mac) から SSH で接続できるようにする。やることの大枠は他のLinuxディストリビューションと変わらない。
ユーザの初期パスワードを変更する
sudo raspi-config
上記コマンドで設定画面を開き 1 Change User Password
で更新。
初期パスだと外部端末から Permission denied
で弾かれるので、「LANでしか繋がないし」と面倒がらずきちんと変更しておこう。
起動時にネットワーク関連処理を待つ
sudo raspi-config
上記コマンドで設定画面を開き 3 Boot Options
> B2 Wait for Network at Boot
で有効化。
この設定をしておかないと、後述のfstab設定をしたとしても起動時にNASを自動マウントしてくれないので注意。
SSH サーバーを enable
sudo raspi-config
上記コマンドで設定画面を開き 5 Interfacing Options
> P2 SSH
で有効化
IPを固定する
192.168.10.128
を割り当てたいので /etc/dhcpcd.conf
に以下を追記しておく。
(ルーターの物理LANポートが埋まってたのでとりあえず無線LANで接続している。スイッチングハブ買わないとな・・)
interface wlan0 static ip_address=192.168.10.128/24 static routers=192.168.10.1 stacit domain_name_servers=192.168.10.1 8.8.8.8
公開鍵を登録しておく
上の状態で Raspberry Pi を再起動したらパスワードを用いた SSH 接続はできるが、頻繁に接続するには面倒なので公開鍵を登録しておく。
pi@raspberrypi:~ $ mkdir .ssh pi@raspberrypi:~ $ touch .ssh/authorized_keys pi@raspberrypi:~ $ chmod 700 .ssh pi@raspberrypi:~ $ chmod 600 .ssh/authorized_keys
接続する端末(Mac)で以下コマンドを実行して鍵を登録しとく。
% cat ~/.ssh/id_rsa.pub | ssh pi@192.168.10.128 'cat >> .ssh/authorized_keys'
NAS をセットアップ
NAS の共有フォルダを NFS 利用できるように
USB接続のHDDを利用する手もあるが、ウチにはNASがあるので有効活用しようかと思う。 (USB接続のHDDでもfstab設定を置き換えるだけで同じようにセットアップできると思う)
NAS の設定変更する
Synology 216j を利用しているので、GUIをポチポチするだけで用意できる。
Raspberry Pi でマウント設定する
マウントポイントを作成。
pi@raspberrypi:~ $ sudo mkdir -p /mnt/nas pi@raspberrypi:~ $ sudo chown pi /mnt/nas/
/etc/fstab
に以下を追記し、自動マウントさせる。
192.168.10.2:/volume1/video /mnt/nas nfs rsize=8192,wsize=8192,timeo=14,intr
自動マウントしたら、保存先のディレクトリ作成と権限を付与しておく。
pi@raspberrypi:~ $ sudo mkdir -p /mnt/nas/recorded pi@raspberrypi:~ $ sudo chown pi /mnt/nas/recorded pi@raspberrypi:~ $ sudo chown :video /mnt/nas/recorded
チューナーサーバと録画サーバをセットアップ
ドライバ等々のインストール
ビルドに必要なものやカードリーダーのライブラリを導入。
ハードウェアも含めてちゃんとできたかは sudo pcsc_scan
で動作確認できる。
(参考にしたQiitaの記事内容とは異なり、B-CASのカードリーダーは SCMと認識されるものが届いており、 libccid_Info.plist
を編集する作業は必要なかった)
pi@raspberrypi:~ $ sudo curl -sL https://deb.nodesource.com/setup_12.x | sudo bash - pi@raspberrypi:~ $ sudo apt-get install -y vim cmake autoconf nodejs pcscd pcsc-tools libpcsclite-dev libccid vainfo
TVチューナーのファームウェアを導入。
pi@raspberrypi:~ $ cd Downloads/ pi@raspberrypi:~/Downloads $ wget http://plex-net.co.jp/plex/px-s1ud/PX-S1UD_driver_Ver.1.0.1.zip pi@raspberrypi:~/Downloads $ unzip PX-S1UD_driver_Ver.1.0.1.zip pi@raspberrypi:~/Downloads $ sudo cp PX-S1UD_driver_Ver.1.0.1/x64/amd64/isdbt_rio.inp /lib/firmware/
B-CASのデコード用ライブラリを導入。
pi@raspberrypi:~/Downloads $ wget https://github.com/stz2012/libarib25/archive/master.zip pi@raspberrypi:~/Downloads $ unzip master.zip pi@raspberrypi:~/Downloads/libarib25-master $ cmake . pi@raspberrypi:~/Downloads/libarib25-master $ make pi@raspberrypi:~/Downloads/libarib25-master $ sudo make install pi@raspberrypi:~/Downloads/libarib25-master $ cd ..
録画用コマンドの導入
pi@raspberrypi:~/Downloads $ wget http://www13.plala.or.jp/sat/recdvb/recdvb-1.3.2.tgz pi@raspberrypi:~/Downloads $ tar xvzf recdvb-1.3.2.tgz pi@raspberrypi:~/Downloads $ cd recdvb-1.3.2/ pi@raspberrypi:~/Downloads/recdvb-1.3.2 $ ./autogen.sh pi@raspberrypi:~/Downloads/recdvb-1.3.2 $ ./configure --enable-b25 pi@raspberrypi:~/Downloads/recdvb-1.3.2 $ make pi@raspberrypi:~/Downloads/recdvb-1.3.2 $ sudo make install
Mirakurun(チューナーサーバ)の導入
pi@raspberrypi:~/Downloads $ sudo npm install pm2 -g pi@raspberrypi:~/Downloads $ sudo npm install mirakurun -g --unsafe-perm --production pi@raspberrypi:~/Downloads $ sudo mirakurun init
Mirakurun にチューナーの設定を追記
pi@raspberrypi:~/Downloads $ sudo mirakurun config tuners
- name: PX-S1UD-1 types: - GR command: recdvb --b25 --dev 0 <channel> - -
pi@raspberrypi:~/Downloads $ sudo mirakurun restart pi@raspberrypi:~/Downloads $ curl -X PUT "http://192.168.10.128:40772/api/config/channels/scan" pi@raspberrypi:~/Downloads $ sudo mirakurun restart
Mirakurun 経由で、TVチューナー・B-CASのデコード・録画用コマンドが動作するか確認
# VLC でネットワークストリーム再生 http://192.168.10.128:40772/api/channels/GR/25/stream
Chinatu (録画サーバ)の導入
pi@raspberrypi:~/Downloads $ git clone https://github.com/Chinachu/Chinachu.git pi@raspberrypi:~/Downloads $ cd Chinachu/ pi@raspberrypi:~/Downloads/Chinachu $ ./chinachu installer # 1) Auto (full) を選択
ARM(Raspberry Pi)だと Chinachu は node と ffmpeg をうまく扱えないので、手動でシンボリックリンクを貼る。
pi@raspberrypi:~/Downloads/Chinachu $ cd .nave pi@raspberrypi:~/Downloads/Chinachu/.nave $ rm node pi@raspberrypi:~/Downloads/Chinachu/.nave $ rm npm pi@raspberrypi:~/Downloads/Chinachu/.nave $ ln -s /usr/bin/node . pi@raspberrypi:~/Downloads/Chinachu/.nave $ ln -s /usr/bin/npm . pi@raspberrypi:~/Downloads/Chinachu/.nave $ cd ../usr/bin pi@raspberrypi:~/Downloads/Chinachu/usr/bin $ rm avconv pi@raspberrypi:~/Downloads/Chinachu/usr/bin $ rm avprobe pi@raspberrypi:~/Downloads/Chinachu/.nave $ ln -s /usr/bin/ffmpeg avconv pi@raspberrypi:~/Downloads/Chinachu/.nave $ ln -s /usr/bin/ffprobe avprobe
pi@raspberrypi:~/Downloads/Chinachu $ echo [] > rules.json pi@raspberrypi:~/Downloads/Chinachu $ cp config.sample.json config.json pi@raspberrypi:~/Downloads/Chinachu $ vim config.json # `"uid": "pi",` `"recorderdDir": "/mnt/nas/recorded/"` へ変更
Chinachu の起動と自動起動。前後に sudo reboot
して再起動しておくと良い。
pi@raspberrypi:~/Downloads/Chinachu $ sudo pm2 start processes.json pi@raspberrypi:~/Downloads/Chinachu $ sudo pm2 save
感想など
これで、Raspberry Pi でVLCを用いたリアルタイムのストリーム再生・録画が可能となった。TVでの視聴にはNAS経由で行えば良い(これは以前から行っていた)ので楽チンだ。エンコードについてはこれはこれで沼っぽいので別途ハマることにする。Raspberry Pi で録画予約のない日中にバッチエンコードでもするかな。
作業内容はネットワークやデバイスドライバのセットアップがほとんどを占めていた・・ものの、ちょこちょことハマっている。再起動をする必要がある箇所でしていない・・といった凡ミスがあったり、原因不明で録画ファイルが作成されずsdカードにOS焼く所からやり直し・・みたいな裏のゴタゴタがあった。のだが、結果ちゃんと動作するものが作れてよかったよかった。
普段お仕事(うぇぶえんじにあ)で触るのはDockerやクラウドで、よしなにしてくれている箇所だったので良い経験になった。
Unity Shader で 0~ 1 の値を扱う際の雑メモ
shader というか、ベクトル 演算する際には 0 ~ 1 の Normalize された値をよく使う。 Unity でこういった値を扱う際、「Mac (Radeon Pro 460) だと大丈夫だけど、Windows (Geforce GTX 1060) だと意図した表示にならない!」みたいな事が頻発する(特にlerpの第三引数)。 両者には、API が Metal か DirectX か、ハードウェアが OpenGL 最適化か DirectX 最適化か、といった違いがあるためどちらが原因になっているかはわからないが、 float の演算精度が異なるのは確実だ。 特に、「乗算いっぱいしてるけど、どう計算しても 0 ~ 1 になるから大丈夫だよね!」というケースで泣きを見る事が多い。 「どちらでも(ある程度)同一の表示をしたいなら、プログラム側で補正する」のが安全のようだ。 拙いながらも同一表示にできた経験をメモしておく。
0 あるいは 1 を使う場合
step()
を必ず通す
0 ~ 1 を使う場合
saturate()
clamp()
を必ず通す
色を扱う場合
inline half3 clip_color(half3 color) { color.x = clamp(color.x, 0.001h, 0.999h); color.y = clamp(color.y, 0.001h, 0.999h); color.z = clamp(color.z, 0.001h, 0.999h); return color; }
上記のようなフィルタを通して 完全な白
完全な黒
にならないようにする。
unity shader でクォータニオンから回転行列を求める
前回に引き続き shader のベクトル演算をメモ。 shader 上で様々な処理を書いていると、 「クォータニオン(回転軸ベクトルと回転角)は容易に想像・算出できる・・が、任意のベクトルに適用・回転させるにはどうすれば・・」 という場面に出会すことが多くある。少なくとも、高校で数ⅡBまでしか履修しなかった私には頻繁にある。。 そんな初級者な私でもよく見るベクトルの回転は座標系変換だ。これならなんとなくわかる。
mul(UNITY_MATRIX_M, vector);
ベクトル vector
に回転行列 UNITY_MATRIX_M
を累乗計算 mul()
してやると、回転後のベクトルが取得できる。シンプル、素敵。
だったらば、クォータ二オンから回転行列を簡単求めるられるようになったらサイキョーね。ということで下記関数ができました。
float3x3 QuaternionToMatrix(float3 axis, float thita) { float3 a = normalize(axis); thita *= 3.14159265; float s = sin(thita); float c = cos(thita); float r = 1.0 - c; return float3x3( a.x * a.x * r + c, a.y * a.x * r + a.z * s, a.z * a.x * r - a.y * s, a.x * a.y * r - a.z * s, a.y * a.y * r + c, a.z * a.y * r + a.x * s, a.x * a.z * r + a.y * s, a.y * a.z * r - a.x * s, a.z * a.z * r + c ); }
参考にしたのはみんな大好き wgld 。何度読み返しても「ここはこういうことか〜」という発見ができるので素敵サイト
利用例
カメラや照明のチルト(XZ軸回転)を表現する際は下記で求められる。
今向いている方向を movableVector
と、向いている方向・向かせたい方向と同じ回転軸上にあるとわかっている方向(チルトだったらY軸) baseVector
がわかっていれば、
外積 cross()
で回転軸を求め、内積 dot()
で基準からの角度がわかり、さらに回転させたい角度を加えてやれば良いのだ。
float3 VectorTilt(float3 baseVector, float3 movableVector, float thita) { return mul( QuaternionToMatrix( cross(baseVector, movableVector), (dot(baseVector, movableVector) * 0.01) + thita ), movableVector ).xyz; }
余談
XYZの各軸単体で回転させるなら回転基準となるベクトルは不要で、回転行列だけで以下のように表現・利用できる。 PostProcess だとか、ちょっとした利用には大変便利。
float3x3 MatrixRotateX(float thita) { float s = sin(thita); float c = cos(thita); return float3x3( 1, 0, 0, 0, c, -s, 0, s, c ); } float3x3 MatrixRotateY(float thita) { float s = sin(thita); float c = cos(thita); return float3x3( c, 0, s, 0, 1, 0, -s, 0, c ); } float3x3 MatrixRotateZ(float thita) { float s = sin(thita); float c = cos(thita); return float3x3( c, -s, 0, s, c, 0, 0, 0, 1 ); }
unity shader 内で3Dオブジェクトがカメラを向いているか判定する
Unity の Monobehavior (C#) では、3D空間(ワールド座標)上の「どの位置にいるか」「どこに近いか」「どの方向を向いているのか」という計算をよく行い、こういった計算用のライブラリ(Quaternion, Vector3 など)も揃っており大変便利です。
ですが、Shader に関してはそこまで手厚くなく(その分ノードエディタがあるが・・)手でイチから計算を記述しなくてはならないことも多く、手が止まりがちです。
なので 汎用的に利用できる
かつ ちょっと応用っぽいやつ
などを気が向いた時にメモしようと思ったのでした。今回はその第一弾。
inline float ObjectLookAtCameraCoef() { float3 objectOrigin = mul(UNITY_MATRIX_MV, float4(0,0,0,1)).xyz; float3 objectForward = mul(UNITY_MATRIX_MV, float4(0,0,-1,1)).xyz; return saturate(0.5 * dot(normalize(objectForward - objectOrigin), float3(0,0,-1)) + 0.5); }
上記記述で、shader の適用オブジェクトがカメラを向いているかを 0 ~ 1 の float で返します。
ポイントとしては、ビュー座標上で計算することで、カメラの位置(0, 0, 0)を気にしなくて良い事。
0.5 * dot() + 0.5
で -1 ~ 1
にふるまう dot()
を 0 ~ 1
に押し上げていること(half lambert とかでもこの計算やりますね)。
0 ~ 1
になってしまえば、あとは pow()
step()
や sigmoid
などを通して好きに味付けしてあげれば良いでしょう。
で、これで何ができるかというと、目があったときに目が光る、などの一癖ある演出ができます。あとはアイデアしだい。
Webディレクター向けSQL講座を開いたので資料共有
所属チーム内で数値を扱うことが増えてきた。エンジニアがいい感じに抽出してたのだけど「皆つかえればサイキョーね?」と思ったので勉強会を開くことに。 なんやかんやあってチーム外にも波及して、ディレクター・デザイナ・CSが10名以上で受ける大所帯になった。 そこそこ好評なので資料を共有します。
カリキュラム
- 第1回 「行と列と正規化」
- お話し
- 第2回 「抽出行をしぼる」
select
from
where
order by
limit
- 第3回 「抽出行をいっぱいしぼる」
and
or
like
>
<
<>
in
- 第3回 「抽出行をまとめる」
distinct
group by
min
max
count
having
- 第4回 「表をつなげる」
inner join
left join
- 第5回 「抽出結果でしぼる」
- サブクエリ
- 第6回 「抽出結果を組み合わせる」
union
- 第7回 「列表示を置換する」
case
- 第8回 「エンジニアが作ったサービス分析用のSQLを眺める」
- 実際の(複雑な)リレーションを理解する
より身につけるには
- 飲み物を持参しよう
- 脳は水が必要
- 身近な例に置き換えて聞いてみよう
- 感情移入しよう
- 遠慮なく声を出そう
- 聞く(input)だけじゃなく、口に出して確認(output)してみよう
第1回 「行と列と正規化」
うまく「使う」ために、製作者(RDBMS, table設計)のねらいを理解します。
質問コーナー
エンジニアさんが「レコード」とか言ったりするのを聞くことがるのですが、「テーブル」と何が違うのでしょうかー?
なるほどなるほど。 初学者とエンジニアではそもそもの認識が違ってそうですね! イメージはこんな感じかな
Excel や物理的に書いた表をイメージするので、テーブル = 行と列を組み合わせたデータが入ってるやつ
という認識ですよね?(本日の講義でも実際にそのように説明した)
ところが、エンジニア同士が会話する場合は、もうちょっと機械に寄った会話をします。
その際テーブルは どんなデータを入られる構造か
という概念を指すことが多く、レコードは テーブルに実際入れたデータ(1行)
を指します。
エンジニア同士だと、日本語だけではなくプログラミング言語でもやり取りするので、双方で都合の良い意味合いで話すことが多いのです
第2回 「抽出行をしぼる」
物事を調査するにはまず「観察」をする必要があります。 自分が欲しい情報だけを見る力を手に入れましょう
前回重要項目の復習
SQLってそもそもなんやねん
第3回 「抽出行をいっぱいしぼる」
SQL がどういった性質をもったモノなのか、前回でわかりました。
思い通りに「質問する力」を養うために WHERE
に続く言葉を知っていきましょう
以降は随時(週一くらい)更新