diff --git a/classes/GUI/Abstract/class.xvmpGUI.php b/classes/GUI/Abstract/class.xvmpGUI.php index 4d26a7f8..ea57a964 100644 --- a/classes/GUI/Abstract/class.xvmpGUI.php +++ b/classes/GUI/Abstract/class.xvmpGUI.php @@ -255,6 +255,7 @@ public function buildPlayerContainerDTO(xvmpMedium $medium) : PlayerContainerDTO $buttons = []; if (!is_null($this->getObject())) { $buttons[] = $this->buildPermLinkUI($medium); + $buttons[] = $this->buildStreamingLink($medium); } if ($medium->isDownloadAllowed()) { @@ -333,6 +334,40 @@ public function buildPermLinkUI(xvmpMedium $video) : array ]; } + /** + * @param xvmpMedium $video + * @return ILIAS\UI\Component\Component[] + */ + public function buildStreamingLink($video) + { + $medium = $video->getMedium(); + if (is_array($medium)){ + $medium = $medium[0]; + } + // decode url + $medium = str_replace('&', '&', $medium); + $link_container = ''; + + if(ilObjViMPAccess::hasAccessToStreamingLink()){ + $link_container = ''; + + $copy_js = ""; + return [ + $this->dic->ui()->factory()->legacy( + '' + ), + $this->dic->ui()->factory()->legacy($link_container), + $this->dic->ui()->factory()->legacy($copy_js) + ]; + } + return []; + } + /** * ajax * @throws xvmpException diff --git a/classes/class.ilObjViMPAccess.php b/classes/class.ilObjViMPAccess.php index 0bfc2d8a..6b4cccd8 100644 --- a/classes/class.ilObjViMPAccess.php +++ b/classes/class.ilObjViMPAccess.php @@ -146,6 +146,19 @@ public static function hasUploadPermission($ref_id = null) : bool return $ilAccess->checkAccess('rep_robj_xvmp_perm_upload', '', (int) $ref_id); } + /** + * @param $ref_id + * + * @return bool + */ + public static function hasAccessToStreamingLink($ref_id = NULL) { + if ($ref_id === NULL) { + $ref_id = $_GET['ref_id']; + } + global $DIC; + $ilAccess = $DIC['ilAccess']; + return $ilAccess->checkAccess('rep_robj_xvmp_perm_readlink', '',(int)$ref_id); + } /** * @param string $cmd * @param string $permission diff --git a/classes/class.ilObjViMPGUI.php b/classes/class.ilObjViMPGUI.php index 836579f3..71093589 100644 --- a/classes/class.ilObjViMPGUI.php +++ b/classes/class.ilObjViMPGUI.php @@ -202,6 +202,10 @@ public function executeCommand() : void $this->deleteObject(); break; } + if($cmd == 'count_views') { + ilObjViMPGUI::countViews(); + break; + } parent::executeCommand(); break; } @@ -443,6 +447,14 @@ public function getPicture() : void $key = $_GET['key']; // TODO: implement picture wrapper, if api action is implemented } + public static function countViews() + { + $mid = intval(filter_input(INPUT_GET, 'mid')); + if($mid && (!ilSession::get('vimp_view') || ilSession::get('vimp_view') != $mid)) { + xvmpRequest::addMediumCount($mid); + ilSession::set('vimp_view', $mid); + } + } public function addUserAutoComplete() { diff --git a/classes/class.xvmp.php b/classes/class.xvmp.php index 87ee3099..206e57b2 100644 --- a/classes/class.xvmp.php +++ b/classes/class.xvmp.php @@ -160,24 +160,48 @@ public static function deliverMedium(xvmpMedium $medium) $medium_url = $medium_url[0]; } $download_url = $medium_url . '?token=' . xvmp::getToken(); - $extension = pathinfo($medium_url)['extension']; + $download_url = $medium->getSource(); + $extension = pathinfo($download_url)['extension']; // get filesize $ch = curl_init($download_url); - curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); - curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); - curl_setopt($ch, CURLOPT_HEADER, true); - curl_setopt($ch, CURLOPT_NOBODY, true); - curl_exec($ch); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($ch, CURLOPT_HEADER, TRUE); + //curl_setopt($ch, CURLOPT_NOBODY, TRUE); + + curl_setopt($ch, CURLOPT_COOKIESESSION, true); + curl_setopt($ch, CURLOPT_COOKIEFILE, CLIENT_DATA_DIR . "/temp/vimp_cookie.txt"); + + + $response = curl_exec($ch); $size = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); - curl_close($ch); - + + $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); + $headers = substr($response, 0, $header_size); + $body = substr($response, $header_size); + + $filename = $medium->getTitle() . '.' . 'mp4'; // Default filename + $content_type = 'application/octet-stream'; // Default content type + if (preg_match('/content-disposition:.*filename=["\']?([^"\']+)/', $headers, $matches)) { + $filename = $matches[1]; + } + + if (preg_match('/Content-Type:\s*([^\s]+)/i', $headers, $matches)) { + $content_type = $matches[1]; + } // deliver file header('Content-Description: File Transfer'); - header('Content-Type: video/' . $extension); - header('Content-Disposition: attachment; filename="' . $medium->getTitle() . '.' . $extension); - header('Content-Length: ' . $size); - readfile($download_url); - exit; + header('Content-Type: ' . $content_type); + header('Content-Disposition: attachment; filename="' . $filename); + header('Content-Transfer-Encoding: binary'); + header('Content-Length: ' . strlen($body)); + header('Cache-Control: post-check=0, pre-check=0, max-age=0'); + header('Pragma: public'); + header('Expires: 0'); + + echo $body; + curl_close($ch); + } /** diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 1e17fc0b..9719c202 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -203,6 +203,7 @@ btn_copy_link#:#Link kopieren btn_copy_link_w_time#:#Link mit Zeitangabe kopieren btn_download#:#Download popover_link_copied#:#Link in Zwischenablage kopiert +perm_readlink#:#Link zum ViMP-Video availability_between#:#Verfügbar %s - %s availability_from#:#Verfügbar ab %s availability_to#:#Verfügbar bis %s diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index c149454b..a807fe66 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -203,6 +203,7 @@ btn_copy_link#:#Copy Link btn_copy_link_w_time#:#Copy Link with current time btn_download#:#Download popover_link_copied#:#Link copied to dashboard +perm_readlink#:#Streaming URL availability_between#:#Available %s - %s availability_from#:#Available from %s availability_to#:#Available until %s diff --git a/sql/dbupdate.php b/sql/dbupdate.php index 772422d0..633441c9 100644 --- a/sql/dbupdate.php +++ b/sql/dbupdate.php @@ -125,4 +125,17 @@ xvmpConf::set(xvmpConf::F_FORM_FIELDS, $form_fields); } } +?> +<#11> + \ No newline at end of file diff --git a/src/UIComponents/Player/VideoPlayer.php b/src/UIComponents/Player/VideoPlayer.php index 837eaa62..d44fb056 100644 --- a/src/UIComponents/Player/VideoPlayer.php +++ b/src/UIComponents/Player/VideoPlayer.php @@ -115,12 +115,7 @@ public static function loadVideoJSAndCSS($load_observer) */ public function getHTML(): string { - if (xvmp::ViMPVersionGreaterEquals('4.4.0') - && $this->increase_view_count - && !($this->video instanceof xvmpDeletedMedium)) { - xvmpRequest::addMediumCount($this->video->getMid()); - } - + if ($this->embed) { $width = $this->options['width'] ?? 0; $height = $this->options['height'] ?? 0; @@ -222,6 +217,12 @@ public function getHTML(): string $videojs_script .= "player.vr();"; } + $this->ctrl->setParameterByClass(ilObjViMPGUI::class, 'mid', $this->video->getMid()); + $link = $this->ctrl->getLinkTargetByClass(ilObjViMPGUI::class, 'count_views', null, true); + $count_views_script = "player.on('play', function(){var xhr = new XMLHttpRequest(); xhr.open('GET', '$link', true); " . + "xhr.onreadystatechange = () => { if (xhr.readyState === 4 && xhr.status === 200) try { JSON.parse(xhr.responseText); } catch (error) {} }; xhr.send();}) "; + $videojs_script .= $count_views_script; + $template->setCurrentBlock('script'); $template->setVariable('SCRIPT', 'if (typeof videojs === "undefined") { document.addEventListener("DOMContentLoaded", function() { ' . $videojs_script . ' });} else { ' . $videojs_script . ' }'); $template->parseCurrentBlock();