☰
基于树莓派与Motion打造智能监控:运动检测视频自动上传Google Photos
2026/10/19 9:16:25 网站建设 项目流程

1. 项目概述:打造一个会思考的“云眼”

几年前,我在家里装了一套传统的监控摄像头,但很快就遇到了几个头疼的问题:存储卡满了得手动清理、回看录像像大海捞针、想随时随地看看家里情况还得折腾复杂的端口映射。最关键的是,它只是个“录像机”,不会主动告诉我发生了什么。直到我开始琢磨用树莓派(Raspberry Pi)和开源软件自己搭建一套系统,事情才变得有趣起来。

这个项目的核心目标很简单:让一个普通的USB摄像头变得“聪明”起来。它不仅能7x24小时待命,还能在检测到画面中有运动时,自动录制一段短视频,并悄无声息地将其上传到你的Google Photos云端相册里。你手机上的Google Photos应用会立刻收到一条“有新内容添加”的通知,点开就能看到刚刚发生了什么。整个过程完全自动化,无需人工干预,成本极低,却实现了一套私有、智能的云端监控方案。

它特别适合那些对隐私有要求、喜欢动手折腾、又希望拥有灵活定制功能的极客和智能家居爱好者。无论是看护宠物、留意家门口的包裹,还是作为工作室的简易安防,这套基于Raspberry Pi、Motion和Google Photos API的方案,都能提供一个稳定可靠的解决方案。接下来,我将带你从零开始,一步步复现这个“云眼”系统,并分享我在搭建过程中踩过的坑和积累的经验。

2. 硬件选型与系统环境搭建

2.1 核心硬件清单与选型考量

这个项目的硬件核心非常精简,主要围绕树莓派和摄像头展开。我的选择基于“手头有什么用什么”的极客精神,但这里也给出一些选型建议,帮助你做出更优决策。

树莓派型号:Raspberry Pi 3B+我使用的是3B+,这是目前性价比和性能非常平衡的一款。它自带Wi-Fi和蓝牙,省去了额外适配器的麻烦,其四核处理器和1GB内存足以流畅运行Motion软件和Python上传脚本。如果你的项目需要同时运行更多服务(如Home Assistant),或者对视频编码速度有更高要求,可以考虑性能更强的Raspberry Pi 4B(建议2GB或4GB内存版本)。对于更基础或低功耗的场景,Zero 2 W也是不错的选择,但需要注意其接口较少,可能需要额外的USB Hub。

摄像头:罗技 C920 USB网络摄像头选择C920主要看中其几点优势:一是即插即用,Linux系统兼容性好,免驱;二是支持1080P全高清录制,画质足以满足监控需求;三是自带麦克风,如果需要录制声音也很方便。当然,你也可以使用树莓派官方的CSI摄像头模块,其优势是连接更稳定、功耗更低,并且能利用GPU进行硬件编码,对CPU负载更小。但USB摄像头的优势在于灵活性高,更换和调整位置方便。

其他必要配件:

  • Micro SD卡:建议至少16GB Class 10或以上速度的卡,用于安装操作系统和存储临时文件。长时间运行会产生日志,容量大一些更省心。
  • 电源适配器:务必使用官方或质量可靠的5V/2.5A以上电源,供电不足会导致树莓派运行不稳定,甚至损坏。
  • 外壳与散热片:建议配备一个散热外壳或至少贴上散热片,长期高负载运行(如视频编码)时,有效的散热能保证系统稳定性。

注意:如果你计划将设备部署在无法直接连接网线的地方,那么一块可靠的Wi-Fi网络就至关重要。对于3B+,确保你的路由器信号在部署点强度足够。我曾尝试使用4G LTE USB上网卡(如华为E3372h-153)为树莓派提供网络,它可以直接被系统识别,配合RaspAP等工具还能让树莓派变身移动热点,非常适合车载或临时场所的监控。但要注意,有些运营商的4G网络不支持从公网直接访问(即没有公网IP),这会导致后续的远程实时流媒体访问功能失效。

