Suggested improvements to Video App's embedded video features (UNA 14.0)
Re: Video App (Timeline)
Currently, a great number of embedded videos can be played at the same time. Users have to scroll back to stop each video individually.
Suggestion: @Mark Purser @LeonidS @Alex T⚜️ @Anton L @Andrey Yasko
- Do not allow an Embedded video to play off-screen. Rather have it play in a pop-up player as soon as it goes off-screen on the timeline.
- Do not allow more than one video to be played back. Stop playing the video as soon as the next video is selected.
- Transfer all settings from the current video to the following video. (Audio on/off, volume, speed, resolution).
- Make the video post screen on the timeline a proper size.
@Romulus has done work on the "uploaded" videos part of the Video App and will hopefully be included in the next upgrade.
See: https://unacms.com/d/una-14-0-0-timeline-autoplay-sound
-
- · Romulus
- ·
There is some work to be done here, but anyone who really wants to can do it. I played around and tested a little, but I have other priorities. If everyone on the platform contributes a few hours of work, this functionality can be made possible.
According to YouTube’s documentation, to make an embedded video autoplay, you need to add
&autoplay=1
to the video’s embed URL, immediately after the video ID (the string that comes afterembed/
in the URL).Important note: Embedded videos that autoplay won’t increase the video’s view count on YouTube.
Example:
iframe width="560" height="315" src="https://www.youtube.com/embed/D6Ac5JpCHmI?&autoplay=1" frameborder="0" allowfullscreen>iframe>
To implement this behavior, I edited the
BxVideosEmbedProviderOEmbed.php
file from the videos module.I also modifiedview.js
from the Timeline module, but it still doesn’t fully work. This is a patch added on top of my previous one, which works fine for videos hosted locally on the platform:👉 https://github.com/kabballa/timeline/blob/14.0.10/js/view.js
For embedded videos though, things get a lot trickier. You’d need to make deeper changes because it heavily depends on the policies of the companies delivering the videos. You can’t manipulate their players however you want since they’re not hosted on your platform. It also depends a lot on the proxy server headers and configuration it’s not easy to control this, and I highly doubt anyone would go through the trouble of doing it for free. Plus, it varies depending on the server setup on both ends, not just your own and the proxy delivering the videos.
Personally, I played around with it a bit, but I’m not interested in YouTube videos. If I have my own site, I don’t care about YouTube or their policies, and I don’t want their videos showing up on my platform. I've spent a few hours trying to solve this problem, but unfortunately, if I'm not interested in something, I can't reach a conclusion. It probably needs more work, but that's what I did. I'm very busy and can't do much more in this direction. Anyone who wants to has a starting point. The player tries to start but something stops it. Only videos posted on the platform work in autoplay.
Modification 1: PHP - Prepare Embed URL for YouTube
This modification is in the
Videos
module, within the file containing theBxVideosEmbedProviderOEmbed
class, specifically in theparseLink
function. Its purpose is to add the necessary parameters to the YouTube iframe URL to enable the JavaScript API and instruct the player to attempt autoplay (initially muted).defined('BX_DOL') or die('hack attempt'); /** * Copyright (c) UNA, Inc - https://una.io * MIT License - https://opensource.org/licenses/MIT. * * @defgroup Videos Videos * @ingroup UnaModules * * @{ */ /** * Class for parsing links which support oembed API. */ class BxVideosEmbedProviderOEmbed { var $_oModule; public function __construct(&$oModule) { $this->_oModule = $oModule; } public function parseLink($sLink) { bx_import('BxDolEmbed'); $oEmbed = BxDolEmbed::getObjectInstance('sys_oembed'); $aResponse = $oEmbed->getUrlData($sLink); if ($aResponse) { $aResponse = $aResponse[$sLink]; if (isset($aResponse['type']) && $aResponse['type'] == 'video' && isset($aResponse['html']) && !empty($aResponse['html'])) { // --- Atomic Modification Start ---$html = $aResponse['html']; // Check if the original link is from YouTube.// Add parameters only for YouTube embeds.// Add checks for other providers if needed.// Check for common YouTube domains/patterns in the original link.if (strpos($sLink, 'youtube.com') !== false || strpos($sLink, 'youtu.be') !== false || strpos($sLink, 'youtu.be') !== false) { // Added common patterns // Use a regular expression to find the src attribute in the iframe tag.// This regex looks for src="..." or src='...' and captures the URL inside the quotes.if (preg_match('/]*src=["\']([^"\']*)["\'][^>]*>/i', $html, $matches)) {$fullSrcAttribute = $matches[0]; // The full src="..." or src='...' attribute string found$originalSrc = $matches[1]; // The captured URL inside the quotes // Check if the original URL already contains query parameters ('?')$separator = (strpos($originalSrc, '?') === false) ? '?' : '&'; // --- FINAL REVISED MODIFICATION (Adding ALL necessary YouTube Embed Params) ---// Append autoplay=1, mute=1, enablejsapi=1, and origin parameters for YouTube.// autoplay=1 & mute=1: For reliable autoplay initiation by browser/YouTube embed player.// enablejsapi=1: CRITICAL to enable YouTube Player API for control via playerjs library.// origin=...: Security requirement for the JS API. BX_DOL_URL_ROOT provides the site's origin.// urlencode is used to properly format the origin URL.$newSrc = $originalSrc . $separator . 'autoplay=1&mute=1&enablejsapi=1&origin=' . urlencode(BX_DOL_URL_ROOT);// --- END FINAL REVISED MODIFICATION --- // Build the new full src attribute string with the modified URL// Ensure the new URL is properly quoted. Determine original quote type.// Find the position of 'src=' and check the character after it.$srcPos = strpos($fullSrcAttribute, 'src=');$quote = ($srcPos !== false && isset($fullSrcAttribute[$srcPos + 4]) && ($fullSrcAttribute[$srcPos + 4] == '"' || $fullSrcAttribute[$srcPos + 4] == "'")) ? $fullSrcAttribute[$srcPos + 4] : '"'; // Default to double quote if unable to determine $newFullSrcAttribute = 'src=' . $quote . $newSrc . $quote; // Replace the original full src attribute string in the HTML with the new one// Using str_replace is usually safe if the attribute string is found uniquely.$html = str_replace($fullSrcAttribute, $newFullSrcAttribute, $html); // Update the 'html' entry in the response array with the modified HTML string$aResponse['html'] = $html; // Note: For Vimeo or other providers, you would need to find their specific// API parameters for autoplay, mute, and JS API enablement/origin and add// similar conditional blocks here. } } // --- Atomic Modification End --- // Return the response array, now containing the potentially modified HTMLreturn ['thumb' => isset($aResponse['thumbnail_url']) ? $aResponse['thumbnail_url'] : '', 'embed' => $aResponse['html'], // Return the potentially modified HTML string ]; } } // Return false if no valid video response was obtainedreturn false; } } /** @} */
Note: The logic to determine the quote type for
src
attribute replacement was slightly refined for robustness.Modification 2: JavaScript - Initialize Embed Player for JS Control
This modification is in the
Timeline
module, within theBxTimelineView
class, in theinitVideosAutoplay
function. Its purpose is to add a listener to theready
event of the embed player. This ensures the player is ready to receive commands from the timeline's JavaScript and helps apply the site's mute/unmute setting./** * Initialize autoplay functionality for video iframes. * Registers iframe players and enforces single-session playback: only one video plays at a time. * Uses IntersectionObserver for visibility detection if available, otherwise falls back to scroll-based logic. * * This version includes an atomic modification to better handle embedded videos * within the existing autoplay logic (0.5 threshold IO or scroll fallback) * and ensure they are ready for JS control. * * @param {jQuery} oParent - jQuery object containing the parent element for video iframes. */ BxTimelineView.prototype.initVideosAutoplay = function(oParent) { var $this = this; if (this._sVideosAutoplay === 'off') return; // Preserve original initialization// This function likely finds the video elements including iframes and may perform initial setup.// It should also be updated/called for dynamically loaded content.this.initVideos(oParent); var sPrefix = oParent.hasClass(this.sClassView) ? oParent.attr('id') : oParent.parents('.' + this.sClassView + ':first').attr('id'); // Register each iframe player once, without deleting existing references// This loop finds iframes (including embed-uri with IDs) and creates/gets playerjs instances for them. oParent.find('iframe[id]').each(function() { var frame = this; var key = sPrefix + '_' + frame.id; var player; // If the player already exists, use the existing instanceif (window.glBxTimelineVapPlayers[key]) { player = window.glBxTimelineVapPlayers[key]; // console.log(`Player ${key} already exists. Skipping reinitialization.`); // Keep optional logging } else { // Initialize the new player if it doesn't exist// playerjs requires the iframe to be in the DOM to initialize. player = new playerjs.Player(frame); // Initial mute is set here based on admin settings, but will be re-applied on 'ready'if ($this._sVideosAutoplay === 'on_mute') player.mute(); // Sync container height on ready/play - Keep original logicvar fFixHeight = function() {var video = $('#' + key).contents().find('video'); if (video.length) $('#' + key).height(video.height() + 'px'); }; player.on('ready', fFixHeight); player.on('play', fFixHeight); // When this player starts, pause all others - Keep original logic// This listener works because playerjs enables the JS API (thanks to PHP modification). player.on('play', function() { for (var k in window.glBxTimelineVapPlayers) { if (k !== key) { try { // playerjs.pause() requires JS API to be enabled.window.glBxTimelineVapPlayers[k].pause(); } catch (e) { // Ignore errors during pause// console.warn(`Unable to pause player ${k}`, e); // Keep optional logging } } } }); // Save the new player in the global list used by autoplay triggerswindow.glBxTimelineVapPlayers[key] = player; } // --- Atomic Modification Start ---// Add a listener to the 'ready' event for THIS player instance.// This event fires when the player's API is ready to receive commands (thanks to PHP modification). player.on('ready', function() { // Use a small timeout to allow the browser layout to settle after player readiness// and the main timeline JS initialization (from init(true) if called).// This helps ensure IntersectionObserver and offset calculations are accurate// when the main autoplay checks run next.setTimeout(function() {// Re-apply the mute/unmute state according to the current settings (_sVideosAutoplay).// This is crucial: if the embed URL started the player muted (via mute=1),// this overrides it to unmute if the site setting (_sVideosAutoplay === 'on') requires sound.if ($this._sVideosAutoplay === 'on_mute') {try { player.mute(); } catch(e) {} } else if ($this._sVideosAutoplay === 'on') { try { player.unmute(); } catch(e) {} } // We do NOT explicitly call the full autoplay check here for *each* player becoming ready.// The existing IntersectionObserver (0.5 threshold) or the scroll handler (fallback)// will perform the necessary play/pause based on visibility/offset checks// on ALL relevant videos periodically or on scroll events. The timeout// ensures this player is fully ready when those checks happen. }, 50); // A small delay (e.g., 50ms) }); // --- Atomic Modification End --- }); // Reset current session trackingthis._sCurrentPlayerKey = null; // This is the original code that sets up the main autoplay triggers// (either IntersectionObserver with 0.5 threshold or the scroll fallback).// This block remains unchanged as requested, but it now operates on players// that are properly initialized and ready for JS control due to the above modification// and the necessary URL parameters added by the PHP modification. // Use IntersectionObserver if availableif ('IntersectionObserver' in window) {// console.log("Using existing IntersectionObserver (0.5 threshold) for autoplay"); // Keep optional loggingvar observer = new IntersectionObserver(function(entries) { entries.forEach(function(entry) { var iframe = entry.target; var key = sPrefix + '_' + iframe.id; var player = window.glBxTimelineVapPlayers[key]; if (!player) return; // Existing logic: play if intersecting (>= 0.5 threshold), pause otherwise// This logic now calls play()/pause() on playerjs instances that are API-enabled.if (entry.isIntersecting) {// Re-apply mute state just before playing, based on current settings.// Added here also for robustness, in case the ready listener timed out too early// or state changed between ready and intersecting.if ($this._sVideosAutoplay === 'on_mute') {try { player.mute(); } catch(e) {} } else if ($this._sVideosAutoplay === 'on') { try { player.unmute(); } catch(e) {} } player.play(); } else { player.pause(); } }); }, { root: null, // Use viewport as rootrootMargin: '0px',threshold: 0.5, // Existing threshold: Play when 50% of the video is visible } ); // Observe all relevant iframes found earlier that have an ID oParent.find('iframe[id]').each(function() { observer.observe(this); }); } else { // Fallback to scroll-based autoplay logic (using autoplayVideosFallback)// console.log("IntersectionObserver not available. Using scroll fallback."); // Keep optional logging // Ensure previous handler is removed before adding the new one $(window).off('scroll.timelineVap').on('scroll.timelineVap', function() { if (!$this.oView.is(':visible')) return; // Debounce scroll eventsif (!window.requestAnimationFrame) {setTimeout(function() { // Keep original fallback call. This function calls player.play()/pause(). $this.autoplayVideosFallback($this.oView, $this._fVapOffsetStart, $this._fVapOffsetStop); }, 100); } else { window.requestAnimationFrame(function() { // Keep original fallback call $this.autoplayVideosFallback($this.oView, $this._fVapOffsetStart, $this._fVapOffsetStop); }); } }); // Trigger fallback autoplay immediately on page loadif (!window.requestAnimationFrame) {setTimeout(function() { // Keep original fallback call $this.autoplayVideosFallback($this.oView, $this._fVapOffsetStart, $this._fVapOffsetStop); }, 100); } else { window.requestAnimationFrame(function() { // Keep original fallback call $this.autoplayVideosFallback($this.oView, $this._fVapOffsetStart, $this._fVapOffsetStop); }); } } // The original code might have had an immediate scroll trigger here.// It's removed in this version as init(true) on page load and on infinite scroll takes care of initialization.// An explicit trigger *after* init(true) is added below, which is more reliable. // Initial autoplay check after the entire timeline view is potentially initialized.// This helps trigger autoplay for videos visible on initial page load or immediately after new content loads.// A small delay is used to ensure all players are added to the glBxTimelineVapPlayers list.setTimeout(function() {if ($this._sVideosAutoplay !== 'off') { if ('IntersectionObserver' in window) { // With IO, calling playCentralVideo checks visibility and plays the most central if autoplay is on.// This ensures a video starts playing immediately if the view is already visible and has videos. $this.playCentralVideo($this.oView); // playCentralVideo uses _getCentralVideoInView and iterates players. } else { // For fallback, trigger the fallback check function. $this.autoplayVideosFallback($this.oView, $this._fVapOffsetStart, $this._fVapOffsetStop); } } }, 100); // Small delay after init completes }; // Keep all other BxTimelineView.prototype functions unchanged, like autoplayVideos, playVideos, pauseVideos, _getCentralVideoInView, etc. /** * Fallback autoplay logic. * If IntersectionObserver is not available or disabled, this function plays the video closest to the center of the viewport. * * @param {jQuery} oView - jQuery object containing the video iframes. * @param {number} fOffsetStart - Offset from top for start of visible region (as a fraction of window height). * @param {number} fOffsetStop - Offset from bottom for stop of visible region (as a fraction of window height). */ // BxTimelineView.prototype.autoplayVideosFallback = function(oView, fOffsetStart, fOffsetStop) { ... } - This function remains unchanged as provided by you. // Keep the rest of the BxTimelineView.prototype functions as provided by you.
Modification 3: JavaScript - Re-initialize Autoplay for Dynamically Loaded Content
This modification is also in the
Timeline
module, within theBxTimelineView
class, in theinitInfiniteScroll
function. Its purpose is to call theinit(true)
function after new content is loaded via scrolling. This ensures thatinitVideosAutoplay
(and other initializations) runs for the newly added elements in the page, making them eligible for autoplay control.BxTimelineView.prototype.initInfiniteScroll = function(oParent) { var $this = this; // Check if infinite scroll is enabled and there are events expected to loadif(!this._bInfScroll || !this._bEventsToLoad)return; // Unbind any previous scroll handler attached by this function to avoid duplicates $(window).off('scroll.timelineInfScroll'); // Bind the scroll handler for infinite scroll $(window).bind('scroll.timelineInfScroll', function(oEvent) { // Only proceed if the timeline view is visibleif(!$this.oView.is(':visible'))return; // Ensure the scroll handler is only active for the specific main timeline view instanceif($this.oView.attr('id') != $this._getHtmlId('main', {name: $this._sName, view: $this._sView, type: $this._sType}, {hash: false}))return; // Only trigger loading if there are more events to load, loading is not already in progress,// and the preload limit has not been reached.if(!$this._bEventsToLoad || $this._bInfScrollBusy || $this._iInfScrollPreloads >= $this._iInfScrollAutoPreloads)return; var iScrollTop = parseInt($(window).scrollTop()); var iWindowHeight = $(window).height(); // --- Check scroll position based on item count or percentage (existing logic) ---var bShouldLoad = false;if($this._sInfScrollAfter == 'item') { var oItems = oParent.find('.' + $this.sClassItem); if (oItems.length > $this._iInfScrollAfterItem) { // Ensure there are enough items to check against the offsetif((iScrollTop + iWindowHeight) >= ($(oItems.get(oItems.length - $this._iInfScrollAfterItem)).offset().top)) { bShouldLoad = true; } } else if (oItems.length > 0) { // If fewer items than offset, load when reaching the last oneif((iScrollTop + iWindowHeight) >= ($(oItems.last()).offset().top)) { bShouldLoad = true; } } // If there are no items, bShouldLoad remains false, preventing premature loading } // Check based on percentage if item-based check didn't trigger loadingif(!bShouldLoad && $this._sInfScrollAfter == 'percent') {var iParentTop = parseInt(oParent.offset().top); var iParentHeight = parseInt(oParent.height()); // Ensure parent has height before calculating percentageif (iParentHeight > 0) {if((iScrollTop + iWindowHeight) >= (iParentTop + iParentHeight * $this._fInfScrollAfterPercent)) { bShouldLoad = true; } } } // If not scrolled far enough based on the configured method, do nothingif (!bShouldLoad) {return; } // --- Trigger loading of more content ---var iStart = $this._oRequestParams.start + ($this._oRequestParams.start == 0 ? $this._oRequestParams.per_page_default : $this._oRequestParams.per_page); $this._bInfScrollBusy = true; // Set busy flag to prevent multiple loads // Call _getPage to load the next portion of content$this._getPage(undefined, iStart, $this._oRequestParams.per_page, function(oData) {// This callback executes after _getPage has successfully loaded data.// Assumes _getPage handles inserting oData.content into the DOM ($this.oView or oParent). $this._bEventsToLoad = oData.events_to_load; // Update flag indicating if there are more events$this._iInfScrollPreloads += 1; // Increment the count of portions preloaded via infinite scroll$this._bInfScrollBusy = false; // Release the busy flag // --- ATOMIC MODIFICATION START ---// IMPORTANT: Re-initialize components for the newly loaded content.// The init() function re-scans the entire timeline view ($this.oView)// and sets up features like autoplay, see-more, flickity, etc., for ALL items currently// in the DOM, including the newly added ones.// This is crucial because autoplay observers/listeners need to be attached// to the video iframes and other relevant elements in the newly added items.$this.init(true); // Optional: Trigger an immediate autoplay check after new content is added// and initialized. While the natural scroll handler will run soon, this// helps ensure the first relevant video autoplays without waiting for a scroll.if ($this._sVideosAutoplay !== 'off') {// Use a small delay to allow the DOM to settle and JS initializations (from init(true))// to complete fully before the autoplay check runs.setTimeout(function() {// The existing scroll handler calls autoplayVideosFallback (if IO not available)// or the IO callback runs based on visibility.// Calling autoplayVideosFallback or playCentralVideo here forces an immediate re-evaluation// based on current viewport state. Let's call playCentralVideo if IO is available,// or autoplayVideosFallback if that's the selected fallback mode.if ('IntersectionObserver' in window) {// If IO is used, playCentralVideo uses the list built by initVideosAutoplay$this.playCentralVideo($this.oView); } else { // If fallback is used, trigger the fallback check$this.autoplayVideosFallback($this.oView, $this._fVapOffsetStart, $this._fVapOffsetStop); } }, 50); // Small delay } // --- ATOMIC MODIFICATION END --- }); }); // No explicit initial trigger needed here if init() is called on page load,// as initVideosAutoplay sets up initial observers/handlers.// An explicit trigger *after* init() on initial page load is added within initVideosAutoplay itself now. };
Please carefully apply these three code modifications. They are designed to work together to enable autoplay for YouTube embeds based on timeline visibility and ensure this functionality works for both initially loaded content and content loaded via infinite scroll. But it is not completed.
Addressing Issues with Autoplay Functionality for Embedded YouTube Videos
The challenge of ensuring embedded YouTube videos autoplay as intended is a common concern for website developers. The user's query, accompanied by PHP code indicative of the BX-DOL platform, suggests difficulties in implementing this feature. This report aims to provide a comprehensive analysis of the factors affecting YouTube embedded video autoplay and offer actionable recommendations.
Modern web browsers have implemented increasingly stringent autoplay policies to enhance user experience by preventing the unexpected playback of audio and video content.1 These policies generally restrict the automatic playback of videos with sound unless specific conditions are met by the user or the website.
For instance, Google Chrome, since version 66, typically disallows autoplay with sound unless the user has previously interacted with the website, the site has a high Media Engagement Index (MEI), or the user has added the site to their mobile device's home screen or installed it as a Progressive Web App (PWA).1 Chrome's MEI dynamically assesses a user's engagement with media on a particular domain. If a user frequently plays videos with sound on a specific website, Chrome is more inclined to permit unmuted autoplay on subsequent visits. This introduces a personalized aspect to autoplay behavior, meaning a solution effective for one user might not work for another if their browsing history differs.1 Muted autoplay, however, is generally permitted in Chrome.1
Mozilla Firefox, in contrast, adopts a user-centric approach by blocking all media with sound from automatic playback by default.6 Firefox provides users with granular control over autoplay settings, allowing them to configure preferences globally or on a per-site basis through the browser's options.6 Furthermore, advanced users can modify about:config settings to fine-tune autoplay behavior.13 This emphasis on user control means that even if the embed code is correctly implemented, the user's browser settings will ultimately dictate whether the video autoplays.
Apple's Safari browser has a particularly restrictive policy, permitting autoplay only when the video lacks audio tracks or when the muted property is set to true. Additionally, for autoplay to function within the page, the <video> element must include the playsinline attribute.9 If a video gains an audio track or becomes unmuted without direct user interaction, or if it is no longer visible on the screen, playback will cease.9 Safari also employs an "automatic inference engine" to determine if media with sound can autoplay on a given website.10 Users can manage autoplay settings for individual websites through Safari's preferences.21 Notably, enabling Low Power Mode on iOS Safari can prevent all forms of autoplay, even for muted videos.18 Safari's policy underscores the importance of either having no audio or explicitly muting the video for automatic playback. The playsinline requirement highlights a specific implementation detail for Safari to enable autoplay within the webpage rather than in fullscreen.
Microsoft Edge, with its default media autoplay setting of "Limit," takes a more adaptive approach by learning from user behavior on different websites.2 This suggests that Edge might allow unmuted autoplay on sites where the user frequently engages with media.
The conventional method for instructing a YouTube embed to autoplay involves adding the autoplay=1 parameter to the src URL of the iframe.24 However, due to the aforementioned browser autoplay policies, this parameter alone is often insufficient, particularly for videos with sound.24
A more reliable approach in contemporary browsers, especially Chrome and Safari, is to also include the mute=1 parameter in the src URL.24 This instructs the browser to initiate playback with the audio muted, allowing the user to manually unmute if desired. The necessity of the mute parameter across most browsers signifies a significant shift in how browser policies are enforced regarding automatic media playback.
Furthermore, the iframe tag itself should include the allow="autoplay" attribute in addition to the autoplay parameter in the URL.26 This attribute explicitly grants permission for the embedded video to autoplay. Without this attribute, some browsers might still prevent automatic playback, even with the autoplay parameter present in the URL.26 The requirement of the allow attribute alongside URL parameters illustrates a layered security mechanism employed by browsers, demanding explicit permission within the HTML structure.
When constructing the YouTube embed URL with multiple parameters, it is crucial to adhere to the correct syntax. The first parameter should be preceded by a question mark (?), and subsequent parameters must be separated by an ampersand (&).25 For example, a correctly formatted src attribute for autoplaying a muted video would be: https://www.youtube.com/embed/VIDEO_ID?autoplay=1&mute=1. Incorrect syntax, such as using ? for subsequent parameters or omitting the ampersand separator, can prevent the autoplay functionality from working as intended.27
YouTube Embed URL Parameters:
- Parameter Name: autoplay
- Values: 0 (disabled), 1 (enabled)
- Description: Specifies whether the initial video will automatically start to play when the player loads.
- Relevant Snippet IDs: 24
- Parameter Name: mute
- Values: 0 (disabled), 1 (enabled)
- Description: Mutes the video. Often required for autoplay to work in modern browsers.
- Relevant Snippet IDs: 24
The most effective way to address the issue of autoplay not working is to first verify the embed code. The current best practice for achieving muted autoplay of embedded YouTube videos across major browsers involves including both &autoplay=1 and &mute=1 in the src URL, along with the allow="autoplay" attribute within the iframe tag.24 A correctly configured embed code would resemble the following:
<iframe width="560" height="315" src="https://www.youtube.com/embed/YOUR_VIDEO_ID?autoplay=1&mute=1" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
Even with a correctly formed embed code, autoplay might still be prevented due to user-defined browser settings.6 Users have the ability to manage autoplay behavior either globally for all websites or specifically for individual sites within their browser's settings. For example, a user might have explicitly disabled autoplay in Firefox preferences.6 Similarly, Safari users can configure autoplay preferences on a per-website basis.21 Brave browser also provides users with control over autoplay permissions.42 Consequently, the ultimate decision regarding autoplay often rests with the end-user's browser settings, making it impossible for website developers to guarantee unmuted autoplay in every scenario.
Given the user's mention of BX-DOL, it is important to consider that the platform itself might have specific configurations or plugins that could interfere with the standard YouTube embed behavior. Content Management Systems (CMS) or website builders can sometimes have their own settings or methods for handling embedded videos, which might override or conflict with manually implemented embed code.41 For instance, Google Sites explicitly prohibits autoplay in embedded iframes.47 Similarly, Articulate Review 360 has noted limitations regarding autoplay for embedded videos.7 Therefore, when utilizing a platform like BX-DOL, it is advisable to consult the platform's documentation or settings related to embedded media to identify any potential conflicts affecting autoplay.
For more advanced control over embedded YouTube videos, the YouTube IFrame Player API offers a powerful solution.26 This JavaScript API enables programmatic interaction with the player, allowing developers to control various aspects such as playing, pausing, muting, and adjusting volume. While implementing the API requires more development effort, it can provide more reliable ways to manage autoplay, especially when combined with user interaction or specific events on the webpage.27 To utilize the API, it is typically necessary to add enablejsapi=1 to the src URL of the iframe and include the YouTube API JavaScript library on the page.31
Finally, it is important to verify that the owner of the YouTube video has enabled embedding for their content.30 If embedding is disabled in the video's settings on YouTube, the video will not play on external websites, regardless of the autoplay configuration. Therefore, it is essential to ensure that the desired video has embedding enabled in its YouTube settings.
Browser Autoplay Support:
- Chrome:
- Autoplay with Sound: Generally blocked unless user interaction, high MEI, or PWA/homescreen installation.
- Muted Autoplay: Generally allowed.
- Key Snippet IDs: 1
- Firefox:
- Autoplay with Sound: Blocked by default; configurable by user (global and per-site).
- Muted Autoplay: Depends on user configuration.
- Key Snippet IDs: 6
- Safari:
- Autoplay with Sound: Only allowed if no audio track or muted attribute is present and playsinline is used.
- Muted Autoplay: Allowed if playsinline is used. Low Power Mode can block all autoplay.
- Key Snippet IDs: 9
- Edge:
- Autoplay with Sound: Limited by default; learns from user behavior.
- Muted Autoplay: Likely allowed.
- Key Snippet IDs: 2
In conclusion, to maximize the chances of achieving autoplay for embedded YouTube videos, particularly within the BX-DOL platform, the following recommendations should be considered:
The most dependable method for enabling autoplay across modern browsers is to prioritize muted autoplay. This involves including both the autoplay=1 and mute=1 parameters in the src URL of the iframe, along with the allow="autoplay" attribute.24 This approach respects the prevailing browser autoplay policies by initiating playback without sound, allowing users to unmute the video if they wish to hear the audio. Therefore, it is recommended to modify the YouTube embed code to incorporate ?autoplay=1&mute=1 in the src URL (or &autoplay=1&mute=1 if other parameters are already present) and ensure the iframe tag includes the allow="autoplay" attribute.
If unmuted autoplay is a critical requirement that is being hindered by browser policies, consider designing the user interface to prompt a user interaction, such as clicking a play button, to initiate video playback.1 This strategy aligns with browser policies that generally permit autoplay with sound following a user interaction with the webpage. If muted autoplay is not sufficient, implementing a clear play button or another interactive element that triggers the YouTube video to play upon being clicked might be necessary. This can be achieved using standard HTML and JavaScript, or through the more advanced YouTube IFrame Player API.
For more intricate scenarios or when standard embed parameters fail to deliver the desired autoplay behavior, exploring the YouTube IFrame Player API is recommended.26 The API allows for programmatic control over the player's behavior, including initiating playback based on specific conditions or user interactions on the page. It is advisable to review the YouTube IFrame Player API documentation and examples to implement more sophisticated autoplay logic, such as triggering playback after a user scrolls the video into view or interacts with another element on the page.
Works cited
- Autoplay policy in Chrome | Blog, accessed on May 12, 2025, https://developer.chrome.com/blog/autoplay
- Video embeds do not autoplay in Google Chrome - ScreenPal, accessed on May 12, 2025, https://support.screenpal.com/portal/en/kb/articles/video-embeds-do-not-autoplay-in-google-chrome
- Google Chrome Autoplay Policy - Viz Flowics Support, accessed on May 12, 2025, https://support.flowics.com/en/articles/8870895-google-chrome-autoplay-policy
- Autoplay - The Chromium Projects, accessed on May 12, 2025, https://www.chromium.org/audio-video/autoplay/
- Autoplay guide for media and Web Audio APIs - Media technologies on the web | MDN, accessed on May 12, 2025, https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Autoplay
- Allow or block media autoplay in Firefox - Mozilla Support, accessed on May 12, 2025, https://support.mozilla.org/en-US/kb/block-autoplay
- Video Auto-Play Dependent on Web Browser Chosen? | Articulate - Community, accessed on May 12, 2025, https://community.articulate.com/discussions/discuss/video-auto-play-dependent-on-web-browser-chosen/808749
- How to detect if Chrome/Safari/Firefox prevented autoplay for video? - Stack Overflow, accessed on May 12, 2025, https://stackoverflow.com/questions/49939436/how-to-detect-if-chrome-safari-firefox-prevented-autoplay-for-video
- Delivering Video Content for Safari | Apple Developer Documentation, accessed on May 12, 2025, https://developer.apple.com/documentation/webkit/delivering-video-content-for-safari
- To Play, or Not to Play - AutoPlay Policies for Safari 14 and Chrome 64 - Bitmovin, accessed on May 12, 2025, https://bitmovin.com/blog/autoplay-policies-safari-14-chrome-64/
- Where can I found "autoplay" on Chrome? - Google Help, accessed on May 12, 2025, https://support.google.com/chrome/thread/86401143/where-can-i-found-autoplay-on-chrome?hl=en
- How do I disable autoplay in Chrome for desktop? Chrome://flags/#autoplay-policy doesn't work now. - Google Help, accessed on May 12, 2025, https://support.google.com/chrome/thread/23017606/how-do-i-disable-autoplay-in-chrome-for-desktop-chrome-flags-autoplay-policy-doesn-t-work-now?hl=en
- Stop automatic video play in Firefox - Super User, accessed on May 12, 2025, https://superuser.com/questions/370246/stop-automatic-video-play-in-firefox
- Mozilla Firefox and a bit better Privacy - Stop Firefox Video Autoplay - Google Sites, accessed on May 12, 2025, https://sites.google.com/view/a-bit-better-privacy/stop-firefox-video-autoplay
- Autoplay of Videos - Mozilla Connect, accessed on May 12, 2025, https://connect.mozilla.org/t5/discussions/autoplay-of-videos/td-p/65914
- I am once again asking for VIDEOS to not AUTOPLAY : r/firefox - Reddit, accessed on May 12, 2025, https://www.reddit.com/r/firefox/comments/lgwbf5/i_am_once_again_asking_for_videos_to_not_autoplay/
- Allow Video Autoplay - firefox - Reddit, accessed on May 12, 2025, https://www.reddit.com/r/firefox/comments/vxqlwp/allow_video_autoplay/
- Autoplay is not available on safari anymore? : r/webdev - Reddit, accessed on May 12, 2025, https://www.reddit.com/r/webdev/comments/1c1bnl2/autoplay_is_not_available_on_safari_anymore/
- Video auto play is not working in Safari and Chrome desktop browser - Stack Overflow, accessed on May 12, 2025, https://stackoverflow.com/questions/17994666/video-auto-play-is-not-working-in-safari-and-chrome-desktop-browser
- 2024: iOS Safari Video Autoplay Options? - Stack Overflow, accessed on May 12, 2025, https://stackoverflow.com/questions/62780281/2024-ios-safari-video-autoplay-options
- Stop autoplay videos in Safari on Mac - Apple Support (SA), accessed on May 12, 2025, https://support.apple.com/en-sa/guide/safari/ibrw29c6ecf8/mac
- How to disable or enable auto-play videos in Apple Safari Browser ? | GeeksforGeeks, accessed on May 12, 2025, https://www.geeksforgeeks.org/how-to-disable-or-enable-auto-play-videos-in-apple-safari-browser/
- Safari doesn't auto play videos - Apple Support Community, accessed on May 12, 2025, https://discussions.apple.com/thread/254263910
- krdevnotes.com, accessed on May 12, 2025, https://krdevnotes.com/how-to-autoplay-youtube-video-embeds-2024/#:~:text=Autoplay%20not%20working%20with%20only%20%26autoplay%3D1&text=In%20these%20situations%2C%20you%20may%20also%20have%20to%20mute%20the%20video.&text=So%20the%20final%20parameters%20you,website%20on%20most%20modern%20browsers.
- How to Fix YouTube Embed Autoplay Not Working - Smash Balloon, accessed on May 12, 2025, https://smashballoon.com/youtube-embed-autoplay-not-working/
- How to Autoplay Youtube Video Embeds (2024) - krdev notes, accessed on May 12, 2025, https://krdevnotes.com/how-to-autoplay-youtube-video-embeds-2024/
- How can I autoplay a video using the new embed code style for Youtube? - Stack Overflow, accessed on May 12, 2025, https://stackoverflow.com/questions/3405242/how-can-i-autoplay-a-video-using-the-new-embed-code-style-for-youtube
- YouTube Video AutoPlay Not Working - Customize with code - Squarespace Forum, accessed on May 12, 2025, https://forum.squarespace.com/topic/219923-youtube-video-autoplay-not-working/
- Embedded Autoplay Youtube Videos Stopped Playing in Chrome - Reddit, accessed on May 12, 2025, https://www.reddit.com/r/youtube/comments/8ksool/embedded_autoplay_youtube_videos_stopped_playing/
- Embed videos & playlists - YouTube Help, accessed on May 12, 2025, https://support.google.com/youtube/answer/171780?hl=en
- YouTube Embedded Players and Player Parameters | YouTube IFrame Player API, accessed on May 12, 2025, https://developers.google.com/youtube/player_parameters
- YouTube Autoplay does not work with iFrame - Stack Overflow, accessed on May 12, 2025, https://stackoverflow.com/questions/40685142/youtube-autoplay-does-not-work-with-iframe
- Getting an Embedded YouTube Video to Auto Play and Loop - Stack Overflow, accessed on May 12, 2025, https://stackoverflow.com/questions/13041088/getting-an-embedded-youtube-video-to-auto-play-and-loop
- Guide to YouTube URL parameters to specify embedded player settings like start time, autoplay, controls, language - Stornaway.io, accessed on May 12, 2025, https://www.stornaway.io/youtube-url-parameters-time-autoplay-loop-controls-language-interactive-video/
- Youtube URL parameters for video: Autoplay, Start, End, Loop (repeat), Subtitle & Co. - List, accessed on May 12, 2025, https://socialmediaagency.one/youtube-url-parameters-for-video-autoplay-start-end-loop-repeat-subtitles-co-list/
- Parameters for embedded YouTube video | Articulate - Community, accessed on May 12, 2025, https://community.articulate.com/discussions/discuss/parameters-for-embedded-youtube-video/937762
- How To Autoplay Youtube Video in HTML | GeeksforGeeks, accessed on May 12, 2025, https://www.geeksforgeeks.org/how-to-autoplay-youtube-video-in-html/
- How do I get my YouTube video to autoplay when my page loads? - HubSpot Community, accessed on May 12, 2025, https://community.hubspot.com/t5/CMS-Development/How-do-I-get-my-YouTube-video-to-autoplay-when-my-page-loads/m-p/191093
- How to autoplay embedded YouTube videos in 2023, accessed on May 12, 2025,