现象说明:
- GStreamer 已经成功打开 `/dev/video80`,并且 **正在源源不断地取帧**(19 秒里没报任何“TRY_FMT failed”或“not-negotiated”)。
- 你按了 `^C` 把 pipeline 停掉,所以 **没有 png 文件生成**——这是 **正常行为**,因为 pngenc 默认只在 **收到 EOS(流结束)** 或 **强制 Ctrl-C** 时才写出 **最后一帧**;而 v4l2src 这种实时源永远不会自己发 EOS,于是 **零字节输出**。
目标只是 **截一张图**,有两种做法:
-------------------------------------------------
1. 只取一帧就停(最简单)
-------------------------------------------------
gst-launch-1.0 自带 **num-buffers** 参数:
```bash
gst-launch-1.0 v4l2src device=/dev/video80 io-mode=dmabuf num-buffers=1 ! \
video/x-raw ! \
videoconvert ! \
pngenc ! \
filesink location=hdmi.png
```
- `num-buffers=1` → v4l2src 拿到 **1 帧** 后就发送 EOS;
- pngenc 收到 EOS 立即写出文件;
- 管道自动停止,**当前目录下会出现 hdmi.png**。
-------------------------------------------------
2. 用“拍摄快照”方式(不停止视频)
-------------------------------------------------
如果你还想 **继续预览/录像**,同时 **随时拍一张**,改用 **multifilesink + 手动发信号** 或 **videomixer + valve**,但单张截图最简单的是:
```bash
# 先让 pipeline 跑起来,同时在 X 里预览
gst-launch-1.0 v4l2src device=/dev/video80 ! \
video/x-raw ! \
videoconvert ! \
xvimagesink &
# 另开终端,抓一张
gst-launch-1.0 v4l2src device=/dev/video80 num-buffers=1 ! \
video/x-raw ! \
videoconvert ! \
pngenc ! \
filesink location=shot_$(date +%s).png
```
-------------------------------------------------
一句话
-------------------------------------------------
**把 `num-buffers=1` 加进去,png 就会写出来;**
**不加的话 pipeline 永远跑不停,Ctrl-C 只会让你空着手离开。**
{{dark_color}}
<style>.codehilite.hljs > pre {color: #fff !important;}</style>