Skip to content

fischi87/MMM-MovingPortrait

Repository files navigation

MMM-MovingPortrait

A MagicMirror² module that displays animated portrait videos with support for multiple portraits, rotation, smooth transitions, and customizable frame styles.

Perfect for creating a Hogwarts-style moving portrait gallery on your MagicMirror!

Example

Features

  • 📹 Multiple Portrait Support - Display and rotate between multiple videos
  • 🔄 Smooth Transitions - Crossfade between portraits with configurable duration
  • 🖼️ Frame Styles - Choose from Hogwarts Gold, Vintage Wood, Modern, or No Frame
  • 📝 Name Overlay - Show character names with stylish overlay
  • 🔔 Notification Support - Control playback and visibility via notifications
  • ⚙️ Fully Configurable - Customize size, opacity, timing, and more
  • 🎨 CSS Customizable - Easy to extend with your own frame styles

Installation

  1. Navigate to your MagicMirror's modules folder:
cd ~/MagicMirror/modules
  1. Clone this repository:
git clone https://github.com/fischi87/MMM-MovingPortrait.git
  1. Add your portrait videos to the videos folder:
# Copy your video files
cp /path/to/your/portrait.mp4 ~/MagicMirror/modules/MMM-MovingPortrait/videos/

Configuration

Add the module to your config/config.js file:

Minimal Configuration

{
    module: "MMM-MovingPortrait",
    position: "middle_center",
    config: {
        portraits: [
            { file: "wizard.mp4", name: "Albus Dumbledore" }
        ]
    }
}

Full Configuration with All Options

{
    module: "MMM-MovingPortrait",
    position: "middle_center",
    config: {
        // Array of portraits
        portraits: [
            { file: "dumbledore.mp4", name: "Albus Dumbledore" },
            { file: "mcgonagall.mp4", name: "Minerva McGonagall" },
            { file: "snape.mp4", name: "Severus Snape" }
        ],
        
        // Display settings
        width: "400px",
        height: "600px",
        opacity: 0.85,
        
        // Frame style: "hogwarts", "vintage", "modern", "none"
        frameStyle: "hogwarts",
        
        // Rotation settings
        rotationInterval: 30000,  // 30 seconds (0 = no rotation)
        fadeTransitionDuration: 2000,  // 2 seconds
        
        // Name display
        showName: false,  // Show portrait name
        namePosition: "bottom",  // "top" or "bottom"
        
        // Video settings
        autoplay: true,
        loop: true,
        muted: true
        
        // --- Erweiterungen für Exklusiv-Trigger ---
        activeDuration: 15000, // Zeit in ms, wie lange das Modul nach Trigger sichtbar ist
        exclusiveMode: true    // Wenn true, werden alle anderen Module ausgeblendet
    }
}

Configuration Options

Option Type Default Description
portraits Array [{file: "portrait.mp4", name: "Portrait 1"}] Array of portrait objects with file and optional name
width String "400px" Width of the portrait display
height String "600px" Height of the portrait display
opacity Number 0.85 Opacity of the entire portrait (0.0 to 1.0)
frameStyle String "hogwarts" Frame style: "hogwarts", "vintage", "modern", "none"
rotationInterval Number 30000 Time in milliseconds between portrait changes (0 = no rotation)
fadeTransitionDuration Number 2000 Duration of crossfade transition in milliseconds
showName Boolean false Display portrait name as overlay
namePosition String "bottom" Position of name overlay: "top" or "bottom"
autoplay Boolean true Autoplay videos
loop Boolean true Loop videos
muted Boolean true Mute video audio
randomOnShow Boolean true Start with random portrait when module is shown
activeDuration Number 10000 Zeit in Millisekunden, wie lange das Modul nach Exklusiv-Trigger sichtbar ist
exclusiveMode Boolean false Wenn true, werden alle anderen Module für die Dauer ausgeblendet

Frame Styles

Hogwarts Gold (frameStyle: "hogwarts")

Ornate golden frame with magical glow effect, perfect for wizard portraits.

Vintage Wood (frameStyle: "vintage")

Classic wooden frame with aged appearance.

Modern (frameStyle: "modern")

Sleek minimal frame with dark tones.

None (frameStyle: "none")

No frame, just soft shadow and rounded corners.

Creating Portrait Videos

Recommended Tools

  1. Runway Gen-3 (runwayml.com) - Best quality animated portraits
  2. Kling AI (klingai.com) - Excellent for longer videos
  3. Pika Labs (pika.art) - Quick and easy

Video Specifications

  • Format: MP4 (H.264 codec recommended)
  • Resolution: 1080x1920 (9:16 portrait) or 768x1152 (2:3)
  • Duration: 5-10 seconds (will loop automatically)
  • Frame Rate: 24-30 fps
  • File Size: Keep under 10MB for best performance

Creating a Hogwarts-Style Portrait

  1. Generate Base Image (Leonardo.ai, Midjourney, or Runway):
Renaissance oil painting portrait, elderly wizard with long white beard,
burgundy velvet robes, white ruff collar, holding wooden wand,
Tudor era clothing, dark background, aged oil painting texture,
craquelure cracks, museum quality, candlelight
  1. Animate in Runway:
Historical oil painting portrait coming to life, subtle head turn,
slow blinking, slight expression change, candlelight flickering,
aged canvas texture visible, dignified movement
  1. Download as MP4 and copy to videos/ folder

Positioning

The module uses absolute positioning by default (centered). You can change this in the CSS or use MagicMirror's standard positions:

  • top_left, top_center, top_right
  • upper_third
  • middle_center
  • lower_third
  • bottom_left, bottom_center, bottom_right

