香橙派使用USB摄像头
文章目录
- 香橙派使用USB摄像头的方法
- USB摄像头测试
- USB摄像头使用
- 启动脚本
- udev规则
- 开机mjpg-streamer服务自启
- 优化服务启动方式
香橙派使用USB摄像头的方法
USB摄像头测试
-
首先将USB摄像头插入到Orange Pi开发板的USB接口中
-
然后通过
lsmod | grep uvcvideo命令可以看到内核自动加载了下面的模块
-
通过
v4l2-ctl命令可以看到USB摄像头的设备节点信息为dev/video1(需要注意的是这里的video1可能会改变,下一次插入它显示的可能就为video0)#1.首先安装v4l-utils工具 sudo apt-get update sudo apt-get install -y v4l-utils#2.使用v4l-untils工具查看摄像头设备节点 orangepi@orangepizero2:~$ v4l2-ctl --list-devices cedrus (platform:cedrus):/dev/video0/dev/media0#这个是我的摄像头 Q8 HD Webcam: Q8 HD Webcam (usb-5200000.usb-1):/dev/video1 #通常是第一个要用的设备节点信息 /dev/video2/dev/media1 -
使用
fswebcam测试USB摄像头-
安装
fswebcamsudo apt-get update sudo apt-get install -y fswebcam -
安装完
fswebcam后可以使用下面的命令来拍照-d选项用于指定USB摄像头的设备节点--no-banner用于去除照片的水印-r选项用于指定照片的分辨率-S选项用于设置与跳过前面的帧数./image.jpg用于设置生成照片的名字和路径
sudo fswebcam -d /dev/video1 --no-banner -r 1280x720 -S 5 ./image.jpg -
在香橙派上拍照完成后,可以使用
scp指令将照片传到Ubuntu上去查看scp image.jpg usrname@192.168.0.31:/home/username #根据实际情况修改用户名、IP地址和路径 -
在Ubuntu中可以直接查看刚刚在香橙派上拍的照片
-
-
使用
mjpg-streamer测试USB摄像头-
下载
mjpg-streamergit clone https://gitee.com/leeboby/mjpg-streamer #这里选用国内的gitee,国外的GitHub对网络要求较高 -
安装依赖的软件包
#Ubuntu系统 sudo apt-get install -y cmake libjpeg8-dev -
编译安装
mjpg-streamercd mjpg-streamer/mjpg-streamer-experimental/ make -j4 #-j4表示使用所有板载内核来处理任务 sudo make install -
然后输入下面的命令启动
mjpg-streamerexport LD_LIBRARY_PATH=. #将当前路径添加到环境变量中 sudo \ ./mjpg_streamer -i "./input_uvc.so -d /dev/video1 -u -f 30" \ -o "./output_http.so -w ./www"#这里的video1要根据上边执行v4l2-ctl --list-devices来确定 -
然后在浏览器输入
开发板IP地址+端口号就能查看摄像头输出的画面了
-
USB摄像头使用
上边已经介绍了怎么测试板子是否能够正确的连接USB摄像头,接下来介绍一下后续怎么使用它。
启动脚本
在/mjpg-streamer/mjpg-streamer-experimental文件夹中默认就有一个启动的脚本start.sh,查看脚本内容发现有一句话和刚刚输入的测试命令很像

直接将这条命令修改成如下内容:
./mjpg_streamer -i "./input_uvc.so -d /dev/video0 -u -f 30" -o "./output_http.so -w ./www"
#这里的/dev/video1不是固定的,修改完内容后保存退出
然后直接在当前目录运行./start.sh看看服务能否正常运行,同上在浏览器输入IP地址进行查看。

udev规则
简单介绍以下udev规则,udev规则就是当一个设备插入到板子中,内核时最先知晓的,这时候udev就给这个设备创建一个单独的文件,当这个设备拔走时,udev又会将这个文件自动删除。这样极大地方便了用户查找对应的设备文件,所以现在给摄像头编写udev规则,保证摄像头对应的设备文件时唯一的。这是维基百科关于udev的概述:udev - 维基百科,自由的百科全书
-
查看usb ID:
lsusb
通过拔插摄像头确定摄像头的设备ID是:
1bcf:2281 -
查看usb设备的信息
#首先使用v4l2-ctl指令查看usb摄像头的设备节点 v4l2-ctl --list-devices Q8 HD Webcam: Q8 HD Webcam (usb-fc880000.usb-1):/dev/video1/dev/video2/dev/media0 #然后使用指令查看usb设备信息,这里的video1不是固定的,是要根据上边的设备节点进行调整的 udevadm info -a -p /sys/class/video4linux/video1looking at device '/devices/platform/soc/5200000.usb/usb2/2-1/2-1:1.0/video4linux/video1':KERNEL=="video1"SUBSYSTEM=="video4linux"DRIVER==""ATTR{dev_debug}=="0"ATTR{index}=="0"ATTR{name}=="Q8 HD Webcam: Q8 HD Webcam"ATTR{power/control}=="auto"ATTR{power/runtime_active_time}=="0"ATTR{power/runtime_status}=="unsupported"ATTR{power/runtime_suspended_time}=="0"looking at parent device '/devices/platform/soc/5200000.usb/usb2/2-1/2-1:1.0':KERNELS=="2-1:1.0"SUBSYSTEMS=="usb"DRIVERS=="uvcvideo"ATTRS{authorized}=="1"ATTRS{bAlternateSetting}==" 0"ATTRS{bInterfaceClass}=="0e"ATTRS{bInterfaceNumber}=="00"ATTRS{bInterfaceProtocol}=="00"ATTRS{bInterfaceSubClass}=="01"ATTRS{bNumEndpoints}=="01"ATTRS{iad_bFirstInterface}=="00"ATTRS{iad_bFunctionClass}=="0e"ATTRS{iad_bFunctionProtocol}=="00"ATTRS{iad_bFunctionSubClass}=="03"ATTRS{iad_bInterfaceCount}=="02"ATTRS{interface}=="Q8 HD Webcam"ATTRS{supports_autosuspend}=="1"looking at parent device '/devices/platform/soc/5200000.usb/usb2/2-1':KERNELS=="2-1"SUBSYSTEMS=="usb"DRIVERS=="usb"ATTRS{authorized}=="1"ATTRS{avoid_reset_quirk}=="0"ATTRS{bConfigurationValue}=="1"ATTRS{bDeviceClass}=="ef"ATTRS{bDeviceProtocol}=="01"ATTRS{bDeviceSubClass}=="02"ATTRS{bMaxPacketSize0}=="64"ATTRS{bMaxPower}=="500mA"ATTRS{bNumConfigurations}=="1"ATTRS{bNumInterfaces}==" 4"ATTRS{bcdDevice}=="0429"ATTRS{bmAttributes}=="80"ATTRS{busnum}=="2"ATTRS{configuration}==""ATTRS{devnum}=="2"ATTRS{devpath}=="1"ATTRS{devspec}=="(null)"ATTRS{idProduct}=="2281"ATTRS{idVendor}=="1bcf"ATTRS{ltm_capable}=="no"ATTRS{manufacturer}=="Q8 HD Webcam"ATTRS{maxchild}=="0"ATTRS{power/active_duration}=="4473204"ATTRS{power/autosuspend}=="2"ATTRS{power/autosuspend_delay_ms}=="2000"ATTRS{power/connected_duration}=="4478404"ATTRS{power/control}=="auto"ATTRS{power/level}=="auto"ATTRS{power/persist}=="1"ATTRS{power/runtime_active_time}=="4472866"ATTRS{power/runtime_status}=="active"ATTRS{power/runtime_suspended_time}=="5128"ATTRS{product}=="Q8 HD Webcam"ATTRS{quirks}=="0x0"ATTRS{removable}=="unknown"ATTRS{rx_lanes}=="1"ATTRS{speed}=="480"ATTRS{tx_lanes}=="1"ATTRS{urbnum}=="1115253"ATTRS{version}==" 2.00"#这里需要注意的是它会输出很多的信息,而且通过观察不难发现它输出的形式是逐级向父目录靠近的,这里我们只需要获取到它的几个关键值,使用grep指令过滤出关键信息,由于知道它是逐级向父目录靠近的,所有第一个拿到的就是摄像头对应的idProduct和idVendor orangepi@orangepizero2:~$ udevadm info -a -p /sys/class/video4linux/video1 | grep "ATTRS{idProduct}"ATTRS{idProduct}=="2281"ATTRS{idProduct}=="0002" orangepi@orangepizero2:~$ udevadm info -a -p /sys/class/video4linux/video1 | grep "ATTRS{idVendor}"ATTRS{idVendor}=="1bcf"ATTRS{idVendor}=="1d6b"#拿到几个关键的信息 KERNEL=="video1" SUBSYSTEM=="video4linux" DRIVERS=="uvcvideo" ATTRS{idProduct}=="2281" ATTRS{idVendor}=="1bcf" #这几个地方都对应的摄像头的唯一标识 -
构建udev规则
基于上述信息,编写唯一的规则来匹配摄像头设备。
cd /etc/udev/rules.d ls #查看当前目录下的udev规则,需要注意的是必须以.rules为后缀,否则不会生效 orangepi@orangepizero2:/etc/udev/rules.d$ ls 10-wifi-disable-powermanagement.rules 50-usb-realtek-net.rules sudo vi orangepi_camera.rules # 匹配摄像头设备 KERNEL=="video*", SUBSYSTEM=="video4linux", \ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2281", \SYMLINK+="orangepi_camara"#KERNEL=="video*": #匹配所有名为 videoX 的设备(例如 video0, video1 等)。 #SUBSYSTEM=="video4linux": #确保设备属于 video4linux 子系统。#ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2281": #根据 USB 设备的 idVendor 和 idProduct 属性进一步确认设备的唯一性。 #SYMLINK+="orangepi_camara": #创建一个符号链接 /dev/orangepi_camara,方便用户访问该设备。 -
测试 udev 规则
-
重新加载udev规则
sudo udevadm control --reload-rules sudo udevadm trigger -
验证符号链接
检查
/dev/目录下是否生成了orangepi_camara符号链接:ls -l /dev/orangepi_camara#使用udev创建的一个符号连接/dev/orangepi_camera -
修改
start.sh文件将里边的设备节点从
/dev/video1改为/dev/orangepi_camera,这时候无论它的设备节点怎么变,只要运行这个脚本就能够启动mjpg-streamer服务 -
在
/home/orangepi路径底下新建一个mjpg.sh,跳转到start.sh所在的目录,然后执行start.shvi start.sh#将下边这段内容加进去#/bin/bashcd /home/orangepi/mjpg-streamer/mjpg-streamer-experimental ./start.sh#保存后然后加权限 sudo chmod +x mjpg.sh#运行看看能不能跑起mjpg-streamer服务 ./mjpg.sh
-
开机mjpg-streamer服务自启
要想实现开机自动启动mjpg-streamer服务需要先写一个脚本来运行当前这个目录下的start.sh,开启自启的文件存放在/etc/xdg/autostart文件夹下。进入到这个目录随后编写mjpg-streamer开机启动的脚本。
cd /etc/xdg/autostart/sudo vi mjpg-streamer.desktop #新建启动脚本#添加以下内容
[Desktop Entry]
Name=mjpg-streamer
Comment=Start mjpg-streamer on boot
Exec=/home/orangepi/mjpg.sh
Path=/home/orangepi/
Type=Application
NoDisplay=true#重启系统
sudo reboot#查看mjpg-streamer服务是否启动
ps -aux | grep mjpg |grep -v greporangepi 2307 0.0 0.0 2308 816 ? S 10:08 0:00 /bin/sh /home/orangepi/mjpg.sh
orangepi 2321 0.5 0.0 455696 5944 ? Sl 10:08 0:02 ./mjpg_streamer -i ./input_uvc.so -d //dev/orangepi_camera -u -f 30 -o ./output_http.so -w ./www
优化服务启动方式
上边的服务能够跑起来的前提是需要在板子还没有启动前将摄像头插入到板子中,如果先启动板子,那么udev规则就检测不到摄像头的设备节点,那么服务就启动失败。因为udev规则是设备插上去以后才生效的,如果没有插上去,规则不会执行,系统也不会报错。并且当中途需要拔掉摄像头再插回去还需要把原有的mjpg-streamer服务杀掉,重新手动运行mjpg.sh,这样才能后启动服务。所以这里优化它的启动方式:插上USB摄像头后启动服务,拔掉以后关闭服务,这样子就会比较方便了。
-
首先查看一下后台是否有
mjpg-streamer的服务运行,如果有就杀掉它ps -aux|grep mjpg | grep -v grep#如果这里有mjpg的进程就杀掉它 kill -9 $PID #PID为进程号 -
然后删掉开机自动启动脚本和
/home/orangepi/下的mjpg.shsudo rm /etc/xdg/autostart/mjpg-streamer.desktoprm mjpg.sh -
然后修改
/home/orangepi/mjpg-streamer/mjpg-streamer-experimental这个文件夹底下的start.shcd mjpg-streamer/mjpg-streamer-experimental/ vi start.sh#!/bin/bashexport LD_LIBRARY_PATH=$(pwd)# 找出 USB 摄像头下的第一个 /dev/videoX 设备,并去除前后空格 #将下边这段内容加进入 VIDEO_DEVICE=$(v4l2-ctl --list-devices | awk ' /usb/ {flag=1; next} /^[^ \t]/ {flag=0} flag && /\/dev\/video/ {print; exit} ' | sed 's/^[ \t]*//;s/[ \t]*$//')# 如果没找到就默认 /dev/video0 [ -z "$VIDEO_DEVICE" ] && VIDEO_DEVICE="/dev/video0"echo "Using video device: $VIDEO_DEVICE"./mjpg_streamer -i "./input_uvc.so -d $VIDEO_DEVICE -u -f 30" -o "./output_http.so -w ./www"
-
测试
start.sh是否能够正常运行#输出以下信息说明启动成功 ./start.sh Using video device: /dev/video0 MJPG Streamer Version: git rev: 85f89a8c321e799fabb1693c5d133f3fb48ee748i: Using V4L2 device.: /dev/video0i: Desired Resolution: 640 x 480i: Frames Per Second.: 30i: Format............: UYVYi: JPEG Quality......: 80i: TV-Norm...........: DEFAULTi: Could not obtain the requested pixelformat: UYVY , driver gave us: MJPG... will try to handle this by checking against supported formats.... Falling back to the faster MJPG mode (consider changing cmd line options). UVCIOC_CTRL_ADD - Error at Pan (relative): Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Tilt (relative): Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Pan Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Tilt Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Pan/tilt Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_ADD - Error at Focus (absolute): Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Pan (relative): Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Tilt (relative): Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Pan Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Tilt Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Pan/tilt Reset: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Focus (absolute): Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at LED1 Mode: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at LED1 Frequency: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Disable video processing: Inappropriate ioctl for device (25) UVCIOC_CTRL_MAP - Error at Raw bits per pixel: Inappropriate ioctl for device (25)o: www-folder-path......: ./www/o: HTTP TCP port........: 8080o: HTTP Listen Address..: (null)o: username:password....: disabledo: commands.............: enabled#测试完以后Ctrl+C杀掉这个进程,要不然后续再启动出错,因为进程已经启动了 -
创建
systemd服务sudo vi /etc/systemd/system/mjpg-streamer.service#添加以下内容 #这里的mjpg-stream的路径若是不一样需要修改 [Unit] Description=MJPG Streamer Service After=network.target[Service] Type=simple WorkingDirectory=/home/orangepi/mjpg-streamer/mjpg-streamer-experimental ExecStart=/home/orangepi/mjpg-streamer/mjpg-streamer-experimental/start.sh Restart=on-failure KillMode=control-group[Install] WantedBy=multi-user.target保存后,执行以下命令测试一下能否手动启动:
sudo systemctl daemon-reexec sudo systemctl daemon-reload sudo systemctl start mjpg-streamer.service#查看进程是否启动 orangepi@orangepi5plus:~$ ps -aux | grep mjpg | grep -v grep orangepi 3730 0.0 0.0 2308 832 ? Ss 10:46 0:00 /bin/sh /home/orangepi/mjpg-streamer/mjpg-streamer-experimental/start.sh orangepi 3737 1.5 0.0 455696 6012 ? Sl 10:46 0:02 ./mjpg_streamer -i ./input_uvc.so -d /dev/video0 -u -f 30 -o ./output_http.so -w ./www -
改写udev规则
sudo vi /etc/udev/rules.d/orangepi_camera.rules# 插入摄像头时启动 mjpg-streamer ACTION=="add", SUBSYSTEM=="video4linux", KERNEL=="video*", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2281", ATTRS{product}=="Q8 HD Webcam", RUN+="/bin/systemctl start mjpg-streamer.service"# 拔出摄像头时停止 mjpg-streamer ACTION=="remove", SUBSYSTEM=="video4linux", KERNEL=="video*", ATTRS{idVendor}=="1bcf", ATTRS{idProduct}=="2281", ATTRS{product}=="Q8 HD Webcam", RUN+="/bin/systemctl stop mjpg-streamer.service"应用规则并测试
sudo udevadm control --reload-rules sudo udevadm trigger然后先运行
journalctl服务, 通过拔插摄像头来查看mjpg-streamer.service是否被自动启动。sudo journalctl -f这里我先拔掉摄像头,显示内容如下:

然后再插上摄像头,显示内容如下:

通过观察发现它确实是插上摄像头开始运行
mjpg-streamer服务,拔掉摄像头停止运行mjpg-streamer服务。到这里就配置完成了!
