Sign inSign up

bayelc/memorygallery

By bayelc

•Updated 26 days ago

让每一张照片以更沉浸、更有温度的方式被看见

Image
Networking
Web servers
0

10K+

bayelc/memorygallery repository overview

Memory Gallery

Version DockerHub

让每一张照片以更沉浸、更有温度的方式被看见。 Memories live on.

Memory Gallery(回忆画廊) 是一款开源、轻量、全平台兼容的智能照片屏显系统。基于 Python + Flask 构建,适配矿渣设备、旧平板、智能电视与多种 ARM 架构硬件,低成本打造属于自己的家用 / 商用智能屏。


⁠功能特性

⁠核心展示
功能说明
多格式图片JPG / PNG / WEBP / HEIC / HEIF / DNG,按年/月归档
历史的今天仅播放历年今日的照片视频;无匹配时自动扩大至当月 ±3 个月
智能轮播可配置轮播间隔(默认 10 秒),支持随机 / 顺序播放
视频播放支持 MP4 / MOV / AVI / MKV / WebM,自动转码为网页友好格式
屏幕常亮防止设备休眠,保持展示不中断
⁠视觉效果
功能说明
Ken Burns 微动效缓慢缩放 + 智能焦点(基于三分法则的 8 个黄金比例点),4 档强度(微弱 / 标准 / 强烈 / 极强)
横竖屏自适应横向图片全屏展示,竖向图片居中并自动填充背景
过渡效果支持淡入淡出 / 滑动切换 / 无特效
⁠智能功能
功能说明
AI Caption本地 LLM(Ollama 等)异步为每张照片生成"每图一语",不阻塞启动
地理位置从 EXIF 读取 GPS 信息,逆地理编码为省/市地名
Bark 通知资源告警(CPU / 内存 / 磁盘)推送到 iOS 设备
监控面板实时 CPU、内存、磁盘占用与 API 响应时间
上传自动压缩用户库照片默认自动压缩(JPEG quality 90 + 24MP 缩放 + EXIF 保留),节省 40-60% 空间,画质接近无损;GIF / 含透明 PNG / 压缩后变大 → 自动跳过
轮播提前加载自适应池深(小库直接吃满,大库封顶 50 张 LRU),按需异步预加载避免切换黑屏
日志系统文件日志(按天轮转)+ 数据库日志,支持日志标签页查看
⁠媒体管理
功能说明
自动导入监控 import/ 目录,新文件自动入库(可配置间隔)
示例库sample_mode 开关,启用内置示例轮播(适合演示)
库隔离支持用户库(media_up/)和示例库(samples/)分离,可在不同模式下独立管理

⁠快速开始

⁠Docker 部署(推荐)
⁠Docker Run
docker run -d \
  --name memory-gallery \
  -p 8080:8080 \
  -v ./data:/app/data \
  -e TZ=Asia/Shanghai \
  -e MONITOR_USERNAME=admin \
  -e MONITOR_PASSWORD=admin123 \
  --restart unless-stopped \
  bayelc/memorygallery:latest

# 访问
open http://localhost:8080
⁠Docker Compose
services:
  memory-gallery:
    image: bayelc/memorygallery:latest
    container_name: memory-gallery
    ports:
      - "8080:8080"
    volumes:
      - ./data:/app/data      # 数据持久化(媒体文件、数据库、配置均在此目录)
    env_file:
      - .env
    restart: unless-stopped
⁠媒体文件

将图片/视频放入挂载的 <your-data-dir>/memorygallery-data/data/media/ 目录(默认配置):