Note: For centered display, use middle_center and the module will handle positioning.

Customization

Custom Frame Styles

Add your own frame style in MMM-MovingPortrait.css:

.portrait-container.frame-custom {
    border: 10px solid #YOUR_COLOR;
    box-shadow: 0 0 30px rgba(0, 0, 0, 0.8);
    /* Add your custom styling */
}

Then use in config:

frameStyle: "custom"

Notifications

The module supports the following notifications for controlling playback and visibility:

Exklusiv-Trigger für zufälliges Portrait

Um das Modul für eine definierte Zeit exklusiv anzuzeigen und ein zufälliges Video abzuspielen, sende die Notification:

this.sendNotification("PORTRAIT_EXKLUSIV");

Ablauf:

  • Bei Empfang der Notification wird ein zufälliges Video gewählt und das Modul angezeigt.
  • Nach Ablauf der Zeit (activeDuration) wird das Modul (und ggf. andere Module) wieder ausgeblendet.

Du kannst z.B. mit dem Modul MMM-MQTTbridge oder aus einem eigenen Modul diese Notification senden.

Show / Hide / Toggle

// Show the module
this.sendNotification("PORTRAIT_SHOW");

// Hide the module
this.sendNotification("PORTRAIT_HIDE");

// Toggle between show/hide
this.sendNotification("PORTRAIT_TOGGLE");

Navigation

// Show next portrait
this.sendNotification("PORTRAIT_NEXT");

// Show previous portrait
this.sendNotification("PORTRAIT_PREVIOUS");

// Select specific portrait by index (0-based)
this.sendNotification("PORTRAIT_SELECT", { index: 2 });

// Select specific portrait by name
this.sendNotification("PORTRAIT_SELECT", { name: "Albus Dumbledore" });

Rotation Control

// Pause automatic rotation
this.sendNotification("PORTRAIT_PAUSE");

// Resume automatic rotation
this.sendNotification("PORTRAIT_RESUME");

// Stop rotation (same as pause, but with different intent)
this.sendNotification("PORTRAIT_STOP_ROTATION");

Example: Control from Other Module

// In another module's script
Module.register("MyControlModule", {
    notificationReceived: function(notification, payload, sender) {
        if (notification === "BUTTON_PRESSED") {
            if (payload.button === "next") {
                this.sendNotification("PORTRAIT_NEXT");
            }
        }
    }
});

Troubleshooting

Videos not playing

  1. Check video path:
ls ~/MagicMirror/modules/MMM-MovingPortrait/videos/
  1. Verify video format:
file ~/MagicMirror/modules/MMM-MovingPortrait/videos/your-video.mp4

Should show: ISO Media, MP4 Base Media v1

  1. Check browser console: Press Ctrl+Shift+I on your MagicMirror and look for errors

Videos are choppy

  • Reduce video resolution
  • Reduce file size (compress videos)
  • Use H.264 codec
  • Reduce rotationInterval if rotating multiple videos

Module not appearing

  1. Check MagicMirror logs:
pm2 logs mm
  1. Verify config.js syntax:
cd ~/MagicMirror
npm run config:check
  1. Restart MagicMirror:
pm2 restart mm

Examples

Single Portrait

{
    module: "MMM-MovingPortrait",
    position: "top_left",
    config: {
        portraits: [
            { file: "dumbledore.mp4", name: "Headmaster" }
        ],
        width: "300px",
        height: "450px",
        frameStyle: "hogwarts",
        showName: true
    }
}

Rotating Gallery

{
    module: "MMM-MovingPortrait",
    position: "middle_center",
    config: {
        portraits: [
            { file: "wizard1.mp4", name: "Albus Dumbledore" },
            { file: "wizard2.mp4", name: "Minerva McGonagall" },
            { file: "wizard3.mp4", name: "Severus Snape" },
            { file: "wizard4.mp4", name: "Pomona Sprout" }
        ],
        width: "500px",
        height: "750px",
        frameStyle: "hogwarts",
        rotationInterval: 20000,  // 20 seconds
        fadeTransitionDuration: 3000,  // 3 second fade
        showName: true,
        namePosition: "bottom"
    }
}

Minimal Modern Style

{
    module: "MMM-MovingPortrait",
    position: "top_right",
    config: {
        portraits: [
            { file: "portrait.mp4" }
        ],
        width: "350px",
        height: "500px",
        opacity: 0.9,
        frameStyle: "modern"
    }
}

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details

Credits

Created by Axel

Inspired by the moving portraits from Harry Potter and the Hogwarts castle.

Changelog

Version 1.3.0 (2026-01-14)

  • NEW: Added PORTRAIT_EXKLUSIV notification for exclusive portrait display
  • NEW: Added activeDuration config option - control how long portrait is visible after trigger
  • NEW: Added exclusiveMode config option - hide all other modules during portrait display
  • NEW: Random video selection on each trigger
  • REMOVED: Soft edges feature (softEdges option removed)
  • Improved MQTT integration documentation
  • Enhanced notification system for external triggers

Version 1.1.0 (2026-01-11)

  • Added Notification Support for external module control
  • Added module visibility control (show/hide/toggle)
  • Enhanced rotation pause/resume capabilities
  • Improved code structure with helper methods
  • Better logging for notifications

Version 1.0.0 (2026-01-11)

  • Initial release
  • Multiple portrait support with rotation
  • Four frame styles (Hogwarts, Vintage, Modern, None)
  • Smooth crossfade transitions
  • Name overlay support
  • Fully configurable

Support

If you encounter any issues or have feature requests, please open an issue on GitHub.


Made with ❤️ for MagicMirror²

About

MagicMirror² module displaying animated videos with smooth transitions and customizable frames

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors