• Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

PHP How do I get the video to unmute when scrolled into view but mute when out of view?

Immortal2004

New Coder
I'm working on a social media platform and I need help fixing my code below so that when the user scrolls to a video, that specific video is unmuted and all other videos are muted, and when the user scrolls to another video, all videos are muted (including the one they just watched) and the new video they're watching is unmuted. I have some code below but I need to find out where I'm going wrong. I can't get the muting and unmuting functionality to work properly.

Here is my code:
PHP:
echo "<div class='card' data-post-id='".$row['id']."' role='group' style='border:2px solid rgba(255, 255, 255, 0.3); background-color:rgba(255, 255, 255, 0.2); width:24%; border-radius:12px; margin:10px'>
       <h4 style='text-align:left; font-weight:600; margin-left:10px; margin-top:11.5px; margin-bottom:-4px; font-family: Montserrat, sans-serif; color:white'>" . $row['title'] . // Display the profile picture to the left of the username
      "</h4>
      <p style='text-align:left; margin-left:10px; margin-right:10px; color:white; font-size:13px'>" . $content . "</p>
      ";


    $fileURL = 'uploads/'.$row['file_name'];
    $fileType = pathinfo($fileURL,PATHINFO_EXTENSION);
 
    if(file_exists($fileURL)){
    if(in_array(strtolower($fileType), array('mp4', 'mov', 'avi', 'flv', 'mkv', 'webm'))){
        // Display video
        echo "
        <video class='context-video context-video-" . $row['id'] . "' autoplay muted loop style='width:100%; z-index: -1; border-top:2px solid rgba(255, 255, 255, 0.3);' title='You are watching ". $row['title'] . "' preload='auto'>
            <source src='".$fileURL."' type='video/".$fileType."'>
        </video>
        <div class='custom-context-menu' id='contextMenu".$row['id']."'>
    <a href='javascript:void(0);' class='share-link' title='Click to copy link'><i class='fa-solid fa-copy'></i> &nbsp;Share</a>
    <a href='".$fileURL."' title='Click to copy link'><i class='fa-solid fa-copy'></i> &nbsp;Copy Link</a>
    <a href='https://raxie.42web.io/".$fileURL."' title='Click to download ".$fileURL."' id='download-link' download><img src='save.png' style='width:15px; margin-bottom:-4px'> &nbsp;Download</a>

</div>

        <style>
       .custom-context-menu {
        display: none;
        position: absolute;
        z-index: 1000;
        background-color: #fff;
        border-radius: 5px;
        box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
    }

    .custom-context-menu a {
        color: black;
        text-align: left;
        padding: 12px;
        text-decoration: none;
        display: block;
        border-radius: 0; /* Added this line */
    }

        </style>
        <script>

function copyToClipboard(text) {
    const textArea = document.createElement('textarea');
    textArea.value = text;
    document.body.appendChild(textArea);
    textArea.select();
    document.execCommand('copy');
    document.body.removeChild(textArea);
}
          // Add unique class to each video element
$('.context-video').addClass('context-video-' + ".$row['id'].");

$('.context-video-' + ".$row['id'].").contextmenu(function(e) {
    e.preventDefault();
    var video = $(this)[0];
    var contextMenu = $('#contextMenu".$row['id']."');
    contextMenu.empty();

    contextMenu.append(\"<a href='https://raxie.42web.io/".$fileURL."' title='Click to download ".$fileURL."' id='download-link' download><img src='save.png' style='width:19px; margin-bottom:-3px'> &nbsp;Download</a>\");
    contextMenu.css({ top: e.pageY + 'px', left: e.pageX + 'px' }).fadeIn(200);

    $(document).click(function() {
        contextMenu.fadeOut(200);
    });

     $('.share-link').click(function(e) {
        e.preventDefault();
        // Copy the link to the clipboard when the 'Share' link is clicked
        copyToClipboard('https://raxie.42web.io/".$fileURL."');
    });
    
});
        </script>
        ";
echo "
<script>
    // Your existing JavaScript code ...

    // Use Intersection Observer to control video muting/unmuting
    let videos = document.querySelectorAll('.context-video');
    videos.forEach((video) => {
        video.muted = true; // Start by muting all videos
        const observer = new IntersectionObserver((entries) => {
            entries.forEach((entry) => {
                if (entry.target.tagName === 'VIDEO') {
                    if (entry.isIntersecting) {
                        // Video entered the viewport, unmute it
                        entry.target.muted = false;
                        muteOtherVideos(entry.target);
                    } else {
                        // Video left the viewport, mute it
                        entry.target.muted = true;
                    }
                }
            });
        });
        observer.observe(video);
    });

    function muteOtherVideos(currentVideo) {
        videos.forEach((video) => {
            if (video !== currentVideo) {
                video.muted = true;
            }
        });
    }

    // ... Your existing JavaScript code ...
</script>
 
Your approach of using Intersection Observer to handle the muting and unmuting of videos as they come into and leave the viewport is a good one!

However, mixing PHP and JavaScript in the way you've done can get a bit tricky, especially when dynamically generating event handlers. Here's a cleaner approach:

  1. Let's separate the JavaScript from the PHP.
  2. Instead of adding a new Intersection Observer for every video, you can utilize one Observer for all videos.
Below is a refactored version of your JavaScript code to handle the muting/unmuting functionality:

JavaScript:
// Function to copy link to clipboard
function copyToClipboard(text) {
    const textArea = document.createElement('textarea');
    textArea.value = text;
    document.body.appendChild(textArea);
    textArea.select();
    document.execCommand('copy');
    document.body.removeChild(textArea);
}

// Handle context menu for videos
document.addEventListener('contextmenu', function(e) {
    if ($(e.target).hasClass('context-video')) {
        e.preventDefault();
        const videoId = $(e.target).data('post-id');
        const fileURL = $(e.target).find('source').attr('src');
        const contextMenu = $('#contextMenu' + videoId);
        contextMenu.empty();

        contextMenu.append("<a href='https://raxie.42web.io/" + fileURL + "' title='Click to download " + fileURL + "' id='download-link' download><img src='save.png' style='width:19px; margin-bottom:-3px'> &nbsp;Download</a>");
        contextMenu.css({ top: e.pageY + 'px', left: e.pageX + 'px' }).fadeIn(200);

        $(document).click(function() {
            contextMenu.fadeOut(200);
        });

        $('.share-link').click(function(e) {
            e.preventDefault();
            // Copy the link to the clipboard when the 'Share' link is clicked
            copyToClipboard('https://raxie.42web.io/' + fileURL);
        });
    }
});

// Mute/Unmute videos using Intersection Observer
const videos = document.querySelectorAll('.context-video');
const observer = new IntersectionObserver((entries) => {
    entries.forEach((entry) => {
        if (entry.isIntersecting) {
            // Video entered the viewport, unmute it
            entry.target.muted = false;
            muteOtherVideos(entry.target);
        } else {
            // Video left the viewport, mute it
            entry.target.muted = true;
        }
    });
});

videos.forEach((video) => {
    video.muted = true; // Start by muting all videos
    observer.observe(video);
});

function muteOtherVideos(currentVideo) {
    videos.forEach((video) => {
        if (video !== currentVideo) {
            video.muted = true;
        }
    });
}

In your PHP code, please make sure you're adding a data-post-id attribute to your video tags:

PHP:
echo "
<video class='context-video' data-post-id='" . $row['id'] . "' autoplay muted loop style='width:100%; z-index: -1; border-top:2px solid rgba(255, 255, 255, 0.3);' title='You are watching ". $row['title'] . "' preload='auto'>
    <source src='".$fileURL."' type='video/".$fileType."'>
</video>
";

With this refactoring, the JavaScript logic is separated from the PHP rendering logic, which can make the code more maintainable and easier to debug.
 

New Threads

Latest posts

Buy us a coffee!

300x250
Top Bottom