Skip to content

Commit f5ed428

Browse files
Merge pull request #282 from opentok/feature/devx-4270-archive-layout-options
Adding Screenshare Layout options
2 parents 2a47c2d + c3a828c commit f5ed428

File tree

6 files changed

+211
-118
lines changed

6 files changed

+211
-118
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ You can set change the layout dynamically, using the
317317
```php
318318
use OpenTok\OpenTok;
319319

320-
$layout Layout::getPIP(); // Or use another get method of the Layout class.
320+
$layout = Layout::getPIP(); // Or use another get method of the Layout class.
321321
$opentok->updateBroadcastLayout($broadcastId, $layout);
322322
```
323323

@@ -338,6 +338,13 @@ $layoutType = Layout::createCustom($options);
338338
$opentok->setArchiveLayout($archiveId, $layoutType);
339339
```
340340

341+
You can also set the Screenshare Layout by calling the `setScreenshareType()` method on a layout object.
342+
343+
```php
344+
$layout = Layout::getBestFit(); // Other types are not currently supported
345+
$layout->setScreenshareType(Layout::LAYOUT_VERTICAL);
346+
```
347+
341348
You can set the initial layout class for a client's streams by setting the `layout` option when
342349
you create the token for the client, using the `OpenTok->generateToken()` method or the
343350
`Session->generateToken()` method. And you can change the layout classes for a stream

src/OpenTok/Layout.php

Lines changed: 97 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -19,61 +19,40 @@
1919
* <a href="https://tokbox.com/developer/guides/broadcast/live-streaming/#configuring-video-layout-for-opentok-live-streaming-broadcasts">Configuring
2020
* video layout for OpenTok live streaming broadcasts</a>.
2121
*/
22-
class Layout
22+
class Layout implements \JsonSerializable
2323
{
24-
// NOTE: after PHP 5.3.0 support is dropped, the class can implement JsonSerializable
25-
26-
/** @ignore */
27-
private static $bestFit;
28-
/** @ignore */
29-
private static $pip;
30-
/** @ignore */
31-
private static $verticalPresentation;
32-
/** @ignore */
33-
private static $horizontalPresentation;
24+
public const LAYOUT_BESTFIT = 'bestFit';
25+
public const LAYOUT_CUSTOM = 'custom';
26+
public const LAYOUT_HORIZONTAL = 'horizontalPresentation';
27+
public const LAYOUT_PIP = 'pip';
28+
public const LAYOUT_VERTICAL = 'verticalPresentation';
3429

3530
/**
36-
* Returns a Layout object defining the "best fit" predefined layout type.
37-
*/
38-
public static function getBestFit()
39-
{
40-
if (is_null(self::$bestFit)) {
41-
self::$bestFit = new Layout('bestFit');
42-
}
43-
return self::$bestFit;
44-
}
31+
* Type of layout that we are sending
32+
* @var string
33+
* @ignore
34+
* */
35+
private $type;
4536

4637
/**
47-
* Returns a Layout object defining the "picture-in-picture" predefined layout type.
38+
* Type of layout to use for screen sharing
39+
* @var string
40+
* @ignore
4841
*/
49-
public static function getPIP()
50-
{
51-
if (is_null(self::$pip)) {
52-
self::$pip = new Layout('pip');
53-
}
54-
return self::$pip;
55-
}
42+
private $screenshareType;
5643

5744
/**
58-
* Returns a Layout object defining the "vertical presentation" predefined layout type.
45+
* Custom stylesheet if our type is 'custom'
46+
* @var string
47+
* @ignore
5948
*/
60-
public static function getVerticalPresentation()
61-
{
62-
if (is_null(self::$verticalPresentation)) {
63-
self::$verticalPresentation = new Layout('verticalPresentation');
64-
}
65-
return self::$verticalPresentation;
66-
}
49+
private $stylesheet;
6750

68-
/**
69-
* Returns a Layout object defining the "horizontal presentation" predefined layout type.
70-
*/
71-
public static function getHorizontalPresentation()
51+
/** @ignore */
52+
private function __construct(string $type, ?string $stylesheet = null)
7253
{
73-
if (is_null(self::$horizontalPresentation)) {
74-
self::$horizontalPresentation = new Layout('horizontalPresentation');
75-
}
76-
return self::$horizontalPresentation;
54+
$this->type = $type;
55+
$this->stylesheet = $stylesheet;
7756
}
7857

7958
/**
@@ -82,45 +61,99 @@ public static function getHorizontalPresentation()
8261
* @param array $options An array containing one property: <code>$stylesheet<code>,
8362
* which is a string containing the stylesheet to be used for the layout.
8463
*/
85-
public static function createCustom($options)
64+
public static function createCustom(array $options): Layout
8665
{
8766
// unpack optional arguments (merging with default values) into named variables
8867
// NOTE: the default value of stylesheet=null will not pass validation, this essentially
8968
// means that stylesheet is not optional. its still purposely left as part of the
9069
// $options argument so that it can become truly optional in the future.
91-
$defaults = array('stylesheet' => null);
70+
$defaults = ['stylesheet' => null];
9271
$options = array_merge($defaults, array_intersect_key($options, $defaults));
9372
list($stylesheet) = array_values($options);
9473

9574
// validate arguments
9675
Validators::validateLayoutStylesheet($stylesheet);
9776

98-
return new Layout('custom', $stylesheet);
77+
return new Layout(static::LAYOUT_CUSTOM, $stylesheet);
9978
}
10079

10180
/** @ignore */
102-
public static function fromData($layoutData)
81+
public static function fromData(array $layoutData): Layout
10382
{
10483
if (array_key_exists('stylesheet', $layoutData)) {
10584
return new Layout($layoutData['type'], $layoutData['stylesheet']);
106-
} else {
107-
return new Layout($layoutData['type']);
10885
}
86+
87+
return new Layout($layoutData['type']);
10988
}
11089

111-
/** @ignore */
112-
private $type;
113-
/** @ignore */
114-
private $stylesheet;
90+
/**
91+
* Returns a Layout object defining the "best fit" predefined layout type.
92+
*/
93+
public static function getBestFit(): Layout
94+
{
95+
return new Layout(static::LAYOUT_BESTFIT);
96+
}
11597

116-
/** @ignore */
117-
private function __construct($type, $stylesheet = null)
98+
/**
99+
* Returns a Layout object defining the "picture-in-picture" predefined layout type.
100+
*/
101+
public static function getPIP(): Layout
118102
{
119-
$this->type = $type;
120-
$this->stylesheet = $stylesheet;
103+
return new Layout(static::LAYOUT_PIP);
104+
}
105+
106+
/**
107+
* Returns a Layout object defining the "vertical presentation" predefined layout type.
108+
*/
109+
public static function getVerticalPresentation(): Layout
110+
{
111+
return new Layout(static::LAYOUT_VERTICAL);
112+
}
113+
114+
/**
115+
* Returns a Layout object defining the "horizontal presentation" predefined layout type.
116+
*/
117+
public static function getHorizontalPresentation(): Layout
118+
{
119+
return new Layout(static::LAYOUT_HORIZONTAL);
120+
}
121+
122+
public function setScreenshareType(string $screenshareType): Layout
123+
{
124+
if ($this->type === Layout::LAYOUT_BESTFIT) {
125+
$layouts = [
126+
Layout::LAYOUT_BESTFIT,
127+
Layout::LAYOUT_HORIZONTAL,
128+
Layout::LAYOUT_PIP,
129+
Layout::LAYOUT_VERTICAL
130+
];
131+
132+
if (!in_array($screenshareType, $layouts)) {
133+
throw new \RuntimeException('Screenshare type must be of a valid layout type');
134+
}
135+
136+
$this->screenshareType = $screenshareType;
137+
return $this;
138+
}
139+
140+
throw new \RuntimeException('Screenshare type cannot be set on a layout type other than bestFit');
121141
}
122142

123143
public function jsonSerialize()
144+
{
145+
return $this->toArray();
146+
}
147+
148+
/**
149+
* Return a json-encoded string representation of the layout
150+
*/
151+
public function toJson(): string
152+
{
153+
return json_encode($this->jsonSerialize());
154+
}
155+
156+
public function toArray(): array
124157
{
125158
$data = array(
126159
'type' => $this->type
@@ -130,11 +163,12 @@ public function jsonSerialize()
130163
if (isset($this->stylesheet)) {
131164
$data['stylesheet'] = $this->stylesheet;
132165
}
133-
return $data;
134-
}
135166

136-
public function toJson()
137-
{
138-
return json_encode($this->jsonSerialize());
167+
// omit 'screenshareType' property unless it is explicitly defined
168+
if (isset($this->screenshareType)) {
169+
$data['screenshareType'] = $this->screenshareType;
170+
}
171+
172+
return $data;
139173
}
140174
}

src/OpenTok/OpenTok.php

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
namespace OpenTok;
44

5+
use OpenTok\Layout;
56
use OpenTok\Util\Client;
67
use OpenTok\Util\Validators;
7-
use OpenTok\Exception\UnexpectedValueException;
88
use OpenTok\Exception\InvalidArgumentException;
9+
use OpenTok\Exception\UnexpectedValueException;
910

1011
/**
1112
* Contains methods for creating OpenTok sessions, generating tokens, and working with archives.
@@ -296,13 +297,17 @@ public function createSession($options = array())
296297
* @return Archive The Archive object, which includes properties defining the archive, including
297298
* the archive ID.
298299
*/
299-
public function startArchive($sessionId, $options = array())
300+
public function startArchive(string $sessionId, $options = []): Archive
300301
{
301302
// support for deprecated method signature, remove in v3.0.0 (not before)
302303
if (!is_array($options)) {
304+
trigger_error(
305+
'Archive options passed as a string is deprecated, please pass an array with a name key',
306+
E_USER_DEPRECATED
307+
);
303308
$options = array('name' => $options);
304309
}
305-
310+
306311
// unpack optional arguments (merging with default values) into named variables
307312
$defaults = array(
308313
'name' => null,
@@ -425,17 +430,11 @@ public function listArchives($offset = 0, $count = null, $sessionId = null)
425430

426431
/**
427432
* Updates the stream layout in an OpenTok Archive.
428-
*
429-
* @param string $archiveId The OpenTok archive ID.
430-
*
431-
* @param string $layout The connectionId of the connection in a session.
432433
*/
433-
434-
public function setArchiveLayout($archiveId, $layoutType)
434+
public function setArchiveLayout(string $archiveId, Layout $layoutType): void
435435
{
436436
Validators::validateArchiveId($archiveId);
437-
Validators::validateLayout($layoutType);
438-
437+
439438
$this->client->setArchiveLayout($archiveId, $layoutType);
440439
}
441440

@@ -497,7 +496,7 @@ public function forceDisconnect($sessionId, $connectionId)
497496
*
498497
* @return Broadcast An object with properties defining the broadcast.
499498
*/
500-
public function startBroadcast($sessionId, $options = array())
499+
public function startBroadcast(string $sessionId, array $options = []): Broadcast
501500
{
502501
// unpack optional arguments (merging with default values) into named variables
503502
// NOTE: although the server can be authoritative about the default value of layout, its
@@ -571,14 +570,9 @@ public function getBroadcast($broadcastId)
571570
*
572571
* @param Layout $layout An object defining the layout type for the broadcast.
573572
*/
574-
public function updateBroadcastLayout($broadcastId, $layout)
573+
public function updateBroadcastLayout(string $broadcastId, Layout $layout): void
575574
{
576575
Validators::validateBroadcastId($broadcastId);
577-
Validators::validateLayout($layout);
578-
579-
// TODO: platform implementation does not meet API Review spec
580-
// $layoutData = $this->client->updateLayout($broadcastId, $layout, 'broadcast');
581-
// return Layout::fromData($layoutData);
582576

583577
$this->client->updateLayout($broadcastId, $layout, 'broadcast');
584578
}

0 commit comments

Comments
 (0)