# 假设你的媒体目录在 /path/to/photos
cp -r /path/to/photos/* "<your-data-dir>/memorygallery-data/data/media/"

> 服务启动时会自动扫描该目录并建立索引,放入照片后无需任何操作。
> 数据目录独立于项目源码,不会随 git 推送或 Docker 镜像分发。

---

## 环境变量

> 完整配置请参考 `.env.example` 模板文件。

| 变量 | 默认值 | 说明 |
|------|--------|------|
| `TZ` | Asia/Shanghai | 时区 |
| `MONITOR_USERNAME` | admin | 管理界面用户名 |
| `MONITOR_PASSWORD` | admin123 | 管理界面密码 |
| `AMAP_API_KEY` | - | 高德地图 API Key(用于地理编码) |
| `LOCAL_LLM_ENABLED` | false | 启用本地 LLM 生成 Caption |
| `LOCAL_LLM_API_URL` | - | 本地 LLM API 地址(如 `http://192.168.1.100:11434`) |
| `LOCAL_LLM_MODEL` | - | LLM 模型名(如 `qwen2.5vl:latest`) |
| `LOCAL_LLM_PROMPT` | - | 自定义 Caption prompt |
| `AI_CAPTION_ENABLED` | false | 启用云端 AI Caption |
| `AI_CAPTION_API_URL` | - | AI Caption API 地址 |
| `AI_CAPTION_API_KEY` | - | AI Caption API Key |
| `AI_CAPTION_MODEL` | - | AI Caption 模型名 |
| `AI_CAPTION_PROMPT` | - | Caption 生成提示词 |
| `BARK_ENABLED` | false | 启用 Bark 告警推送 |
| `BARK_URL` | - | Bark 通知地址(如 `https://api.day.app/YOUR_KEY`) |
| `WECHAT_WEBHOOK_URL` | - | 企业微信 Webhook 通知地址 |
| `MG_HEALTH_INTERVAL_SEC` | 300 | 健康检查上报间隔(秒),设为 0 关闭 |

---

## 配置说明

配置文件位于容器内 `/app/data/config.json`,可通过挂载覆盖:

```json
{
    "server": {
        "port": 8080,
        "host": "0.0.0.0",
        "media_dir": "media",
        "user_media_dir": "media_up",
        "import_dir": "import",
        "sample_dir": "samples"
    },
    "slideshow": {
        "interval": 10,
        "mode": "random",
        "preload_count": 2
    },
    "display": {
        "ken_burns": true,
        "ken_burns_style": "subtle",
        "ken_burns_duration": 6,
        "show_time": true,
        "time_position": "center",
        "date_format": "YYYY年MM月DD日",
        "show_weekday": true
    },
    "advanced": {
        "supported_formats": [".jpg",".jpeg",".png",".webp",".heic",".heif",".dng",".cr2",".cr3",".arw",".nef",".nrw",".raf",".orf",".rw2",".srw",".pef",".mp4",".mov",".avi",".mkv",".webm"],
        "video_transcode": true,
        "video_fps": 30,
        "video_codec": "h264",
        "video_crf": 23
    },
    "features": {
        "sample_mode": true,
        "auto_import": true,
        "watch_interval": 30,
        "play_video": true
    }
}

⁠目录结构

架构原则:项目源码与运行时数据严格分离。

# 项目源码(git 仓库,Docker 镜像源)
./MemoryGallery/
├── backend/              # Flask 后端代码
├── frontend/             # 前端(HTML/CSS/JS)
├── bundled_samples/      # 项目自带示例库(公开,构建时嵌入镜像)
├── scripts/              # 构建/部署/运维脚本
├── tests/                # pytest 测试用例
├── Dockerfile            # 镜像构建
├── docker-compose.yaml   # 生产部署
└── .github/workflows/    # CI/CD

# 运行时数据(独立目录,git 忽略,不会推送/打包)
<your-data-dir>/memorygallery-data/
├── data/                 # 容器内 /app/data 的实际存储
│   ├── config.json       # 配置文件(运行时生成)
│   ├── media/                # 用户媒体库
│   ├── media_up/            # 用户上传目录
│   ├── import/              # 自动导入监控目录
│   └── samples/             # 用户自定义示例
└── logs/                 # 应用日志、监控日志
    └── memory-gallery.db   # 监控数据库(IP、API 错误、告警历史)

容器内完整路径:
/app/
├── backend/              # 后端代码
│   ├── server.py         # Flask 主服务
│   ├── config.py         # 配置管理
│   ├── medias.py         # 媒体扫描、EXIF、地理编码
│   ├── database.py       # SQLite 媒体库 + 异步 Caption 队列
│   ├── media_manager.py  # 文件管理、自动导入
│   ├── ai_caption.py     # 本地 LLM / 云端 AI Caption 生成
│   ├── monitor_db.py     # 指标/告警/事件数据库
│   ├── logger.py         # 统一日志模块
│   └── video_utils.py    # ffmpeg 视频处理
└── frontend/             # 前端界面

⁠技术栈

|| 组件 | 版本 | 来源 / 备注 | ||------|------|------| || Python | 3.11 | 基础镜像 python:3.11-alpine | || Flask | 3.0.0 | requirements.txt 锁定 | || Werkzeug | 3.0.3 | Flask 依赖(随 Flask 锁定) | || Flask-Cors | 5.0.0 | 前后端分离 / 跨域请求 | || Pillow | 12.3.0 | 图片解码 + 缩略图 + EXIF | || pillow-heif | 1.6.0 | iPhone HEIC/HEIF 解码 | || psutil | 7.2.2 | 监控面板 CPU / 内存 / 磁盘 | || waitress | 3.0.1 | 生产 WSGI 服务器(多线程) | || requests | 2.31.0 | 高德 API / Bark / 企微 Webhook | || ffmpeg | 6.1.2-r1(Alpine community) | 视频转码 + Raw 解码 + 缩略图抽帧 | || SQLite | (内置于 Python) | 媒体库 + 监控数据库(库非服务) |

基础镜像:python:3.11-alpine(基于 Alpine Linux 3.21+)

说明:上述版本以 requirements.txt 与 Alpine apk 包索引为准。 如需精确构建后版本,可运行 docker exec memory-gallery apk info ffmpeg 查看。

⁠架构支持

镜像通过 docker buildx 同时构建 linux/amd64 + linux/arm64 双架构(默认平台由 scripts/build_and_push.py 的 DEFAULT_PLATFORMS 控制),可在树莓派 / 矿渣小主机 / NAS / x86 服务器同一镜像 tag 下无缝运行。

Docker Hub: bayelc/memorygallery⁠


⁠常见问题

⁠Q: 如何全屏播放?

浏览器访问后,点击右下角 全屏按钮 或按 F11。

⁠Q: 如何显示照片信息(时间/地点/设备)?

在设置面板中开启 显示照片信息,可选择信息位置(左下/右下)。

⁠Q: 视频无法播放?

确保文件格式在 supported_formats 中,且 play_video: true。视频会自动转码为 H.264/MP4,首次播放可能稍慢。

⁠Q: AI Caption 如何启用?
  1. 部署 Ollama 或其他兼容 OpenAI ChatGPT API 的本地 LLM
  2. 设置 LOCAL_LLM_ENABLED=true 及相关环境变量
  3. 服务启动后,新照片会自动异步生成 Caption(不阻塞轮播)
⁠Q: 媒体文件不显示?
# 进入容器检查
docker exec -it memory-gallery /bin/sh

# 示例库:数据库位于 /app/sample/media.db
# 用户库:数据库位于 /app/data/logs/media.db(需先创建)
sqlite3 /app/sample/media.db "SELECT COUNT(*) FROM media;"

# 查看媒体文件
find /app/samples -type f | wc -l   # 示例库
find /app/data/media -type f | wc -l  # 用户库(如有)
⁠Q: 如何更新到新版本?
cd /path/to/MemoryGallery
docker compose pull
docker compose up -d

数据在 bind mount ./data 目录中,更新镜像不会丢失任何数据。


⁠获取帮助

Tag summary

Content type

Image

Digest

sha256:5e7cbe517…

Size

126.5 MB

Last updated

26 days ago

docker pull bayelc/memorygallery