Raspberry pi上のOSMCにstreamlinkをインストールする


streamlink」をOSMC環境に入れてみた

VLCでHDMI経由の音声出力はできたのですが、HDMI映像出力がうまくいきませんでした。このため、VLCで受信したものをrtspサーバとして出力し、そのデータをkodi側で受け取るという実装にしました。

追加したもの

再生用にVLC

$ sudo apt install vlc vlc-plugin-sdl 

pythonでpipコマンドを使うために

$ sudo apt install python-pip python-setuptools

コンパイルをするために

$ sudo apt install build-essential python-dev

エラー解決のために

下記のエラー解決のために「sudo apt install libffi-dev」

    c/_cffi_backend.c:15:17: fatal error: ffi.h: No such file or directory
     #include <ffi.h>

「sudo apt install libssl-dev」

    build/temp.linux-armv7l-2.7/_openssl.c:498:30: fatal error: openssl/opensslv.h: No such file or directory
     #include <openssl/opensslv.h>

で・・・これでようやくstreamlinkインストールに成功しました。

「sudo pip install streamlink」

再生に至るまで

以下のような感じで、OSMCにログインした状態でコマンドを実行して、ポート8554にてrtspのストリーミングサーバを実行します。

$ streamlink https://www.showroom-live.com/ringo-005 best --player="cvlc --sout '#rtp{sdp=rtsp://:8554/}'"

ちなみに、streamlinkのマニュアルを見ると「–player-args」というオプションで引数を渡すことができるとありましたが、「streamlink https://www.showroom-live.com/ringo-005 best –player=cvlc –player-args=”–sout ‘#rtp{sdp=rtsp://:8554/}'”」を実行すると、以下のエラーになってしまって起動できませんでした。

osmc@osmc:~$ streamlink https://www.showroom-live.com/yui-010 worst --player=cvlc --player-args="--sout '#rtp{sdp=rtsp://:8554/}'"
/usr/local/lib/python2.7/dist-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.25.2) or chardet (3.0.4) doesn't match a supported version!
  RequestsDependencyWarning)
[cli][info] Found matching plugin showroom for URL https://www.showroom-live.com/yui-010
[cli][info] Available streams: 144p (worst), low, high, 1080p (best)
[cli][info] Opening stream: 144p (hls)
[cli][info] Starting player: cvlc
[cli][info] Closing currently open stream...
Traceback (most recent call last):
  File "/usr/local/bin/streamlink", line 11, in <module>
    sys.exit(main())
  File "/usr/local/lib/python2.7/dist-packages/streamlink_cli/main.py", line 1033, in main
    handle_url()
  File "/usr/local/lib/python2.7/dist-packages/streamlink_cli/main.py", line 594, in handle_url
    handle_stream(plugin, streams, stream_name)
  File "/usr/local/lib/python2.7/dist-packages/streamlink_cli/main.py", line 447, in handle_stream
    success = output_stream(plugin, stream)
  File "/usr/local/lib/python2.7/dist-packages/streamlink_cli/main.py", line 320, in output_stream
    output.open()
  File "/usr/local/lib/python2.7/dist-packages/streamlink_cli/output.py", line 24, in open
    self._open()
  File "/usr/local/lib/python2.7/dist-packages/streamlink_cli/output.py", line 221, in _open
    self._open_subprocess()
  File "/usr/local/lib/python2.7/dist-packages/streamlink_cli/output.py", line 242, in _open_subprocess
    args = self._create_arguments()
  File "/usr/local/lib/python2.7/dist-packages/streamlink_cli/output.py", line 203, in _create_arguments
    args = self.args.format(filename=filename)
KeyError: 'sdp=rtsp'
osmc@osmc:~$ streamlink https://www.showroom-live.com/yui-010 best --player="cvlc --sout '#rtp{sdp=rtsp://:8554/}'"
/usr/local/lib/python2.7/dist-packages/requests/__init__.py:91: RequestsDependencyWarning: urllib3 (1.25.2) or chardet (3.0.4) doesn't match a supported version!
  RequestsDependencyWarning)
[cli][info] Found matching plugin showroom for URL https://www.showroom-live.com/yui-010
[cli][info] Available streams: 144p (worst), low, high, 1080p (best)
[cli][info] Opening stream: 1080p (hls)
^CInterrupted! Exiting...
[cli][info] Closing currently open stream...
osmc@osmc:~$

