2015-03-08 12:42:58 +00:00
|
|
|
<?php
|
|
|
|
|
2015-03-30 14:20:30 +00:00
|
|
|
class Stream
|
|
|
|
{
|
2023-05-29 16:48:34 +00:00
|
|
|
public $room;
|
|
|
|
public $selection;
|
|
|
|
public $language;
|
|
|
|
public $translation_label;
|
|
|
|
|
2017-12-09 22:44:47 +00:00
|
|
|
public function __construct(Room $room, $selection, $language, $translation_label = null)
|
2015-03-30 14:20:30 +00:00
|
|
|
{
|
|
|
|
$this->room = $room;
|
|
|
|
$this->selection = $selection;
|
|
|
|
$this->language = $language;
|
2017-12-09 22:44:47 +00:00
|
|
|
$this->translation_label = (empty($translation_label)) ? $language : $translation_label;
|
2015-03-30 14:20:30 +00:00
|
|
|
}
|
2015-03-08 12:42:58 +00:00
|
|
|
|
2015-03-30 14:20:30 +00:00
|
|
|
public function getRoom()
|
|
|
|
{
|
|
|
|
return $this->room;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getSelection()
|
|
|
|
{
|
|
|
|
return $this->selection;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getLanguage()
|
|
|
|
{
|
|
|
|
return $this->language;
|
|
|
|
}
|
|
|
|
|
2017-12-09 22:44:47 +00:00
|
|
|
public function getTranslationLabel()
|
|
|
|
{
|
|
|
|
return $this->translation_label;
|
|
|
|
}
|
|
|
|
|
2015-03-30 14:20:30 +00:00
|
|
|
public function isTranslated()
|
|
|
|
{
|
2017-12-11 19:03:35 +00:00
|
|
|
return !empty($this->getLanguage()) &&
|
2020-05-07 21:42:45 +00:00
|
|
|
$this->getLanguage() !== 'native';
|
2015-03-30 14:20:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public function getVideoSize()
|
|
|
|
{
|
|
|
|
switch($this->getSelection())
|
|
|
|
{
|
|
|
|
case 'sd':
|
|
|
|
return array(1024, 576);
|
|
|
|
|
2018-12-28 13:47:59 +00:00
|
|
|
case 'slides':
|
2015-03-30 14:20:30 +00:00
|
|
|
case 'hd':
|
|
|
|
return array(1920, 1080);
|
|
|
|
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getVideoWidth()
|
|
|
|
{
|
|
|
|
$sz = $this->getVideoSize();
|
|
|
|
return $sz[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getVideoHeight()
|
|
|
|
{
|
|
|
|
$sz = $this->getVideoSize();
|
|
|
|
return $sz[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getTab()
|
|
|
|
{
|
|
|
|
switch($this->getSelection())
|
|
|
|
{
|
|
|
|
case 'sd':
|
|
|
|
case 'hd':
|
|
|
|
return 'video';
|
|
|
|
|
|
|
|
default:
|
|
|
|
return $this->getSelection();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getPlayerType()
|
|
|
|
{
|
|
|
|
return $this->getTab();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDisplay()
|
|
|
|
{
|
|
|
|
$display = $this->getRoom()->getDisplay().' ';
|
|
|
|
switch($this->getSelection())
|
|
|
|
{
|
|
|
|
case 'hd':
|
|
|
|
$display .= 'FullHD Video';
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'sd':
|
|
|
|
$display .= 'SD Video';
|
|
|
|
break;
|
|
|
|
|
2015-12-09 20:46:46 +00:00
|
|
|
case 'music':
|
|
|
|
$display .= 'Radio';
|
|
|
|
break;
|
|
|
|
|
2021-12-27 04:41:55 +00:00
|
|
|
case 'hls':
|
|
|
|
// do not add suffix when we only provide HLS
|
|
|
|
if($this->getRoom()->h264Only()) {
|
|
|
|
break;
|
|
|
|
}
|
2018-04-01 13:16:02 +00:00
|
|
|
case 'dash':
|
2021-12-27 04:41:55 +00:00
|
|
|
if($this->getRoom()->h264Only()) {
|
2021-12-26 05:17:25 +00:00
|
|
|
$display .= 'DASH';
|
2021-12-27 04:41:55 +00:00
|
|
|
break;
|
2021-12-26 05:17:25 +00:00
|
|
|
}
|
2015-03-30 14:20:30 +00:00
|
|
|
default:
|
|
|
|
$display .= ucfirst($this->getSelection());
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($this->isTranslated())
|
2017-12-09 22:44:47 +00:00
|
|
|
$display .= ' ('. $this->getTranslationLabel() .')';
|
2015-03-30 14:20:30 +00:00
|
|
|
|
|
|
|
return $display;
|
|
|
|
}
|
|
|
|
|
2015-04-05 22:28:03 +00:00
|
|
|
public function getEmbedUrl()
|
|
|
|
{
|
2016-12-27 09:50:48 +00:00
|
|
|
return joinpath([
|
|
|
|
baseurl(),
|
|
|
|
$this->getRoom()->getConference()->getSlug(),
|
|
|
|
'embed',
|
|
|
|
rawurlencode($this->getRoom()->getSlug()),
|
|
|
|
rawurlencode($this->getSelection()),
|
|
|
|
rawurlencode($this->getLanguage()),
|
|
|
|
]);
|
2015-04-05 22:28:03 +00:00
|
|
|
}
|
|
|
|
|
2017-12-28 11:27:51 +00:00
|
|
|
public function getVideoUrl($proto, $selection=null)
|
2015-03-30 14:20:30 +00:00
|
|
|
{
|
2017-12-28 11:27:51 +00:00
|
|
|
if (!$selection) {
|
|
|
|
$selection = $this->getSelection();
|
|
|
|
}
|
|
|
|
|
2023-08-15 09:16:13 +00:00
|
|
|
if($selection == 'slides') {
|
|
|
|
return proto().'://'.joinpath([$GLOBALS['CONFIG']['CDN'], 'hls', rawurlencode($this->getRoom()->getStream()).'/Slides.m3u8']);
|
|
|
|
}
|
|
|
|
|
2015-03-30 14:20:30 +00:00
|
|
|
switch($proto)
|
|
|
|
{
|
|
|
|
case 'hls':
|
2024-01-28 23:33:47 +00:00
|
|
|
if ($this->getRoom()->getConference()->has('cdn.hls_playlist_url')) {
|
|
|
|
return str_replace('{streamId}', $this->getRoom()->getStream(), $this->getRoom()->getConference()->get('cdn.hls_playlist_url'));
|
|
|
|
}
|
2021-04-03 21:51:54 +00:00
|
|
|
return proto().'://'.joinpath([$GLOBALS['CONFIG']['CDN'], 'hls', rawurlencode($this->getRoom()->getStream()).'/'.rawurlencode($this->getLanguage()).'_'.rawurlencode($selection).'.m3u8']);
|
2015-04-05 17:05:33 +00:00
|
|
|
}
|
2015-03-30 14:20:30 +00:00
|
|
|
|
2015-04-05 17:05:33 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
public function getVideoTech($proto)
|
|
|
|
{
|
|
|
|
switch($proto)
|
|
|
|
{
|
|
|
|
case 'hls':
|
|
|
|
if($this->getSelection() == 'hd')
|
|
|
|
return '1920x1080, h264+AAC im MPEG-TS-Container via HTTP, 3 MBit/s';
|
|
|
|
|
|
|
|
else if($this->getSelection() == 'sd')
|
|
|
|
return '1024x576, h264+AAC im MPEG-TS-Container via HTTP, 800 kBit/s';
|
2020-05-02 20:34:48 +00:00
|
|
|
|
|
|
|
case 'dash':
|
|
|
|
return 'VP9+Opus mit WebM-Segmenten';
|
2015-03-30 14:20:30 +00:00
|
|
|
}
|
2015-04-05 17:05:33 +00:00
|
|
|
|
|
|
|
return null;
|
2015-03-30 14:20:30 +00:00
|
|
|
}
|
|
|
|
public static function getVideoProtos()
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
'hls' => 'HLS',
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getSlidesUrl($proto)
|
|
|
|
{
|
|
|
|
return $this->getVideoUrl($proto);
|
|
|
|
}
|
2015-04-05 17:05:33 +00:00
|
|
|
public function getSlidesTech($proto)
|
|
|
|
{
|
|
|
|
switch($proto)
|
|
|
|
{
|
|
|
|
case 'hls':
|
2016-12-29 02:55:34 +00:00
|
|
|
return '1024x576, h264+AAC im MPEG-TS-Container via HTTP, 400 kBit/s';
|
2015-04-05 17:05:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2015-03-30 14:20:30 +00:00
|
|
|
public static function getSlidesProtos()
|
|
|
|
{
|
|
|
|
return Stream::getVideoProtos();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public function getAudioUrl($proto)
|
|
|
|
{
|
|
|
|
switch($proto)
|
|
|
|
{
|
2021-12-26 05:17:25 +00:00
|
|
|
case 'hls':
|
2023-12-28 11:40:06 +00:00
|
|
|
return proto().'://'.joinpath([$GLOBALS['CONFIG']['CDN'], 'hls/'.rawurlencode($this->getRoom()->getStream()).'/'.rawurlencode(ucfirst($this->getLanguage())).'.m3u8']);
|
2015-04-05 17:05:33 +00:00
|
|
|
}
|
2015-03-30 14:20:30 +00:00
|
|
|
|
2015-04-05 17:05:33 +00:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
public function getAudioTech($proto)
|
|
|
|
{
|
|
|
|
switch($proto)
|
|
|
|
{
|
2021-12-26 05:17:25 +00:00
|
|
|
case 'hls':
|
|
|
|
return 'AAC, VBR';
|
2015-03-30 14:20:30 +00:00
|
|
|
}
|
2015-04-05 17:05:33 +00:00
|
|
|
|
|
|
|
return null;
|
2015-03-30 14:20:30 +00:00
|
|
|
}
|
|
|
|
public static function getAudioProtos()
|
|
|
|
{
|
|
|
|
return array(
|
2021-12-26 05:17:25 +00:00
|
|
|
'hls' => 'HLS',
|
2015-03-30 14:20:30 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getMusicUrl($proto)
|
|
|
|
{
|
|
|
|
switch($proto)
|
|
|
|
{
|
|
|
|
case 'mp3':
|
2020-06-09 19:24:18 +00:00
|
|
|
return proto().'://'.joinpath([$GLOBALS['CONFIG']['CDN'], rawurlencode($this->getRoom()->getStream()).'.mp3']);
|
2015-03-30 14:20:30 +00:00
|
|
|
|
|
|
|
case 'opus':
|
2020-06-09 19:24:18 +00:00
|
|
|
return proto().'://'.joinpath([$GLOBALS['CONFIG']['CDN'], rawurlencode($this->getRoom()->getStream()).'.opus']);
|
2015-03-30 14:20:30 +00:00
|
|
|
|
|
|
|
default:
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
2015-04-05 17:05:33 +00:00
|
|
|
public function getMusicTech($proto)
|
|
|
|
{
|
|
|
|
switch($proto)
|
|
|
|
{
|
|
|
|
case 'mp3':
|
|
|
|
return 'MP3-Audio, 192 kBit/s';
|
|
|
|
|
|
|
|
case 'opus':
|
|
|
|
return 'Opus-Audio, 96 kBit/s';
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
}
|
2015-03-30 14:20:30 +00:00
|
|
|
public static function getMusicProtos()
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
'mp3' => 'MP3',
|
|
|
|
'opus' => 'Opus',
|
|
|
|
);
|
|
|
|
}
|
2018-12-28 16:38:23 +00:00
|
|
|
public function getPoster() {
|
2024-01-28 23:33:47 +00:00
|
|
|
if ($this->room->getConference()->has('cdn.poster_url')) {
|
|
|
|
return str_replace('{streamId}', $this->getRoom()->getStream(), $this->room->getConference()->get('cdn.poster_url'));
|
|
|
|
}
|
2020-06-09 19:24:18 +00:00
|
|
|
return proto().'://'.joinpath([$GLOBALS['CONFIG']['CDN'], 'thumbnail', $this->getRoom()->getStream(), 'poster.jpeg']);
|
2018-12-28 16:38:23 +00:00
|
|
|
}
|
2015-03-08 12:42:58 +00:00
|
|
|
}
|