🛴
カメラからのMJPEGをTCPで送って別のPCで観られるようにした
USBWebcamはラズパイやjetson nanoにつないで使っていますが、どちらもディスプレイはつないでいません。なので、MJPEGで保存したファイルをscpで転送してから画面のあるPC(MacBookAir)で再生していました。
ファイルに書く代わりにTCP socketに流す
前回のサンプルプログラムを少し改造して、MJPEGをファイルに書き込む代わりに直接TCPで別のPCに送って見ることができるようにしてみました
修正は以下の通り。ファイルをcreateする代わりにtcpのstreamに書くようにしただけ。
$ git show
commit d2526b52d7edbd594493d59cf25dac4755d07a33 (HEAD -> temp_tcp_socket, origin/temp_tcp_socket)
Author: Tetsuyuki Kobayashi <tetsu.koba@gmail.com>
Date: Sun Apr 23 16:05:07 2023 +0900
temp: Send to TCP socket instead of writing to file
diff --git a/src/main.zig b/src/main.zig
index 32e16bd..8e3483a 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -5,7 +5,8 @@ const time = std.time;
const v = @import("v4l2capture.zig");
var running: bool = false;
-var outFile: std.fs.File = undefined;
+//var outFile: std.fs.File = undefined;
+var tcp: std.net.Stream = undefined;
fn signalHandler(signo: c_int) align(1) callconv(.C) void {
switch (signo) {
@@ -22,7 +23,8 @@ fn signalHandler(signo: c_int) align(1) callconv(.C) void {
}
fn frameHandler(frame: []const u8) bool {
- outFile.writeAll(frame) catch {
+ //outFile.writeAll(frame) catch {
+ tcp.writeAll(frame) catch {
// TODO err handling
return false;
};
@@ -53,8 +55,12 @@ pub fn main() !void {
framerate = try std.fmt.parseInt(u32, args[5], 10);
}
- outFile = try std.fs.cwd().createFile(outfile, .{});
- defer outFile.close();
+ // outFile = try std.fs.cwd().createFile(outfile, .{});
+ // defer outFile.close();
+
+ // temporary: use outfile as hosthame
+ tcp = try std.net.tcpConnectToHost(alc, outfile, 8999);
+ defer tcp.close();
var cap = try v.Capturer.init(alc, devname, width, height, framerate);
defer cap.deinit();
使い方
ポート番号は8999に固定です。ファイル名を指定するところをに代わりにホスト名を指定します。
受信側
MacBookAir のffplayを使用しました。
ffplay -hide_banner -autoexit "tcp://:8999?listen=1"
こちらを先に起動しておきます。これのホスト名はkoba-mac.local
です。
送信側
temp_tcp_socket
のブランチでビルドし、保存するファイル名の代わりにホスト名を指定します。
zig-out/bin/v4l2capture /dev/video0 koba-mac.local 320 240 15
MJPEGは圧縮率が高くないのでとりあえず小さめの映像サイズでやってみました。320x240@15fpsでも2Mbpsくらいの帯域を使っているようです。
高画質な映像には向きませんが、手っ取り早くMJPEGの映像取得の動作確認する手段としてはアリかと思います。
2024/04/24 追記
ファイルへの保存とTCPへの送信の両方に対応させて、mainブランチにマージしました。
$ zig-out/bin/v4l2capture
Usage: zig-out/bin/v4l2capture /dev/videoX URL [width height framerate]
default is 640x480@30fps
URL is 'file://filename', 'tcp://hostname:port' or just filename.
README.mdも更新しました。使い方はこちらを見てください。
関連
Discussion