aullman / opentok-layout-js Goto Github PK
View Code? Open in Web Editor NEWLayout Manager for OpenTok - automatically lays out your Publishers and Subscribers nicely
License: MIT License
Layout Manager for OpenTok - automatically lays out your Publishers and Subscribers nicely
License: MIT License
Hi @aullman. I've played extensively to try to get opentok-layout-js
to work like the GIF in the README but have had no luck at all. I'd be happy if you could point out what I could be doing wrong.
First of all, I see this note in the README
This library adds an ot-layout className to elements once they have been layed out.
Now, I don't see any ot-layout
class on my elements so this makes me think there's something wrong right off the bat. I can verify I have added the library.
So far my HTML looks something like this:
<div id="layoutContainer">
<div id="publisherContainer" style="position: absolute; left: 731px; top: 0px; height: 0px;">
<video autoplay="" id="local-video-undefined"></video>
<video autoplay="" id=""></video>
</div>
</div>
And the animation doesn't work. If I move the video element with ID "local-video-undefined" out of the "publisherContainer" div
, the animation works but the layout is broken and doesn't fill the screen like in the GIF on the README.
What could I have messed up? Any pointers please?
PS: I'm not using OpenTok. My guess is it doesn't matter as long as I have video elements in a container.
Im trying to get the functionality of your demo where I can click a subscriber or publisher and have it become big and have the others go to the right side. I've followed your guidelines to the point where the sub streams will appear in a container. I'm looking at issue #52 for reference. Is there any example code we can see for your demo?
Hi, im using your library with React Opentok and i have this issue:
Im trying to use the opentok layout but i can't deliver the streams or the layout to my component:
<div className={classes.streams}>
<OTStreams>
<OTSubscriber
onSubscribe={onSubscribe}
onError={onSubscribeError}
eventHandlers={subscriberEventHandlers}
properties={{
fitMode: "contain",
}}
/>
</OTStreams>
</div>
Is there anything im missing?.
Thanks for the reply!
The layout should take into account border, padding and margin as stated in the readme.
However this is not working. It appears to be due to the css properties being in cameCasel e.g. here https://github.com/aullman/opentok-layout-js/blob/master/opentok-layout.js#L691
I wrote this test html page and opened it on a few browsers. None seemed to support these properties in camelCase format.
<html>
<head>
<style>
.my-element {
border-top: 1px;
border-bottom: 2px;
padding-top: 2px;
margin-top: 3px;
}
</style>
</head>
<body>
<div id="myElement" class="my-element">
</div>
<script type="text/javascript">
const myElement = document.getElementById('myElement');
const computedStyle = getComputedStyle(myElement);
const checkCssPropName = (propName) => {
const value = computedStyle.getPropertyValue(propName);
console.log(`${propName}: ${value}`);
}
const propNames = [
'borderTop',
'border-top',
'marginTop',
'margin-top',
'paddingTop',
'padding-top',
];
propNames.forEach(checkCssPropName);
</script>
</body>
</html>
Hi. Love this, thanks. Would it be an easy change to top align elements in their container. At the moment they are vertically middle aligned which makes it hard for me to line things up as per design. Thanks!
When layout() is called on event streamDestroyed the video element turn into a tiny square
do we think this component is ready for distribution on bower? if so, i think it should be on the registry.
Thank you for that package it saved us hours of work. We use the streamDestroyed snipped, but always get the following warning in the console:
Subscriber#destroy is deprecated and will be removed. Please use Session#unsubscribe instead +0ms
On the other side session.unsubscribe(subscriber) brings back:
OT.Session.unsubscribe:: tried to unsubscribe a subscriber that had no stream +0ms
Is there anything we do wrong, or do we just not need the destroy() command anymore?
session.on('streamDestroyed', (event) => {
event.preventDefault();
session.getSubscribersForStream(event.stream).forEach((subscriber) => {
subscriber.element.classList.remove('ot-layout');
setTimeout(() => {
subscriber.destroy();
layout();
}, 200);
});
});
So I am using the layout library to automatically resize the caller's window. I added the option of maxWidth: Infinity to both the subscribers and the publishers. However, I am adding another element to the main call div, that is, subscribers, publisher, customElement and I want the customElement to get the option of "OT_big" to make the customElement bigger than the other elements. But the issue is, I tried to add the attribute of class="OT_big" to the customElement in my html but the effect does not apply when customElement joins the call. I have to resize my window for it to apply for some reasons. Is there any way to fix it?
I tried installing the library with npm, but it fails during the postinstall gulp
step. It failed on both OSX and my Linux box with similar errors.
OSX
npm ERR! Darwin 15.2.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "i" "opentok-layout-js"
npm ERR! node v4.1.2
npm ERR! npm v2.14.4
npm ERR! code ELIFECYCLE
npm ERR! [email protected] postinstall: `gulp`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the [email protected] postinstall script 'gulp'.
npm ERR! This is most likely a problem with the opentok-layout-js package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! gulp
npm ERR! You can get their info via:
npm ERR! npm owner ls opentok-layout-js
npm ERR! There is likely additional logging output above.
CentOS
error Linux 3.10.0-229.20.1.el7.x86_64
error argv "/usr/local/bin/node" "/usr/local/bin/npm" "i" "opentok-layout-js"
error node v4.2.1
error npm v2.14.7
error code ELIFECYCLE
error [email protected] postinstall: `gulp`
error Exit status 1
error Failed at the [email protected] postinstall script 'gulp'.
error This is most likely a problem with the opentok-layout-js package,
error not with npm itself.
error Tell the author that this fails on your system:
error gulp
error You can get their info via:
error npm owner ls opentok-layout-js
error There is likely additional logging output above.
Hello, big fan of this library.
So one thing that is common in mainstream video applications is padding between video elements. See here
.
One thing that I think could be possible with this library is to have a variable padding option (default 0) that puts this padding on elements to give them a more spaced look.
I would be happy to do the work and put in a PR, I'm just a bit lost when I'm looking at the code. Would it be possible to work with you on this to get the feature merged?
When more that 2 persons are in a call and then one of the users reloads the entire page, sometimes other users views on other screens also disappear. see https://www.screenmailer.com/v/x2xhwM4I3Sa2aTo
Creating a new issue because I can't reopen #89
In response to your comment on #89, I'm calling the layout method when the first video element of the publisher shows up. And for each time a peer join the call also I call the layout method again. No luck.
Hi @aullman. I've played extensively to try to get opentok-layout-js
to work like the GIF in the README but have had no luck at all. I'd be happy if you could point out what I could be doing wrong.
First of all, I see this note in the README
This library adds an ot-layout className to elements once they have been layed out.
Now, I don't see any ot-layout
class on my elements so this makes me think there's something wrong right off the bat. I can verify I have added the library.
So far my HTML looks something like this:
<div id="layoutContainer">
<div id="publisherContainer" style="position: absolute; left: 731px; top: 0px; height: 0px;">
<video autoplay="" id="local-video-undefined"></video>
<video autoplay="" id=""></video>
</div>
</div>
And the animation doesn't work. If I move the video element with ID "local-video-undefined" out of the "publisherContainer" div
, the animation works but the layout is broken and doesn't fill the screen like in the GIF on the README.
What could I have messed up? Any pointers please?
PS: I'm not using OpenTok. My guess is it doesn't matter as long as I have video elements in a container.
EDIT:
Also I see classes like "OT_bar OT_edge-bar-item OT_mode-auto" in the demo app where are they coming from?
since the 2.4.0 update, the layout container's resizing of elements improperly impacts the crop/zoom behavior of publishers/subscribers. examples using the demo page in this repo:
1 publisher (doesn't capture full frame and black bar on right):
2 publishers (black bars on bottom):
3 publishers (black bars on bottom - all different):
middle publisher made big (really weird cropping):
sorry about the killer stare face ๐
I'm setting up a browser-based subscriber stream that broadcasts a portrait (1280x720p) stream to the viewer.
i'm using Layout and it properly sizes the video container in Chrome. The container first loads as a square then adopts the correct proportions.
However in Firefox, the container first loads as a squasre, and only resizes after I resize the window. It looks like the first "layout()" call (see code below) is entirely ignored.
I've attached 2 images. One shows the initial loading appearance of the video container (it lasts about .5 seconds) then the correct appearance as it shows on Chrome afterwards.
Here is the code:
session.on('streamCreated', function(event){
console.log("Successfully linked to session");
session.subscribe(event.stream, 'publisher',{
insertMode: 'append',
height: '100%',
width: '100%'
}, function (error){
if (error){
console.log("an error");
}else{
layout();
console.log("we're subscribed");
var resizeTimeout;
window.onresize = function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function () {
console.log("Hello Resize");
layout();
}, 20);
};
}
});
opentok-layout.js prints console message. it would be good to get rid of those
Correct me I'm off track here, but it seems that this uses JQuery for animations, however I see no reference made to JQuery in the readme.
There's also a check:
if (animate && $) {
https://github.com/aullman/opentok-layout-js/blob/master/src/layout.js#L65
but if $ is not defined this throws:
ReferenceError: $ is not defined
Initial lines of this library define a global exports
property on window
:
if (typeof module === 'undefined' || typeof module.exports === 'undefined') {
exports = window;
} else {
var window = null;
}
This results in breaking all other libraries that are loaded in the same webpage that does checks for Node environment by the use of exports object: typeof exports === 'object'
. Therefore I think that modifying window by adding exports object to it is a bad idea and should be fixed and released as fast as possible.
One solution would be to wrap everything in self invoking function and define local variables, instead of global ones, since this exports object isn't used anywhere other than defining initLayoutContainer
on it, and in turn on window.
How would you like it handled?
Could you publish this to npm so that it can be used with browserify?.
When a new stream is added, the mute control is placed at the bottom of the stream element and begins to move upward with a transition.
Can't reproduce the issue without using a layout library.
Are there any ways to avoid this? Thanks in advance!
opentok-layout-js v4.2.0
Browser: Google chrome for windows, v94.0.4606.61
Can you help me how to implement this in my app which is build on angular .
Thanks
I observed that something in opentok-layout is stripping off the overflow:hidden from the publisher in the demo for opentok-angular. I had to add an overflow:hidden to the CSS.
Is it not possible to resize subscriber streams? I'm using WebRTC on a browser so viewers can consume a live stream that comes from a mobile app. So the viewers on browser are exclusively subscribers, they don't publish (for now).
Once I define the layout in my CSS, however, the subscriber container never changes size. Is this an implementation problem or a decision on your part not to handle subscriber stream resizing?
#tokbox_layout{
margin: auto;
position: relative;
height: 427px;
width: 240px;
}
And the layout() javascript call:
var layoutContainer = $("#tokbox_layout").get(0);
var layout = initLayoutContainer(layoutContainer,{
fixedRatio: true,
bigFixedRatio: true
}).layout;
I'd like to use the opentok-layout-js app to rearrange the user displays on demand. Layouts I'd like to provide are:
Can you point me in the right direction on how to accomplish this efficiently using this library? I'm proofing it out within the opentok-meet app at the moment.
Fix code climate issues https://codeclimate.com/github/aullman/opentok-layout-js/issues
Is it possible to keep the aspect ratio for only one element (fixedRatio: true) but not for the others (fixedRatio: false)?
This would be helpful if someone adds a screen to share with others to show a presentation which shouldn't be cropped. (Maybe a "fixedRatio" class)
This was reported on the OpenTok forums:
https://forums.tokbox.com/viewtopic.php?t=45869#57914
You can't require this file in node anymore. You get an error:
ReferenceError: window is not defined
at Object.<anonymous> (/Users/adamu/src/opentok-layout-js/opentok-layout.js:292:5)
Hello,
It's not working like expected:
That is what I see, but I expected this kind of behavior:
Code:
<section id="videos">
<div id="publish-view"></div>
<div id="subscribers"></div>
</section>
<script>
let self = this;
const initLayoutContainer = require("opentok-layout-js");
const options = {
maxRatio: 3 / 2, // The narrowest ratio that will be used (default 2x3)
minRatio: 9 / 16, // The widest ratio that will be used (default 16x9)
fixedRatio: false, // If this is true then the aspect ratio of the video is maintained and minRatio and maxRatio are ignored (default false)
alignItems: "center", // Can be 'start', 'center' or 'end'. Determines where to place items when on a row or column that is not full
bigClass: "OT_big", // The class to add to elements that should be sized bigger
bigPercentage: 0.8, // The maximum percentage of space the big ones should take up
bigFixedRatio: false, // fixedRatio for the big ones
bigAlignItems: "center", // How to align the big items
smallAlignItems: "center", // How to align the small row or column of items if there is a big one
maxWidth: Infinity, // The maximum width of the elements
maxHeight: Infinity, // The maximum height of the elements
smallMaxWidth: Infinity, // The maximum width of the small elements
smallMaxHeight: Infinity, // The maximum height of the small elements
bigMaxWidth: Infinity, // The maximum width of the big elements
bigMaxHeight: Infinity, // The maximum height of the big elements
bigMaxRatio: 3 / 2, // The narrowest ratio to use for the big elements (default 2x3)
bigMinRatio: 9 / 16, // The widest ratio to use for the big elements (default 16x9)
bigFirst: true, // Whether to place the big one in the top left (true) or bottom right (false).
// You can also pass 'column' or 'row' to change whether big is first when you are in a row (bottom) or a column (right) layout
animate: true, // Whether you want to animate the transitions
window: window, // Lets you pass in your own window object which should be the same window that the element is in
ignoreClass: "OT_ignore" // Elements with this class will be ignored and not positioned. This lets you do things like picture-in-picture
};
const layout = initLayoutContainer(
document.getElementById("videos"),
options
);
layout.layout();
const OT = require("@opentok/client");
var session = OT.initSession(self.apikey, self.sessionid);
var publisherOptions = {
insertMode: "append",
fitMode: "cover"
};
var publisher = OT.initPublisher(
"publish-view",
publisherOptions
);
self.current_publisher = publisher;
publisher.on({
accessDenied: function() {
alert(
"Error."
);
// window.location.reload();
}
});
session.connect(self.token, function(error) {
if (error) {
console.error("Failed to connect", error);
} else {
session.publish(publisher, function(error) {
if (error) {
console.error("Failed to publish", error);
}
});
}
});
session.on("streamCreated", function(event) {
session.subscribe(
event.stream,
"subscribers",
{
// width: 740,
// height: 480,
insertMode: "append",
fitMode: "cover"
// style: { nameDisplayMode: "on" }
},
function(error) {
if (error) {
console.error("Failed to subscribe", error);
} else {
if (!self.live) {
self.live = true;
}
}
}
);
});
</script>
<style >
#videos {
width: 100%;
min-height: 400px;
/* background-color: #DDD; */
position: relative;
}
.container > * {
transition - property: all;
transition-duration: 0.5s;
}
</style>
Is there an example on how to use it without OpenTok? Especially which HTML layout does the library expect in order to work properly. I see it mentioned in the README that it is supposed to work without OpenTok but all the code references seem to be expecting OpenTok
How can i integrate this package using the opentok-react library also?
I'm generating the streams like this, by using components from Opentok-react.
<OTStreams>
<OTSubscriber
ref={this.props.setRef}
properties={{
subscribeToAudio: this.props.audio,
subscribeToVideo: this.props.video,
style: { buttonDisplayMode: 'off' }
}}
/>
</OTStreams>
Hi @aullman, first of all I want to say thanks for this great library!
Do you think we could include containerWidth
and containerHeight
as part of the options in readme file?
I'm using this lib together with opentok-react
and I was wondering why my layout data is not updated when I call the getLayout()
on a dynamic-sized container (I passed in default options) until I found out that there are other options: container width & height (i.e undocumented) with default value of 640px
for width and 480px
for height.
browserify expects you to assign your exports to either properties of the exports
object or directly to module.exports
. (node style CommonJS)
i think that shouldn't be too difficult, but if for some reason a less invasive approach is desired, you can specify additional metadata to shim the CommonJS compatibility by filling out the values for keys that browserify-shim define.
Add typescript definitions for lib
Hi i am new to tokbox. how to setup fixed one big and rest all small, onclick replace the big with clicked small element and the make the big one is small . I tried to achive the same,but unable to get it done. Please guide me on this. thanks for your wonderful work.
Hi @aullman,
I got the library to work but run into this problem where sometimes when I enter the page with video, the video appears smaller on the top-left part of the window, only upon resizing the window that the video element fills up the screen. Why's that?
These are the options I'm using:
let opts = {
maxRatio: 3 / 2,
minRatio: 9 / 16,
fixedRatio: false,
scaleLastRow: true,
maxWidth: Infinity, // The maximum width of the elements
maxHeight: Infinity, // The maximum height of the elements
smallMaxWidth: Infinity, // The maximum width of the small elements
smallMaxHeight: Infinity, // The maximum height of the small elements
bigMaxWidth: Infinity, // The maximum width of the big elements
bigMaxHeight: Infinity,
alignItems: 'center',
bigClass: 'OT_big',
smallClass:'OT_small',
bigPercentage: 0.8,
bigFixedRatio: false,
bigMaxRatio: 3 / 2,
bigMinRatio: 9 / 16,
bigFirst: true,
animate: true
}
This is how I'm calling "layout". With this I expect that when the page opens with a video it fills the screen immediately.
let layoutContainer = document.getElementById("layout");
let layout = initLayoutContainer(layoutContainer, opts).layout;
layout();
var resizeTimeout;
window.onresize = function() {
clearTimeout(resizeTimeout);
resizeTimeout = setTimeout(function () {
layout();
}, 20);
};
Also, I see classes like "OT_bar OT_edge-bar-item OT_mode-auto" in the demo app where are they coming from? And why don't I see the "ot-layout" class that the library is supposed to add?
We have tried to get opentok-layout compatible with Apache Cordova and the use of https://github.com/songz/cordova-plugin-opentok. We successfully made some changes to get this implemented.
What we did:
See adjusted file on pastebin: http://pastebin.com/vjF5g5sf
just trying to keep track of our discussion.
instead of optionally depending on jQuery, which has no good way to be declared via the bower.json
, we could actually create a hard dependency on something that is smaller, less likely to collide, and specifically built to do animations.
one such library is the zepto.fx module, and it has the same API as jQuery. the only problem is that its not distributed on bower, and even the "clones" do not expose the fx module (with any of its dependencies) on its own.
i think that for now, we just stick to what we've done, which is do a runtime detection of jQuery and use it to animate. one thing we can do to make it a bit nicer is do a console.warn()
if the user specifically requested to animate but jQuery wasn't found.
Hi,
Basically what the title says. Specifically, as the screen width moves into smartphone-size range, elements with the 'OT_big' class get smaller while elements without the class get larger, until at a certain point the 'OT_big' elements actually get smaller than the unadorned elements. This is unexpected behavior, & makes using the class on responsive layout for large screens & mobile devices have opposite effects in those two contexts.
Any ideas on how to fix or work around this?
Thanks for your great work!
When I set scaleLastRow to false, the last row of videos are still scaled up. Here are my settings:
{
minRatio: 2 / 3,
maxRatio: 2 / 3,
fixedRatio: false,
scaleLastRow: false,
bigFirst: false,
bigFixedRatio: true,
bigAlignItems: 'top',
}
See attached image for reference to issue.
Is there any other info I can/need to supply?
Hi,
What should be your recommend approach to integrate this layout with https://github.com/opentok/accelerator-core-js
Thank you
Hi @aullman, first of all I want to say thanks for this great library!
Do you think we could include containerWidth
and containerHeight
as part of the options in readme file?
It's undocumented at the moment and I was wondering why my layout data is not updated and turns out I found that it used the default value which is 640px
for width and 480px
for height.
Hi, be a good feature to add that if bigPercentage = 1 then the small videos align below by default and don't stack on the right. Im not sure if i'm just missing this in the advance settings to force this functionality to work, if i am let me know otherwise i will try and arrange a pr for this feature.
Thanks
Hi,
I have OpenTok working with Vue, so it's different to get the DOM-elements. I found out that "window" was the property to change. So I did.:
var layout = initLayoutContainer(layoutContainer, {
animate: false,
window: document.getElementById("subscribers")
}).layout;
With the HTML:
<div class="flex bg-red-50">
<div id="subscribers"></div>
</div>
But I keep getting:
TypeError: Argument 1 ('element') to Window.getComputedStyle must be an instance of Element
getComputedStyle โ opentok-layout.js:524
n โ opentok-layout.js:524
(anonieme functie) โ opentok-layout.js:640
(anonieme functie)
(anonieme functie) โ Session.vue:219
o โ opentok.js:45097
How to set "big" to a specific stream? @aullman
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.