问题描述
所以,我有这个摄像头系统,当它检测到运动时,它会自动将视频上传到 FTP 服务器。
那些文件,我想自动移动到另一个 FTP 服务器(我的家庭助理服务器),然后通过通知 ping 我的手机。
为了在两个 FTP 服务器之间下载和上传,我使用了一个名为 FavoriteFTP 的工具,用于 Mac OS X。它允许我设置可以通过命令行运行的配置文件。
然后我通过 Automator 启动了 2 个“应用程序”以在最喜欢的 FTP 中启动不同的配置文件。一个用于从远程 FTP 服务器下载所有文件,另一个用于将这些文件上传到另一个 FTP(我的家庭助理服务器)。
最后但并非最不重要的是,我制作了第三个 Automator 应用程序,使用 HandbrakeCLI 将文件从 AVI 转码为 MP4。
以下是 3 个 Automator 应用:
这是 ftpdownload 应用程序:
/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile "Download from FTP"
这是 ftptranscode 应用程序:
SRC="/Users/frederik/cctv/motion"
DEST="/Users/frederik/cctv/motion"
DEST_EXT=mp4
HANDBRAKE_CLI=HandBrakeCLI
for FILE in "$SRC"/.avi
do
filename=$(basename "$FILE")
extension=${filename##.}
filename=${filename%.}
/usr/local/bin/HandBrakeCLI -i "$FILE" -o "$DEST"/"$filename".$DEST_EXT
done
find /Users/frederik/cctv/motion -name '.avi' -exec rm -r {} ;
这是 ftpsync 应用程序(上传到第二个 FTP):
/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile "Upload CH1 to HASS
然后我的 AppleScript 会无限循环地运行这 3 个应用程序
on idle
tell application "System Events"
tell application "ftpdownload"
run
delay 10
end tell
tell application "ftptranscode"
run
delay 20
end tell
tell application "ftpsyncapp"
run
end tell
tell application "ftpsyncappCH2"
run
end tell
return 10
end tell
end idle
总结一下: ftpdownload 是从远程 FTP 服务器下载所有 AVI 文件的应用程序 ftptranscode 是将这些文件转换为 MP4 的应用程序 ftpsyncapp 是将这些文件上传到第二个 FTP 服务器的应用程序 和 ftpsyncappCH2 执行相同的操作,但仅适用于文件名中包含“CH2”一词的文件
问题来了 一两天后,我收到一个来自 Automator 脚本的错误(见下图)。但是我只得到一个窗口弹出窗口。所以我认为它只是 3 个自动化应用之一。
https://i.imgur.com/bmz7Xxv.png
这个循环次数好像有限制 (我只需要这个永远运行)
所以现在每天都要点“确定”,有点烦。
如何避免每天收到一次此错误消息,以便我的脚本可以永远循环运行?
解决方法
我将提供两个建议。
首先:不要使用自动程序,而是创建一个保持开放的脚本应用程序,该应用程序使用 AppleScript 的 do shell script
函数来完成这项工作。空闲处理程序看起来像这样:
on idle
do shell script "/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Download from FTP'"
do shell script "
SRC='/Users/frederik/cctv/motion'
DEST='/Users/frederik/cctv/motion'
DEST_EXT=mp4
HANDBRAKE_CLI=HandBrakeCLI
for FILE in \"$SRC\"/.avi
do
filename=$(basename \"$FILE\")
extension=${filename##.}
filename=${filename%.}
/usr/local/bin/HandBrakeCLI -i \"$FILE\" -o \"$DEST\"/\"$filename\".$DEST_EXT
done
find /Users/frederik/cctv/motion -name '.avi' -exec rm -r {} ;"
do shell script "/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Upload CH1 to HASS'"
do shell script "/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Upload CH2 to HASS'"
-- check every 30 seconds
return 30
end idle
请注意,do shell script
在大多数情况下会在前进到下一个 applescript 命令之前等待来自被调用脚本的响应,因此 delay
命令不是必需的。如果收藏夹 FTP 在分离的后台线程上运行其命令可能会导致问题,但这似乎不太可能。
此外,我使用了 30 秒的空闲时间,因为我不想过于频繁地重新调用 FavoriteFTP 应用程序。默认情况下,脚本应用程序有 1 秒的空闲间隔;返回 30 使该间隔为 30 秒,这应该足以让应用完成其最后一个周期。
其次,由于这实际上只是一组 shell 脚本,而您只是使用 AppleScript 作为定期运行它们的容器,因此您可以将整个内容编写为单个 shell 脚本:
/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Download from FTP'
SRC='/Users/frederik/cctv/motion'
DEST='/Users/frederik/cctv/motion'
DEST_EXT=mp4
HANDBRAKE_CLI=HandBrakeCLI
for FILE in \"$SRC\"/.avi
do
filename=$(basename \"$FILE\")
extension=${filename##.}
filename=${filename%.}
/usr/local/bin/HandBrakeCLI -i \"$FILE\" -o \"$DEST\"/\"$filename\".$DEST_EXT
done
find /Users/frederik/cctv/motion -name '.avi' -exec rm -r {} ;
/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Upload CH1 to HASS'
/Applications/FavoriteFTP.app/Contents/MacOS/FavoriteFTPPro -profile 'Upload CH2 to HASS'
将其保存到磁盘,并作为启动作业按计划运行。 Launchd 旨在做到这一点。您将编写一个看起来像这样的 plist 文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>user.ftp.transfer.mdvideos</string>
<key>Program</key>
<string>/path/to/shellscript</string>
<key>StartInterval</key>
<integer>30</integer>
</dict>
</plist>
将其保存在 ~/Library/LaunchAgents/user.ftp.transfer.mdvideos.plist
,然后使用 unix 命令将其作为作业加载
launchctl load ~/Library/LaunchAgents/user.ftp.transfer.mdvideos.plist`
详情见man launchctl
和man launchd.plist