How to auto-play videos using IntersectionObserver in a Django project?

Problem Description:
I’m working on a Django project where I want to auto-play videos when they are at least 70% visible in the viewport and pause them when they fall below 70%. I’ve written the JavaScript using IntersectionObserver, and the logic works well on its own. However, I’m facing some issues when integrating it into my Django template.

What I Have Tried:
I have a Video model in Django where each video file is stored. In the template, I loop through the videos and apply the IntersectionObserver logic for auto-play and pause. The videos load and display correctly, but the auto-play behavior isn’t consistent.

Here’s my setup:

models.py:

class Video(models.Model):
    vidid=ShortUUIDField(length=10,max_length=100,prefix="video",alphabet="abcdefgh")
    title = models.CharField(max_length=100)
    description = models.TextField(blank=True)
    video_file = models.FileField(upload_to='videos/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

views.py:

def shorts_view(request,vidid):
    shorts1 = Video.objects.filter(vidid=vidid)
    shorts2 = Video.objects.all()

    context = {
        "shorts1":shorts1,
        "shorts2":shorts2,
    }

    return render(request,"videoshareing/shorts.html")

shorts.html

{%load static%}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Lazy Load Shorts</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0-beta3/css/all.min.css" rel="stylesheet">
    <style>
        /* Global Styles */
        body, html {
            margin: 0;
            padding: 0;
            background-color: #181818;
            color: #fff;
            font-family: Arial, sans-serif;
            height: 100%;
            overflow-y: scroll;
        }

        .shorts-container {
            display: flex;
            flex-direction: column;
        }

        .video-container {
            position: relative;
            height: 100vh;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        video {
            width: 500px;
            height: 100%;
            object-fit: cover;
        }

        .follow-button {
            position: absolute;
            top: 10px;
            left: 10px;
            padding: 8px 12px;
            background-color: #ff0000;
            color: white;
            border: none;
            border-radius: 20px;
            cursor: pointer;
            font-size: 14px;
        }

        .actions {
            position: absolute;
            right: 10px;
            top: 50%;
            transform: translateY(-50%);
            display: flex;
            flex-direction: column;
            align-items: center;
        }

        .action-button {
            margin: 10px 0;
            color: white;
            text-align: center;
            cursor: pointer;
            padding: 10px;
            background-color: rgba(0, 0, 0, 0.5);
            border-radius: 50%;
            width: 50px;
            height: 50px;
            opacity: 0.8;
        }

        .action-button span {
            display: block;
            font-size: 12px;
            margin-top: 4px;
        }

        .fa-heart, .fa-thumbs-down, .fa-comment, .fa-share {
            font-size: 20px;
        }
    </style>
</head>
<body>
    <div class="shorts-container">
        <!-- Video 1 -->
        <div class="video-container">
            {%for s in shorts2%}
            <video class="video-player" src="{% static './assets/videos/video-1.mp4' %}" muted></video>
            <button class="follow-button">Follow</button>
            <div class="actions">
                <div class="action-button like">
                    <span><i class="fa-regular fa-heart"></i></span>
                    <span>161K</span>
                </div>
                <div class="action-button dislike">
                    <span><i class="fa-regular fa-thumbs-down"></i></span>
                    <span>Dislike</span>
                </div>
                <div class="action-button comment">
                    <span><i class="fa-regular fa-comment"></i></span>
                    <span>378</span>
                </div>
                <div class="action-button share">
                    <span><i class="fa-solid fa-share"></i></span>
                    <span>Share</span>
                </div>
            </div>
            {%endfor%}
        </div>

        <!-- Video 2 -->
        <!-- <div class="video-container">
            <video class="video-player" src="{% static './assets/videos/video-2.mp4' %}" muted></video>
            <button class="follow-button">Follow</button>
            <div class="actions">
                <div class="action-button like">
                    <span><i class="fa-regular fa-heart"></i></span>
                    <span>200K</span>
                </div>
                <div class="action-button dislike">
                    <span><i class="fa-regular fa-thumbs-down"></i></span>
                    <span>Dislike</span>
                </div>
                <div class="action-button comment">
                    <span><i class="fa-regular fa-comment"></i></span>
                    <span>450</span>
                </div>
                <div class="action-button share">
                    <span><i class="fa-solid fa-share"></i></span>
                    <span>Share</span>
                </div>
            </div>
        </div> -->
    </div>
    
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            const videos = document.querySelectorAll('.video-player');

            // Create an intersection observer
            const observer = new IntersectionObserver((entries) => {
                entries.forEach(entry => {
                    const video = entry.target;

                    // If the video is in view
                    if (entry.isIntersecting) {
                        video.play(); // Play the video when it enters the viewport
                    } else {
                        video.pause(); // Pause the video when it leaves the viewport
                    }
                });
            }, {
                threshold: 0.7  // Play the video when 70% is visible
            });

            // Observe each video element
            videos.forEach(video => {
                observer.observe(video);
            });
        });
    </script>
</body>
</html>

The Problem:
Even though the videos load, the auto-play and pause functionality sometimes doesn’t work properly. It works fine when I test the plain HTML + JavaScript, but something seems off when I integrate it with Django.

What I Need Help With:

  1. Is my approach correct for integrating JavaScript with Django templates in this scenario?
  2. Are there any best practices I should follow when using IntersectionObserver with Django’s templating system?
  3. Any suggestions on how I can debug or fix the issue would be greatly appreciated.