2.2 操作系统安装与基础配置

首先,我们需要为树莓派安装一个操作系统。这里推荐使用Raspberry Pi OS Lite(32位),这是一个没有图形界面的精简版本,对资源消耗更少,更适合作为长期运行的服务端。

  1. 下载与烧录:从树莓派官网下载Raspberry Pi Imager工具。插入SD卡,运行Imager,选择“Raspberry Pi OS (other)” -> “Raspberry Pi OS Lite (32-bit)”。在烧录前,点击齿轮图标进行高级设置,这步非常关键:

    • 启用SSH:勾选“Enable SSH”,建议使用“Use password authentication”并设置一个强密码。
    • 配置Wi-Fi:填写你的国家、SSID和密码,这样树莓派启动后就能自动连接网络。
    • 设置地区选项:设置时区(如Asia/Shanghai)和键盘布局。
    • 完成设置后,点击“Write”烧录系统。
  2. 首次启动与SSH连接:将烧录好的SD卡插入树莓派,接通电源。等待一分钟后,你需要找到树莓派在局域网中的IP地址。可以登录路由器管理界面查看已连接设备,或者使用网络扫描工具(如Advanced IP Scanner)。找到IP后,在电脑上使用SSH客户端(如Windows的PuTTY或终端)连接:

    ssh pi@[你的树莓派IP]

    默认密码是raspberry(如果你没在Imager中修改)。首次登录会提示修改密码,请务必设置一个复杂的新密码。

  3. 基础系统更新:连接成功后,首先更新系统软件包列表并升级现有软件,这是一个好习惯。

    sudo apt update sudo apt full-upgrade -y

    升级完成后,可以执行sudo raspi-config进行一些常用设置,例如扩展文件系统(使用整张SD卡)、更改主机名、内存分配等。

2.3 网络与安全初步设置

由于设备将长期在线并可能涉及视频流访问,基础安全设置不容忽视。

  1. 更改默认用户密码:如果你还没改,立即执行passwd命令修改pi用户的密码。
  2. (可选)创建新用户:为了提高安全性,可以创建一个新的专用用户来运行服务,而不是一直使用pi。但为了教程简洁,我们仍以pi用户操作,但会注意权限管理。
  3. 配置静态IP或DHCP保留:为了后续端口转发等操作稳定,最好让树莓派在局域网内有一个固定的IP地址。有两种方法:
    • 路由器DHCP保留:在路由器管理界面中,根据树莓派的MAC地址,为其分配一个固定的IP地址。这是最推荐的方法,无需修改树莓派配置。
    • 树莓派静态IP:编辑/etc/dhcpcd.conf文件进行配置,但容易与路由器冲突,不推荐新手使用。
  4. 防火墙考虑:Raspberry Pi OS默认没有启用防火墙(UFW)。对于暴露在公网的服务,强烈建议设置。但本项目前期仅在局域网测试,可暂不配置,待需要公网访问时再详细设置。

3. Motion运动检测软件深度配置

Motion是一款功能强大、轻量级的开源运动检测软件,它能够从视频设备(如摄像头)捕获图像,当画面发生变化(即检测到运动)时,触发一系列动作,如保存图片或视频。

3.1 Motion的安装与验证

安装Motion非常简单,通过包管理器即可完成。

sudo apt install motion -y

安装完成后,可以先不启动服务,因为我们首先要对其进行大量配置。你可以通过motion -h查看其帮助信息。默认情况下,Motion会以后台守护进程(daemon)模式运行,并通过一个配置文件控制所有行为。

3.2 核心配置文件详解与调优

Motion的配置文件位于/etc/motion/motion.conf,内容繁多,但我们只需关注其中关键部分。建议先备份原始文件:

sudo cp /etc/motion/motion.conf /etc/motion/motion.conf.backup

然后使用sudo nano /etc/motion/motion.conf进行编辑。下面逐条解释需要修改或确认的配置项及其背后的原理:

