Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cover the thumbnail of an iframe video 100% to the wrapper in 9:16 aspect ratio?

I am using an iframe tag to play a 9:16 aspect ratio video from my google drive. The iframe is wrapped around a div and the div is styled so that there are no black bars. The video is maintaining its aspect ratio but the thumbnail is not. The thumbnail covers all the wrapper's height but not the width. I want the thumbnail to also maintain the aspect ratio of 9:16.

Also, I did not add a custom thumbnail.

.potrait_9by16
   {
      position: relative;
      overflow: hidden;
      width: 100%;
      padding-bottom: 177.777%; /* 9:16 Aspect Ratio*/
   }

.potrait_9by16 iframe 
  {
     position: absolute;
     top: 0;
     left: 0;
     bottom: 0;
     right: 0;
     width: 100%;
     height: 100%;
 }
<div className="potrait_9by16">
     <iframe            
        width="100%"
        height="100%"
        frameborder="0"
        src={videoObject.src}
        allow="fullscreen"
     ></iframe>
</div>

Here is an image of the wrapper

like image 334
infernus-85 Avatar asked Dec 22 '25 15:12

infernus-85


1 Answers

Try below at https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_video:

<!DOCTYPE html>
<html>
<body>

<style>
div.outer { overflow: hidden }
div.outer > div.inner { position: relative; margin: 0 -109.7283%; padding: 88.8888888% 0; overflow: hidden }
div.outer > div.inner > iframe { position: absolute; top: 0; right: 0; bottom: 0; left: 0 }
</style>

<div class="outer">
<div class="inner">
<iframe width="100%" height="100%" src="https://drive.google.com/file/d/16iDKGJXBszk2nI9h9BNG3rJ2zD85FSNy/preview">
</iframe>
</div>
</div>

</body>
</html>

It may mess up the video playback, though. The video controls (progress-bar etc.) get cropped when playback starts.

Replace the code there with the one I have provided.


I just checked your code, and looks like what you need is:

.x { overflow: hidden }
.neg { position: relative; margin: 0 -109.7283; padding: 88.8888888% 0 }
.neg > iframe { position: absolute; top: 0; right: 0; bottom: 0; left: 0 }

and use only x class for outer div, only neg class for inner div. That should probably do it.


I thought about removing the negative margin on playback, and was experimenting with something along those lines, but didn't get around to completing it. It should work to some extent, but what I found was that the black bordered thumbnail may be displayed for a short time before the playback starts (at least the way I tried it). If that's Ok, you could try that method. What I thought of was to display an invisible div (transparent overlay) covering the iframe that can capture a click and switch the iframe src to autoplay=1 URL. See if you can get that to work. If I have some time, I may look further into that.

I was adding a div using JavaScript with the same style as the iframe, just after the iframe:

.overlay { position: absolute; top: 0; right: 0; bottom: 0; left: 0 }

If this div is added last, it will already be topmost. Otherwise, use z-index.

Then handle the 'click' event on the div.


The above div overlay technique has it's limitations. The below technique may be better:

<!DOCTYPE html>
<html>
    <meta charset="UTF-8">
    <title>Player</title>
    <div id="player"></div>

body { background: #efe; padding: 2em; color: #575 }
h1:first-child { margin-top: 0 }

.player, #player { overflow: hidden }
.player > div, #player > div { position: relative; padding: 88.88888% 0; overflow: hidden }
.player video, .player iframe,
#player video, #player iframe
{ position: absolute; top: 0; right: 0; bottom: 0; left: 0 }
.player:not(.playing) > div, #player:not(.playing) > div
{ margin: 0 -109.7283% }

((W, D) => {
    let $ = a => document.getElementById(a)
    class Player {}
    Player.play = (id, url) => {
        let p = $(id)
            , f = D.createElement('iframe')
            , d = D.createElement('div')
        f.src = url
        f.setAttribute('frameborder', 0)
        f.height =
        f.width = '100%'
        f.addEventListener( 'mouseover', e => f.dataset.overMe = 1 )
        f.addEventListener( 'mouseout', e => delete f.dataset.overMe )
        W.addEventListener( 'blur', e => {
            if (f.dataset.overMe === '1')
                setTimeout(a => p.classList.add('playing'), 1000)
        } )
        p.innerHTML = ''
        d.appendChild(f)
        p.appendChild(d)
    }
    W.Player = Player
})(window, document);

Player.play('player', 'https://drive.google.com/file/d/16iDKGJXBszk2nI9h9BNG3rJ2zD85FSNy/preview')

See if you can use this latest update with multiple iframes...

Your issue could be because you may be using an id (maybe the same id) with all player divs. When using multiple player divs, you need to use unique ids and use class="player" for the divs instead of id="player":

<div id="player-1" class="player"></div>
<div id="player-2" class="player"></div>
<div id="player-3" class="player"></div>

If it still doesn't work, show me a demo (on your site, maybe), and I'll take a look. Call the play method with the id like

Player.play('player-1', 'https://drive.google.com/file/d/16iDKGJXBszk2nI9h9BNG3rJ2zD85FSNy/preview')
Player.play('player-2', 'https://drive.google.com/file/d/16iDKGJXBszk2nI9h9BNG3rJ2zD85FSNy/preview')
like image 96
dVVIIb Avatar answered Dec 24 '25 03:12

dVVIIb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!