Browse Source

Improved Firefox support for video layout and make use of object-fit support in FF>=36.

pull/176/head
Simon Eisenmann 11 years ago
parent
commit
d12471445d
  1. 3
      src/styles/components/_audiovideo.scss
  2. 2
      static/css/main.min.css
  3. 148
      static/js/services/videolayout.js

3
src/styles/components/_audiovideo.scss

@ -97,7 +97,7 @@ @@ -97,7 +97,7 @@
z-index: 2;
}
video {
object-fit: contain;
object-fit: cover;
}
}
@ -133,6 +133,7 @@ @@ -133,6 +133,7 @@
max-height: 100%;
max-width: 100%;
height: 100%;
width: 100%;
}
.localVideo {
background: $video-background;

2
static/css/main.min.css vendored

File diff suppressed because one or more lines are too long

148
static/js/services/videolayout.js

@ -22,13 +22,17 @@ @@ -22,13 +22,17 @@
"use strict";
define(["jquery", "underscore", "modernizr", "injectCSS"], function($, _, Modernizr) {
var dynamicCSSContainer = "audiovideo-dynamic";
var renderers = {};
var defaultSize = {
width: 640,
height: 360
};
var defaultAspectRatio = defaultSize.width/defaultSize.height;
var getRemoteVideoSize = function(videos, streams) {
var size = {
width: 1920,
height: 1080
width: defaultSize.width,
height: defaultSize.height
}
if (videos.length) {
if (videos.length === 1) {
@ -41,7 +45,16 @@ define(["jquery", "underscore", "modernizr", "injectCSS"], function($, _, Modern @@ -41,7 +45,16 @@ define(["jquery", "underscore", "modernizr", "injectCSS"], function($, _, Modern
}
}
return size;
}
};
var dynamicCSSContainer = "audiovideo-dynamic";
var injectCSS = function(css) {
$.injectCSS(css, {
containerName: dynamicCSSContainer,
truncateFirst: true,
useRawValues: true
});
};
var objectFitSupport = Modernizr["object-fit"] && true;
@ -83,80 +96,65 @@ define(["jquery", "underscore", "modernizr", "injectCSS"], function($, _, Modern @@ -83,80 +96,65 @@ define(["jquery", "underscore", "modernizr", "injectCSS"], function($, _, Modern
}
if (!videoWidth) {
videoWidth = 640;
videoWidth = defaultSize.width;
}
if (!videoHeight) {
videoHeight = 360;
videoHeight = defaultSize.height;
}
if (this.countSelfAsRemote) {
videos.unshift(null);
}
var aspectRatio = videoWidth / videoHeight;
var innerHeight = size.height;
var innerWidth = size.width;
// We use the same aspect ratio to make all videos look the same.
var aspectRatio = defaultAspectRatio;
//console.log("resize", innerHeight, innerWidth);
//console.log("resize", container, videos.length, aspectRatio, innerHeight, innerWidth);
var extraCSS = {};
if (!objectFitSupport) {
// Make mini video fit into available space on browsers with no object-fit support.
// http://caniuse.com/object-fit
var aspectRatioLocal = scope.localVideo.videoWidth / scope.localVideo.videoHeight;
extraCSS = {};
extraCSS[".renderer-"+this.name+" .miniVideo"] = {
width: ($(scope.mini).height() * aspectRatioLocal) + "px"
};
// Always set size of mini video.
extraCSS[".renderer-"+this.name+" .miniVideo"] = {
width: ($(scope.mini).height() * defaultAspectRatio) + "px"
};
var space = innerHeight * innerWidth; // square pixels
var videoSpace = space / videos.length;
var singleVideoWidthOptimal = Math.pow(videoSpace * aspectRatio, 0.5);
var videosPerRow = Math.ceil(innerWidth / singleVideoWidthOptimal);
if (videosPerRow > videos.length) {
videosPerRow = videos.length;
}
if (videos.length === 1) {
var newVideoWidth = innerWidth < aspectRatio * innerHeight ? innerWidth : aspectRatio * innerHeight;
var newVideoHeight = innerHeight < innerWidth / aspectRatio ? innerHeight : innerWidth / aspectRatio;
container.style.width = newVideoWidth + 'px';
container.style.left = ((innerWidth - newVideoWidth) / 2) + 'px';
} else {
var space = innerHeight * innerWidth; // square pixels
var videoSpace = space / videos.length;
var singleVideoWidthOptimal = Math.pow(videoSpace * aspectRatio, 0.5);
var videosPerRow = Math.ceil(innerWidth / singleVideoWidthOptimal);
if (videosPerRow > videos.length) {
videosPerRow = videos.length;
}
var singleVideoWidth = Math.ceil(innerWidth / videosPerRow);
var singleVideoHeight = Math.ceil(singleVideoWidth / aspectRatio);
var newContainerWidth = (videosPerRow * singleVideoWidth);
var newContainerHeight = Math.ceil(videos.length / videosPerRow) * singleVideoHeight;
if (newContainerHeight > innerHeight) {
var tooHigh = (newContainerHeight - innerHeight) / Math.ceil(videos.length / videosPerRow);
singleVideoHeight -= tooHigh;
singleVideoWidth = singleVideoHeight * aspectRatio;
}
/*
console.log("space", space);
console.log("videospace", videoSpace);
console.log("singleVideoWidthOptimal", singleVideoWidthOptimal);
console.log("videosPerRow", videosPerRow);
console.log("singleVideoWidth", singleVideoWidth);
console.log("singleVideoHeight", singleVideoHeight);
*/
container.style.width = newContainerWidth + "px";
container.style.left = ((innerWidth - newContainerWidth) / 2) + 'px';
var extraCSS2 = {};
extraCSS2[".renderer-"+this.name+" .remoteVideos"] = {
">div": {
width: singleVideoWidth + "px",
height: singleVideoHeight + "px"
}
};
extraCSS = $.extend(extraCSS, extraCSS2);
var singleVideoWidth = Math.ceil(innerWidth / videosPerRow);
var singleVideoHeight = Math.ceil(singleVideoWidth / aspectRatio);
var newContainerWidth = (videosPerRow * singleVideoWidth);
var newContainerHeight = Math.ceil(videos.length / videosPerRow) * singleVideoHeight;
if (newContainerHeight > innerHeight) {
var tooHigh = (newContainerHeight - innerHeight) / Math.ceil(videos.length / videosPerRow);
singleVideoHeight -= tooHigh;
singleVideoWidth = singleVideoHeight * aspectRatio;
}
$.injectCSS(extraCSS, {
truncateFirst: true,
containerName: dynamicCSSContainer,
useRawValues: true
});
/*
console.log("space", space);
console.log("videospace", videoSpace);
console.log("singleVideoWidthOptimal", singleVideoWidthOptimal);
console.log("videosPerRow", videosPerRow);
console.log("singleVideoWidth", singleVideoWidth);
console.log("singleVideoHeight", singleVideoHeight);
*/
container.style.width = newContainerWidth + "px";
container.style.left = ((innerWidth - newContainerWidth) / 2) + 'px';
extraCSS[".renderer-"+this.name+" .remoteVideos"] = {
">div": {
width: singleVideoWidth + "px",
height: singleVideoHeight + "px"
}
};
injectCSS(extraCSS);
};
@ -255,33 +253,32 @@ define(["jquery", "underscore", "modernizr", "injectCSS"], function($, _, Modern @@ -255,33 +253,32 @@ define(["jquery", "underscore", "modernizr", "injectCSS"], function($, _, Modern
}
var remoteSize = getRemoteVideoSize(videos, streams);
var aspectRatio = remoteSize.width / remoteSize.height;
var innerHeight = size.height - 110;
var innerWidth = size.width;
var extraCSS = {};
// Use the same aspect ratio for all videos.
var aspectRatio = defaultAspectRatio;
var bigVideoWidth = innerWidth < aspectRatio * innerHeight ? innerWidth : aspectRatio * innerHeight;
var bigVideoHeight = innerHeight < innerWidth / aspectRatio ? innerHeight : innerWidth / aspectRatio;
this.bigVideo.style.width = bigVideoWidth + 'px';
this.bigVideo.style.height = bigVideoHeight + 'px';
// Make space for own video on the right if width goes low.
if (((size.width - (videos.length - 1) * 192) / 2) < 192) {
extraCSS = {};
extraCSS[".renderer-"+this.name+" .remoteVideos"] = {
"margin-right": "192px",
"overflow-x": "auto",
"overflow-y": "hidden"
};
}
// Big video size.
extraCSS[".renderer-"+this.name+" .bigVideo .remoteVideo"] = {
"height": bigVideoHeight + 'px',
"width": bigVideoWidth + 'px',
"margin": "auto",
"display": "block"
};
$.injectCSS(extraCSS, {
truncateFirst: true,
containerName: dynamicCSSContainer,
useRawValues: true
});
injectCSS(extraCSS);
};
@ -320,8 +317,13 @@ define(["jquery", "underscore", "modernizr", "injectCSS"], function($, _, Modern @@ -320,8 +317,13 @@ define(["jquery", "underscore", "modernizr", "injectCSS"], function($, _, Modern
this.makeBig(streams[videos[0]].element);
this.bigVideo.style.opacity = 1;
}
}
var extraCSS = {};
// Always set size of mini video.
extraCSS[".renderer-"+this.name+" .miniVideo"] = {
width: ($(scope.mini).height() * defaultAspectRatio) + "px"
};
injectCSS(extraCSS);
};
// Register renderers.

Loading…
Cancel
Save