基础与守护进程设置:

# 以守护进程模式运行,释放终端 daemon on # 指定日志文件位置,方便排查问题 logfile /var/log/motion/motion.log

将daemon设为on,让Motion在后台运行。指定一个固定的日志文件路径,比默认输出到系统日志(syslog)更方便查询。

图像与视频参数:

# 图像宽度和高度,根据摄像头能力设置。C920支持1920x1080 width 1920 height 1080 # 帧率,太高会增加CPU负担,30fps对于监控足够流畅 framerate 30 # 输出图片质量(1-100),100为最佳 quality 100 # 运动检测前预捕获的帧数,用于生成包含运动开始瞬间的视频 pre_capture 5 # 运动停止后继续捕获的帧数,确保事件记录完整 post_capture 5 # 关闭输出静态图片,我们只关注视频 output_pictures off

pre_capture和post_capture是让录像更实用的关键。假设一个快递员走到门口放下包裹然后离开,pre_capture 5能确保录像包含他走进画面的最初几帧,post_capture 5则能录到他离开后的画面,避免了录像只从运动中间开始、到运动中间结束的尴尬。

视频编码与输出设置(重点与难点):

# 关闭Motion内置的FFmpeg电影生成功能,我们将使用更灵活的外部管道 ffmpeg_output_movies off # 启用外部管道(extpipe)功能 use_extpipe on # 定义外部管道命令:使用ffmpeg进行实时编码 extpipe ffmpeg -y -f rawvideo -pix_fmt yuv420p -video_size %wx%h -framerate %fps -i pipe:0 -vcodec libx264 -preset ultrafast -f mp4 %f.mp4

这是配置中最精妙也最容易出错的部分。Motion内置的ffmpeg_output_movies功能生成的视频格式和参数比较固定,且与事件触发的配合有时不理想。我们选择use_extpipe on,即让Motion将原始的YUV视频流通过管道(pipe)实时传递给一个外部命令处理,这里就是ffmpeg。

  • -f rawvideo -pix_fmt yuv420p:指定输入是原始YUV420格式的视频数据。
  • -video_size %wx%h -framerate %fps:Motion会自动将宽度、高度和帧率作为参数传递给ffmpeg。
  • -i pipe:0:从标准输入(管道)读取数据。
  • -vcodec libx264 -preset ultrafast:使用H.264编码器,ultrafast预设能最大程度降低编码对树莓派CPU的消耗,保证实时性,代价是文件体积会稍大一些。对于监控场景,速度优先于压缩率。
  • -f mp4 %f.mp4:输出为MP4容器格式,%f由Motion替换为生成的文件名(基于时间戳)。
  • -y:自动覆盖已存在的输出文件。

目标目录与事件触发命令:

# Motion输出文件(如图片、视频)的存放目录 target_dir /var/lib/motion # 当视频文件生成完成时执行的命令(暂时用分号注释掉) ; on_movie_end sudo python3 /var/lib/motion/photos.py %f.mp4 &

target_dir指定了录像文件的存放位置。on_movie_end是整个自动化的灵魂。它定义了一个钩子(hook):每当一个视频文件(由extpipe生成)最终完成写入时,就执行后面定义的命令。我们计划在这里调用Python上传脚本。注意:初始配置时,请保持这行被注释(以分号开头),等我们测试好上传脚本后再启用。

3.3 用户权限与服务启动的陷阱

Motion服务默认以一个名为motion的系统用户运行。这带来了一个关键问题:这个用户对/home/pi目录下的文件通常没有读写权限。如果我们把Python脚本和凭证放在/home/pi下,Motion触发命令时会因权限不足而失败。

正确的文件部署路径:我们之前将target_dir设为/var/lib/motion,这是Motion进程拥有写权限的目录。我们的上传脚本photos.py和认证文件token.pickle也应该放在这里。你需要使用sudo权限来移动文件到这个目录。

修改Motion服务启动开关:编辑Motion的默认服务配置,确保它开机自启:

sudo nano /etc/default/motion

找到start_motion_daemon=这一行,确保其值为yes:

start_motion_daemon=yes

一个关键的权限教训:我最初在安装Python依赖包时,直接以pi用户运行pip3 install ...。这样安装的包位于/home/pi/.local目录下。当Motion服务(以motion用户身份)触发Python脚本时,它找不到这些包,导致脚本静默失败(无错误输出到日志,极难排查)。

解决方案是全局安装依赖包:

sudo pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

使用sudo安装,包会被安装到系统全局目录(如/usr/local/lib/python3.9/dist-packages/),对所有用户可用。这是解决此类“后台服务调用脚本”权限问题的常用方法。

4. Google Photos API集成与自动化上传

让树莓派自动把视频传到Google Photos,是整个项目“云化”的关键。这需要通过Google Photos API来实现。

4.1 API项目创建与凭证获取

  1. 访问Google Cloud Console:用你的Google账号登录 Google Cloud Console 。
  2. 创建新项目:点击顶部项目下拉框,选择“新建项目”,给它起个名字,例如“RPi-Motion-Uploader”。
  3. 启用API:在项目仪表板中,点击“启用API和服务”,搜索并启用“Google Photos Library API”。
  4. 创建凭据:
    • 在API概览页,点击“创建凭据”。
    • 应用类型选择“桌面应用”。
    • 填写名称后点击“创建”。
    • 完成后,你会下载一个名为credentials.json的JSON文件。这个文件包含了你的应用密钥,务必妥善保管,不要泄露或上传到公开仓库。

安全建议:强烈建议专门创建一个新的Google账号来运行这个监控项目,而不是使用你的主账号。原因有三:一是隔离风险,即使该项目的API凭证意外泄露,也不会影响主账号;二是你可以将共享相册分享给主账号来接收通知,实现功能分离;三是Google Photos每个账号有免费的15GB存储空间,专用账号可以避免占用主账号空间。

4.2 Python环境与上传脚本解析

我们将使用Google官方提供的Python客户端库来与API交互。脚本的核心逻辑是:验证身份 -> 创建或获取共享相册 -> 上传媒体文件 -> 将文件添加到相册。

以下是一个精简版的上传脚本photos.py的核心逻辑剖析,你可以在我的GitHub仓库找到完整可用的版本。

#!/usr/bin/env python3 """ Google Photos 自动上传脚本 用于被Motion的on_movie_end事件调用 """ import os import pickle import sys from google.auth.transport.requests import Request from google.oauth2.credentials import Credentials from google_auth_oauthlib.flow import InstalledAppFlow from googleapiclient.discovery import build from googleapiclient.http import MediaFileUpload # 如果修改了这些作用域,请删除本地的token.pickle文件 SCOPES = ['https://www.googleapis.com/auth/photoslibrary', 'https://www.googleapis.com/auth/photoslibrary.sharing'] def get_authenticated_service(): """��行OAuth2.0认证并返回构建好的API服务对象""" creds = None # token.pickle文件存储了用户的访问和刷新令牌 if os.path.exists('token.pickle'): with open('token.pickle', 'rb') as token: creds = pickle.load(token) # 如果凭证不存在或��失效,则让用户登录 if not creds or not creds.valid: if creds and creds.expired and creds.refresh_token: creds.refresh(Request()) # 尝试刷新令牌 else: # 首次运行会打开浏览器进行授权 flow = InstalledAppFlow.from_client_secrets_file( 'credentials.json', SCOPES) creds = flow.run_local_server(port=0) # 保存凭证供下次使用 with open('token.pickle', 'wb') as token: pickle.dump(creds, token) # 构建Photos API服务 return build('photoslibrary', 'v1', credentials=creds, static_discovery=False) def upload_to_album(service, file_path, album_name="Motion_Detected"): """ 将文件上传到指定相册(如果不存在则创建) """ # 1. 查找或创建相册 albums_response = service.albums().list(pageSize=50).execute() album_id = None for album in albums_response.get('albums', []): if album['title'] == album_name: album_id = album['id'] break if not album_id: # 创建新相册并设置为共享 created_album = service.albums().create(body={'album': {'title': album_name}}).execute() album_id = created_album['id'] # 启用共享,获取分享链接(可选) service.albums().share(albumId=album_id, body={}).execute() # 2. 上传文件 file_name = os.path.basename(file_path) media_upload = MediaFileUpload(file_path, mimetype='video/mp4', resumable=True) upload_request = service.mediaItems().upload(body={}, media_body=media_upload) upload_response = upload_request.execute() upload_token = upload_response.get('uploadToken') if upload_token: # 3. 将上传的媒体项添加到相册 request_body = { 'albumId': album_id, 'newMediaItems': [{ 'description': file_name, 'simpleMediaItem': {'uploadToken': upload_token} }] } service.mediaItems().batchCreate(body=request_body).execute() print(f"Successfully uploaded and added '{file_name}' to album '{album_name}'.") else: print(f"Upload failed for '{file_name}'.") if __name__ == '__main__': if len(sys.argv) != 2: print("Usage: python3 photos.py <file_path>") sys.exit(1) file_to_upload = sys.argv[1] if not os.path.exists(file_to_upload): print(f"Error: File '{file_to_upload}' does not exist.") sys.exit(1) try: service = get_authenticated_service() upload_to_album(service, file_to_upload) except Exception as e: print(f"An error occurred: {e}")

脚本工作流程解析:

  1. 认证:get_authenticated_service函数处理OAuth2.0流程。首次运行会在树莓派上启动一个本地服务器,并打印授权URL。由于树莓派通常无浏览器,你需要在一台有浏览器的电脑上完成首次授权(将脚本和credentials.json临时复制到PC运行一次)。授权成功后生成的token.pickle文件包含了长期有效的刷新令牌,可复制回树莓派。
  2. 相册管理:upload_to_album函数首先检查是否存在名为“Motion_Detected”的相册,没有则创建并自动设置为共享相册。
  3. 上传与关联:使用分块上传方式上传视频文件,获得一个upload_token。然后通过batchCreate方法,将这个token代表的媒体项添加到目标相册中。这是关键一步:Google Photos API中,上传和加入相册是两个独立的操作。

4.3 授权流程实战与文件部署

这是集成环节最容易卡住的地方,请严格按照步骤操作:

  1. 在个人电脑(非树莓派)上完成首次授权:

    • 在电脑上安装Python3和所需库:pip3 install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib。
    • 将credentials.json和上面的photos.py脚本放在同一目录。
    • 运行python3 photos.py test.jpg(可以随便用一张图片测试)。脚本会提示你访问一个URL,并输入显示的验证码。
    • 在浏览器中完成登录和授权(确保登录的是你为项目创建的专用Google账号)。
    • 授权成功后,脚本目录下会生成token.pickle文件,测试图片也会出现在该账号Google Photos的“Motion_Detected”相册中。
  2. 将关键文件部署到树莓派:

    • 使用scp命令将photos.py和token.pickle从电脑传到树莓派的pi用户家目录:
      scp photos.py token.pickle pi@[树莓派IP]:/home/pi/
    • 登录树莓派,将它们移动到Motion的工作目录,并确保Motion用户有执行权限:
      ssh pi@[树莓派IP] sudo mv /home/pi/photos.py /home/pi/token.pickle /var/lib/motion/ sudo chmod +x /var/lib/motion/photos.py
    • 重要:将credentials.json也复制到/var/lib/motion/目录下。虽然脚本运行一次后主要依赖token.pickle,但某些情况下刷新令牌失效时,仍需要credentials.json来重新获取授权。
  3. 在树莓派上进行上传测试:

    • 使用fswebcam拍一张测试图片:
      sudo fswebcam /var/lib/motion/test.jpg
    • 手动运行上传脚本进行测试:
      cd /var/lib/motion sudo python3 photos.py test.jpg
    • 观察输出是否成功,并立即检查专用Google账号的“Motion_Detected”相册里是否有新图片。同时,在你的主账号(已与该相册共享)的Google Photos手机App上,应该会收到“XXX添加了照片”的通知。

5. 系统联调与全流程测试

当各个部件都准备好后,现在是时候将它们组装起来,进行端到端的测试了。

5.1 启动Motion并验证基础功能

  1. 启动Motion服务:

    sudo service motion start

    使用sudo service motion status检查服务是否正常运行。

  2. 实时监控日志:打开一个新的SSH终端窗口,实时查看Motion的日志输出,这是排查问题最重要的窗口。

    sudo tail -f /var/log/motion/motion.log
  3. 查看实时视频流:Motion默认在8081端口提供实时视频流。在局域网内另一台设备的浏览器中,输入http://[树莓派IP]:8081,你应该能看到摄像头实时画面。这是一个简单的监控界面。

  4. 触发运动检测:在摄像头前挥手或移动物体。观察日志窗口,你应该能看到类似Motion detected和End of event的日志。同时,检查/var/lib/motion/目录,应该会出现一个以时间戳命名的.mp4文件(例如01-20250410120000-01.mp4)。这说明Motion已经成功检测到运动,并通过外部管道调用ffmpeg生成了视频文件。

5.2 手动触发上传与调试

在自动化之前,我们先手动模拟Motion调用上传脚本的过程,确保万无一失。

  1. 假设Motion刚生成了一个文件01-20250410120000-01.mp4。
  2. 在树莓派上手动执行我们未来要自动化的命令:
    cd /var/lib/motion sudo python3 photos.py 01-20250410120000-01.mp4
  3. 仔细观察脚本输出。成功的话,会打印上传成功的信息。
  4. 立刻检查手机Google Photos App的通知栏,以及“Motion_Detected”相册中是否出现了这个视频。

如果手动上传失败,按以下思路排查:

  • 权限问题:确保/var/lib/motion/目录下的photos.py、token.pickle、credentials.json以及新生成的.mp4文件,对于motion用户或root用户(因为用了sudo)是可读的。可以用sudo ls -la查看。
  • Python依赖:确认是使用sudo pip3全局安装的Google API库。可以运行sudo python3 -c "import google.auth; print('OK')"测试。
  • 网络问题:确保树莓派可以正常访问互联网。ping 8.8.8.8测试连通性。
  • Token失效:删除token.pickle文件,然后在有图形界面的环境下重新运行一次脚本生成token。这是OAuth流程最麻烦的一步。

5.3 启用全自动上传

当手动上传测试成功后,就可以解开最后的“封印”,让整个流程自动化。

  1. 编辑Motion主配置文件,取消on_movie_end命令的注释:

    sudo nano /etc/motion/motion.conf

    找到此行,删除行首的分号;:

    on_movie_end sudo python3 /var/lib/motion/photos.py %f.mp4 &

    注意:命令末尾的&符号非常重要,它让这个命令在后台异步执行。这样Motion在完成视频写入后,不会等待上传脚本结束就继续处理其他事件,避免了上传过程阻塞Motion主进程。

  2. 保存配置文件,并重启Motion服务使更改生效:

    sudo service motion restart
  3. 再次观察日志sudo tail -f /var/log/motion/motion.log,并触发一次运动。

  4. 这次,除了看到视频文件生成,你还应该在日志中看到Motion启动了外部进程的提示。稍等片刻(取决于视频大小和网络速度),去检查Google Photos相册和手机通知。如果一切顺利,视频已经自动出现在云端了!

5.4 配置优化与日常维护

