基于树莓派与Motion打造智能监控:运动检测视频自动上传Google Photos
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 Lite32位这是一个没有图形界面的精简版本对资源消耗更少更适合作为长期运行的服务端。下载与烧录从树莓派官网下载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”烧录系统。首次启动与SSH连接将烧录好的SD卡插入树莓派接通电源。等待一分钟后你需要找到树莓派在局域网中的IP地址。可以登录路由器管理界面查看已连接设备或者使用网络扫描工具如Advanced IP Scanner。找到IP后在电脑上使用SSH客户端如Windows的PuTTY或终端连接ssh pi[你的树莓派IP]默认密码是raspberry如果你没在Imager中修改。首次登录会提示修改密码请务必设置一个复杂的新密码。基础系统更新连接成功后首先更新系统软件包列表并升级现有软件这是一个好习惯。sudo apt update sudo apt full-upgrade -y升级完成后可以执行sudo raspi-config进行一些常用设置例如扩展文件系统使用整张SD卡、更改主机名、内存分配等。2.3 网络与安全初步设置由于设备将长期在线并可能涉及视频流访问基础安全设置不容忽视。更改默认用户密码如果你还没改立即执行passwd命令修改pi用户的密码。可选创建新用户为了提高安全性可以创建一个新的专用用户来运行服务而不是一直使用pi。但为了教程简洁我们仍以pi用户操作但会注意权限管理。配置静态IP或DHCP保留为了后续端口转发等操作稳定最好让树莓派在局域网内有一个固定的IP地址。有两种方法路由器DHCP保留在路由器管理界面中根据树莓派的MAC地址为其分配一个固定的IP地址。这是最推荐的方法无需修改树莓派配置。树莓派静态IP编辑/etc/dhcpcd.conf文件进行配置但容易与路由器冲突不推荐新手使用。防火墙考虑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-100100为最佳 quality 100 # 运动检测前预捕获的帧数用于生成包含运动开始瞬间的视频 pre_capture 5 # 运动停止后继续捕获的帧数确保事件记录完整 post_capture 5 # 关闭输出静态图片我们只关注视频 output_pictures offpre_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 %fpsMotion会自动将宽度、高度和帧率作为参数传递给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这一行确保其值为yesstart_motion_daemonyes一个关键的权限教训我最初在安装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项目创建与凭证获取访问Google Cloud Console用你的Google账号登录 Google Cloud Console 。创建新项目点击顶部项目下拉框选择“新建项目”给它起个名字例如“RPi-Motion-Uploader”。启用API在项目仪表板中点击“启用API和服务”搜索并启用“Google Photos Library API”。创建凭据在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(port0) # 保存凭证供下次使用 with open(token.pickle, wb) as token: pickle.dump(creds, token) # 构建Photos API服务 return build(photoslibrary, v1, credentialscreds, static_discoveryFalse) def upload_to_album(service, file_path, album_nameMotion_Detected): 将文件上传到指定相册如果不存在则创建 # 1. 查找或创建相册 albums_response service.albums().list(pageSize50).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(albumIdalbum_id, body{}).execute() # 2. 上传文件 file_name os.path.basename(file_path) media_upload MediaFileUpload(file_path, mimetypevideo/mp4, resumableTrue) upload_request service.mediaItems().upload(body{}, media_bodymedia_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(bodyrequest_body).execute() print(fSuccessfully uploaded and added {file_name} to album {album_name}.) else: print(fUpload 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(fError: 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(fAn error occurred: {e})脚本工作流程解析认证get_authenticated_service函数处理OAuth2.0流程。首次运行会在树莓派上启动一个本地服务器并打印授权URL。由于树莓派通常无浏览器你需要在一台有浏览器的电脑上完成首次授权将脚本和credentials.json临时复制到PC运行一次。授权成功后生成的token.pickle文件包含了长期有效的刷新令牌可复制回树莓派。相册管理upload_to_album函数首先检查是否存在名为“Motion_Detected”的相册没有则创建并自动设置为共享相册。上传与关联使用分块上传方式上传视频文件获得一个upload_token。然后通过batchCreate方法将这个token代表的媒体项添加到目标相册中。这是关键一步Google Photos API中上传和加入相册是两个独立的操作。4.3 授权流程实战与文件部署这是集成环节最容易卡住的地方请严格按照步骤操作在个人电脑非树莓派上完成首次授权在电脑上安装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”相册中。将关键文件部署到树莓派使用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来重新获取授权。在树莓派上进行上传测试使用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并验证基础功能启动Motion服务sudo service motion start使用sudo service motion status检查服务是否正常运行。实时监控日志打开一个新的SSH终端窗口实时查看Motion的日志输出这是排查问题最重要的窗口。sudo tail -f /var/log/motion/motion.log查看实时视频流Motion默认在8081端口提供实时视频流。在局域网内另一台设备的浏览器中输入http://[树莓派IP]:8081你应该能看到摄像头实时画面。这是一个简单的监控界面。触发运动检测在摄像头前挥手或移动物体。观察日志窗口你应该能看到类似Motion detected和End of event的日志。同时检查/var/lib/motion/目录应该会出现一个以时间戳命名的.mp4文件例如01-20250410120000-01.mp4。这说明Motion已经成功检测到运动并通过外部管道调用ffmpeg生成了视频文件。5.2 手动触发上传与调试在自动化之前我们先手动模拟Motion调用上传脚本的过程确保万无一失。假设Motion刚生成了一个文件01-20250410120000-01.mp4。在树莓派上手动执行我们未来要自动化的命令cd /var/lib/motion sudo python3 photos.py 01-20250410120000-01.mp4仔细观察脚本输出。成功的话会打印上传成功的信息。立刻检查手机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 启用全自动上传当手动上传测试成功后就可以解开最后的“封印”让整个流程自动化。编辑Motion主配置文件取消on_movie_end命令的注释sudo nano /etc/motion/motion.conf找到此行删除行首的分号;on_movie_end sudo python3 /var/lib/motion/photos.py %f.mp4 注意命令末尾的符号非常重要它让这个命令在后台异步执行。这样Motion在完成视频写入后不会等待上传脚本结束就继续处理其他事件避免了上传过程阻塞Motion主进程。保存配置文件并重启Motion服务使更改生效sudo service motion restart再次观察日志sudo tail -f /var/log/motion/motion.log并触发一次运动。这次除了看到视频文件生成你还应该在日志中看到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 配置动态DNSDDNS家庭宽带通常没有固定的公网IP地址IP会变化。我们需要一个DDNS服务将一个固定的域名指向我们变化的家庭IP。选择DDNS服务商如文中提到的FreeDNS或者No-IP、DuckDNS等。注册一个账户并创建一个子域名例如myhomecam.freedns.xyz。在路由器上配置DDNS大多数家用路由器都内置了常见DDNS服务商的客户端。在路由器管理界面找到DDNS设置项填入你注册的服务商、域名、用户名和密码。这样每次路由器IP变化时它会自动通知DDNS服务商更新记录。备选在树莓派上配置如果路由器不支持可以在树莓派上安装DDNS客户端脚本并通过Cron定时运行。FreeDNS等网站都提供了示例脚本。6.3 配置路由器端口转发这是让外部流量进入你家网络的关键一步。登录你的家庭路由器管理后台。找到“端口转发”、“虚拟服务器”或“NAT”相关设置。添加一条新规则外部端口选择一个不常用的高端口例如51081。内部IP地址填写你树莓派在局域网的固定IP如192.168.1.100。内部端口8081Motion的流媒体端口。协议TCP或TCP/UDP。保存设置。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. 安装ffmpegsudo 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 实操心得与进阶建议图片 vs 视频原文作者最后提到Google Photos的AI功能如人脸、物体分组对图片的分析效果远好于视频。经过我的长期使用确实如此。如果你更看重云端AI的识别和整理功能可以考虑修改Motion配置将output_pictures设为on并设置on_picture_save钩子来上传图片。图片文件更小上传更快AI处理也更精准。你可以同时保存图片和视频或者只保存图片。存储空间管理Google Photos免费空间有限。定期清理专用账号相册里的旧媒体文件是个好习惯。你可以写一个脚本利用Google Photos API定期列出并删除超过一定天数的项目或者手动将重要内容保存到主账号后清空专用账号的相册。系统稳定性树莓派长时间运行SD卡可能因频繁读写而损坏。建议考虑将/var/lib/motion这个频繁写入的目录挂载到USB移动硬盘或者网络存储NAS上或者使用OverlayFS来减少对SD卡的写入。此外为树莓派配备一个UPS不间断电源可以在意外断电时提供安全关机的时间。扩展可能性这套框架的潜力不止于此。on_movie_end或on_picture_save钩子可以触发任何脚本。你可以扩展它在检测到运动时同时发送一封带缩略图的邮件、一条Telegram消息、或者将信息发布到Home Assistant中触发更复杂的智能家居联动。