|
|
這個是純粹好玩但意外有成就感的專案。
每天自動拍一張,累積一年之後做成影片,
可以看到陽台的植物長大、季節的光線變化、施工中的房子成形。

基本做法
第一步:每天定時拍一張
- alias: 每日縮時快照
- id: daily_timelapse
- triggers:
- - trigger: time
- at: "12:00:00"
- actions:
- - action: camera.snapshot
- target:
- entity_id: camera.balcony
- data:
- filename: >
- /media/timelapse/balcony/{{ now().strftime('%Y-%m-%d') }}.jpg
- mode: single
複製代碼
注意事項:
- 檔案路徑要在 HA 的 allowlist_external_dirs 裡
- 用 /media/ 底下的話,可以在 HA 的媒體瀏覽器看
- 檔名用日期,排序才會正確
- # configuration.yaml
- homeassistant:
- allowlist_external_dirs:
- - /media
- - /config/www
複製代碼
第二步:用固定時間還是固定光線?
這是一個重要的決定。
固定時間(例如每天中午 12:00):
- 優點:簡單,時間一致
- 缺點:季節變化會讓光線差很多,影片會忽亮忽暗
固定光線(例如日出後三小時):
- triggers:
- - trigger: sun
- event: sunrise
- offset: "03:00:00"
複製代碼
- 優點:光線比較一致,影片比較順
- 缺點:拍攝時間會隨季節漂移
我的建議:用「太陽仰角」
- triggers:
- - trigger: numeric_state
- entity_id: sun.sun
- attribute: elevation
- above: 45
- conditions:
- # 一天只拍一次
- - condition: template
- value_template: >
- {{ states('input_datetime.last_timelapse') | as_datetime
- | as_local | as_timestamp < today_at('00:00') | as_timestamp }}
- actions:
- - action: camera.snapshot
- target: {entity_id: camera.balcony}
- data:
- filename: /media/timelapse/balcony/{{ now().strftime('%Y-%m-%d') }}.jpg
- - action: input_datetime.set_datetime
- target: {entity_id: input_datetime.last_timelapse}
- data:
- datetime: "{{ now().strftime('%Y-%m-%d %H:%M:%S') }}"
- mode: single
複製代碼
太陽仰角相同 = 光線角度相同,這是最一致的做法。
(冬天太陽仰角可能達不到 45 度,門檻要依你的緯度調整。
台灣冬至中午的仰角大約 43-48 度,看緯度。)

第三步:提升品質的幾個技巧
一、天氣條件過濾
陰天和晴天的照片差很多。
- conditions:
- - condition: template
- value_template: >
- {{ states('weather.home') in ['sunny', 'partlycloudy'] }}
複製代碼
但這樣會有缺漏的日子。
折衷做法:每天都拍,但另外標記天氣,
後製時可以選要不要用。
- filename: >
- /media/timelapse/balcony/{{ now().strftime('%Y-%m-%d') }}_{{
- states('weather.home') }}.jpg
複製代碼
二、鎖定攝影機設定
很多 IP 攝影機會自動調整曝光和白平衡,
導致每張照片的色調不一樣。
可以的話在攝影機設定裡鎖定:
- 曝光模式改成手動
- 白平衡鎖定
- 關掉 WDR / HDR 自動調整
三、確認攝影機不會被移動
- 固定得夠牢
- 每個月檢查一次角度(可以做一個「跟上個月比對」的提醒)
角度跑掉的話,之前累積的全部白費。
第四步:合成影片
累積夠多之後,用 ffmpeg 合成。
- cd /media/timelapse/balcony
- # 先看有幾張
- ls -1 *.jpg | wc -l
- # 合成(每秒 10 張,所以 365 張約 36 秒)
- ffmpeg -framerate 10 -pattern_type glob -i '*.jpg' \
- -c:v libx264 -pix_fmt yuv420p -crf 20 \
- -vf "scale=1920:-2" \
- balcony_2026.mp4
複製代碼
幾個實用的 ffmpeg 參數:
- -framerate 10 —— 每秒幾張。太快會看不清楚,太慢會拖
- -crf 20 —— 畫質(越小越好,18-23 是常用範圍)
- -vf "scale=1920:-2" —— 縮到 1080p(-2 代表等比例,而且是偶數)
- -pix_fmt yuv420p —— 不加的話很多播放器放不出來
加上日期字幕:
- ffmpeg -framerate 10 -pattern_type glob -i '*.jpg' \
- -vf "drawtext=fontfile=/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf:\
- text='%{metadata\:date}':x=20:y=20:fontsize=36:fontcolor=white:\
- box=1:boxcolor=black@0.5" \
- -c:v libx264 -pix_fmt yuv420p out.mp4
複製代碼
比較簡單的做法是用一個 Python 腳本先把日期印上去:
- from PIL import Image, ImageDraw, ImageFont
- import glob, os
- FONT = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', 40)
- for f in sorted(glob.glob('*.jpg')):
- date = os.path.basename(f)[:10]
- im = Image.open(f)
- d = ImageDraw.Draw(im)
- # 半透明底
- d.rectangle([20, 20, 300, 80], fill=(0, 0, 0, 128))
- d.text((32, 28), date, font=FONT, fill=(255, 255, 255))
- im.save('dated/' + os.path.basename(f), quality=92)
複製代碼

