PowerShellでポートが空いているかチェック


PowerShellの「Test-NetConnection」使って指定したポートがアクセスできるかを確認することができる。

ただ、細かいあたりは指定できないようで、タイムアウト待ち時間やリトライ回数の指定などはできない。標準だと10秒待つようです。

雑に、192.168.1.1~192.168.1.254の範囲でssh用のポート22番が空いているものがあるかを確認するものとして以下を書いた。

for ($count=1; $count -lt 255; $count++){
    $ipaddr="192.168.1."+$count
    if( (Test-NetConnection $ipaddr -port 22).TcpTestSucceeded -eq "True"){
        Write-Host $ipaddr
    }
}

ただ、アクセスできなかった場合、下記の様に「警告」が出力される作りになっている。

警告: TCP connect to (192.168.1.10 : 22) failed
警告: Ping to 192.168.1.10 failed with status: TimedOut

探せば警告を抑止する手法もありそうですが、面倒なので省略しています。


Test-NetConnectionを使う限りはカスタマイズできないので「Test network ports faster with PowerShell」にていくつか例が提示されています。

その1

function testport ($hostname='yahoo.com',$port=80,$timeout=100) {
  $requestCallback = $state = $null
  $client = New-Object System.Net.Sockets.TcpClient
  $beginConnect = $client.BeginConnect($hostname,$port,$requestCallback,$state)
  Start-Sleep -milli $timeOut
  if ($client.Connected) { $open = $true } else { $open = $false }
  $client.Close()
  [pscustomobject]@{hostname=$hostname;port=$port;open=$open}
}

testport

hostname  port  open
--------  ----  ----
yahoo.com   80  True

その2

Param([string]$srv,$port=135,$timeout=3000,[switch]$verbose)

# Test-Port.ps1
# Does a TCP connection on specified port (135 by default)

$ErrorActionPreference = "SilentlyContinue"

# Create TCP Client
$tcpclient = new-Object system.Net.Sockets.TcpClient

# Tell TCP Client to connect to machine on Port
$iar = $tcpclient.BeginConnect($srv,$port,$null,$null)

# Set the wait time
$wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)

# Check to see if the connection is done
if(!$wait)
{
    # Close the connection and report timeout
    $tcpclient.Close()
    if($verbose){Write-Host "Connection Timeout"}
    Return $false
}
else
{
    # Close the connection and report the error if there is one
    $error.Clear()
    $tcpclient.EndConnect($iar) | out-Null
    if(!$?){if($verbose){write-host $error[0]};$failed = $true}
    $tcpclient.Close()
}

# Return $true if connection Establish else $False
if($failed){return $false}else{return $true}

Windows10とLinuxの両方で動くPowerShellスクリプトの考慮点


https://github.com/osakanataro/showroom-live のPowerShellスクリプトを作っている際に問題となった点のメモ書きです。

その1:改行コード

改行コードはWindows10ならCR+LF、LinuxならLFにする必要がある。それぞれ逆だとエラーになった。

コードを共有するのであれば、git for Windowsを使って管理し、Windowsに持ってくる時に改行コードを変換するようにした方が良い。

github上でreleaseとしてzipを提供する場合は、github側の機能でzipを作ると改行コードがLFになるので、Windowsユーザ向けに改行コードをCR+LFにしたバージョンを追加でアップロードした方が良い。

その2:文字エンコーディング

Windows10上のVisual Studio Codeで日本語文字列を含んで保存したところ、UTF-8 BOMなしで保存され、それをLinuxに持って行ったところ問題無く動作した。

しかし、UTF-8 BOMなしのファイルをWindows10上のPowerShell ISEで開くと文字化けする。

PowerShell ISEではUTF-8 BOMありを想定しているということで、BOMありに変えてみたところ、Linux上では「#!/usr/bin/pwsh」の#!より前にBOMのコードが挿入されてしまうため問題が発生した。

Windows10標準notepadなどでの編集には全く問題なく、PowerShell ISEのみの問題であるため、PowerShell ISEでの編集を諦め、UTF-8 BOMなしとした。

その3:ファイル名の取り扱い

まず、WindowsとUNIXでパス名の「\」と「/」の違い問題がある。

また、日本語文字列を使いファイル名を作成しようとした場合、許可される文字列がどの範囲かという判定が必要になったりする。

クロスプラットフォームで確実に動作させることを考えた場合は、いわゆるASCII文字だけでファイル名を構成した方が無難である。

