[RTSP]macでKinesis Video Streamsを使う

$ git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp.git
$ cd amazon-kinesis-video-streams-producer-sdk-cpp
$ mkdir build
$ cd build
$ brew link openssl –force
$ brew install pkg-config openssl cmake gstreamer gst-plugins-base gst-plugins-good gst-plugins-bad gst-plugins-ugly log4cplus gst-libav
$ make
$ export GST_PLUGIN_PATH=`pwd`/build
$ export LD_LIBRARY_PATH=`pwd`/open-source/local/lib
$ gst-inspect-1.0 kvssink

$ gst-device-monitor-1.0
Probing devices…

Device found:

name : FaceTime HD Camera
class : Video/Source
caps : video/x-raw(memory:GLMemory), width=1280, height=720, format=UYVY, framerate=[ 1/1, 30/1 ], texture-target=rectangle
video/x-raw, width=1280, height=720, format={ (string)UYVY, (string)YUY2, (string)NV12, (string)BGRA }, framerate=[ 1/1, 30/1 ]
properties:
device.api = avf
avf.unique_id = CC28053MGKXGJJM3Z
avf.model_id = “Apple\ Camera\ VendorID_0x106B\ ProductID_0x1570”
avf.has_flash = false
avf.has_torch = false
avf.manufacturer = “Apple\ Inc.”
gst-launch-1.0 avfvideosrc device-index=0 ! …

最後に、gst-launch-1.0 avfvideosrc device-index=0 と書いてあるので、これを使う

$ gst-launch-1.0 avfvideosrc device-index=0 ! videoconvert ! video/x-raw,format=I420,width=1280,height=720 ! vtenc_h264_hw allow-frame-reordering=FALSE realtime=TRUE max-keyframe-interval=45 bitrate=512 ! h264parse ! video/x-h264,stream-format=avc,alignment=au,profile=baseline ! kvssink stream-name=MyKinesisVideoStream storage-size=512 access-key=”YourAccessKeyId” secret-key=”YourSecretAccessKey” aws-region=”ap-northeast-1″

うおおおおおおおおおお
まじか、、、
sugeeeeeeeeeeee

[RTSP]Kinesis Video Streamsを使いたい

C++プロデューサーSDKをGStreamerプラグインとして使用する
ubuntu20.4にbuildする

$ git clone https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp.git
$ cd amazon-kinesis-video-streams-producer-sdk-cpp
$ mkdir build
$ sudo apt-get install libssl-dev libcurl4-openssl-dev liblog4cplus-dev libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-base-apps gstreamer1.0-plugins-bad gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly gstreamer1.0-tools
$ cmake .. -DBUILD_DEPENDENCIES=OFF -DBUILD_GSTREAMER_PLUGIN=ON
$ make
// 省略
[ 97%] Built target gstkvssink
Scanning dependencies of target kvs_gstreamer_sample
[ 98%] Building CXX object CMakeFiles/kvs_gstreamer_sample.dir/samples/kvs_gstreamer_sample.cpp.o
[100%] Linking CXX executable kvs_gstreamer_sample
[100%] Built target kvs_gstreamer_sample

$ cd ..
$ export GST_PLUGIN_PATH=`pwd`/build
$ export LD_LIBRARY_PATH=`pwd`/open-source/local/lib

AWS IAMで、AmazonKinesisVideoStreamsFullAccessのユーザを作成し、access key, secret keyをコピー

$ gst-inspect-1.0 kvssink
$ gst-launch-1.0 autovideosrc ! videoconvert ! video/x-raw,format=I420,width=1280,height=720 ! vtenc_h264_hw allow-frame-reordering=FALSE realtime=TRUE max-keyframe-interval=45 bitrate=512 ! h264parse ! video/x-h264,stream-format=avc,alignment=au,profile=baseline ! kvssink stream-name=MyKinesisVideoStream storage-size=512 access-key=”YourAccessKeyId” secret-key=”YourSecretAccessKey” aws-region=”ap-northeast-1″

no element “vtenc_h264_hw”

OS xのみで使えるのでエラーになるとのこと
>@Raghava248 vtenc_h264_hw is a hardware codec which is available on OSx only. Please try your platform specific encoder or use a software encoder like x264
https://github.com/awslabs/amazon-kinesis-video-streams-producer-sdk-cpp/issues/138

[RTSP]VLCを使ってRTP配信を行いたい

macにvlcをdownloadします
https://vlc-media-player.jp.uptodown.com/mac/download

1. VLCを起動し、ファイル -> キャプチャーデバイスを開く

2. ストリーミングの設定
RTCで224.0.0.1でポートを1900に設定

### 受信側
稼働しているvlcとは別にもう一つのvlcを起動します

ファイル -> ネットワークを開く
rtp://@224.0.0.1:1900 を設定します

すると、rtpで受信できることがわかります

おおおおおおおおおおおおおおお
Sugeeeeeeeeeeeeeeeeee

RTSPでは224.0.0.0 ~ 239.255.255.255のアドレスを指定する

うん、これをAmazon Kinesis Video Streams で受信したい

RTSPとは

RTSPとは
-> Real Time Streaming Protocol
-> 映像、音声のリアルタイムなストリーミング配信を制御する為のプロトコル
-> ネットワークカメラがクライアント(NVR, VMS)に配信
*NVRはNetwork Video Recoderの略で録画システム
*VMSはVideo Management Softwareで映像を録画、管理、閲覧するソフトウェア

動画はTCP通信ではなく、UDP通信

### 記述
– 要求資源の位置は「rtsp://」を用いて、TCP554ポート(5554)

なるほど、RTSPの概要はわかりました。

[Go Revel] ランダムな文字列作成

app.go

import (
	"github.com/revel/revel"
	"app/app/models"
	"fmt"
	_ "image/jpeg"
	"io/ioutil"
	"os"
	"net/smtp"
	"crypto/rand"
	"errors"
)

func (c App) Rand() revel.Result {

	random, _ := MakeRandomStr(8)
	fmt.Println(random)
	return c.Render()
}

func MakeRandomStr(digit uint32)(string, error){
	const letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

	b := make([]byte, digit)
	if _, err := rand.Read(b); err != nil {
		return "", errors.New("unexpected error...")
	}

	var result string
	for _, v := range b {
		result += string(letters[int(v)%len(letters)])
	}
	return result, nil
}

dJdJvsWf

OK, これでPasswordを作成する

[Go Revel] Mailtrapによるメール送信

gmailのsmtpで送信する場合と書き方はほぼ同じ

func (c App) Mail() revel.Result {

	name := "hpscript"
	email := "test@hpscript.com"
	comments := "桜木町の夜景は良いですね"

	auth := smtp.PlainAuth (
		"",
		"hogehoge", // Mailtrap Username
		"fugafuga", // Mailtrap Password
		"smtp.mailtrap.io",
	)

	msg := []byte("From: info@hpscript.com\r\n" +
		"To: " +email + "\r\n" +
		"Subject: SMTPテスト\r\n" +
		"\r\n" +
		"名前: " + name + "\r\n" +
		"メールアドレス" + email + "\r\n" +
		"問い合わせ内容: " + comments + "\r\n")

	err := smtp.SendMail(
		"smtp.mailtrap.io:25",
		auth,
		"info@hpscrpt.com",
		[]string{email}, // 宛先
		msg,
	)

	if err != nil {
		fmt.Println(err)
	}
	return c.Render()
}

OKOK

[Go Revel] メール送信の実装方法

まずメール送信用のルートを作成

GET		/mail				  App.Mail

app.go
– net/smtpをimport
– パスワードはアプリ固有のパスワード