続いて、拡張子が.m3uで、以下の内容をテキストエディタで作成します。

#EXTM3U
#EXTINF:-1 
rtsp://127.0.0.1:8554

このm3uファイルをkodiで開くとshowroom動画が再生されました。

Windowsのhostsにワイルドカードを使いたい(proxy.pacの活用)


OpenShiftの試験中、例えば、「osakana.local」というADドメインに参加しているクライアント端末から、テスト環境「apps.osakana.local」に作ったOpenShift上に作ったサービスにアクセスしようとする。

このとき、ADドメインの方に「*.app.osakana.local A 192.168.12.132」といったような感じでDNSレコードが登録されていれば特に問題はない。

しかし、テスト段階では、DNS登録がされていない場合がある。その場合、c:\windows\system32\drivers\etc\hosts にエントリを書くという手段があるが、hostsファイルにはワイルドカード記述を書くことはできないので、いちいち列挙していく必要があるし、管理者権限が必要になる。

権限が低くても対処する方法があるのか確認してたところ、ブラウザのproxy設定で自動構成スクリプトproxy.pacを設定する、という適用しやすい手法があった。

まず、下記記述のproxy.pacファイルを作成する。

function FindProxyForURL(url, host) {
  if (shExpMatch(host, "*.app.osakana.local")) {
    return "PROXY 192.168.12.132";
  }
  return "DIRECT";
}

上記ファイルをproxy設定の「自動構成スクリプトを使用する」のアドレス欄で指定する。

Windows10の場合「file:///~」といった記述をしなくても、そのままのドライブパスで問題なかった。

php.iniを変更せずにdisable_functionsの内容を無効化してroundcubeのアップグレードスクリプトを動作させる方法



/etc/php.iniでdisable_functionsに「system」を含めている場合、roundcubeのアップグレードを行う時に「./bin/installto.sh /var/www/roundcube」を実行すると、エラーとなってしまう。

# ./bin/installto.sh /var/www/roundcubemail
Error 500: PHP system() function is required. Check disable_functions in php.ini.
#

この際、/etc/php.iniを変更するのではなく、一時的に回避するための手法。
「php -d disable_functions=”” ./bin/installto.sh /var/www/roundcubemail」と実行することで、disable_functionsの設定に関しては無視して実行することができる。

# php -d disable_functions="" ./bin/installto.sh /var/www/roundcubemail
<略>

ネットワーク上にあるhpサーバのiLO IPアドレスとライセンスを収集するスクリプト


2019/01/09 追記

オリジナルのNachoTech Blogがアクセスできなくなっていたので、「https://github.com/osakanataro/findilos」にオリジナルと後述の改変版をアップロードした。


hpサーバをリモートから制御するために使用するiLO。
稼働させたあとにIPアドレスを確認するのがめんどくさい。
そういう場合に、総当たりでiLOのIPアドレスを確認するスクリプトがあった。

NachoTech Blogの「How to find all the iLO’s on your network」にあるfindilosである。

早速ダウンロードして実行してみる。

[root@adserver ~]# ./findilos 172.17.17.0/24<br>
Scanning...</p>
<p>--------------- ------ -------- ------------ -------------------------<br>
iLO IP Address  iLO HW iLO FW   Server S/N   Server Model<br>
--------------- ------ -------- ------------ -------------------------<br>
172.17.17.xxx   N/A    1.26     CN71xxxMxx   ProLiant DL360 G7</p>
<p>1 iLOs found on network target 172.17.17.0/24</p>
<p>[root@adserver ~]#

iLO HWのモデル名は拾ってくれない。
blogのコメントを確認していくと、元のスクリプトはiLO-2までしか対応しておらず、その後のバージョンについてはコメント欄にある修正を実施すれば良いようだ。

また、iLO Advanceを買っている場合に、そのライセンスコードを表示するための案も提示されていた。
ただ、スクリプト例は汚い実装となっていて、せっかくの元スクリプトを活かしていない形だったので、元スクリプトの実装に従ってライセンスを表示するバージョンを作成した。

その実行例がこちら

