CPU負荷対策的な
以下の記事の続きですー。
https://qiita.com/eucalyhome/items/731d38655fdb3f3cad91
https://qiita.com/eucalyhome/items/b2e2374db6e580186987
なんですって!?。
CPU、貼り付けてますやん・・・。
なのでまあ、どうにかしようかと。
解析
まず、shairport-syncのパイプを観察。
catで見てみましょうか。
root@nanopineo:/data/airplay_control#cat /ramdisk/shairport-sync-metadata
<item><type>73736e63</type><code>666c7372</code><length>10</length>
<data encoding="base64">
MzExMDc2MzExMg==</data></item>
<item><type>73736e63</type><code>70666c73</code><length>0</length></item>
<item><type>73736e63</type><code>70656e64</code><length>0</length></item>
<item><type>73736e63</type><code>636c6970</code><length>14</length>
<data encoding="base64">
MTkyLjE2OC4yNC4yMjE=</data></item>
<item><type>73736e63</type><code>73766970</code><length>14</length>
<data encoding="base64">
MTkyLjE2OC4yNC4xMDI=</data></item>
<item><type>73736e63</type><code>736e7561</code><length>89</length>
<data encoding="base64">
aVR1bmVzLzEyLjcuMSAoV2luZG93czsgTWljcm9zb2Z0IFdpbmRvd3MgMTAgeDY0IFByb2Zlc3Npb25hbCBFZGl0aW9uIChCdWlsZCAxNjI5OSk7IHg2NCk=</data></item>
<item><type>73736e63</type><code>61637265</code><length>10</length>
<data encoding="base64">
MzUwMDE0NDAxMw==</data></item>
<item><type>73736e63</type><code>64616964</code><length>16</length>
<data encoding="base64">
REFBQkRBNDlDQTBFRkE4Ng==</data></item>
<item><type>73736e63</type><code>70626567</code><length>0</length></item>
<item><type>73736e63</type><code>70666c73</code><length>0</length></item>
<item><type>73736e63</type><code>70766f6c</code><length>21</length>
<data encoding="base64">
MC4wMCwwLjAwLC05Ni4zMCwwLjAw</data></item>
<item><type>73736e63</type><code>70766f6c</code><length>21</length>
<data encoding="base64">
MC4wMCwwLjAwLC05Ni4zMCwwLjAw</data></item>
<item><type>73736e63</type><code>70766f6c</code><length>21</length>
<data encoding="base64">
MC4wMCwwLjAwLC05Ni4zMCwwLjAw</data></item>
<item><type>73736e63</type><code>6461706f</code><length>4</length>
<data encoding="base64">
MzY4OQ==</data></item>
<item><type>73736e63</type><code>6d647374</code><length>9</length>
<data encoding="base64">
NzgzMjczNjMx</data></item>
<item><type>636f7265</type><code>6d696b64</code><length>1</length>
<data encoding="base64">
Ag==</data></item>
ふむ、xmlチックに流れてくるようです。
なんとなく、typeとcodeが、reader出力のタイトルに割当たってる気がします。
こいつをファイルに保存し、shairport-sync-metadata-readerに食わせてみましょう。
root@nanopineo:/data/airplay_control# shairport-sync-metadata-reader </ramdisk/testmeta.txt
"ssnc" "flsr": "3110763112".
"ssnc" "pfls": "".
"ssnc" "pend": "".
Client's IP: "192.168.24.221".
"ssnc" "svip": "192.168.24.102".
"ssnc" "snua": "iTunes/12.7.1 (Windows; Microsoft Windows 10 x64 Professional Edition (Build 16299); x64)".
"ssnc" "acre": "3500144013".
"ssnc" "daid": "DAABDA49CA0EFA86".
"ssnc" "pbeg": "".
"ssnc" "pfls": "".
"ssnc" "pvol": "0.00,0.00,-96.30,0.00".
"ssnc" "pvol": "0.00,0.00,-96.30,0.00".
"ssnc" "pvol": "0.00,0.00,-96.30,0.00".
"ssnc" "dapo": "3689".
"ssnc" "mdst": "783273631".
お、どんぴしゃっぽい。
よっしゃーとソース見てみると。
static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/'};
あら、不穏な雰囲気。
もう面倒なので、上から追ってみましょう。
まあ、BASE64ベースで、キーはUser-Agent。
明らかに「Length:89」がそれっぽいので。
その下がRemote-accessだろうなと予測。
perl実装
まあ、BASE64にそのまま入ってるべ、多分、と。
perlでサクっとデコーダを作ってみたり。
#!/usr/bin/perl
use MIME::Base64 ();
$activeremotefile = "/ramdisk/airplay_activeremote";
$metadatafile = "/ramdisk/shairport-sync-metadata";
$| = 1;
$datacount = 0;
open (PIPEFILE,$metadatafile);
while (<PIPEFILE>){
if ($_ =~ /<type>73736e63<\/type><code>61637265<\/code>/){
$datacount = 1;
next;
}
if ($datacount == 1){
$datacount = 2;
next;
}
if ($datacount == 2){
if ($_ =~ /^(.+?)<\/data>/){
$adata = MIME::Base64::decode($1);
# print "$_ $adata\n";
open (OUTPUTFILE,">$activeremotefile");
print OUTPUTFILE $adata;
close (OUTPUTFILE);
}
$datacount = 0;
}
}
xmlパーサとかかっこいいことせず、単純に「61637265」な行の2行下を取り出して整形、BASE64デコードしてるだけ。
ま、こんなんでも、いけました。
root@nanopineo:/data/airplay_control# perl ./getactiveremote.pl
ODQ1NDkzOTcz</data></item>
845493973
あとはまあ、systemdな設定書き換えて、終了。
[Unit]
Description = getactiveremote
After = shairport-sync.service
[Service]
ExecStart=/usr/bin/perl /data/airplay_control/getactiveremote.pl
Restart=always
Type=simple
[Install]
WantedBy=multi-user.target
ま、同名ファイル書き換えたので、そりゃデーモンの再起動要りますわな・・・。
root@nanopineo:/data/airplay_control# systemctl start getactiveremote
Warning: getactiveremote.service changed on disk. Run 'systemctl daemon-reload' to reload units.
root@nanopineo:/data/airplay_control# systemctl daemon-reload
root@nanopineo:/data/airplay_control# systemctl start getactiveremote