その4:ParsedHtmlは使えない

Invoke-WebRequestで取得したWebページをParsedHtmlで解析して使用する、ということが出来るのは、Windows上でInternetExplorerコンポーネントを使える場合のみで、PowerShell Core環境では使えない。

このため、地道にパース処理を実装する必要がある。

その5:他のコマンド実行処理

PowerShellスクリプト内から、他のコマンドを実行するための処理として「Start-Process」というのがある。

ただ、実験してみた限りでは、Windows環境でDOSコマンドを実行する場合、Start-ProcessではPowerShellを実行した画面と同じ場所にDOSコマンドの出力内容をそのまま出力させることができなかった。(-Wait -PassThru -NoNewWindowをつけてもダメだった)

Windows環境の場合、PowerShell内から「cmd /c」を利用してDOSコマンドを実行した場合はPowerShellを実行した画面と同じ場所にDOSコマンドの出力内容を表示させることができた。

それに対して、Linux環境ではStart-Processを「-Wait -PassThru -NoNewWindow」オプション付きで実行することで通常のコマンドの出力内容をそのまま表示させることはできた。

その6:機種依存処理の条件分け

その3、その5のような機種依存処理をどのように実行するかについては「[Environment]::OSVersion.Platform」を利用した。

どのような文字列が取得できるかという点については「PlatformID Enum」にあるように「MacOSX」「Unix」「Win32NT」の3種類(他にもあるけど過去のモノなので無視)

MacOSXとUnixの処理はだいたい似たようにできるので、「Win32NT」の場合を検出した方がよさそうだったので、下記の様な処理を書いた。

    if([Environment]::OSVersion.Platform -eq "Win32NT"){
        cmd /c $streamlinkcmd $streamtypes $liveurl $quolity $streamlinkoption $streamlinkfilename
    }else{
        Start-Process -FilePath $streamlinkcmd -ArgumentList $streamtypes,$liveurl,$quolity,$streamlinkoption,$streamlinkfilename -Wait -PassThru -NoNewWindow
    }

ブラウザを開かずにshowroomを視聴する


ブラウザを開かずにshowroom liveを視聴する方法はないかなぁ・・・と調べて見たら、livestreamを使い視聴するためのscriptを発見。fcicq/showroomlive.sh

ただ、これはそのままではshowroomの仕様変更に対応しておらず使えない。また、livestreamは現在メンテナンスされておらずstreamlinkを使え、と書いてある。

streamlinkはpythonインストールとか考えなくても使えるようなWindows用バイナリが用意されているため、簡単に実験ができそうだったので試してみた。

とりあえずstreamlinkをインストールして、showroom liveの配信やってるページに出てくる.m3u8ファイルを与えてみると・・・

C:\Program Files (x86)\Streamlink\bin>streamlink.exe https://edge-210-140-227-26.showroom-live.com/liveedge/52e66cae6b58a08641bd702e091c7f94fee147899da1a714c38312bab75ea7f0/chunklist_w791438536.m3u8
[cli][info] Found matching plugin hls for URL https://edge-210-140-227-26.showroom-live.com/liveedge/52e66cae6b58a08641bd702e091c7f94fee147899da1a714c38312bab75ea7f0/chunklist_w791438536.m3u8
Available streams: live (worst, best)

C:\Program Files (x86)\Streamlink\bin>

高画質(best)/低画質(worst)の選択を求められた。

C:\Program Files (x86)\Streamlink\bin>streamlink.exe https://edge-210-140-227-26.showroom-live.com/liveedge/52e66cae6b58a08641bd702e091c7f94fee147899da1a714c38312bab75ea7f0/chunklist_w791438536.m3u8 worst
[cli][info] Found matching plugin hls for URL https://edge-210-140-227-26.showroom-live.com/liveedge/52e66cae6b58a08641bd702e091c7f94fee147899da1a714c38312bab75ea7f0/chunklist_w791438536.m3u8
[cli][info] Available streams: live (worst, best)
[cli][info] Opening stream: live (hls)
error: The default player (VLC) does not seem to be installed. You must specify the path to a player executable with --player.
[cli][info] Closing currently open stream...

C:\Program Files (x86)\Streamlink\bin>

VLCを使って動画再生を開始しようとしたが、VLCがインストールされていないため失敗した。

そこでVLCをインストールしてから再度実行してみると、こんどはVLCアプリが起動して再生が始まった。