系统运行起来后,还可以进行一些优化:

  • 调整运动检测灵敏度:在motion.conf中,threshold(像素变化阈值)、noise_level(噪点容忍度)等参数可以调整,以适应不同环境,避免因光线变化或小昆虫飞过产生误报。
  • 设置录制时间限制:max_movie_time参数可以限制单个视频的最长时间,防止因持续运动(如风扇转动)产生巨大的视频文件。
  • 本地文件清理:Motion不会自动删除target_dir中的旧文件。可以写一个简单的Cron定时任务(例如每天凌晨3点),删除超过7天的本地视频文件,避免占满SD卡空间。
    # 编辑crontab: sudo crontab -e # 添加一行: 0 3 * * * find /var/lib/motion -name "*.mp4" -mtime +7 -delete
  • 监控服务状态:可以配置一个简单的“看门狗”,如果Motion进程意外退出,则自动重启。使用systemd的服务管理功能或cron定期检查即可。

6. 进阶功能:实现远程实时流媒体访问

如果你希望不在家时也能随时查看摄像头实时画面,就需要将树莓派的服务暴露到公网。警告:此操作存在安全风险,请务必做好安全加固。

6.1 配置Motion的远程访问与认证

首先,修改Motion配置,允许从外部网络访问视频流,并设置密码保护。

sudo nano /etc/motion/motion.conf

修改或添加以下行:

# 将流媒体服务绑定到所有网络接口 stream_localhost off # 设置流媒体认证方式,2为MD5摘要认证(更安全) stream_auth_method 2 # 设置用户名和密码,格式为 用户名:密码 stream_authentication username:your_strong_password # 提高流媒体的最大帧率 stream_maxrate 30 # Web控制界面建议只允许本地访问(默认即可) webcontrol_localhost on

重启Motion服务:sudo service motion restart。

6.2 配置动态DNS(DDNS)

家庭宽带通常没有固定的公网IP地址,IP会变化。我们需要一个DDNS服务,将一个固定的域名指向我们变化的家庭IP。

  1. 选择DDNS服务商:如文中提到的FreeDNS,或者No-IP、DuckDNS等。注册一个账户并创建一个子域名(例如myhomecam.freedns.xyz)。
  2. 在路由器上配置DDNS:大多数家用路由器都内置了常见DDNS服务商的客户端。在路由器管理界面找到DDNS设置项,填入你注册的服务商、域名、用户名和密码。这样每次路由器IP变化时,它会自动通知DDNS服务商更新记录。
  3. (备选)在树莓派上配置:如果路由器不支持,可以在树莓派上安装DDNS客户端脚本,并通过Cron定时运行。FreeDNS等网站都提供了示例脚本。

6.3 配置路由器端口转发

这是让外部流量进入你家网络的关键一步。

  1. 登录你的家庭路由器管理后台。
  2. 找到“端口转发”、“虚拟服务器”或“NAT”相关设置。
  3. 添加一条新规则:
    • 外部端口:选择一个不常用的高端口,例如51081。
    • 内部IP地址:填写你树莓派在局域网的固定IP(如192.168.1.100)。
    • 内部端口:8081(Motion的流媒体端口)。
    • 协议:TCP(或TCP/UDP)。
  4. 保存设置。

6.4 远程访问测试

完成以上步骤后,理论上你就可以在任何有互联网的地方,通过浏览器访问http://myhomecam.freedns.xyz:51081来查看实时画面了。首次访问会弹出输入用户名和密码的对话框,填入你在Motion配置中设置的即可。

至关重要的安全提醒:

  • 强密码:为流媒体访问设置一个高强度、独一无二的密码。
  • 非默认端口:使用非8081的外部端口,可以避免被自动化脚本扫描。
  • 考虑VPN:更安全的方式是先连接到家庭网络的路由器,再访问树莓派的本地IP。这完全避免了将服务暴露在公网。
  • 定期更新:保持树莓派系统、Motion和所有依赖库的更新,以修补安全漏洞。

7. 常见问题排查与经验心得

在搭建和长期使用这套系统的过程中,我遇到了不少“坑”,这里集中总结,希望能帮你节省时间。

7.1 问题排查速查表

