类似指令:
ffmpeg -f avfoundation -s 1920x1080 -framerate 25 -i 0: -vsync 0 -f image2 /path/2/.../wframe/%06d.jpg
直接运行:
ffmpeg version N-92539-g1035206102 Copyright (c) 2000-2018 the FFmpeg developers
built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
...
[avfoundation @ 0x7fa94c800000] Selected pixel format (yuv420p) is not supported by the input device.
[avfoundation @ 0x7fa94c800000] Supported pixel formats:
[avfoundation @ 0x7fa94c800000] uyvy422
[avfoundation @ 0x7fa94c800000] yuyv422
[avfoundation @ 0x7fa94c800000] nv12
[avfoundation @ 0x7fa94c800000] 0rgb
[avfoundation @ 0x7fa94c800000] bgr0
[avfoundation @ 0x7fa94c800000] Overriding selected pixel format to use uyvy422 instead.
[avfoundation @ 0x7fa94c800000] Stream #0: not enough frames to estimate rate; consider increasing probesize
Input #0, avfoundation, from '0:':
Duration: N/A, start: 11907.278033, bitrate: N/A
Stream #0:0: Video: rawvideo (UYVY / 0x59565955), uyvy422, 1920x1080, 1000k tbr, 1000k tbn, 1000k tbc
Stream mapping:
Stream #0:0 -> #0:0 (rawvideo (native) -> mjpeg (native))
Press [q] to stop, [?] for help
[swscaler @ 0x7fa94b871600] deprecated pixel format used, make sure you did set range correctly
Output #0, image2, to '/path/2/.../wframe/%06d.jpg':
Metadata:
encoder : Lavf58.23.100
Stream #0:0: Video: mjpeg, yuvj422p(pc), 1920x1080, q=2-31, 200 kb/s, 1000k fps, 1000k tbn, 1000k tbc
Metadata:
encoder : Lavc58.40.100 mjpeg
Side data:
cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: -1
frame= 55 fps= 16 q=24.8 Lsize=N/A time=00:00:03.56 bitrate=N/A speed=1.01x
...
没有问题...
核心代码:
import subprocess, time
cmd = ['ffmpeg'
, '-f', 'avfoundation'
, '-s', '1920x1080'
, '-framerate', '25' # frames per second
, '-i', '{}:'.format(drivers['w'])
, '-vsync', '0'
, '-f', 'image2'
, '{}/wframe/%06d.jpg'.format(_expath)
]
p = subprocess.Popen(cmd
, shell=False
, stdin=subprocess.PIPE
#, stdout=subprocess.PIPE
# merge err>out
#, stderr=subprocess.STDOUT
)
time.sleep(4)
p.terminate()
用 subprocess.Popen
包裹后, 在合理时机用 terminate()
来安全结束,
可是在 mac 中运行时报错:
[avfoundation @ 0x7f9f01000000] Failed to create AV capture input device: Cannot Use UNIQUESKY_CAR_CAMERA
0:: Input/output error
修订 shell=True
,或是打开其它 PIPE 都不能解决;
相同硬件, 到 win10 环境中, 用相同版本 FFmpeg 来调用, 调整好的指令类似:
ffmpeg -f dshow -s:v 1920x1080 -framerate 25 video="Integrated Webcam" -f image2 /path/2/.../wframe/%06d.jpg
一样直接在 cmd 中运行正常, 但是, 用 python 包装后, 一样出现不可用报错:
: Input/output error
[avfoundation @ 0x7fa5f7802c00] Failed to create AV capture input device: Cannot Use UNIQUESKY_CAR_CAMERA #2
0:: Input/output error
: 设备争用
[dshow @ 0000014269bab740] Could not run graph (sometimes caused by a device already in use by other application)
video=@device_pnp_\\?\usb#vid_05a3&pid_9230&mi_00#6&1d3a4c24&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global: I/O error
此时检查:
λ taskkill /IM ffmpeg.exe
错误: 没有找到进程 "ffmpeg.exe"。
并没有其它进程在使用硬件
用 FFmpeg 在 win10 环境中检验设备时是这样的
λ ffmpeg -list_devices true -f dshow -i dummy
ffmpeg version N-92539-g1035206102 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 8.2.1 (GCC) 20181017
...
[dshow @ 0000021f90a2a840] DirectShow video devices (some may be both video and audio devices)
[dshow @ 0000021f90a2a840] "Integrated Webcam"
[dshow @ 0000021f90a2a840] Alternative name "@device_pnp_\\?\usb#vid_1bcf&pid_0b09&mi_00#7&1bf8ceab&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
[dshow @ 0000021f90a2a840] DirectShow audio devices
[dshow @ 0000021f90a2a840] "楹﹀厠椋?(4- USB PnP Sound Device)"
[dshow @ 0000021f90a2a840] Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{25AB1848-CB77-42E5-9985-767755AA0C9C}"
dummy: Immediate exit requested
即, 所有可用设备有两种指代:
有老司机称:
其实是这样的,windows 那个 cmd,如果你给它双引号,好像也是会被 shell 吃掉的,然后程序的 argv 没有引号,跟 bash 有点类似;
另外,
但是, 按照以上建议无论怎么折腾都是无法正常通过 Python 完成 FFMpeg 的调用.
大家有什么其它思路?
1
menc 2018-12-01 18:25:55 +08:00
如果只是要定期杀掉,那不如用 os.system 运行 nohup 命令,然后把 pid 输出,sleep 后 kill 掉该 pid 就好
|
2
hsfzxjy 2018-12-01 18:39:35 +08:00 via Android
不明白为什么要 sleep(4)? p.communicate() 阻塞等待不好么
|
3
Philippa 2018-12-01 21:14:15 +08:00 via iPhone
Subprocess 不能保证 terminated 能够杀死进程,你要弄一个父进程然后杀整个进程树,把这个进程挂在 setsid。不要自然堵塞,要实际监控。ffmpeg 应该重新编译确保插件完备不要用 apt。摄像头要用硬编码输出不要用软件编码,否则 Cpu 占比很高。最后用 output 输出查看情况不要用 Popen,虽说其实也是封装了它。最最后加个输出视频质量检查,用 opencv。或弄个超简单的机器学习模型也可以。我弄了一个去采集数据跑了很多了没什么问题,具体原理我也不感兴趣。如果搞不定也只是拍照,去找 v4l2capture。另外建议不要搞多平台,应该用 docker。
|
4
e9e499d78f 2018-12-01 21:25:25 +08:00
用 plumbum
|
6
ZoomQuiet OP @Philippa 是也乎,( ̄▽ ̄)
多谢建议 v4l2capture , 只是这是 linux only 的? 俺也不想折腾多平台, 只是当前被迫要先部署 win10 环境发布, 客户要求... 所以..... 不过, 也打开了另外的思路, FFmpeg 并不是唯一的高性能图像 /视频抓取平台... |
7
ZoomQuiet OP |
8
ZoomQuiet OP |
9
julyclyde 2018-12-02 10:37:36 +08:00
zq 你现在做啥工作啊?咋有这么倒霉的需求要解决?
|
12
lolizeppelin 2018-12-06 14:25:08 +08:00
这个和 python 没关系
了解下 wait waitpid fork 父子进程 信号 相关的 linux 知识 回头再来看你的问题就一目了然了 |
13
ZoomQuiet OP @lolizeppelin 是也乎,( ̄▽ ̄)
问题是要解决的场景主要是 win10 中的...这就和以往 linux 进程信号机制没关系了... |
14
lolizeppelin 2018-12-06 16:16:45 +08:00
win 的原理差不多 管道什么的 都差不多逻辑
因为没 fork 处理起来比较复杂 subprocess 里怎么处理的详细读下就好,win 相关的代码还是蛮恶心的 但主要是要清楚系统这部分的原理就好了 |