C:\Program Files (x86)\Streamlink\bin>streamlink.exe https://edge-210-140-227-26.showroom-live.com/liveedge/52e66cae6b58a08641bd702e091c7f94fee147899da1a714c38312bab75ea7f0/chunklist_w791438536.m3u8 worst
[cli][info] Found matching plugin hls for URL https://edge-210-140-227-26.showroom-live.com/liveedge/52e66cae6b58a08641bd702e091c7f94fee147899da1a714c38312bab75ea7f0/chunklist_w791438536.m3u8
[cli][info] Available streams: live (worst, best)
[cli][info] Opening stream: live (hls)
[cli][info] Starting player: "C:\Program Files\VideoLAN\VLC\vlc.exe"
[cli][info] Player closed
[cli][info] Stream ended
[cli][info] Closing currently open stream...

C:\Program Files (x86)\Streamlink\bin>

(上記のログはVLCの終了までを含む)

さらにいろいろ実験中、うっかりとstreamlinkに対してルームのURLそのものを渡してしまったところ、何事もないかの表示表示された。

C:\Program Files (x86)\Streamlink\bin>streamlink.exe https://www.showroom-live.com/sena-hiiragi
[cli][info] Found matching plugin showroom for URL https://www.showroom-live.com/sena-hiiragi
Available streams: 144p (worst), low, 360p, high (best)

C:\Program Files (x86)\Streamlink\bin>
C:\Program Files (x86)\Streamlink\bin>streamlink.exe https://www.showroom-live.com/sena-hiiragi best
[cli][info] Found matching plugin showroom for URL https://www.showroom-live.com/sena-hiiragi
[cli][info] Available streams: 144p (worst), low, 360p, high (best)
[cli][info] Opening stream: high (rtmp)
[cli][info] Starting player: "C:\Program Files\VideoLAN\VLC\vlc.exe"
[cli][info] Player closed
[cli][info] Stream ended
[cli][info] Closing currently open stream...

C:\Program Files (x86)\Streamlink\bin>

「Opening stream: high (rtmp)」となっているが、この形式はFlash Video形式となる。デフォルトでは「”rtmp,hls,hds,http,akamaihd,*”」という順序で優先順位を決めているので、MPEG4-TS形式で受信するには「–stream-types=hls」オプションをつけてhlsを指定する必要がある。

C:\Program Files (x86)\Streamlink\bin>streamlink.exe --stream-types=hls https://www.showroom-live.com/sena-hiiragi best
[cli][info] Found matching plugin showroom for URL https://www.showroom-live.com/sena-hiiragi
[cli][info] Available streams: 144p (worst), 360p (best)
[cli][info] Opening stream: 360p (hls)
[cli][info] Starting player: "C:\Program Files\VideoLAN\VLC\vlc.exe"
[cli][info] Player closed
[cli][info] Stream ended
[cli][info] Closing currently open stream...

C:\Program Files (x86)\Streamlink\bin>

よくみたら「streamlinkのpluginページ」にshowroomが対応していると掲載されていた。

他にabematv、 bilibili、 nhkworld、pixiv(sketch)が掲載されていて興味深い。

で・・・ここで調べたことを元に、showroom liveで目的とするルームの配信が始まったらVLCを起動して視聴開始するためのPowerShellスクリプトを実装してみた。

https://github.com/osakanataro/showroom-live

なぜPowerShellで組んだかといえば、WindowsとLinuxの両方で同じスクリプトを使いたかったからですね。

プラットフォームの違いを考慮しなければならない点がいくつかありましたが、まぁなんとかなりました。

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


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

streamlinkから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動画が再生されました。

RAPIDSについてのメモ


あとで職務で関係しそうな気もするので、メモとして残しておく・・・

ブリュッセルで開かれたオープンソース系のイベントFOSDEM2019でnVidiaによる「RAPIDS : Data Science on GPUs」という講演があり、その講演動画とスライドpdfが公開されてる。

ざらっと内容を流し読んでみたところ、以下であるという理解。

AI処理などでGPU上で処理させる時、1つの処理だけでは終わらず次の処理にデータを回す際、一度メインメモリにデータを持ってきてから次の処理のデータを渡しているのが現状。

これを「Apache Arrow 」というのを使って、GPU上のメモリにデータを残しながら次の処理にうつれるようにする、データサイエンス向けのプラットフォームが「RAPIDS」 という感じのようだ。

common data layer
(Apache Arrowsのページより引用)