问题现象可能原因排查步骤与解决方案
Motion服务启动失败配置文件语法错误运行sudo motion -c /etc/motion/motion.conf -n测试配置并查看错误输出。
摄像头无画面/无法打开1. 摄像头未识别
2. 权限问题
3. 被其他进程占用
1. 运行lsusb和v4l2-ctl --list-devices检查摄像头。
2. 将用户加入video组:sudo usermod -a -G video motion(或pi)。
3. 确保没有其他软件(如fswebcam)正在使用摄像头。
检测到运动但无视频生成1.target_dir权限错误
2.extpipe命令错误
3. ffmpeg未安装
1. 检查/var/lib/motion目录所有者是否为motion:motion,并有写权限。
2. 仔细检查extpipe命令拼写和路径。手动执行该命令测试。
3. 安装ffmpeg:sudo apt install ffmpeg -y。
视频生成但未自动上传1.on_movie_end命令未生效
2. Python脚本执行权限或路径错误
3. Python依赖包缺失(对motion用户)
1. 确认motion.conf中该行已取消注释,且路径正确。
2. 检查/var/lib/motion/photos.py是否有执行权限 (sudo chmod +x)。
3.最关键:使用 `sudo pip3 list
上传脚本手动运行成功,自动触发失败环境变量问题Motion守护进程的环境变量可能与Shell环境不同。尝试在Python脚本开头显式设置Python路径:#!/usr/bin/env python3,并在on_movie_end命令中使用脚本的绝对路径。
Google Photos上传失败,报认证错误1.token.pickle失效
2.credentials.json丢失或路径不对
3. API未启用或配额超限
1. 删除token.pickle,在有浏览器的环境重新生成。
2. 确保credentials.json与脚本在同一目录,且Motion用户可读。
3. 去Google Cloud Console检查API是否启用,并查看配额使用情况。
手机收不到Google Photos通知1. 相册未共享或主账号未加入
2. 手机App通知被关闭
1. 登录专用账号,进入“Motion_Detected”相册,点击分享图标,确认主账号已被添���为成员。
2. 检查主账号手机Google Photos App的通知权限是否开启。
远程无法访问视频流1. DDNS未更新
2. 端口转发错误
3. 运营商封锁端口
4. 路由器防火墙阻止
1. 在DDNS服务商网站检查域名解析的IP是否与你当前公网IP���致。
2. 在局域网内用手机流量开热点,连接后测试域名+端口,排除内网回环问题。
3. 尝试更换外部端口(如从51081改为52081)。
4. 检查路由器是否有额外的“防火墙”或“访问控制”规则阻止了入站连接。

7.2 实操心得与进阶建议

  1. 图片 vs 视频:原文作者最后提到,Google Photos的AI功能(如人脸、物体分组)对图片的分析效果远好于视频。经过我的长期使用,确实如此。如果你更看重云端AI的识别和整理功能,可以考虑修改Motion配置,将output_pictures设为on,并设置on_picture_save钩子来上传图片。图片文件更小,上传更快,AI处理也更精准。你可以同时保存图片和视频,或者只保存图片。
  2. 存储空间管理:Google Photos免费空间有限。定期清理专用账号相册里的旧媒体文件是个好习惯。你可以写一个脚本,利用Google Photos API定期列出并删除超过一定天数的项目,或者手动将重要内容保存到主账号后,清空专用账号的相册。
  3. 系统稳定性:树莓派长时间运行,SD卡可能因频繁读写而损坏。建议考虑将/var/lib/motion这个频繁写入的目录挂载到USB移动硬盘或者网络存储(NAS)上,或者使用OverlayFS来减少对SD卡的写入。此外,为树莓派配备一个UPS(不间断电源)可以在意外断电时提供安全关机的时间。
  4. 扩展可能性:这套框架的潜力不止于此。on_movie_end或on_picture_save钩子可以触发任何脚本。你可以扩展它,在检测到运动时同时发送一封带缩略图的邮件、一条Telegram消息、或者将信息发布到Home Assistant中触发更复杂的智能家居联动。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询