【備忘録】RTMPサーバーを構築する方法

準備

初めに使用するサーバーはUbuntu 20.04 LTS conoha の環境で進めていきます。

コンソールを開き

sudo apt update && sudo apt upgrade -y

を実行し、一応再起動してください。

次に

sudo apt install nginx libnginx-mod-rtmp

設定

お好きなエディタで /etc/nginx/nginx.conf を開き以下の内容を好きな場所に追加します。

rtmp {
  server {
    listen 1935;
    chunk_size 4096;
    application live {
      live on;
      hls on;
      hls_path /var/www/html;
      hls_fragment 5s;
    }
  }
}

設定を保存して再起動すれば

OBS等のソフトからライブを始められるはずです。

rtmp://{IP}:1935/live/{好きな名前}

視聴も↑か、 /var/www/html ないにある {好きな名前}.m3u8 を参照してください。

 

認証機能

ここから本題・・・。

テーマとしては例えばYoutubeのようなライブ機能でただURLにアクセスしても意味がないもの

これは例えばスパムだとか、Botを通して大量のパケットだとか、サーバーの容量を圧迫しないようにするため。

認証を踏むことで例えば同時に配信できる数に制限をかけたり、視聴用のページをカスタマイズすることができる。

設定項目に以下を加える

on_publish http://{IP}/{認証ページ}

また配信終了の合図は

on_publish_done http://{IP}/{認証ページ}

また以下の設定を追加することでアーカイブを残すことができるが、

これはサーバーの容量と相談しながら決めたほうがよい。

hls_cleanup off;

認証にPOSTかGETを使用するかは

notify_method get;
notify_method post;

できまる。

認証の仕組み

特に難しいことはなく、POST または GET された データにある配信用のキーが登録または許可されているものかどうかが分かればいい。

ただし、HTTP 200 コードだとすべて許可になるため、必ずそれ以外の値を返すようにした方がいいだろう。

また配信用のキーは name プロパティに格納されている。

 

統計情報

以下のサイトが参考になるだろう。

https://github.com/arut/nginx-rtmp-module/wiki/Getting-number-of-subscribers

 

参考文献

https://ccbaxy.xyz/blog/2020/05/05/video2/

データの取り扱いが簡単になるPacketクラス

使用するメリット

データの終端など意識することなく読み書きが可能

デメリット

少ないデータのやり取りでは逆にデータ量が増える

public enum PacketType {
  BINARY,
  META,
  KEEP
}

public class Packet {
  public Packet(PacketType type, byte[] data)
        {
            this.Type = type;
            this.Data = data;
        }

        public PacketType Type { get; protected set; }
        public byte[] Data { get; protected set; }

        public int BinarySize
        {
            get
            {
                return Data.Length;
            }
        }
}

public class PacketWriter {
  public PacketWriter(Stream stream) {
    this.stream = stream;
  }
  private Stream stream;
  public Packet Read() {
    byte[] sof = new byte[4];
    int ty;
    byte[] buffer;
    stream.Read(sof, 0, sof.Length);
    ty = stream.ReadByte();
    int size = BitConverter.ToInt32(sof, 0);
    buffer = new byte[size];
    stream.Read(buffer, 0, size);
    PacketType type = (PacketType) ty;
    return new Packet(type, buffer);
  }
  public void Write(Packet packet) {
    int size = packet.Data.Length;
    byte[] sof = BitConverter.GetBytes(size);
    byte type = (byte) packet.Type;
    stream.Write(sof, 0, sof.Length);
    stream.WriteByte(type);
    stream.Write(packet.Data, 0, size);
  }
}

ラズパイとDHT11を使って温度を測定する

概要

ラズパイとDHT11を使用して、周囲の温度を測定し、データベースに保存する

用意するもの

ラズパイ 3-4

DHT11 本体

自分の環境は ラズパイ 3 b+ に上のDHT11モジュールを使用しています。

参考サイト

https://www.souichi.club/raspberrypi/temperature-and-humidity/

DHT11とラズパイとの接続図

ピン配置は上の通り

プログラム

実はPythonにあまり触れたことがなく、知識も浅いのでとりあえずJSONにしてコマンドラインで出力を行うことにした。

import GPi.GPIO as GPIO
import dht11
import time
import datetime
import json

# ◆儀式◆
# 詳しくはわかりません
GPIO.setwarnings(True)
GPIO.setmode(GPIO.BCM)

# Output が GPIO 4 なので
# pin=4 になります
ins = dht11.DHT11(pin=4)

while True:
  result = ins.read()
  if result.is_valid():
    # JSON 出力用に辞書作成
    d = dict()
    # 日付
    d["date"] = str(datetime.datetime.now())
    # 温度
    d["temp"] = result.temperature
    # 湿度
    d["humi"] = result.humidity

    # 出力
    print(json.dumps(d, ensure_ascii=False, indent=2))
    break
  # 取得失敗
  # 1秒待って再度チャレンジ
  time.sleep(1)

GPIO.cleanup()

コマンドラインで実行すると

{
"date": "2021-06-18 20:29:05.163202",
"humi": 48.0,
"temp": 28.1,
}

というようなデータが取れるようになります。

データベースに保存するのにはPHPを使用します。

以下のようなコードでJSONを取得できます。

$raw = shell_exec("python output.py");
$json = json_decode($raw, true);

shell_exec でコマンドを実行して、出力データを $raw に代入し、

$raw を json_decode で配列に変換しています。

温度は $json[“temp”] で取得できるようになっています。

あとはこのデータをデータベースに保存するだけです。