go言語でvl53l0xを使ってみる
以前、vl53l0xで距離測定を行いました。
elsammit-beginnerblg.hatenablog.com
どうせなら、go言語でも実施してみたいな!!と思い調べてみました!!
せっかく調べたのでまとめておこうと思います!!
■使用環境
用いたデバイスは下記です。
・ラズパイ4
・測距センサ
測距センサですが、こちらを利用。
VL53L0Xレーザー測距センサーToF測距飛行時間測距センサーモジュール 新品価格 |
VL53L0Xを用いた構成は下記となります。
■ラズパイへのI2C設定
ラズパイへのI2C設定は以前こちらにまとめましたので必要に応じて確認ください。
elsammit-beginnerblg.hatenablog.com
■Go言語でのvl53l0x事前準備
Go言語でvl53l0xを用いるにあたり、すでにライブラリが用意されております!!
ライブラリをインストールするにあたり、こちらのコマンドを実行。
go get -u github.com/d2r2/go-vl53l0x
エラーメッセージが表示されなければインストールは完了です!!
設定は以上になります!!すでにライブラリが用意されているのでセッティングが楽ですね!!
■Go言語でvl53l0xを用いた距離測定
ではセッティングが完了しましたので、さっそく距離測定を行うコードを書いていきたいと思います!!
と言ってもすでに本ライブラリを作成した方がサンプルを展開されておりますので、そちらを流用!!
package vl53l0x import ( "fyne.io/fyne/widget" i2c "github.com/d2r2/go-i2c" vl53l0x "github.com/d2r2/go-vl53l0x" "log" "strconv" "time" ) func main() { i2c, err := i2c.NewI2C(0x29, 1) if err != nil { log.Fatal(err) } defer i2c.Close() sensor := vl53l0x.NewVl53l0x() err = sensor.Reset(i2c) if err != nil { log.Fatal(err) } err = sensor.Init(i2c) if err != nil { log.Fatal(err) } for { rng, err := sensor.ReadRangeSingleMillimeters(i2c) if err != nil { log.Fatal(err) } log.Printf("Measured range = %v mm", rng) time.Sleep(time.Second) } }
こちらのコードですが、
i2c, err := i2c.NewI2C(0x29, 1)
でI2Cのデバイス番号(0x29)とI2Cのデバイスドライバ番号(1)を設定します。
それぞれ、
デバイス番号
i2cdetect -y 1
デバイスドライバ番号
ls /dev/i2c*
で確認できます。
そしてこちらのコードでセンサを定義するのと同時にI2Cの初期化を行います。
sensor := vl53l0x.NewVl53l0x() err = sensor.Reset(i2c) err = sensor.Init(i2c)
最後に、
for { rng, err := sensor.ReadRangeSingleMillimeters(i2c) if err != nil { log.Fatal(err) } log.Printf("Measured range = %v mm", rng) time.Sleep(time.Second) }
で1秒ごとに距離の測定を行います。
距離はミリメートルで取得できます。
■困っていること
デバッグログがかなり出力されてしまうので他のログが醜くなっているのが厄介だな、と感じております。
無効方法が分かっていないのでもう少し調べてみようと思います!!
Go言語 GUIアプリ Fyneへの動画表示
先日Fyneを使用して簡単なGUIアプリを作成しました。
elsammit-beginnerblg.hatenablog.com
今回はFyneを利用して動画を表示・再生させるアプリを作成していこうと思います!!
■環境
・OS:Ubuntu20.04(virtualBox上)
※すでにFyneがインストールされていることを前提にします。
■Fyneへの画像表示
動画表示・再生を行う前にまずは画像の表示を行っていきます。
コードはこんな感じ。
package main import ( "fmt" "fyne.io/fyne/app" "fyne.io/fyne/canvas" "fyne.io/fyne/widget" "gocv.io/x/gocv" "image" ) func main() { Flg = false fileName := "ファイルパス" img := gocv.IMRead(fileName, -1) gocv.Resize(img, &img, image.Point{250, 250}, 0, 0, gocv.InterpolationDefault) imgD, _ := img.ToImage() myApp := app.New() w := myApp.NewWindow("Image") ShowImg := canvas.NewImageFromImage(imgD) ShowImg.FillMode = canvas.ImageFillOriginal label := widget.NewLabel("Show image") w.SetContent(widget.NewVBox( ShowImg, label, )) w.ShowAndRun() }
やっていることは、
opencvで画像データを読み出す。
img := gocv.IMRead(fileName, -1) gocv.Resize(img, &img, image.Point{250, 250}, 0, 0, gocv.InterpolationDefault)
画像表示用画像イメージに変換。
imgD, _ := img.ToImage()
用意したcanvasの上に読み出した画像データをセット。
ShowImg := canvas.NewImageFromImage(imgD) ShowImg.FillMode = canvas.ImageFillOriginal
最後にGUIとしてレイアウトを決めて、
w.SetContent(widget.NewVBox( ShowImg, label, ))
画面表示、
w.ShowAndRun()
になります。
今回画像をこちらとした場合、
先ほどのコードを実行するとこちらのアプリが表示されます。
■動画表示
では本題の動画を表示させます。
全体のコードはこちらになります。
package main import ( "fyne.io/fyne/app" "fyne.io/fyne/canvas" "fyne.io/fyne/widget" "gocv.io/x/gocv" "image" "time" ) func MakeMovie(ShowImg *canvas.Image) { movie, _ := gocv.OpenVideoCapture("再生させる動画パス") img := gocv.NewMat() imgDD, _ := img.ToImage() for { movie.Read(&img) gocv.Resize(img, &img, image.Point{250, 250}, 0, 0, gocv.InterpolationDefault) imgDD, _ = img.ToImage() ShowImg.Image = imgDD canvas.Refresh(ShowImg) time.Sleep(time.Millisecond * 33) } } func main() { fileName := "lena.jpg" img := gocv.IMRead(fileName, -1) gocv.Resize(img, &img, image.Point{250, 250}, 0, 0, gocv.InterpolationDefault) imgD, _ := img.ToImage() myApp := app.New() w := myApp.NewWindow("Image") ShowImg := canvas.NewImageFromImage(imgD) ShowImg.FillMode = canvas.ImageFillOriginal label := widget.NewLabel("Show Movie") go MakeMovie(ShowImg) w.SetContent(widget.NewVBox( ShowImg, label, )) w.ShowAndRun() }
先ほどの画像表示と異なる点は、
func MakeMovie(ShowImg *canvas.Image) { movie, _ := gocv.OpenVideoCapture("再生させる動画パス") img := gocv.NewMat() imgDD, _ := img.ToImage() for { movie.Read(&img) gocv.Resize(img, &img, image.Point{250, 250}, 0, 0, gocv.InterpolationDefault) imgDD, _ = img.ToImage() ShowImg.Image = imgDD canvas.Refresh(ShowImg) time.Sleep(time.Millisecond * 33) } }
を追加して、
go MakeMovie(ShowImg)
により並列処理を行っている点です。
MakeMovie関数ですが、
引数に用意した*canvas.Imageを渡し、
動画の1フレーム毎に取得、canvas.Imageにセットする
処理を行っております。
先ほどの画像と同様、canvasへセットするために読みとったフレーム画像は
imgDD, _ = img.ToImage()
より変換を行っております。
最後に!!
毎回フレーム画像をリフレッシュしないと反映されないので必ずこちらの関数を用いてください。
canvas.Refresh(ShowImg)
では、実際にこちらのコードを用いて、動画を再生してみます!!
実行するとこんな感じで再生されます。
■再生・停止ボタン追加(おまけ)
おまけとして、再生・停止ボタンを用意して動画の停止・再開の機能を追加したいと思います。
コードはこちらになります。
package main import ( "fmt" "fyne.io/fyne/app" "fyne.io/fyne/canvas" "fyne.io/fyne/widget" "gocv.io/x/gocv" "image" "time" ) var Flg bool func MakeMovie(ShowImg *canvas.Image) { Movie, _ := gocv.OpenVideoCapture("./Underwater - 37712.mp4") img := gocv.NewMat() imgDD, _ := img.ToImage() for { if Flg == true { Movie.Read(&img) gocv.Resize(img, &img, image.Point{250, 250}, 0, 0, gocv.InterpolationDefault) imgDD, _ = img.ToImage() ShowImg.Image = imgDD canvas.Refresh(ShowImg) time.Sleep(time.Millisecond * 33) } else { time.Sleep(time.Second) } } } func main() { Flg = false fileName := "lena.jpg" img := gocv.IMRead(fileName, -1) gocv.Resize(img, &img, image.Point{250, 250}, 0, 0, gocv.InterpolationDefault) imgD, _ := img.ToImage() myApp := app.New() w := myApp.NewWindow("Image") ShowImg := canvas.NewImageFromImage(imgD) ShowImg.FillMode = canvas.ImageFillOriginal label := widget.NewLabel("Show Movie") go MakeMovie(ShowImg) var button *widget.Button button = widget.NewButton("Start", func() { label.SetText("Welcome") fmt.Println("push Button") if Flg == true { button.SetText("Start") Flg = false } else { button.SetText("Stop") Flg = true } }) w.SetContent(widget.NewVBox( ShowImg, label, button, )) w.ShowAndRun() }
追加しているのはStart/Stopフラグのみ(のはず)。
こちらを実行するとこちらのようになります!!
raspberryPiでの仮想ビデオデバイス(/dev/video)の作成
今回は仮想ビデオデバイスを作成して作成したビデオデバイス経由で動画データのやり取りを行っていきます。
動画データのやり取りに用いるのはgstreamerです。
gstreamerについてはこちらにまとめておりますのでぜひ!!
elsammit-beginnerblg.hatenablog.com
elsammit-beginnerblg.hatenablog.com
■環境
今回の環境はこちらです。
・デバイス:raspberry Pi4
・OS:
・カメラ:UCAM-C520FBBK
■事前準備
仮想ビデオデバイス作成にあたり、v4l2loopを用います。
v4l2loopをインストールするために、
sudo apt-get install v4l2loopback-dkms
を実行。
■仮想ビデオデバイス作成
仮想ビデオデバイスを作成するコマンドは、
sudo modprobe v4l2loopback
です。
こちらを実行してから、
ls /dev/video*
を実行するとビデオドライバが1つ増えていることが確認できます。
さらに、複数ビデオデバイスを作成する場合には、
sudo modprobe v4l2loopback devices=デバイス数
となります。
■仮想デバイスを用いた動画表示
では実際に仮想ビデオデバイス経由で動画の再生を行ってみます!!
まずは作成したビデオデバイスへの動画データ書き込みです。
仮想ビデオデバイスがvideo2の場合、コマンドはこちらのようになります。
gst-launch-1.0 -v v4l2src device=/dev/video0 ! videoconvert ! v4l2sink device=/dev/video2 sync=false
device=/dev/video2
を作成したビデオデバイスに置き換えればOKです。
では次に仮想ビデオデバイスからの読み出しです。
コマンドはこちらのようになります。
gst-launch-1.0 -v v4l2src device=/dev/video2 ! videoconvert ! autovideosink
先ほどの動画書き込み側のコマンドを実行した後に、読み出し用のコマンドを実行すれば、
カメラからのキャプチャ動画が表示されるかと思います。
■go言語で仮想ビデオデバイスから読み出してみる
次にgo言語を用いて、仮想ビデオデバイスから動画データを読み出し、表示をしてみます。
コードはこちらです。
package main import ( "gocv.io/x/gocv" "image" ) func main() { webcam, _ := gocv.OpenVideoCapture("v4l2src device=/dev/video2 ! videoconvert ! appsink") window := gocv.NewWindow("hello") img := gocv.NewMat() for { webcam.Read(&img) gocv.Resize(img, &img, image.Point{640, 480}, 0, 0, gocv.InterpolationDefault) window.IMShow(img) window.WaitKey(1) } }
gocvを用いて、仮想ビデオデバイスから画像データを読み出し、
IMShowで表示しております。
gocv.OpenVideoCapture("v4l2src device=/dev/video2 ! videoconvert ! appsink")
go言語 GUIアプリ Fyne導入
今回はgo言語でGUIアプリの作成を行っていきます。
go言語のGUIアプリですが複数種類あります。
が、QtやGtkは使ったことがあったので出来れば別の方法が良いな!!
と思い、調べてみたら見つけたので早速使用してみることにしました。
■動作環境
・OS:Ubuntu20.04(VirtualBox 仮想環境)
・go version:1.13.08
go versionが1.9以下ですと、Fyneはインストールできるのですが、
コードを作成してビルド・実行を行うと、
../go/src/fyne.io/fyne/storage/uri.go:29:10: undefined: strings.ReplaceAll ../go/src/fyne.io/fyne/storage/uri.go:30:10: undefined: strings.ReplaceAll
といったエラーが発生してしまいます。
必ず1.10以上(出来る限り最新の)go言語をご利用ください。
■Fyneインストール
ではFyneをインストールしていきます。
こちらを実行。
go get fyne.io/fyne
これでインストール完了!!
では動作確認!!
動作確認用のソースコードをダウンロード。
go get fyne.io/fyne/cmd/fyne_demo/
そして、fyne_demo配下に格納されているmain.goを実行。
go run main.go
こちらのようなGUIアプリが表示されればFyneのインストールは成功です。
■簡単なコード作成
では簡単なサンプルコードを作成し、実行してみます。
まずはコードから。
package main import ( "fyne.io/fyne/app" "fyne.io/fyne/widget" ) func main() { a := app.New() w := a.NewWindow("Hello") hello := widget.NewLabel("Hello Fyne") w.SetContent( widget.NewHBox( hello, widget.NewButton("Hi", func() { hello.SetText("Welcome") }), ), ) w.ShowAndRun() }
こちらはfyneが公式で公開しているサンプルコードを写経したものですw
a := app.New() w := a.NewWindow("Hello")
でアプリやウィンドウ(表示画面)を定義。
そして、
w.SetContent( widget.NewVBox( hello, widget.NewButton("Hi", func() { hello.SetText("Welcome") }), ), )
で表示する形状を定義。
最後に、
w.ShowAndRun()
でGUIアプリを実行。
といった形になります。
結構直感的に作成できるのが良いですね!!
こちらを実行すると、
が表示されます。
そして、Hiと記載されたボタンを押下すると、
というようにLabelの文字が変化します。
この
widget.NewVBox(
を
widget.NewHBox(
に変更すると、
というように横に並びます。
■簡単なコード作成2
今後はこちらのコードを作成。
package main import ( "fyne.io/fyne/app" "fyne.io/fyne/widget" ) func main() { a := app.New() w := a.NewWindow("Hello") hello_1 := widget.NewLabel("Hello Fyne") hello_2 := widget.NewLabel("Hello world") w.SetContent( widget.NewHBox( widget.NewVBox( hello_1, widget.NewButton("No.1", func() { hello_1.SetText("Welcome") }), ), widget.NewVBox( hello_2, widget.NewButton("No.2", func() { hello_2.SetText("AAA") }), ), ), ) w.ShowAndRun() }
こちらを実行すると、
といったアプリが作成できます。
ラベル+ボタンを縦に並べ、
widget.NewVBox( hello_1, widget.NewButton("No.1", func() { hello_1.SetText("Welcome") }), ),
それぞれを、
widget.NewHBox(
によって横に並べております。
■最後に
今回はfyneについて使用してみました。
結構感覚的に使用できたので、結構簡単に使えるライブラリだな!!と感じました。
使っていってみようかしら?
画像データをバイト(文字列)データに変換
今回は画像データをバイト(文字列)データに変換する方法についてまとめておこうと思います!!
■画像データをバイト列に変換
変換のコードはこちらになります。
import os import io from PIL import Image import numpy as np class ImgByteChange: def __init__(self): pass def ImageToByte(self,Img): tmpimg = Image.open(Img) with io.BytesIO() as output: tmpimg.save(output,format="PNG") ImgToByte = output.getvalue() return ImgToByte imgByteChange = ImgByteChange() test = imgByteChange.ImageToByte(画像ファイルパス)
重要なのは、
def ImageToByte(self,Img): tmpimg = Image.open(Img) with io.BytesIO() as output: tmpimg.save(output,format="PNG") ImgToByte = output.getvalue()
です。
イメージファイルをオープンしてから、
with io.BytesIO() as output: tmpimg.save(output,format="PNG") ImgToByte = output.getvalue()
にて開いた画像に対してバイト列に変換。変数に格納しております。
こちらの画像に対して
コードを実行すると、
b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x96\x00\x00\x00\x96\x08\x00\x00\x00\x00\x19j.>\x00\x00\x00\xa7IDATx\x9c\xed\xd9A\n\x021\x10\x00\xc1(\xfb\xff/\xeb\x0b\xe6\xd0\x8b\xe8\x08U\xd7\x10\xd2\xccm\xc89\x00\x00\x00\xb0\xdec<y\xfd\xf2\xf5\xe7\x17\x1e\xbfAV!\xab\x90U\xc8*d\x15\xb2\nY\x85\xacBV!\xab\x90U,\xcd\xba\xfa\x95y\xe3\x9d\xf4Mx\xe9\xb4d\x15\xb2\nY\x85\xacBV!\xab\x90U\xc8*d\x15\xb2\nY\x85\xacBV!\xab\x90U\xc8*d\x15\xb2\nY\x85\xacBV!\xab\x90U\xc8*\xe6\xdf\xd7\xfe\xc9\xfaAK\xa7%\xab\x90U\xc8*d\x15\xb2\nY\x85\xacBV!\xab\x90U\xc8*\x96f\x01\x00\x00\xc0\x1fx\x03\xe9R\x02\xcdQ\x93\xdcP\x00\x00\x00\x00IEND\xaeB`\x82'
というようにバイト列(文字列)が得られます。
■バイト列から画像イメージに変換
今度は逆にバイト列から画像イメージに変換するコードを記載します。
そのコードはこちら。
import os import io from PIL import Image import numpy as np class ImgByteChange: def __init__(self): pass def ByteToImage(self, str): ByteToImg = Image.open(io.BytesIO(str)) return ByteToImg imgByteChange = ImgByteChange() img = imgByteChange.ByteToImage(バイト列)
こちらが今回の重要点。
Image.open(io.BytesIO(str))
こちらのコードで文字列から画像イメージに変換しています。
バイト列を変数に与えるのは大変なので、
こちらのコードを用いて、画像⇒文字列⇒画像の順に変換して画像を見比べてみたいと思います。
import os import cv2 import io from PIL import Image import numpy as np class ImgByteChange: def __init__(self): pass def ImageToByte(self,Img): tmpimg = Image.open(Img) with io.BytesIO() as output: tmpimg.save(output,format="PNG") ImgToByte = output.getvalue() return ImgToByte def ByteToImage(self, str): ByteToImg = Image.open(io.BytesIO(str)) return ByteToImg imgByteChange = ImgByteChange() test = imgByteChange.ImageToByte(入力画像) img = imgByteChange.ByteToImage(test) img.save('出力画像)
今度はこちらの画像を入力。
結果はこちらです。
同じ画像が得られました!!
良かった!!
■最後に
今回は画像データのバイト列(文字列データ変換とバイト列データを画像データに変換する方法についてまとめました。
実はこちらを用いて、実行ファイル同士で共有メモリ通信的なことをしてデータのやり取りしようかな?と思っていたのですが、
別の方法が分かったのでそちらで画像データのやり取りをする方法をまとめたいと思います!!
この変換方法も後で後で何かに使えるかな?
go言語でカメラ映像配信を受信してみる
前回、gstreamingを用いたrtpでのカメラ映像の配信・受信を行いました。
ですが、前回の方法ですとコマンドベースでの動作でした。
elsammit-beginnerblg.hatenablog.com
今度はgo言語でrtpで送信されたデータを受信してみたいと思います!!
go言語でgstreamingを実施するにあたって、gocv用います。
gocvのインストール手順はこちらを参考ください。
elsammit-beginnerblg.hatenablog.com
■事前準備
gocvを用いるにあたり、デフォルトだとgstreamerがOFF(無効)になっているようです。
このため、gstreamerを有効にする必要があり、再度ビルドしなおす必要があります。
まずはgstreamerを有効にするために設定を変更します。
gocv.io/x/gocv配下に格納された"travis_build_opencv.sh"を変更・追加します。
cmake -D WITH_IPP=${GRAPHICAL} \ -D WITH_OPENGL=${GRAPHICAL} \ -D WITH_QT=${GRAPHICAL} \ -D BUILD_EXAMPLES=OFF \ -D BUILD_TESTS=OFF \ -D BUILD_PERF_TESTS=OFF \ -D BUILD_opencv_java=OFF \ -D BUILD_opencv_python=OFF \ -D BUILD_opencv_python2=OFF \ -D BUILD_opencv_python3=OFF \ -D OPENCV_GENERATE_PKGCONFIG=ON \ -D CMAKE_INSTALL_PREFIX=$HOME/usr \ -D OPENCV_ENABLE_NONFREE=ON \ -D WITH_FFMPEG=OFF \ ←OFFに変更. -D WITH_GTK=ON \ ←追加. -D WITH_GSTREAMER=ON \ ←追加. -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib-${OPENCV_VERSION}/modules ..
-D WITH_FFMPEG=OFF
は不要かもしれませんが、、、
どうやら、FFMPEGとGSTREAMERが両方ONになっていると動作不安定になるとのことで念のため。
修正変更したら、
sudo make install
を実行してgocvのビルドとインストールを行います。
インストール成功したら動作確認!!
■動作確認
では動作確認を行います。
まずはこちらのコードを実行。
package main import ( "fmt" "gocv.io/x/gocv" ) func main() { test := "videotestsrc ! videoconvert ! appsink" webcam, _ := gocv.OpenVideoCapture(test) window := gocv.NewWindow("Hello") img := gocv.NewMat() for { if ok := webcam.Read(&img); !ok { fmt.Printf("cannot read device \n") return } if img.Empty() { continue } window.IMShow(img) if window.WaitKey(1) >= 0 { break } } }
こちらの映像が表示されればOKです。
こちらのコードですが、OpenVideoCaptureに与えるデータを
test := "videotestsrc ! videoconvert ! appsink"
としており、gstreamerで用意?されたテスト動画をinputとして与えています。
後は、
webcam.Read(&img)
でフレーム映像を取得、
window.IMShow(img)
で映像表示しております。
この
test := "videotestsrc ! videoconvert ! appsink"
を、
test := "v4l2src! videoconvert ! appsink"
に置き換えればカメラ映像を表示させることが出来ます。
■rtp配信動画受信
セットアップが出来たので、本題のrtp配信動画を扱っていきます。
まずは、送信されてきた動画データの受信です。
まずはコードから。
package main import ( "fmt" "gocv.io/x/gocv" ) func main() { test := "udpsrc port=5005 ! application/x-rtp,media=video,encoding-name=H264 ! queue ! rtph264depay ! avdec_h264 ! videoconvert ! appsink" webcam, _ := gocv.OpenVideoCapture(test) window := gocv.NewWindow("Hello") img := gocv.NewMat() for { if ok := webcam.Read(&img); !ok { fmt.Printf("cannot read device \n") return } if img.Empty() { continue } window.IMShow(img) if window.WaitKey(1) >= 0 { break } } }
先ほどの動作確認とほぼほぼ同じコードで実現できますw。
異なる点は、
test := "udpsrc port=5005 ! application/x-rtp,media=video,encoding-name=H264 ! queue ! rtph264depay ! avdec_h264 ! videoconvert ! appsink"
で、データ受信先を
udpsrc port=5005
に変更し、エンコードを
application/x-rtp,media=video,encoding-name=H264 ! queue ! rtph264depay ! avdec_h264 ! videoconvert
としている点です。
前回のrtp受信コマンドで用いたコードをそのまま入力すれば実行できます。
事前に、
gst-launch-1.0 -v videotestsrc ! videoscale ! video/x-raw,width=160,height=120 ! videorate ! video/x-raw,framerate=100/1 ! x264enc ! rtph264pay ! udpsink host=127.0.0.1 port=5005 sync=false
を実行し、先ほどのコードを実行すると、
が表示されるかと思います。
■最後に
go言語でgstreamerを用いた映像受信方法についてまとめました。
送信側はただいま勉強中。
gstreamerでrtp経由でストリーミング
今回はgstreamerでrtp(udp)でストリーミングする方法についてまとめておこうと思います!!
コマンド1つで動画配信できるようなので少しまとめておこうと思います!!
■環境
・OS:Ubuntu16.04(VirtualBox上)
・カメラ:UCAM-C520FBBK
エレコム WEBカメラ マイク内蔵 200万画素 高精細ガラスレンズ ブラック UCAM-C520FBBK 新品価格 |
カメラですが、ちょっと興味があって別のカメラ買って見ましたww
結構こちらのカメラも写りよかった。
■セッティング
今回gstreamerはインストール済みでしたが、ちょっと足りないライブラリもあったのでインストールします。
sudo apt-get install gstreamer1.0-plugins-ugly sudo apt-get install gstreamer1.0-libav
■テスト動作確認
ではテスト動画を再生させてみたいと思います!!
こちらを実行してテスト動画確認できます。
gst-launch-1.0 videotestsrc ! videoconvert ! autovideosink
問題がなければこちらの動画が画面上に表示されるかと思います。
次にカメラから取得した映像を画面上に表示させてみます。
こちらのコマンドを実行します。
gst-launch-1.0 -v v4l2src ! videoconvert ! autovideosink
これでカメラから取得した映像が表示されればOKです。
■カメラ映像について
先ほどのコマンドですが、それぞれ
テスト動画:テスト動画を受信 ! エンコード/デコード ! ビデオ表示用ドライバにデータ格納
カメラ動画:カメラからの動画受信 ! エンコード/デコード ! ビデオ表示用ドライバにデータ格納
の意味になっています。
gst-launch-1.0では上記のように、
何等かのデバイスやテストデータから~~srcで取得。
取得したデータをエンコード/デコードして加工。
最後に~~sinkで指定したドライバにデータを格納。
するように指定します。
要するに、
・v4l2src:カメラ映像取得
・videotestsrc :テスト動画取得
・autovideosink:モニタへの動画表示
といった形です。
■gstreamerを用いたrtpストリーミング
まずは配信側です。
こちらのコマンドで配信可能です。
gst-launch-1.0 -v v4l2src ! videoscale ! video/x-raw,width=320,height=240 ! videorate ! video/x-raw,framerate=100/1 ! x264enc ! rtph264pay ! udpsink host=127.0.0.1 port=5005 sync=false
こちらのコマンドの意味ですが、
v4l2src
でカメラ映像を取得し、
videoscale ! video/x-raw,width=320,height=240 ! videorate ! video/x-raw,framerate=100/1
で映像サイズやフレームレートを指定。
x264enc ! rtph264pay
で映像をrtp用にデータをエンコード。
最後に、
udpsink host=127.0.0.1 port=5005 sync=false
でIPアドレスとポート番号を指定してrtp配信用のドライバにデータを格納します。
今回はローカルへの配信としています。
次に配信されているデータを受信します。
こちらのコマンドで実行可能です。
gst-launch-1.0 -v udpsrc port=5005 ! application/x-rtp,media=video,encoding-name=H264 ! queue ! rtph264depay ! avdec_h264 ! videoconverter ! autovideosink
まず、
udpsrc port=5005
で配信された動画を取得。
そして、こちらでH.264形式のフォーマットに変換。
application/x-rtp,media=video,encoding-name=H264 ! queue ! rtph264depay ! avdec_h264 ! videoconverter
最後に、
autovideosink
で映像表示用のドライバにデータを格納。
といった流れになります。
■最後に
今回はgstreamerを用いてコマンドではありますがrtp経由で動画ストリーミングを行いました。
。。。用語間違っていたらすいません。