[root@adserver ~]# ./findilos 172.17.17.0/24<br>
Scanning...</p>
<p>--------------- ------ -------- ------------ ------------------------- -------------------- -----------------------------<br>
iLO IP Address  iLO HW iLO FW   Server S/N   Server Model              iLO Edition          iLO Licence Key<br>
--------------- ------ -------- ------------ ------------------------- -------------------- -----------------------------<br>
172.17.17.xxx   iLO-3  1.26     CN71xxxMxx   ProLiant DL360 G7         iLO 3 Advanced       xxxxx-xxxxx-xxxxx-xxxxxx-xxxxx</p>
<p>1 iLOs found on network target 172.17.17.0/24</p>
<p>[root@adserver ~]#

スクリプトの修正例は以下

#!/bin/bash<br>
#<br>
# findilos - Search a local network segment for iLOs<br>
#            The iLO is the Integrated Lights-Out management processor<br>
#            used on HP ProLiant and BladeSystem servers<br>
#<br>
scriptversion="1.0"<br>
#<br>
# Author: iggy@nachotech.com<br>
#<br>
# Website: http://blog.nachotech.com<br>
#<br>
# Requires: tr sed expr curl nmap<br>
#<br>
# Tested with: Nmap 4.20, curl 7.17.1, RHEL4<br>
#<br>
# Note: Discovery of an iLO is dependent upon the Virtual Media port<br>
#       being set to the default of 17988.  If this has been changed<br>
#       by the iLO administrator, then this script will NOT find it.<br>
#<br>
#       Also, if the iLO XML Reply Data Return has been Disabled by<br>
#       the iLO administrator, this script will not be able to<br>
#       gather any information about the server.  It will still be<br>
#       discovered, but all you will see is its IP address.<br>
#</p>
<p># GLOBAL VARIABLES</p>
<p>scriptname="findilos"<br>
iloips="/tmp/tmpilos.$$"<br>
iloxml="/tmp/tmpiloxml.$$"<br>
ilohwvers="/tmp/tmpilohwvers.$$"</p>
<p>declare -i ilosfound=0</p>
<p># FUNCTIONS</p>
<p>function parseiloxml {<br>
  fgrep "$1" $iloxml &gt; /dev/null 2&gt;&amp;1<br>
  if [ $? -ne 0 ]<br>
  then<br>
    # tag not found in xml output, return empty string<br>
    parsedstring="N/A"<br>
  else<br>
    # tag was found - now we parse it from the output<br>
    tempstring=$( cat $iloxml | tr -d -c [:print:] | sed "s/^.*&lt;$1&gt;//" | sed "s/&lt;.$1.*//")<br>
    # trim off leading and trailing whitespace<br>
    parsedstring=`expr match "$tempstring" '[ \t]*\(.*[^ \t]\)[ \t]*$'`<br>
  fi<br>
}</p>
<p>function is_installed {<br>
  which $1 &gt; /dev/null 2&gt;&amp;1<br>
  if [ $? -ne 0 ]<br>
  then<br>
    printf "\nERROR: %s not installed.\n\n" $1<br>
    exit 255<br>
  fi<br>
}</p>
<p># MAIN</p>
<p># check for tools that we depend upon</p>
<p>is_installed tr<br>
is_installed sed<br>
is_installed expr<br>
is_installed curl<br>
is_installed nmap</p>
<p># check syntax - should have 1 and only 1 parameter on cmdline</p>
<p>if [ $# -ne 1 ]; then<br>
  printf "%s %s ( http://blog.nachotech.com/ )\n" $scriptname $scriptversion<br>
  printf "Usage: %s {target network specification}\n" $scriptname<br>
  printf "TARGET NETWORK SPECIFICATION:\n"<br>
  printf "  Can pass hostnames, IP addresses, networks, etc.\n"<br>
  printf "  Ex: server1.company.com, company.com/24, 192.168.0.1/16, 10.0.0-255.1-254\n"<br>
  printf "EXAMPLE:\n"<br>
  printf "  %s 16.32.64.0/22\n" $scriptname<br>
  exit 255<br>
fi</p>
<p>iprange=$1</p>
<p># prepare lookup file for iLO hardware versions</p>
<p>cat &gt; $ilohwvers &lt;&lt; EOF<br>
iLO-1 shows hw version ASIC:  2<br>
iLO-2 shows hw version ASIC:  7<br>
iLO-3 shows hw version ASIC: 8<br>
iLO-3 shows hw version ASIC: 9<br>
iLO-4 shows hw version ASIC: 12<br>
iLO-4 shows hw version ASIC: 16<br>
i-iLO shows hw version T0<br>
EOF</p>
<p>#<br>
# scan a range of IP addresses looking for an<br>
# open tcp port 17988 (the iLO virtual media port)<br>
#</p>
<p>printf "Scanning..."</p>
<p>nmap -n -P0 -sS -p 17988 -oG - $iprange | fgrep /open/ | awk '{print $2}' &gt; $iloips</p>
<p>printf "\n\n"</p>
<p>#<br>
# open and read the list of IP addresses one at a time<br>
#</p>
<p>exec 3&lt; $iloips</p>
<p>echo "--------------- ------ -------- ------------ ------------------------- -------------------- -----------------------------"<br>
echo "iLO IP Address  iLO HW iLO FW   Server S/N   Server Model              iLO Edition          iLO Licence Key"<br>
echo "--------------- ------ -------- ------------ ------------------------- -------------------- -----------------------------"</p>
<p>while read iloip &lt;&amp;3 ; do<br>
  ilosfound=$ilosfound+1<br>
  #<br>
  # attempt to read the xmldata from iLO, no password required<br>
  #<br>
  curl --proxy "" --fail --silent --max-time 3 http://$iloip/xmldata?item=All &gt; $iloxml</p>
<p>  #<br>
  # parse out the Server model (server product name)<br>
  # from the XML output<br>
  #</p>
<p>  parseiloxml SPN;  servermodel=$parsedstring<br>
  parseiloxml SBSN; sernum=$parsedstring<br>
  parseiloxml PN;   ilotype=$parsedstring<br>
  parseiloxml FWRI; ilofirmware=$parsedstring<br>
  parseiloxml HWRI; ilohardware=$parsedstring</p>
<p>  ilohwver=$(grep "$ilohardware" $ilohwvers|awk '{print $1}')<br>
  if [ "$ilohwver" == "" ]; then<br>
    ilohwver="N/A"<br>
  fi</p>
<p>  if [ "$sernum" == "" ]; then<br>
    sernum="N/A"<br>
  fi</p>
<p>  # add start<br>
  curl --proxy "" --fail --silent --max-time 3 http://$iloip/xmldata?item=CpqKey &gt; $iloxml<br>
  parseiloxml LNAME; ilomodel=$parsedstring<br>
  parseiloxml KEY; ilokey=$parsedstring<br>
  # add end</p>
<p>  printf "%-15s %-6s %-8s %-12s %-25s %-20s %-30s\n" $iloip "$ilohwver" "$ilofirmware" "$sernum" "$servermodel" "$ilomodel" "$ilokey"</p>
<p>done</p>
<p>printf "\n%d iLOs found on network target %s.\n\n" $ilosfound $iprange</p>
<p>rm -f $iloips $iloxml $ilohwvers</p>
<p>exit 0

Windowsバッチファイルでping応答の違いで動作をかえる



Windowsバッチファイルで、指定IPアドレスから応答がなくなったら次の作業を実施する、という処理をやりたかったので作った。

普通にping実行時のERRORLEVELを見ればいいか、と思っていたが、試験した環境では応答があってもなくてもERRORLEVEL0だったので判別ができなかった・・・
調べたところ「otnx.jpのコマンド別/ping」に調査した結果と回避方法があったのでそれを使った。

ちなみにotnx.jpではfindで「bytes=32」を引っかけていたが、日本語環境だと「 バイト数 =32」になってしまうが、バッチには書きたくなかったので、その後ろにある「ms TTL=」の方を引っかけるようにした。

・停止待ちバッチファイル
応答がなかったら終了。
応答があったら3回繰り返す

@echo off

set COUNT=0

:error
set /a COUNT=COUNT+1
echo %COUNT%
if "%COUNT%" == "3" goto errorout
ping -n 1 IPアドレス | find "ms TTL=" > NUL
if ERRORLEVEL 1 goto notrespond
timeout /t 5  > nul
goto error

:notrespond
echo host stopped
goto end

:errorout
echo host not stop

:end

・起動待ちバッチファイル
ping応答がなかったら3回繰り返してみる

@echo off

set COUNT=0

:error
set /a COUNT=COUNT+1
if "%COUNT%" == "3" goto errorout
ping -n 1 IPアドレス | find "ms TTL=" > NUL
if ERRORLEVEL 1 goto error

echo host working
goto end

:errorout
echo host not working

:end