arditt
arditt

Reputation: 11

Youtube video as div background not working with all videos

I am making use of the following solution for using a Youtube video as a website div background: https://stackoverflow.com/a/45377998

A JSFiddle example can be found in https://jsfiddle.net/350D/uq1vvavf/

The problem I am currently having is that not all videos will be shown. For example, the video in the JSFiddle works properly (https://www.youtube.com/watch?v=R3AKlscrjmQ). However, this video, for example will not work: https://www.youtube.com/watch?v=V5YOhcAof8I

I suspect this may have to do with the signal format (720p, 360p, etc.). I have made an attempt to debug the problem and found that a link for the non-working Youtube video is still returned within the streams array (just like the working video). I appreciate any hints to solving the problem.

HTML:

<video loop muted autoplay playsinline id="video"></video>
<pre></pre>

JS:

var vid = "R3AKlscrjmQ",
streams,
video_focused = true,
video_tag = $("#video"),
video_obj = video_tag.get(0);
$.getJSON("https://query.yahooapis.com/v1/public/yql", {
q: "select * from csv where     url='https://www.youtube.com/get_video_info?video_id=" + vid + "'",
format: "json"
}, function(data) {
if (data.query.results && !data.query.results.row.length) {
    streams = parse_youtube_meta(data.query.results.row.col0);
    video_tag.attr({
        src: streams['1080p'] || streams['720p'] || streams['360p']
    });

    document.addEventListener("visibilitychange", function() {
        video_focused = !video_focused ? video_obj.play() : video_obj.pause();
    });
} else {
        $('pre').text('YQL request error...');
}
});

function parse_youtube_meta(rawdata) {
var data = parse_str(rawdata),
    streams = (data.url_encoded_fmt_stream_map + ',' + data.adaptive_fmts).split(','),
    result = {};
$.each(streams, function(n, s) {
    var stream = parse_str(s),
        itag = stream.itag * 1,
        quality = false,
        itag_map = {
            18: '360p',
            22: '720p',
            37: '1080p',
            38: '3072p',
            82: '360p3d',
            83: '480p3d',
            84: '720p3d',
            85: '1080p3d',
            133: '240pna',
            134: '360pna',
            135: '480pna',
            136: '720pna',
            137: '1080pna',
            264: '1440pna',
            298: '720p60',
            299: '1080p60na',
            160: '144pna',
            139: "48kbps",
            140: "128kbps",
            141: "256kbps"
        };
    //if (stream.type.indexOf('o/mp4') > 0) console.log(stream);
    if (itag_map[itag]) result[itag_map[itag]] = stream.url;
});
return result;
};

function parse_str(str) {
return str.split('&').reduce(function(params, param) {
    var paramSplit = param.split('=').map(function(value) {
        return decodeURIComponent(value.replace('+', ' '));
    });
    params[paramSplit[0]] = paramSplit[1];
    return params;
}, {});
}

Upvotes: 1

Views: 2191

Answers (1)

Nicholas
Nicholas

Reputation: 1229

As a workaround for now I used following solution https://codepen.io/henripeetsmann/pen/KpVVLq thanks to Henri Peetsmann. For me this works fine, even when changing the URL to one from Youtube. The only downside of using Youtube is that now you can't hide related video's when pausing. So I had to cover this part with something else.

HTML

<div class="videobg">
  <div class="videobg-width">
    <div class="videobg-aspect">
      <div class="videobg-make-height">
        <div class="videobg-hide-controls">
            <iframe src="https://player.vimeo.com/video/8970192?autoplay=1&loop=1&title=0&byline=0&portrait=0" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>
        </div>
      </div>
    </div>
  </div>
</div>

CSS

/* Quick reset */

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* Make elements as high as viewport */

html {
  height: 100%;
}

body {
  position: relative;
  height: 100%;
}

/* Video background */

.videobg {
  position: relative;
  width: 100%; /* Set video container element width here */
  height: 100%; /* Set video container element height here */
  overflow: hidden;
  background: #111; /* bg color, if video is not high enough */
}

/* horizontally center the video */
.videobg-width {
  position: absolute;
  width: 100%; /* Change width value to cover more area*/
  height: 100%;
  left: -9999px;
  right: -9999px;
  margin: auto;
}

/* set video aspect ratio and vertically center */
.videobg-aspect {
  position: absolute;
  width: 100%;
  height: 0;
  top: -9999px;
  bottom: -9999px;
  margin: auto;
  padding-bottom: 56.25%; /* 16:9 ratio */
  overflow: hidden;

}

.videobg-make-height {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
}

.videobg-hide-controls {
  box-sizing: content-box;
  position: relative;
  height: 100%;
  width: 100%;
  /* Vimeo timeline and play button are ~55px high */
  padding: 55px 97.7777px; /* 16:9 ratio */
  top: -55px; 
  left: -97.7777px; /* 16:9 ratio */
}

.videobg iframe {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  border: 0 none;
}

jQuery

var timeoutId;
var $videoBgAspect = $(".videobg-aspect");
var $videoBgWidth = $(".videobg-width");
var videoAspect = $videoBgAspect.outerHeight() / $videoBgAspect.outerWidth();

function videobgEnlarge() {
  console.log('resize');
  windowAspect = ($(window).height() / $(window).width());
  if (windowAspect > videoAspect) {
    $videoBgWidth.width((windowAspect / videoAspect) * 100 + '%');
  } else {
    $videoBgWidth.width(100 + "%")
  }
}

$(window).resize(function() {
  clearTimeout(timeoutId);
  timeoutId = setTimeout(videobgEnlarge, 100);
});

$(function() {
  videobgEnlarge();
});

Upvotes: 1

Related Questions