[Python] HTML5 <video> poster thumbnail not showing in Odoo — want to show thumbnail initially...

Discussão em 'Python' iniciado por Stack, Julho 17, 2025.

  1. Stack

    Stack Membro Participativo

    I'm trying to implement lazy loading of videos in a dashboard view in Odoo 18. My goal is to:

    Show a thumbnail (poster) initially

    Avoid loading/buffering any video on page load

    Load and play the video only when the user hovers over it

    ✅ It works outside Odoo When I test the below code in a simple standalone HTML file, everything works perfectly. The poster loads, and the video loads/plays on hover:

    HTML

    <video
    data-src="https://storage.googleapis.com/simstar-videos/50001593/3D.mp4"
    poster="https://storage.googleapis.com/simstar-videos/50001593/still.jpg"
    muted
    playsinline
    preload="none"
    loop
    width="180"
    height="180"
    style="object-fit: cover; border: 1px solid #ccc; border-radius: 5px;"
    onmouseenter="if (!this.src) { this.src = this.dataset.src; this.load(); this.play(); }"
    onmouseleave="this.pause(); this.currentTime = 0;"
    ></video>


    ❌ But the same logic doesn't work in Odoo When I generate the same video block from Python in Odoo like this:

    Python

    def build_video_tag(url, label, width="180px", height="180px", extra_class=""):
    if url:
    poster_url = url.replace(".mp4", "/still.jpg")
    return f"""
    <div class="video-wrapper {extra_class}" style="position:relative; display:inline-block; margin:5px;">
    <video
    data-src="{url}"
    poster="{poster_url}"
    muted
    playsinline
    preload="none"
    loop
    class="media-video"
    style="width: {width}; height: {height}; object-fit: cover; border: 1px solid #ccc; border-radius: 5px;"
    ></video>
    </div>


    And bind hover events via JavaScript like this:

    js

    function bindVideoEvents(video) {
    if (video.dataset.bound) return;
    video.dataset.bound = "1";

    video.addEventListener('mouseenter', () => {
    const container = video.closest('.video-container');
    const allContainers = document.querySelectorAll('.video-container');

    if (!video.src && video.dataset.src) {
    video.src = video.dataset.src;
    video.load();
    }

    video.play().catch(() => {});
    video.style.transform = 'scale(1.8)';
    video.style.zIndex = '1000';
    video.style.position = 'relative';

    allContainers.forEach(c => {
    if (c !== container) {
    c.classList.add('blur');
    }
    });
    });

    video.addEventListener('mouseleave', () => {
    const container = video.closest('.video-container');
    const allContainers = document.querySelectorAll('.video-container');

    video.pause();
    video.currentTime = 0;
    video.style.transform = 'scale(1)';
    video.style.zIndex = '';
    video.style.position = '';

    allContainers.forEach(c => {
    c.classList.remove('blur');
    });
    });
    }

    // MutationObserver to bind events to dynamically loaded videos
    const observer = new MutationObserver(() => {
    document.querySelectorAll('video').forEach(bindVideoEvents);
    });


    In Odoo, I get a blank gray box — no thumbnail and no playback. The poster image does not load at all. It’s like the video element is rendered but not initialized properly.

    What I've Checked: ✅ Poster image URL is valid and accessible (loads fine in browser)

    ✅ Video URL is also correct (tested directly)

    ✅ preload="none" is set

    ✅ MutationObserver is attaching events

    ✅ HTML output is correct in the browser DOM

    ❓ My Questions: Why does the behave differently in Odoo, even though the same HTML works outside?

    Is there anything about Odoo’s rendering or QWeb templating that interferes with poster or data-src?

    What’s the correct way to achieve true lazy-loading video in Odoo, where videos load only on hover?

    Notes: This is inside an Odoo 18 list view

    HTML is rendered via Python controller (build_video_tag)

    JS is written as an Odoo module (odoo.define(...))

    poster URL looks like: https://storage.googleapis.com/simstar-videos/50001593/still.jpg

    Everything works perfectly in static HTML, but fails when rendered in Odoo

    Continue reading...

Compartilhe esta Página