0%

树莓派(三)使用 Python 获取摄像头推流

  • 设备:树莓派4B 8G
  • 系统:Ubuntu Server 22.04.2 LTS
  • 语言:Python3.10.6

安装环境和依赖

安装 ffmpeg 推流

1
sudo apt-get install ffmpeg 

首次运行可能需要安装 pip3

1
sudo apt install python3-pip

安装 opencv

1
pip3 install opencv-contrib-python -i https://mirrors.aliyun.com/pypi/simple/

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import cv2
import subprocess

# 读取摄像头
cap = cv2.VideoCapture(0)

# 推流设置
rtmp = "rtmp://192.168.0.109/stream/example"
command = ['ffmpeg',
'-y',
'-f', 'rawvideo',
'-vcodec', 'rawvideo',
'-pix_fmt', 'bgr24',
# 花屏时 调整分辨率(可在获取分辨率后 进行调整)
'-s', '{}x{}'.format(640, 480),
'-r', str(30.0),
'-i', '-',
'-c:v', 'h264',
'-pix_fmt', 'yuv420p',
'-preset', 'ultrafast',
'-f', 'flv',
rtmp]

# 启动推流
pipe = subprocess.Popen(command, stdin=subprocess.PIPE)
# 获取分辨率
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
# print(size)

# 循环获取帧数
while True:
# 读取一帧
ret, frame = cap.read()

# 判断是否读取成功
if frame is None:
# 读取失败
print('read frame err!')
# 退出
continue

# 镜像
# frame = cv2.flip(frame, 1)

# 显示视频
# cv2.imshow("frame", frame)

# 按q退出
# if cv2.waitKey(1) & 0xFF == ord("q"):
# break

# 调整分辨率
img = cv2.resize(frame, size)
# 推流
pipe.stdin.write(img.tobytes())

# 释放资源
cv2.destroyAllWindows()

# 释放摄像头
cap.release()

运行

文件提权

1
sudo chmod 777 ./main.py

后台运行

1
nohup python3 ./main.py > output.log &

main.py 是你要运行的 Python 脚本。
output.log 是脚本的输出日志文件名,可以将脚本输出保存到该文件中。
& 符号将该命令放入后台运行。

执行完该命令后,你可以关闭终端或退出登录,该进程仍会继续在后台运行。脚本的输出将被重定向到 output.log 文件中,你可以使用 tail -f output.log 命令来实时查看脚本的输出。

查看进程

1
ps -ef | grep python

直播服务

直播服务可以购买大公司的直播服务,直接推流就可以了。
这里使用的 NodeJS 自己搭建直播服务。使用 Node-Media-Server,根据示例代码,可以直接搭建起来。