import (
	"github.com/revel/revel"
	"net/smtp"
)
func (c App) Mail() revel.Result {

	name := "hpscript"
	email := "test@hpscript.com"
	comments := "桜木町の夜景は良いですね"

	auth := smtp.PlainAuth (
		"",
		"myaddress@gmail.com", // gmailのアドレス
		"hogehoge", // アプリ固有のパスワード
		"smtp.gmail.com",
	)

	msg := []byte("From: info@hpscript.com\r\n" +
		"To: info@hpscript.com\r\n" +
		"Subject: SMTPテスト\r\n" +
		"\r\n" +
		"名前: " + name + "\r\n" +
		"メールアドレス" + email + "\r\n" +
		"問い合わせ内容: " + comments + "\r\n")

	err := smtp.SendMail(
		"smtp.gmail.com:587",
		auth,
		"info@hpscrpt.com",
		[]string{"fugafuga@hotmail.com"}, // 宛先
		msg,
	)

	if err != nil {
		fmt.Println(err)
	}
	return c.Render()
}

これmailtrapでも送れそうだな

[Go Revel] MySQLのuniqueなvalidationでredirect

ユーザのsigninの際に、既に同じユーザ名の登録があれば、登録できないようにしたい。

mysql側ではnameにUnique keyをつけている

mysql> describe users;
+———-+————–+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+———-+————–+——+—–+———+—————-+
| id | int | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | UNI | NULL | |
| email | varchar(255) | YES | | NULL | |
| password | varchar(255) | YES | | NULL | |
| filepath | varchar(255) | YES | | NULL | |
| message | text | YES | | NULL | |
+———-+————–+——+—–+———+—————-+
6 rows in set (0.01 sec)

これだと、実際に同じnameで入力があった場合、mysql側にはinsertされないが、
ページがそのまま遷移してしまう。
そのため、同じnameの入力があった場合は、入力画面に戻るようにしたい

revelでc.Validation.${} でunique判定が見当たらないので、
実際にselectして、処理する

	result := []models.Users{}
	DB.Where("name = ?", name).First(&result)


	if len(result) != 0 {
		c.Flash.Error("Same username is registered!")
		c.Validation.Keep()
		c.FlashParams()
		return c.Redirect(App.Signin)
	}
	
	hashPassword := getMD5Hash(password)
	DB.Create(&models.Users{
		Name: name,
		Email: email,
		Password: hashPassword,
	})
	
	return c.Render()

これ2時間ぐらいかかった…
go revelとか、documentなさすぎやろ😖😖😖😖

[Go Revel] Templateで else ifを使う

html
– uploadファイルがあればuploadファイル、元からセットされてらファイルがあればその画像、なければplaceholdeの画像を表示する

              {{if .filepath}}
               <img src="{{ .filepath }}" width="150px" height="150px" class="img-icon preview1">
              {{else if .set_filepath}}
              <img src="{{ .set_filepath }}" width="150px" height="150px" class="img-icon preview1">
              {{else}}
              <img src="http://placehold.jp/150x150.png" class="img-icon">
              {{end}}

普通にif, else ifで実装できますね。
controllerがそこそこ複雑になってきた。
djangoもそうだが、controllerを1ファイルでまとめると、縦に長くなるので、controllerを分けたいという欲求が少なからずある

[Go Revel] Templateで値がnilか否かで条件分岐

画像uploadの確認画面で、uploadファイルがあればその画像を表示し、なければplaceholdの画像を表示したい

app.go
– filepathを””で宣言し、uploadファイルがあれば、保存するファイルパスに置き換える

                filepath := ""
	if file1 != nil {
		fmt.Println(c.Params.Files["file1"][0].Filename)
		filename := c.Params.Files["file1"][0].Filename
		data, e := ioutil.ReadAll(file1)
		if e != nil {
			fmt.Println("error")
		}
		ioutil.WriteFile("public/tmp/" + filename, data, 777)
		filepath = "public/tmp/" + filename
	}

uploadconfirm.html
– if eq で値の中身を確認して条件分岐で表示する。 {{if .filepath == “” }}と書くとエラーになるので注意が必要

            <td>
              {{if eq .filepath ""}}
              <img src="http://placehold.jp/150x150.png" class="img-icon">
              {{ else }}
              <img src="{{ .filepath }}" width="150px" height="150px" class="img-icon preview1">
              {{end}}
              <div class=""></div>
            </td>

go本体では、if .filepath == “” という順番でかけるのに、templateでは if eq と書かなければダメなのは面白いですね。いっその事統一して欲しいですが…