ReadyMedia + Reverse Proxy でDLNAを無理やり持ち出す

# 概要
自宅にある音声メディアを屋外で利用するにあたり、DLNAを持ち出すことを試した。
環境は限定されるが一応なんとか出来たのでその備忘録。

※DLNAはロケーション フリーを加味しておらず。
　応答速度が仕様含まれており、実質認められていない行為です。

# 環境構成と設定値例

|端末        |場所    |OS例                               | 役割           |host name       | Global IP | VPN IP    | Private IP |
|:-----------|:-------|:----------------------------------|:--------------|:---------------|:----------|:-----------|:-----------|
| Server (1) |自宅    | Cent OS 7 <br /> (Raspberry Pi 3) |DLNA Server    |                |           |192.168.5.2 |192.168.1.2 |
| Server (2) |レンタル| Cent OS 7 <br /> (レンタル)       |HTTP Gateway   |dlna.mydomain.org|available  |192.168.5.3 |            |
| Client     |屋外    | android / iPhone                  | Player      |                |           |            |            |


# 利用ツール
* ドメイン (Dynamic DNSでも普通に買うでも可)
* Server
 * Linux (Cent OS)
 * Apache Httpd
 * mod_substitute
 * ReadyMedia (miniDLNA)
 * Tinc VPN
* Client
 * foobar2000 (android / iOS)

# 手順
## 手順(1) ドメイン設定
Server(2)のグローバルIPとホスト名との紐付け設定をする。
(ドメイン レジストラとか、DDNSサービスのサイトとか)


## 手順(2) [Server(1)] ReadyMediaの構築
ローカルのサーバーにReadyMediaをインストールし、DLNAサーバーを構築する。
(構築方法は2^10番煎じのため省略)

## 手順(3) [Server(1), Server(2)] VPN構築
Reverse Proxyのため、サーバー間の相互通信を可能にしておくのが目的。
両サーバーが同一ネットワークにある場合は不要。
また、VPN構築もTinc VPN以外でも可能なため、割愛。
(と言うか、書くと長くなるので。。。)


## 手順(4) [Server(2)] Reverse Proxyの設定
本稿のメイン。
Virtual HostでReverse Proxyの設定を行う。
DLNAはサーバーとのやり取りはXMLで行われるが、
コンテンツへのパスにIPアドレスを含んだフルパスで返されるため、
Reverse Proxy越しでは、メディアに到達することが出来ない。
そのため、XML内に記載されているIPをアドレスをホスト アドレスに置換する。
サーバー間はVPNでの通信になるため、置換元のIPはVPNでのIPになる。

|項目|値|
|:--|:--|
|ホスト名| dlna.mydomain.org |
|転送先  | 192.168.5.2:8200 |


```apache:/etc/httpd/conf.d/httpd-vhosts.conf
<VirtualHost *:80>
  ServerName dlna.mydomain.org

  AddOutputFilterByType SUBSTITUTE text/xml
  Substitute "s|192.168.5.2:8200|dlna.mydomain.org|i"

  ProxyRequests Off
  ProxyPass / http://192.168.5.2:8200/
  ProxyPassReverse / http://192.168.5.2:8200/
</VirtualHost>
```

```shell:terminal
systemctl restart httpd.service
```

## 手順(5) [Client]
スマートフォン版 foobar2000を使用して聴く。

|項目|値|
|:--|:--|
|Client| foober2000 <br/> ([Google Play](https://play.google.com/store/apps/details?id=com.foobar2000.foobar2000), [App Store](https://apps.apple.com/app/foobar2000/id1072807669))|
|URL| http://dlna.mydomain.org/rootDesc.xml |

### 設定画面
![foober2000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72257/a2951910-cbcf-0a84-d1fa-5ffbdc85d21f.png)

### 画面サンプル
![foober2000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72257/44a432d1-ef7a-8b5c-1371-492ce8664309.png)


# 所感
* なかなかネットワーク越しにメディア ファイルを逐字再生する方法が無いので、ありがたい。
* ReadyMediaでプレイリスト ファイルが使えるので、PCでプレイリストを作成して垂れ流し出来るのは嬉しい。
* DLNAをURLで追加出来るクライアントはfoobar2000が唯一なので選択肢がない。
* しかし、foobar2000のGUIが悪すぎなので、そもそもDLNAクライアントとしても微妙。
  * BTやヘッドホンの切断で再生が停止するのをOFFに出来ない。。
  * 左右のスワイプは曲選(前の曲、後の曲)であってほしい、
* httpsやBASIC認証がかけられない、
  * セキュリティを上げたきゃport forwardingでlocalhostに置換とか？<br />(そこまでする？)
* BubleUPnPに比べたら、まだ使える方？
  * 読み込み前に曲送りをすると、画面と実際の曲がズレる阿呆バグがあるので、、、
  * UIもあまり変わらないし、、、
* もうPlexで良いじゃない？
* ただ、少ないリソースで簡単に導入出来た感はある。
* とりあえず、先日フラッシュ セールで買った500曲あたりをひたすら消化するのには良さそう


# 参考
・mod_substitute - Apache HTTP Server Version 2.4
https://httpd.apache.org/docs/2.4/mod/mod_substitute.html
・まったく違うIP/ホスト名でアクセスするための、リバースプロキシ用VirtualHost - Qiita
https://qiita.com/tkykmw/items/d7f07f26b89f923d57d5
・Apacheによる本文書き換え　mod_substitute + mod_filter - doodle-on-web
https://www.doodle-office.work/entry/mod_substitute_mod_filter
・mod rewrite - 逆プロキシされたホストへのHTTPリクエストでのApache mod_substitute - 初心者向けチュートリアル
https://tutorialmore.com/questions-757269.htm