如何在 Python 中使用 subprocess 设置和验证 v4l2-ctl 参数

以下代码使用 v4l2-ctl 可执行文件来获取和设置 v4l2 参数如 exposure_absolute。它还提供了写入参数并验证是否已正确设置的方法。

v4l2_set_params.py
def v4l2_set_parameters_once(params, device="/dev/video0"):
    """
    给定参数字典:
    {
        "exposure_auto": 1,
        "exposure_absolute": 10,
    }
此函数使用 v4l2-ctl 命令行可执行文件设置这些参数
    """
    set_ctrl_str = ",".join([f"{k}={v}" for k,v in params.items()]) # expsosure_absolute=400,exposure_auto=1
    subprocess.check_output(["v4l2-ctl", "-d", device, f"--set-ctrl={set_ctrl_str}"])

def v4l2_get_parameters(params, device="/dev/video0"):
    """
    查询一组 v4l2 参数。
    params is a list like
    [
        "exposure_auto",
        "exposure_absolute"
    ]

    返回值字典:
    {
        "exposure_auto": 1,
        "exposure_absolute": 10,
    }
    """
    get_ctrl_str = ",".join([f"{k}" for k in params])
    out = subprocess.check_output(["v4l2-ctl", "-d", device, f"--get-ctrl={get_ctrl_str}"])
    out = out.decode("utf-8")
    result = {}
    for line in out.split("\n"):
        # line should be like "exposure_auto: 1"
        if ":" not in line:
            continue
        k, _, v = line.partition(":")
        result[k.strip()] = v.strip()
    return result

def v4l2_set_params_until_effective(params, device="/dev/video0"):
    """
    设置 V4L2 参数并检查它们是否已正确设置。
    如果 V4L2 未正确确认参数,将再次设置它们直到生效

    params 是类似这样的字典 {
        "exposure_auto": 1,
        "exposure_absolute": 10,
    }
    """
    while True:
        v4l2_set_parameters_once(params, device=device)
        result = v4l2_get_parameters(params.keys(), device=device)
        # 检查查询的参数是否与设置的参数匹配
        had_any_mismatch = False
        for k, v in params.items():
            if k not in result:
                raise ValueError(f"Could not query {k}")
            # 注意:来自 v4l2 的值始终是字符串。因此我们需要以字符串方式比较
            if str(result.get(k)) != str(v):
                print(f"Mismatch in {k} = {result.get(k)} but should be {v}")
                had_any_mismatch = True
        # 检查是否有任何不匹配
        if not had_any_mismatch:
            return

使用示例:

v4l2_usage_example.py
v4l2_set_params_until_effective({
    "exposure_auto": 1,
    "exposure_absolute": 1000,
})

Check out similar posts by category: Audio/Video, Linux, OpenCV, Python