自動化整個流程
每月自動合成一次:
- shell_command:
- make_timelapse: >
- bash /config/scripts/timelapse.sh {{ camera }} {{ year }}
複製代碼- #!/bin/bash
- # /config/scripts/timelapse.sh
- CAM="$1"
- YEAR="$2"
- DIR="/media/timelapse/$CAM"
- OUT="/media/timelapse/${CAM}_${YEAR}.mp4"
- cd "$DIR" || exit 1
- COUNT=$(ls -1 ${YEAR}-*.jpg 2>/dev/null | wc -l)
- if [ "$COUNT" -lt 10 ]; then
- echo "照片太少($COUNT 張),跳過"
- exit 0
- fi
- ffmpeg -y -framerate 10 -pattern_type glob -i "${YEAR}-*.jpg" \
- -c:v libx264 -pix_fmt yuv420p -crf 20 \
- -vf "scale=1920:-2" "$OUT" 2>&1 | tail -5
- echo "完成:$OUT($COUNT 張)"
複製代碼- alias: 每月合成縮時影片
- triggers:
- - trigger: time
- at: "03:00:00"
- conditions:
- - "{{ now().day == 1 }}"
- actions:
- - action: shell_command.make_timelapse
- data:
- camera: balcony
- year: "{{ now().year }}"
- - action: notify.mobile_app_charles
- data:
- title: 縮時影片已更新
- message: 本月的縮時影片合成完成
- mode: single
複製代碼
儲存空間
一張 1080p 的 JPG 大概 200-500 KB。
- 一年 365 張 → 約 100-180 MB
- 四台攝影機 → 約 400-700 MB
完全不是問題。
值得拍的題材
- 陽台植物 —— 最有成就感,一年後看很誇張
- 窗外的天空 —— 季節的光線變化
- 施工中的建築 —— 如果窗外剛好在蓋房子
- 水族箱 —— 但要加補光
- 家裡的某個角落 —— 看得出家具怎麼慢慢改變
進階:一天之內的縮時
上面是「每天一張、一年一支」。
還有另一種是「一天之內每分鐘一張」,拍雲的移動、日落。
- triggers:
- - trigger: time_pattern
- minutes: "/2"
- conditions:
- - condition: sun
- after: sunrise
- before: sunset
- actions:
- - action: camera.snapshot
- target: {entity_id: camera.sky}
- data:
- filename: >
- /media/timelapse/sky/{{ now().strftime('%Y%m%d_%H%M') }}.jpg
複製代碼
記得加清理機制,不然一天就 300 多張。
---
這篇是這一百篇裡面最不實用的一篇,
但也是我自己做得最開心的一個。
去年底看陽台那支影片的時候,
看到自己種的那盆植物從一根枝條長成一整片,
那個感覺跟省電費完全不一樣。
智能家居不一定要有用,好玩也是理由。 |
|