Skip to content

Commit 97028cc

Browse files
authored
Merge pull request #307 from opentok/dev
Release candidate, DVR/HLS
2 parents 1493c01 + 0d8efa2 commit 97028cc

File tree

13 files changed

+469
-62
lines changed

13 files changed

+469
-62
lines changed

README.md

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ The OpenTok PHP SDK provides methods for:
1313
* Working with [OpenTok archives](https://tokbox.com/opentok/tutorials/archiving)
1414
* Working with [OpenTok live streaming broadcasts](https://tokbox.com/developer/guides/broadcast/live-streaming/)
1515
* Working with [OpenTok SIP interconnect](https://tokbox.com/developer/guides/sip)
16-
* [Sending signals to clients connected to a session](https://www.tokbox.com/developer/guides/signaling/)
16+
* [Sending signals to clients connected to a session](https://tokbox.com/developer/guides/signaling/)
1717
* [Disconnecting clients from sessions](https://tokbox.com/developer/guides/moderation/rest/)
1818
* [Forcing clients in a session to disconnect or mute published audio](https://tokbox.com/developer/guides/moderation/)
1919

@@ -278,19 +278,36 @@ You can only start live streaming broadcasts for sessions that use the OpenTok M
278278
Start the live streaming broadcast of an OpenTok Session using the
279279
`startBroadcast($sessionId, $options)` method of the `OpenTok\OpenTok` class.
280280
This will return an `OpenTok\Broadcast` instance. The `$options` parameter is
281-
an optional array used to assign broadcast options such as layout, maxDuration, resolution, and more.
281+
an array used to define the broadcast streams, assign broadcast options such as layout,
282+
maxDuration, resolution, and more.
282283

283284
```php
284-
// Start a live streaming broadcast of a session
285-
$broadcast = $opentok->startBroadcast($sessionId);
286-
285+
// Define options for the broadcast
286+
$options = [
287+
'layout' => Layout::getBestFit(),
288+
'maxDuration' => 5400,
289+
'resolution' => '1280x720',
290+
'output' => [
291+
'hls' => [
292+
'dvr' => true,
293+
'lowLatency' => false
294+
],
295+
'rtmp' => [
296+
[
297+
'id' => 'foo',
298+
'serverUrl' => 'rtmps://myfooserver/myfooapp',
299+
'streamName' => 'myfoostream'
300+
],
301+
[
302+
'id' => 'bar',
303+
'serverUrl' => 'rtmps://myfooserver/mybarapp',
304+
'streamName' => 'mybarstream'
305+
],
306+
]
307+
]
308+
];
287309

288-
// Start a live streaming broadcast of a session, using broadcast options
289-
$options = array(
290-
'layout' => Layout::getBestFit(),
291-
'maxDuration' => 5400,
292-
'resolution' => '1280x720'
293-
);
310+
// Start a live streaming broadcast of a session
294311
$broadcast = $opentok->startBroadcast($sessionId, $options);
295312

296313
// Store the broadcast ID in the database for later use
@@ -474,7 +491,7 @@ Reference documentation is available at
474491
## Requirements
475492

476493
You need an OpenTok API key and API secret, which you can obtain by logging into your
477-
[TokBox account](https://tokbox.com/account).
494+
[Vonage Video API account](https://tokbox.com/account).
478495

479496
The OpenTok PHP SDK requires PHP 7.2 or higher.
480497

src/OpenTok/Broadcast.php

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@
3535
* @property boolean $isStopped
3636
* Whether the broadcast is stopped (true) or in progress (false).
3737
*
38+
* @property boolean $isHls
39+
* Whether the broadcast supports HLS.
40+
*
41+
* @property boolean $isDvr
42+
* Whether the broadcast supports DVR functionality for the HLS stream.
43+
*
44+
* @property boolean $isLowLatency
45+
* Whether the broadcast supports low-latency mode for the HLS stream.
46+
*
3847
* @property string $streamMode
3948
* Whether streams included in the broadcast are selected automatically (<code>StreamMode.AUTO</code>)
4049
* or manually (<code>StreamMode.MANUAL</code>). When streams are selected automatically (<code>StreamMode.AUTO</code>),
@@ -48,26 +57,35 @@
4857
*/
4958
class Broadcast
5059
{
51-
// NOTE: after PHP 5.3.0 support is dropped, the class can implement JsonSerializable
52-
5360
/** @ignore */
5461
private $data;
5562
/** @ignore */
56-
private $isStopped = false;
63+
private $isStopped;
5764
/** @ignore */
5865
private $client;
66+
/** @ignore */
67+
private $isHls;
68+
/** @ignore */
69+
private $isLowLatency;
70+
/** @ignore */
71+
private $isDvr;
5972

6073
/** @ignore */
6174
public function __construct($broadcastData, $options = array())
6275
{
6376
// unpack optional arguments (merging with default values) into named variables
77+
// when adding these properties like this, it's worth noting that the method that
78+
// starts a broadcast ALSO sets a load of defaults
6479
$defaults = array(
6580
'apiKey' => null,
6681
'apiSecret' => null,
6782
'apiUrl' => 'https://api.opentok.com',
6883
'client' => null,
6984
'isStopped' => false,
70-
'streamMode' => StreamMode::AUTO
85+
'streamMode' => StreamMode::AUTO,
86+
'isHls' => true,
87+
'isLowLatency' => false,
88+
'isDvr' => false
7189
);
7290
$options = array_merge($defaults, array_intersect_key($options, $defaults));
7391
list($apiKey, $apiSecret, $apiUrl, $client, $isStopped, $streamMode) = array_values($options);
@@ -80,6 +98,9 @@ public function __construct($broadcastData, $options = array())
8098
$this->data = $broadcastData;
8199

82100
$this->isStopped = $isStopped;
101+
$this->isHls = isset($this->data['settings']['hls']);
102+
$this->isLowLatency = $this->data['settings']['hls']['lowLatency'] ?? false;
103+
$this->isDvr = $this->data['settings']['hls']['dvr'] ?? false;
83104

84105
$this->client = isset($client) ? $client : new Client();
85106
if (!$this->client->isConfigured()) {
@@ -110,10 +131,17 @@ public function __get($name)
110131
return $this->data['broadcastUrls']['hls'];
111132
case 'isStopped':
112133
return $this->isStopped;
134+
case 'isHls':
135+
return $this->isHls;
136+
case 'isLowLatency':
137+
return $this->isLowLatency;
138+
case 'isDvr':
139+
return $this->isDvr;
113140
default:
114141
return null;
115142
}
116143
}
144+
117145
/**
118146
* Stops the broadcast.
119147
*/

src/OpenTok/OpenTok.php

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
* Contains methods for creating OpenTok sessions, generating tokens, and working with archives.
1313
* <p>
1414
* To create a new OpenTok object, call the OpenTok() constructor with your OpenTok API key
15-
* and the API secret for your <a href="https://tokbox.com/account">TokBox account</a>. Do not
15+
* and the API secret for your <a href="https://tokbox.com/account">OpenTok Video API account</a>. Do not
1616
* publicly share your API secret. You will use it with the OpenTok() constructor (only on your web
1717
* server) to create OpenTok sessions.
1818
* <p>
@@ -67,7 +67,7 @@ public function __construct($apiKey, $apiSecret, $options = array())
6767
* connecting to an OpenTok session, the client passes a token when connecting to the session.
6868
* <p>
6969
* For testing, you generate tokens or by logging in to your
70-
* <a href="https://tokbox.com/account">TokBox account</a>.
70+
* <a href="https://tokbox.com/account">OpenTok Video API account</a>.
7171
*
7272
* @param string $sessionId The session ID corresponding to the session to which the user
7373
* will connect.
@@ -152,7 +152,7 @@ public function generateToken($sessionId, $options = array())
152152
* Check the error message for details.
153153
* <p>
154154
* You can also create a session by logging in to your
155-
* <a href="https://tokbox.com/account">TokBox account</a>.
155+
* <a href="https://tokbox.com/account">OpenTok Video API account</a>.
156156
*
157157
* @param array $options (Optional) This array defines options for the session. The array includes
158158
* the following keys (all of which are optional):
@@ -625,7 +625,7 @@ public function disableForceMute(string $sessionId, array $options): bool
625625
* Video Layout for the OpenTok live streaming feature</a>.
626626
* </li>
627627
*
628-
* <li><code>'streamMode'</code> (String) &mdash; Whether streams included in the broadcast
628+
* <li><code>streamMode</code> (String) &mdash; Whether streams included in the broadcast
629629
* are selected automatically (<code>StreamMode.AUTO</code>, the default) or manually
630630
* (<code>StreamMode.MANUAL</code>). When streams are selected automatically
631631
* (<code>StreamMode.AUTO</code>), all streams in the session can be included in the broadcast.
@@ -637,6 +637,36 @@ public function disableForceMute(string $sessionId, array $options): bool
637637
* <a href="https://tokbox.com/developer/guides/archive-broadcast-layout/#stream-prioritization-rules">stream
638638
* prioritization rules</a>.</li>
639639
*
640+
* <li><code>outputs</code> (Array) &mdash;
641+
* Defines the HLS broadcast and RTMP streams. You can provide the following keys:
642+
* <ul>
643+
* <li><code>hls</code> (Array) &mdash; available with the following options:
644+
* <p>
645+
* <ul>
646+
* <li><code>'dvr'</code> (Bool) &mdash; Whether to enable
647+
* <a href="https://tokbox.com/developer/guides/broadcast/live-streaming/#dvr">DVR functionality</a>
648+
* — rewinding, pausing, and resuming — in players that support it (<code>true</code>),
649+
* or not (<code>false</code>, the default). With DVR enabled, the HLS URL will include
650+
* a ?DVR query string appended to the end.
651+
* </li>
652+
* <li><code>'lowLatency'</code> (Bool) &mdash; Whether to enable
653+
* <a href="https://tokbox.com/developer/guides/broadcast/live-streaming/#low-latency">low-latency mode</a>
654+
* for the HLS stream. Some HLS players do not support low-latency mode. This feature
655+
* is incompatible with DVR mode HLS broadcasts.
656+
* </li>
657+
* </ul>
658+
* </p>
659+
* </li>
660+
* <li><code>rtmp</code> (Array) &mdash; An array of arrays defining RTMP streams to broadcast. You
661+
* can specify up to five target RTMP streams. Each RTMP stream array has the following keys:
662+
* <ul>
663+
* <li><code>id</code></code> (String) &mdash; The stream ID (optional)</li>
664+
* <li><code>serverUrl</code> (String) &mdash; The RTMP server URL</li>
665+
* <li><code>streamName</code> (String) &mdash; The stream name, such as
666+
* the YouTube Live stream name or the Facebook stream key</li>
667+
* </ul>
668+
* </li>
669+
* </ul>
640670
* </ul>
641671
*
642672
* @return Broadcast An object with properties defining the broadcast.
@@ -647,11 +677,28 @@ public function startBroadcast(string $sessionId, array $options = []): Broadcas
647677
// NOTE: although the server can be authoritative about the default value of layout, its
648678
// not preferred to depend on that in the SDK because its then harder to garauntee backwards
649679
// compatibility
650-
$defaults = array(
680+
681+
if (isset($options['output']['hls'])) {
682+
Validators::validateBroadcastOutputOptions($options['output']['hls']);
683+
}
684+
685+
if (isset($options['output']['rtmp'])) {
686+
Validators::validateRtmpStreams($options['output']['rtmp']);
687+
}
688+
689+
$defaults = [
651690
'layout' => Layout::getBestFit(),
652-
'streamMode' => 'auto'
653-
);
691+
'streamMode' => 'auto',
692+
'output' => [
693+
'hls' => [
694+
'dvr' => false,
695+
'lowLatency' => false
696+
]
697+
]
698+
];
699+
654700
$options = array_merge($defaults, $options);
701+
655702
list($layout, $streamMode) = array_values($options);
656703

657704
// validate arguments

src/OpenTok/Session.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ public function __toString()
120120
* the client passes a token when connecting to the session.
121121
* <p>
122122
* For testing, you can also generate tokens or by logging in to your
123-
* <a href="https://tokbox.com/account">TokBox account</a>.
123+
* <a href="https://tokbox.com/account">OpenTok Video API account</a>.
124124
*
125125
* @param array $options This array defines options for the token. This array include the
126126
* following keys, all of which are optional:

src/OpenTok/Util/Client.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838

3939
// TODO: build this dynamically
4040
/** @internal */
41-
define('OPENTOK_SDK_VERSION', '4.10.0');
41+
define('OPENTOK_SDK_VERSION', '4.11.0');
4242
/** @internal */
4343
define('OPENTOK_SDK_USER_AGENT', 'OpenTok-PHP-SDK/' . OPENTOK_SDK_VERSION);
4444

@@ -628,7 +628,8 @@ public function dial($sessionId, $token, $sipUri, $options)
628628
'token' => $token,
629629
'sip' => array(
630630
'uri' => $sipUri,
631-
'secure' => $options['secure']
631+
'secure' => $options['secure'],
632+
'observeForceMute' => $options['observeForceMute']
632633
)
633634
);
634635

src/OpenTok/Util/Validators.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ public static function validateOpenTok($opentok)
288288
);
289289
}
290290
}
291+
291292
public static function validateBroadcastData($broadcastData)
292293
{
293294
if (!self::$broadcastSchemaUri) {
@@ -304,6 +305,14 @@ public static function validateBroadcastData($broadcastData)
304305
);
305306
}
306307
}
308+
309+
public static function validateRtmpStreams(array $rtmpData)
310+
{
311+
if (count($rtmpData) > 5) {
312+
throw new InvalidArgumentException('The maximum permitted RTMP Streams is set to 5');
313+
}
314+
}
315+
307316
public static function validateBroadcastId($broadcastId)
308317
{
309318
if (!is_string($broadcastId) || preg_match(self::$guidRegEx, $broadcastId)) {
@@ -312,6 +321,18 @@ public static function validateBroadcastId($broadcastId)
312321
);
313322
}
314323
}
324+
325+
public static function validateBroadcastOutputOptions(array $outputOptions)
326+
{
327+
if (
328+
isset($outputOptions['lowLatency'], $outputOptions['dvr'])
329+
&& $outputOptions['lowLatency'] === true && $outputOptions['dvr'] === true
330+
) {
331+
throw new InvalidArgumentException('When starting in HLS mode, DVR AND lowLatency
332+
cannot both be true');
333+
}
334+
}
335+
315336
public static function validateLayout($layout)
316337
{
317338
if (!($layout instanceof Layout)) {

tests/OpenTokTest/ArchiveTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public function testStopsArchive()
161161
// TODO: test the dynamically built User Agent string
162162
$userAgent = $request->getHeaderLine('User-Agent');
163163
$this->assertNotEmpty($userAgent);
164-
$this->assertStringStartsWith('OpenTok-PHP-SDK/4.10.0', $userAgent);
164+
$this->assertStringStartsWith('OpenTok-PHP-SDK/4.11.0', $userAgent);
165165

166166
// TODO: test the properties of the actual archive object
167167
$this->assertEquals('stopped', $this->archive->status);
@@ -278,7 +278,7 @@ public function testDeletesArchive()
278278
// TODO: test the dynamically built User Agent string
279279
$userAgent = $request->getHeaderLine('User-Agent');
280280
$this->assertNotEmpty($userAgent);
281-
$this->assertStringStartsWith('OpenTok-PHP-SDK/4.10.0', $userAgent);
281+
$this->assertStringStartsWith('OpenTok-PHP-SDK/4.11.0', $userAgent);
282282

283283
$this->assertTrue($success);
284284
// TODO: assert that all properties of the archive object were cleared

0 commit comments

Comments
 (0)