スピーカーとアンプのインピーダンスの組み合わせ
結論
背景
スピーカーを更新しようかと思って色々と調べてると「インピーダンスがー」という話をチラホラと見かけた. 「発電所がー」のレベルであれば無視していいのだが,最悪スピーカーかアンプが故障するというのだから無視できない. そんな重要な問題にも関わらずオームの法則を使った中途半端な記事や, 逆に詳細すぎて結論としてどうしたらいいのか判然としない記事に多くぶつかったため,自分で問題を整理しようと思った.
カタログスペック
実例を元に故障しない使用範囲を計算する. 故障するかを考えるだけならインピーダンスの周波数特性など必要ないため, インピーダンスを直流抵抗として扱う. こうなるとほぼ中学校理科のレベルで議論ができる.
スピーカー
私が気になっているものと保有しているもののヤマハ製品を例に見てみる.
型番 | インピーダンス | 許容入力 | 最大入力 | 能率@1m | 構成 |
---|---|---|---|---|---|
NS-F901 | 6 ohm | 50 W | 200 W | 89dB/2.83V | フロアスタンディング |
NS-B750 | 6 ohm | 30 W | 120 W | 87dB/2.83V | ブックシェルフ |
NS-C500 | 6 ohm | 40 W | 160 W | 87dB/2.83V | センター |
これらが壊れるのは許容入力を常時超える電力もしくは,最大入力を瞬間的に超える電力が入力された場合になる. ではスピーカーに電力が入力される状況は?と問われれば当然,音を出す時である. すなわちスピーカーが無事かという問題はどこまでの音量 = 電力を入力してもいいのかという問題になる.
電力と音量の関係を能率を例に計算してみる. 今回のスピーカーは全て6 ohmのため,能率で示されている2.83 Vはから1.33 Wに相当する. つまり,
許容入力>30 Wに対してたった1.3 Wで87dBもの音量
が得られる. dBの値と実際の音はデノンのブログの下部の表が一番わかりやすいのだが, 87dBなどというのは家庭で聞く分には非常に大きな音に分類される. ということで近所迷惑にならない範囲で鳴らしていれば,音量由来でスピーカーが壊れることはまずない. そんな簡単に壊れてたらクレームの嵐で商売にならないのだから当然だろう.
参考として許容入力をスピーカーに投入したらどうなるかを計算しておこう, まず音の大きさを音のエネルギーで表す. と音の振幅の関係は音量の単位dBの定義に従うと以下のように変換できる.
ここでは音の基準音圧,はのエネルギーを表す. 能率で求めた1.33 W以上の投入電力が全て音に変換されると仮定する. 能率をとすればを入力した時の音量は次のようになる.
許容入力の最も小さいNS-B750のスペックを代入した時の音量は87dB + 10 log(30/1.33) = 100dBとなる. これはデノンによればライブハウスやカラオケの音量に相当する. こんなものを常用していればスピーカーの前に自分の耳やご近所関係が壊れる.
アンプ
同様にアンプも確認する.私はAVアンプを使用しているため,ヤマハのAVアンプを例にとる.
型番 | インピーダンス | 定格出力 | 定格出力時の電圧 | 実用最大出力 | ch数 |
---|---|---|---|---|---|
RX-S601 | 6 ohm | 60 W/ch | 19.0 V | 125 W | 5 |
RX-V4A | 6 ohm | 80 W/ch | 21.9 V | 145 W | 5 |
RX-A2A | 8 ohm | 100 W/ch | 28.3 V | 165 W | 7 |
上で計算した通りスピーカーは1.33 Wもあれば大音量で鳴るため,アンプを定格出力で稼働させることは通常はない. 誤って音量最大 = 定格出力にしてしまっても,上2つはインピーダンスが一致しているため明らかにスピーカーの最大入力以下に収まる.
では残るRX-A2Aを計算してみよう.定格出力時の電圧は28.3 Vになる.これを6 ohmのスピーカーにかけるとより133 Wと計算される. 残念ながらNS-B750の最大入力120 Wを超えてしまうため,間違ってボリュームを最大に振り切ることがないように注意が必要となる. さらには定格出力100 Wのつもりがスピーカー側のインピーダンスが低いために,想定以上の出力133 W (< 実用最大出力165 W)をしてしまっている.
音源のクリップ問題
音源の問題でスピーカーが破損することはあるらしい. マスタリングで限界まで詰め込まれた音源とかが危険なのかもしれない.
真空管アンプ
上で計算したのはあくまでスピーカーと半導体アンプの組み合わせで故障するかを議論しただけ. 真空管アンプの性能を引き出すには色々と考えるよう.
ImageJとpythonで粒子解析を自動化する
追記(2022/06/26)
自動化の難易度が高い画像を手動で分析する方法も投稿しました.
やったこと
ImageJを用いて粒子形状を自動で解析する初歩的な内容はこちらの方がまとめられている. ただ個人的には改善したい点もたくさんあって,
- もっとオブジェクト指向にしてコードの見通しを良くしたい
RoiManager
が表示されてると実行速度が絶望的に遅い- 同じく
IJ.run()
は裏でGUIを操作しているため速くない - 長さとか面積とかに単位が欲しい
ParticleAnalyzer
のオプションを色々弄りたい- 元画像のどこが粒子として認識されたか確認したい
とか色々ある.
このため前述の巨人の肩に乗りながら(コードを流用しながら),上記の要望を叶える方法を調べてコードを改変した.
なお少なくともImagePlus
とImageProcessor
の関係と使い方は理解していないと本コードを理解するのは苦労するため,
拙著を流し読みした方が良いかもしれない.
改変したpythonコード
import os from ij import IJ from ij.process import ImageProcessor from ij.plugin import Colors from ij.plugin.frame import RoiManager from ij.plugin.filter import ParticleAnalyzer, BackgroundSubtracter, EDM from ij.measure import ResultsTable, Measurements def main(imagefilepath): # 画像を開いてImagePlusを取得する imp = IJ.openImage(imagefilepath) # 1ピクセルが相当する実世界の長さを設定 # ImagePlusから該当するmetaデータを取り出して編集する cal = imp.getCalibration() cal.pixelHeight = 0.1 cal.pixelWidth = 0.1 cal.setUnit('um') # 忘れずにImagePlusに反映する cal.setImage(imp) # 背景を均一にする bs = BackgroundSubtracter() ip = imp.getProcessor() # 後でimp.setProcessor()すると戻せなくなるため # 無編集のデータも先に分けておく ip0 = imp.getProcessor().duplicate() # 背景の差引 # bs.rollingBallBackground(ColorProcessor, radius, createBackground, lightBackground, useParaboloid, doPresmooth, correctCorners) bs.rollingBallBackground(ip, 40.0, False, True, False, True, True) # 粒界を定める閾値を設定する # 第一引数で2値化のアルゴリズムを選択できる # ip.setAutoThreshold(method, darkBackground, lutUpdate) ip.setAutoThreshold('Default', False, ImageProcessor.NO_LUT_UPDATE) # 2値化した画像を取得 mask = ip.createMask() # 今回は粒界が離れているため省略 #EDM().toWatershed(mask) # 2値化していてもParticleAnalyzerのために閾値の設定は必要 mask.setAutoThreshold('Default', True, ImageProcessor.NO_LUT_UPDATE) # 粒子解析 # 粒子の輪郭をROIで保存する # 引数にTrueかFalseを与えるとウィンドウが表示されなくなって高速化できる # どちらを与えても同じで,どちらも与えないと表示される rm = RoiManager(False) # 解析結果の保存先 # こちらは何もしなくてもウィンドウは表示されない rt = ResultsTable() # 粒子解析する本体 # インスタンス化せずにクラスメソッドとして実行すると次のインスタンス化時に反映される ParticleAnalyzer.setRoiManager(rm) # インスタンス化 # 第一引数は解析方法の指定を行なっており2進数の和で表現されている # ただそれぞれ覚えていられないため次のようにクラス変数を参照する # 第二引数も同様に数値化する項目を指定できるが全部解析して後で省けばよし # 第4,5,6,7引数は解析対象とするそれぞれ最小面積,最大面積,最小円形度,最大円形度 # 工夫してノイズを除外すること pa = ParticleAnalyzer( ParticleAnalyzer.EXCLUDE_EDGE_PARTICLES + ParticleAnalyzer.INCLUDE_HOLES + ParticleAnalyzer.ADD_TO_MANAGER, Measurements.ALL_STATS, rt, 0., 1.e9, 0., 1, ) # 長さの情報をもつImagePlusと2値化画像のImageProcessorを渡す pa.analyze(imp, mask) # 保存 savefilepath = imagefilepath[:-4]+"_" rt.saveAs(savefilepath + "Results.csv") imp.setProcessor(mask) IJ.saveAs(imp, "bmp", savefilepath + "masks.bmp") rm.runCommand("Save", savefilepath + "Roi.zip") # 抽出した粒子の輪郭を描画する # 輪郭を黄色にする # 使いたい色の16進数表記を変換してColorsオブジェクトにする c = Colors().decode('#ffff00') # そのままだとグレースケールの画像になっている # そこに色を渡してもグレースケールに変換されてしまうため # 元の画像をRGBカラーに変換しておく ip = ip0.convertToColorProcessor() # やっと色を指定できる ip.setColor(c) # ROIそれぞれを描画するとImageProcessorに渡した色が使われる for roi in rm.getRoisAsArray(): ip.draw(roi) # ImagePlusに画像を反映して保存 imp.setProcessor(ip) IJ.saveAs(imp, "jpg", savefilepath + "AnalyzedResult.jpg") # close roi manager, results table and images rm.close() rt.reset() imp.close()
フォルダ内の画像に一括適用したいなら
この関数をos.walk
する.
ip.setAutoThreshold()
の第一引数は文字列で
他のアルゴリズムを与えられる.
解析した粒子を明示するのは重要で,自動化していると想定外な輪郭を取得される可能性もあり,それを簡単に確認できる必要がある.
初めて扱う種類の画像であればip.setAutoThreshold()
の第一引数を全て試して最適なアルゴリズムを選択するべきだろう.
なおRoiManager
を使っているとheadless
モードでエラーが出てRoiManager
のインスタンス化に失敗する.このため本コードはImageJのエディタから実行する必要がある.
ImageJ Fijiとpythonでフォルダ内の画像を一括処理
ImageJを使う理由
ImageJ Fijiとpython(Jython)を使って自動で画像処理する方法を調べたので,何段階かに分けて投稿していく. pythonならopencvとかあるのになんでImageJを選んだかといえば, 材料配合が主体の職場ではpythonの環境構築すらハードルが高く,部内配布が事実上不可能だから・・・. ImageJなら最悪GUIでtry-and-errorを繰り返せば誰でもそれらしい結果が得られるのも,画像処理を検討する雰囲気の醸成に役立つはず.
この記事で説明する内容
第一弾では画像の開き方と保存方法を確認した後,切り取り方法を確認する.
その後,上記を関数にまとめてフォルダ内の画像に一括処理する方針で進める.
なおGUIで頑張る方法はマウスポチポチしてればいいので一切説明しない.
光学顕微鏡とかSEMとかの画像が数十枚以上ある場合を想定.
そもそもpythonの文法についても知っていることを前提.
pythonのコード
コードの書き方
材料系の職場だと笑い事じゃなく,エディタがメモ帳しかない可能性が高い.
幸いにしてImageJにもエディタが付属しておりシンタックスハイライトくらいはできる.
ImageJを開いて,File>New>Text windowもしくはFile>New>Script...で起動できる.
なおこれで作業しているとデバッグは苦しい.
persistentにチェックを入れてコードを実行すると,実行完了時の環境から抜けずに止まる.
その状態でインタラクティブシェルとして変数を調査することになる.
ここではpdb
は機能しないため覚悟すること.
pdb
でのデバッグが必要であればコマンドラインからheadless
モードにて実行する必要がある(後述).
画像の開きと保存(と閉じ)
from ij import IJ from ij.io import Opener if __name__=='__main__': '''詳しいパラメータ等は下記の公式APIを参照. https://imagej.nih.gov/ij/developer/api/ij/ij/io/Opener.html ''' # 画像のパスを設定.絶対パスでなければエラー. # 今回はImageJに付属のサンプル画像をデスクトップに保存して利用. src = '/Users/OkazakiP/Desktop/AuPbSn40.jpg' # 画像を開く. imp = Opener().openImage(src) # 他の開き方.結果は同じ. imp = IJ.openImage(src) # 何も変更せずに保存.IJクラスは色々な便利メソッドの塊. IJ.saveAs(imp, 'jpg', '/Users/OkazakiP/Desktop/AuPbSn40_.jpg') # 使い終わったら片付ける. imp.close() # 作業完了の報告. print 'Finish.'
難しいことはないでしょう.
私のテスト環境がmacだからパス文字列が/
で区切られてるけど,windowsパスでも動くはず.
この程度でif __nam__=='__main__':
で始める意味はないが,
最後にこの部分(の派生系)を関数にまとめるため,インデントがあると微妙に楽.
Opener
の他にFileOpener
やFileSaver
なるクラスがあるが,
これらは事前にFileInfo
というクラスで画像の情報を与える必要があるため面倒そう.
IJ
だけ覚えれば十分だから理解するの諦めた.
スクリプトの最後には画像を明示的に閉じないと,backgroundで開きっぱなしになってしまうから注意.
画像の切り取り
from ij import IJ from ij.io import Opener if __name__=='__main__': '''ImageProcessorに対して作業をしていく. https://imagej.nih.gov/ij/developer/api/ij/ij/process/ImageProcessor.html ''' # 先ほどと同じく画像を開く.開くとImagePlusオブジェクトが返される. src = '/Users/OkazakiP/Desktop/AuPbSn40.jpg' imp = Opener().openImage(src) # ImagePlusが持つImageProcessorを取得する. ip = imp.getProcessor() # ImageProcessorに対して切り取り領域を指定. # 画像の原点は左上. # ip.setRoi(int x, int y, int width, int height) ip.setRoi(0, 0, 200, 200) # 切り取り.切り取り後のImageProcessorが返される. ip_ = ip.crop() # 切り取りの結果をImagePlusに反映する. imp.setProcessor(ip_) # 保存. IJ.saveAs(imp, 'jpg', '/Users/OkazakiP/Desktop/AuPbSn40_cropped1.jpg') # 違う位置で切り取り. ip.setRoi(200, 200, 200, 200) ip_ = ip.crop() imp.setProcessor(ip_) IJ.saveAs(imp, 'jpg', '/Users/OkazakiP/Desktop/AuPbSn40_cropped2.jpg') # 最初に取得したImageProcessorには何も変更がなされていない. imp.setProcessor(ip) IJ.saveAs(imp, 'jpg', '/Users/OkazakiP/Desktop/AuPbSn40_cropped0.jpg') imp.close() print 'Finish.'
突如現れるImagePlus
とImageProcessor
.
画像を開いた時に返されるのがImagePlus
でImageProcessor
はその中に含まれる.
ImageProcessor
は画素値を含む,いわゆる画像そのもの.
これに加えて画像のパスとか,1ピクセルあたり何umとかのmeta情報を合わせるとImagePlus
になる.
このため画像の切り取りは画素を相手にするためImageProcessor
を抜き取って操作する.
操作後の画像を保存するには上の画像を開く時に諦めたFileInfo
が必要となるため,
それを保持するImagePlus
に画素の情報を戻してから保存する.
フォルダ内の画像を一括処理
import os from ij import IJ from ij.io import Opener # 切り取りと保存を行う関数 def crop_image(src, output, x=0, y=0, w=200, h=200): imp = Opener().openImage(src) ip = imp.getProcessor() ip.setRoi(x, y, w, h) ip_ = ip.crop() imp.setProcessor(ip_) IJ.saveAs(imp, 'jpg', output) imp.close() if __name__=='__main__': folder = '/Users/OkazakiP/Desktop/Images' # 保存用のフォルダを同じ階層のConverted以下に作る parent = os.path.dirname(folder) result = os.path.join(parent, 'Converted') try: os.mkdir(result) except OSError: _result = result # 11回までは新しく作る for i in range(10): result = _result + str(i) try: os.mkdir(result) except OSError: continue break for root, dirnames, filenames in os.walk(folder): folder_name = os.path.basename(root) root_ = result + root[len(folder):] try: os.mkdir(root_) except: pass for filename in filenames: src = os.path.join(root, filename) output = os.path.join(root_, filename) # 画像以外が含まれてエラーを吐くことへの対策 try: crop_image(src, output) except: print 'Error on %s' % (src) print 'Finish.'
もはやImageJに特有の事項はなし.普通にos.walk
で関数を回すだけ.
自動処理の目的は果たせるけど,フォルダ選択はスクリプトを書き換える必要があってuser friendlyでない.
そこでフォルダ選択用のGUIをくっつける.
GUIでフォルダを選択する
import os from ij import IJ from ij.io import Opener, DirectoryChooser ... ... if __name__=='__main__': chooser = DirectoryChooser('一括処理したい最上位のフォルダを選択して下さい.') folder = chooser.getDirectory() # 次の行は誤植ではない.パスの末尾に区切り文字が付与されてしまうため必要. folder = os.path.dirname(folder) # 保存用のフォルダを同じ階層のConverted以下に作る parent = os.path.dirname(folder) result = os.path.join(parent, 'Converted') ... ... print 'Finish.'
変更がない部分は省略した.DirectoryChooser
を使うとGUIでフォルダが選択できる.
ただし末尾に区切り文字が追加されるため,そのままだと先のコードと挙動が変わってしまう.
これを避けるために一行追加している.
ばら撒くにはこれでいいけどさ?自分で使う分にはマウスポチポチも無駄じゃん?どうせなら全部コマンドで済むと楽じゃん?
フォルダをコマンドライン引数で受け付ける(headless
モード)
#@String folder import os from ij import IJ from ij.io import Opener ... ... if __name__=='__main__': # もはや不要 #folder = '/Users/OkazakiP/Desktop/Images' # 保存用のフォルダを同じ階層のConverted以下に作る parent = os.path.dirname(folder) result = os.path.join(parent, 'Converted') ... ... print 'Finish.'
一行目に追加した#@
で始まる分はScript parameterとかいうらしい.
こうするとコマンドラインから引数を渡せるようになる.ImageJはpython2系でargparse
がないから助かる.
sys.argv
?知らん.使ったことない.
さてこのスクリプトをコマンドラインからheadless
モードで実行するには次のようにする.
ここはOSによって異なるため公式のガイドを参照すること
>> cd Fiji.app/Contents/MacOS >> ./ImageJ-macos --ij2 --headless --console --run test_walk_parameter.py 'folder="/Users/OkazakiP/Desktop/Images"'
今回は追加しなかったが,関数crop_image
に渡す引数を全て#@int x
などとしてコマンドラインから渡すことも可能.
このheadless
という割には起動時のヘッドが激重.headless
モードであればpdb
を用いてのデバッグも普通に実行できる.
なおheadless
モードでは使えない機能も存在するため注意.要するにGUIに依存するタイプ.
ウィンドウ非表示ならいけるか?と思ったらそんなことなかったからタチ悪い.
所感
ImageJ APIが死ぬほど分かりにくい.pythonの標準モジュールや,デファクトスタンダード化してるモジュールのリファレンスは本当に関心する.
ただしmatplotlib
,お前はダメだ.
windowsにOpenSSHサーバを立てた
やったこと
- windows10の標準機能となったOpenSSHの有効化
- Windows Subsystem for Linux(WSL)のOpenSSHも使えるようにした
- VNCでMacやiPadからwindowsの画面を表示できるようにした
Jupyterサーバとして動く! ……はず!
環境
- Windows10 Home
- iPad Pro11
- MacBook Pro(Catalina)
ことの始まり
VRゲームに興味があって
比較的上位なGPUを積んだwindows機を購入した.
よくよく考えてみればまともなGPUがあるということは
ディープラーニングも捗ると気付いたため,
windowsにjupyterサーバを立てることにした.
ただ私はmacに慣れきっていてwindowsのゴミUIが操作しにくいため,
windowsのjupyterサーバにMacからデータを投げる方針とした.
実作業
PythonやTensorflow,Cudaの導入は特に難しいことはないため省略.
特にTensorflowのドキュメントが非常に分かりやすく素晴らしかった.
microsoftも見習え.
この記事を書いている2020年2月現在,
KerasがPython3.6までにしか対応していない.
このKerasが便利そうなのでPythonのバージョンは3.6をインストールした.
標準のOpenSSH
インストール
一応microsoftの分かりにくい公式ドキュメントに全部書いてある.
簡単で間違えようがない方法が分かりにくく平文で書いてあって,
おそらくPowershellを推すために,
とっつきにくい方法をダラダラと丁寧に書いてある.
GUI経由でwindowsの設定からインストールしてしまうのが吉.
初期設定
Powershellでのインストールは何をしているか少し分かりにくい一方で,
ファイアウォールや常駐サービス化の初期設定はPowershellの方が確実.
これら設定をGUIでポチポチ探していくのは私には辛かった…….
ドキュメントのコピペで放っておくとポート22を使用することになってしまうため,
sshd_configでポートを弄った後にでも他の設定を追加しておく.
詳細設定
何故公式はここまでしか載せていないのか.
SSH入れたらまずはsshd_config
弄ってポート変更とパスワード認証の禁止をするでしょ.
そしてsshd_config
の場所は公式には見当たらない.
というか日本語でこの点を明記してあるページもここ以外見つからない.
こちらの情報をありがたく拝謁すれば,
C:\ProgramData\ssh\sshd_config
にあると分かった.
そこで以下の設定を管理者権限で編集する.
#Port 22
→Port "他と被らないポート"
#PermitRootLogin without-password
→PermitRootLogin forced-commands-only
#MaxAuthTries 6
→MaxAuthTries 1
#MaxSessions 10
→MaxAuthSessions 2
#PubkeyAuthentication yes
→PubkeyAuthentication yes
#PermitEmptyPasswords no
→PermitEmptyPasswords no
Match Group administrators
の下のAuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys
→AuthorizedKeysFile .ssh/authorized_keys
特に管理者ユーザで作業している場合,
最後を忘れると鍵認証方式での接続がいつまで経ってもできない.
続いて公開鍵の設定.
C:\Users\USERNAME\.ssh\authorized_keys
にSSHクライアントの公開鍵を記載する.
上で管理者グループの公開鍵の設定を変えなかった場合はそちらにも記載する.
以上の設定をしてからサービスなりコマンドラインなりからOpenSSHを再起動する.
他の端末から鍵認証方式でSSH接続できることが確認できたら
パスワード認証を完全に排除する.
再びsshd_config
に戻って
#PasswordAuthentication yes
→PasswordAuthentication no
としてパスワード認証を禁止してしまう.
WSLのOpenSSH
microsoft storeからUbuntuをインストールすれば後の設定はunix系そのもの.
……ではなかった.
wslではパーミッションの基本設定がwindows準拠で通常のunixと異なるため,
ただのubuntuと思って設定するとSSH接続できない .
(windowsにSSH接続してからwslなりubuntuなりbashなりで起動はできる)
wsl上のtmuxを使うつもりのため,一応直接wslに接続できるようにしておく.
パーミッションの設定
おとなしくこちらに従う.
パーミッション既定を変えるファイルにsudo service ssh restart
も一緒に仕込んでおけば
windowsを再起動してもこのファイルを実行するだけでsshdとパーミッションを戻せる.
OpenSSHの設定
パーミッションさえクリアしていればこのまま.
起動が確認できたら/etc/ssh/sshd_config
と
~/.ssh/authorized_keys
を編集してsshdを再起動.
VNCサーバ
Ultra VNCでも入れればよし.
iPadからの接続はJump Desktopが便利.
Macからはfinderで⌘+Kのサーバへ接続でvnc://windowsのip:5900
とすれば
windowsのデスクトップが表示できるはず.
MacでVNCクライアントをフルスクリーンにすると
magic trackpadのスワイプだけでMacとwindowsを切り替えられて便利.
感想
SSHサーバを立てたいまともな人間はwindowsやwslで誤魔化さずに
最初からlinux機を準備しているんだなあと感じるほどまともな情報が見当たらなかった.
出勤中の業務と在宅時のゲーム以外でwindowsを触る機会が減って精神衛生的にいい.
microsoftは機械翻訳&たらい回しのクソドキュメントを修正しろ.
MinimServerにVPN経由でリモートアクセスする
やったこと
DLNAサーバー立ち上げの手順
MinimServerのインストール
公式HPの通り。
- NASのWEBデスクトップにログイン
- App Centerを起動
- MinimServerを検索してインストールボタンを押す
- JREが未インストールの場合は自動でインストールされる
- 以前にMinimServer用にJRE_ARMをインストールした場合は削除する
- マイアプリでMinimServerの起動を確認する
- MinimServerの開くボタンを押す
- ライセンスを承認する
MinimServerの設定
- MinimServerの設定ページが開かれるので、音楽ファイルを保存しているフォルダの最上位を指定する。
保存先が
music
の場合、/share/music
と入力してUpdateボタンを押す。 - NASにSSH接続する。adminである必要はない。
cd /share/CACHEDEV1_DATA/.qpkg/MinimServer/bin
する。
ただしCACHEDEV1_DATA
はNASの構築状態によって異なるらしい。
configファイルを直接編集しても反映されない上に、
MinimServerの起動すらできなくなることがあるので絶対にやってはいけない。mscript -i
でMinimServerのインタラクティブコンソールに入るprop excludePattern=@Recycle, 除外したいフォルダ名が含む文字列, 除外したいファイル名が含む文字列
- Enterを押してインタラクティブコンソールを抜ける
vi ../data/minimserver.config
minimserver.udn =
以降の文字列をコピーする
リモートからMinimServerにアクセスする手順
通常、DLNAはローカルLAN内でしか機能しない。
これはDLNA通信の始まりがマルチキャストパケットであり、こいつが普通にはルータの壁を越えられないからだ。
VPN接続してようがリモートからのマルチキャストパケットはDLNAサーバに届かない。
ただしこれは自動でDLNAサーバと接続する場合の問題。自動がダメなら手動で接続してしまえば良し。
そんな芸当ができるiOSアプリとして、今回は8player Proを購入して使う。
昔はPlugPlayerなるアプリでもできたらしいが、2019年現在はApp Storeにない。
MinimServerと同じLAN内で作業できる場合
公式通り。英語を読む以上の苦労はない。
リモートからMinimServerを探さざるを得ない場合
本記事を書いてる今の私のような奇特な人間の道標。
帰省前にルータ交換して色々と設定変わったらリモートアクセスできなくなった。
mscript
を使う方法を知らず、直接configファイルを弄ったら起動すらしなくなって、
最終的に再インストールする羽目になる人間はそういないんじゃないか・・・。
- Settingsをタップ
- Remote Accessをタップ
- Addをタップ
- Nameは好きな名前を付ける。
URLにhttp://NASのIPアドレス:9791/minimserver.udn以降の文字列/Upnp/device.xml
を入力 - Saveして✔︎
これでMinimServerにVPN経由でリモートアクセスできる。
上記のxmlファイルのURLさえ分かっていればMinimServerに限らずどんなDLNAサーバでも接続は可能なはず。
私のようにサーバ再インストールとかしなければ、
8player Proに片っ端からDLNAサーバを記憶させておけば出先でも困らない。
QNAP 231PにAdGuard Homeを導入した
環境
- QNAP 231P
要約
- arm-x41用のqpkgをダウンロード
- インストール
- ナビに従って初期設定
- AdGuard Homeを停止
- QNAPにssh接続
- 各種ファイルを変更
- dnsmasqを再起動
- AdGuard Homeを起動
実作業
やったことはQNAPのフォーラム(英語)を
忠実に実行しただけ。なんだけどトップの通りではほぼ使えない。
なぜならデフォルトでAdGuard Home(以下、AGH)はポート16553への問い合わせに応答するが、私の知る限りDNSサーバのポートまで設定できるマシンはないから。一般的にDNSサーバはポート53で稼働している。このためマシンにDNSサーバのIPアドレスを指定すると、マシンは設定したIPアドレスのポート53に問い合わせる。ところがQNAPにインストールしたAGHはポート53以外で稼働しているため、マシンがQNAPのポート53に問い合わせても応答がないわけだ。
このポート問題に対応するためにフォーラムに従ってQNAPの設定ファイルを弄った。ページ中程、2018年10月21日の回答によるとQNAPでデフォルトでポート53を使用しているdnsmasqを他のポートに移動、その後AGHをポート53で稼働させる。
arm-x41用のqpkgをダウンロード
このページを参考にダウンロードすべきqpkgのバージョンを確認する。QNAP 231PであればQNAP arm x41に該当する。バージョンを確認できたらQNAP CLUBからqpkgをダウンロードする。
インストール
ナビに従って初期設定
アプリを起動して言われるがままに設定。フォーラムではAGHの設定ページはポート9638とか書いてあるけど、この初期設定で自由に変更できる。DNSサーバとしてのポートは使用中と怒られない好きな数字を設定する。どうせ後で変更するから何でもいい。
AGHを停止
はい、私はここを読み落として苦戦してました。どうにも稼働中のアプリは、インストール先(/share/CACHEDEV1_DATA/.qpkg/
)とは別の場所(/opt/
)にコピーもしくはリンクを貼られて変更できないようで、私は必死に/opt/
のコピーを弄っていたため設定を変更できなかった。今から考えると書き込み時にそれっぽいログが表示されていた気がする。ログを読まずに痛い目にあったり解決が遅れるのは何度も経験してるのに、英文だと全然読むする習慣ができない、読んでも理解できない。
QNAPにssh接続
一時的にadminを有効化して、adminでssh接続
各種ファイルを変更
まずはAGHのポートの待ち受けポートを53に変更する。vimでファイルを開いて、
vi /share/CACHEDEV1_DATA/.qpkg/AdGuardHome/AdGuardHome.yaml
以下を設定する。
port: 53
protection_enabled: true
続いてプリインストールされているdnsmasqの設定を変える。
vi /etc/dnsmasq.conf
port = 1053
最後に次の設定を行う。
vi /etc/resolv.conf
nameserver = 127.0.1.1:1053
dnsmasqを再起動
killall -9 dnsmasq
dnsmasq
ユーザ名かユーザグループが正しくないと怒られたが私の場合は動いている。sshでの操作は終わりなのでログアウト、adminを無効化する。
AGHを再起動
Appセンターから起動すると無事、ポート53で稼働するようになっている。ルータもしくは各マシンのDNSサーバとしてQNAPのIPアドレスを設定すれば完了。
Macの画面共有にiPadからアクセスした
要約
実行環境
接続 | マシン | OS |
---|---|---|
先 | MacBook Pro 13inch(mid 2014) | Catalina |
元 | iPad Pro 11(2018) | iOS 13.2.3 |
やったこと
失敗したこと
書かないこと
本題
何を何故やったのか
外出先からMacを触りたくなった時のために画面共有を設定した. Macの画面共有が使うVNCプロトコルは暗号化がされないため, そのまま使用するとどんな作業をしているか丸見えで恐ろしい. いくら自宅LAN内でファイアウォールに守られていようが, WiFiを使っていると結構不安になる. そもそもログインする時のユーザ名とパスワードがどんな状態で送信されてるのか.
対策としてVNC over SSHという方式で通信の安全性を高めた. SSHで暗号化と改竄防止を担保したトンネルを確立, その安全なトンネルにVNCプロトコルを通すと作業内容は秘匿できる. 本当はSSHのポートフォワード以外からは画面共有を受け付けないようにしたかったが, 調べても全く分からなかった. 仕方がないのでデフォルトポートの変更で我慢中.
前提としてiPadからMacへの鍵認証SSH接続は設定済み. 外出先からアクセスするためのVPNサーバも構築済みだ.
MacのSSHとVNCのポートをデフォルトから変更
MacのSSH, VNCサーバを起動する前にやっておくべき. 鍵認証やパスワードで堅牢な守りを立てるのは当然だが, それでも不正アクセスを試みられたログはそこそこ残って精神衛生的に悪い. ポートも変えてしまった方が足跡も激減して安心できる. Macでのポートの変え方はこちらを参考にした.
調べていると*.plistを変えないといけないと書いているページもあるが,
私の場合は/etc/services
の変更だけで動作している.
SSHは上のページの通りでいいが,VNCは
rfb 5900/tcp vnc-server # VNC Server
rfb 5900/udp vnc-server # VNC Server
を
rfb xxxx/tcp vnc-server # VNC Server
rfb xxxx/udp vnc-server # VNC Server
と変える.xxxxには49152–65535の間から好きな数字を入れる.
よくポートには1024以降の数字を指定すると書いてるページがあるが,
wikipediaを見ると
1024–49151も何かしら使われてたりする.
被って不具合が出ても嫌だから49152–65535から選ぶと良さそう.
iPadからMacへ鍵認証方式でSSH接続を設定
よしなに.自分はBlinkを使ってssh-keygenした.
iPadにVNCクライアントを導入
JUMP DESKTOPならVNC over SSHを使えて かつRSA暗号化鍵が使えた. 設定は特に難しいこともなく,最初にVNC接続の設定を作ってから 改めて編集でsshトンネルを追加する.
ただ秘密鍵の登録で困ったことがあった. Blinkで生成した秘密鍵をコピペしようとしても受け付けてくれなかったのだ. 苦肉の策でBlinkから秘密鍵をiCloudフォルダにコピー, その後MacのFinderでJUMP DESKTOPのフォルダに秘密鍵を移動した. 秘密鍵がクラウドを経由(同期が間に合ったかは知らないが)しているのが気持ち悪かった.
Macで画面共有とリモートログインをオンにして接続
何も苦労なく繋がった. 接続は簡単だが,Macで画面共有にかけたはずのパスワードが確認されないわ, 秘密鍵のパスフレーズが2回目以降は確認されないわで 期待したセキュリティになっているかは怪しい. 後者についてはパスフレーズに嘘の文字列を登録しておくと 接続時に正しいパスフレーズを確認される.
失敗
scpでのファイル転送
RSA暗号化鍵が使えないVNCクライアントの購入
このページを参考にRemoter Proを購入して秘密鍵をコピペしようとしたら
iPadでSSH&VNCを使ったリモート・デスクトップ環境構築
暗号化はDES-EDE3-CBCしか受け付けてくれない.
簡単に調べたところDESは暗号強度が低いからRSAに変えるべきらしく,今回のセキュアなVNCの目的からしたら論外.(暗号方式ついてはよく分かってないので違ったら教えて下さい)
以上