Fix iframe/embedded youtube video size relative to screen size?

Here is my experiment:
https://run.pavlovia.org/ayjayar/webgazerot3

I’m trying to make an embedded video at 80% of the visual viewport, regardless of the participant’s monitor size. I’ve been using a version of

Embedded YouTube video success story - Online experiments - PsychoPy

which was an extension of

Custom web component for online experiments: Forms, surveys, questionnaires, and other web-based content - Online experiments - PsychoPy

Currently, it looks like

I’d like it to look like

My experiment calls youtube.html using the following routine code

if ((showVideo !== undefined)) {
let src = 'youtube.html';
params = {};  // Results added here after form is submitted
continue_routine = true; // Routines can't be ended from within Begin Routine
$(document).ready(function() {
    // Add custom contents from html file using an iframe:
    $('body').append('<div id="iframe-o" style="visibility: hidden; position: relative; display: table; margin: auto;"><div id="iframe-m" style="display: table-cell; vertical-align: middle;"><div id="iframe-i" style="display: inline-block; width:100%; overflow-y: auto; overflow-x: hidden;"><iframe id="iframe" src="'+src+'" frameborder=0 style="width: 100%"></iframe></div></div></div>');

    $('#iframe').on('load',function(iframe){
        // Auto-adjust iframe size:
        $(this).contents().find('html').css({ 'display': 'table', 'width': '100%', 'overflow-x': 'hidden' });
        $('#iframe-o').height($(window).height()-20, true);
        $('#iframe-m').width($(this).contents().find('html').width()+20);
        $('#iframe-i').height ( Math.min ( $(this).contents().find('html').height()+20, $(window).height()-20 ), true );
        $(this).height($(this).contents().find('html').height());
        $('#iframe-o').css('visibility','visible');

        // If iframe contains a form, then capture its output:
        $(this).contents().find('form').on('submit',function(e){
            e.preventDefault();
            $.each($(this).serializeArray(),function(i, param){
                params[param.name] = param.value;
                psychoJS.experiment.addData(param.name, param.value);
            });
            console.log ( 'DEBUG:FRM', params );
            // Remove iframe and continue to next routine when done:
            $('#iframe-o').remove();
            continue_routine = false;
        });
    });
});
//$('#iframe').attr( 'src', function(i,val){ return val;} );
}

It calls on the youtube.html file:

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="user-scalable=no">
    <style>
    .container {
  position: fixed;
  margin: 0;
  min-width: win.size[0]; 
  min-height: win.size[1];
  max-width: 80%;
  max-height: 80%;
  padding: 5%;
}

.responsive-iframe {
  position: absolute;
  width: 80vw;
  height: 80vh;
  border: none;
}
    </style>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script>
    </script>
  </head>
  <body style="container">
        <iframe width=80vw height=80vh src="https://www.youtube.com/embed?v=EdYyuUUY-nc?controls=0&amp;autoplay=1&amp;start=0&amp;allowfullscreen=0&amp;loop=1&amp;playlist=je5Vw0rMiWk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
       </body>
    </html>

I’d like to make the iframe auto-adjust so that it stays at 80% of the visual viewport, even if the participant tries to resize the page, but I’ll figure that out later.

Can anyone help me figure out where I need to adjust my code so that the video is at about 80% of the viewport? I’m troubleshooting using the “troubleshoot” routine.

Here is the repository Andrew Rozsa / WebGazerOT3 · GitLab (pavlovia.org)

Any help would be greatly appreciated!

Per wakecarter’s code, I originally had

<iframe width="840" height="475" src="https://www.youtube-nocookie.com/embed/je5Vw0rMiWk?controls=0&amp;autoplay=1&amp;start=0&amp;allowfullscreen=0&amp;loop=1&amp;playlist=je5Vw0rMiWk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

But I need this to be about 80% of the visual viewport. I figured calling the window.size function to determine the width and height would work, but I’m having trouble making it work.

Update:

I’ve gotten just the iframe in the youtube.html iframe file to influence the size, but I cannot get it to adjust according to the viewport.

I’ve set the variable “canvas” in psychopy to the current window size (canvas = psychoJS.window.size).

How can I use this “canvas” variable dictate the iframe size in the html file?

Here you can see the canvas variable

I’ve read that vh and vw don’t normally work the way they are meant to.
CSS vh units inside an iframe - Stack Overflow

If I manually debug and edit the size in the console, I can get it size properly.

Anyone have any ideas?

Thanks.

This was challenging to do, particularly as the web components should support both absolute and relative sizes.

I’ve upgraded the project and added a new responsive.html example showing how to do something like this - hopefully you find it useful.

1 Like

Can I tell you how amazing you are? You went far beyond what I was expecting. This is incredibly helpful and it will very useful! I know for a fact this will help so many others as well.

Thank you for taking the time to provide these examples and these tutorials.

1 Like