/** * @return array primary URL and backup URL */ private function getLiveEntryBaseUrls() { $this->initFlavorParamsIds(); $tag = null; $tags = $this->deliveryAttributes->getTags(); if (count($tags) == 1) { $tag = reset($tags); } $protocol = $this->deliveryAttributes->getMediaProtocol(); if (in_array($this->deliveryAttributes->getFormat(), self::$httpFormats) && !in_array($protocol, self::$httpProtocols)) { $protocol = requestUtils::getProtocol(); } $liveStreamConfig = $this->entry->getLiveStreamConfigurationByProtocol($this->deliveryAttributes->getFormat(), $protocol, $tag, false, $this->flavorParamsIds); /* @var $liveStreamConfig kLiveStreamConfiguration */ if ($liveStreamConfig) { return array($liveStreamConfig->getUrl(), $liveStreamConfig->getBackupUrl()); } switch ($this->deliveryAttributes->getFormat()) { case PlaybackProtocol::RTMP: $baseUrl = $this->entry->getStreamUrl(); $baseUrl = rtrim($baseUrl, '/'); if (strpos($this->deliveryAttributes->getMediaProtocol(), "rtmp") === 0) { $baseUrl = $this->deliveryAttributes->getMediaProtocol() . '://' . preg_replace('/^rtmp.*?:\\/\\//', '', $baseUrl); } return array($baseUrl, null); case PlaybackProtocol::APPLE_HTTP: return array($this->entry->getHlsStreamUrl(), null); // TODO pass single tag } return array(null, null); }
/** * @return array primary URL and backup URL */ private function getLiveEntryStreamConfig() { $this->initFlavorParamsIds(); $tag = null; $tags = $this->deliveryAttributes->getTags(); if (count($tags) == 1) { $tag = reset($tags); } $protocol = $this->deliveryAttributes->getMediaProtocol(); if (in_array($this->deliveryAttributes->getFormat(), self::$httpFormats) && !in_array($protocol, self::$httpProtocols)) { $protocol = requestUtils::getProtocol(); } // use only cloud transcode flavors if timeAlignedRenditions was set $partnerId = $this->entry->getPartnerId(); $partner = PartnerPeer::retrieveByPK($partnerId); $partnerTimeAligned = $partner->getTimeAlignedRenditions(); if ($partnerTimeAligned && $this->getRequestParameter("playerType") === 'flash') { // check entry's flavors $entryFlavorParams = assetParamsPeer::retrieveByPKs(explode(',', $this->entry->getFlavorParamsIds())); $hasTranscode = false; foreach ($entryFlavorParams as $flavor) { // check if we have any transcode flavor if (!$flavor->hasTag("ingest")) { $hasTranscode = true; } } // if so, use only the transcode if ($hasTranscode) { $tag = 'mbr'; } } $liveStreamConfig = $this->entry->getLiveStreamConfigurationByProtocol($this->deliveryAttributes->getFormat(), $protocol, $tag, false, $this->flavorParamsIds); /* @var $liveStreamConfig kLiveStreamConfiguration */ if ($liveStreamConfig) { return $liveStreamConfig; } switch ($this->deliveryAttributes->getFormat()) { case PlaybackProtocol::RTMP: $baseUrl = $this->entry->getStreamUrl(); $baseUrl = rtrim($baseUrl, '/'); if (strpos($this->deliveryAttributes->getMediaProtocol(), "rtmp") === 0) { $baseUrl = $this->deliveryAttributes->getMediaProtocol() . '://' . preg_replace('/^rtmp.*?:\\/\\//', '', $baseUrl); } $liveStreamConfig = new kLiveStreamConfiguration(); $liveStreamConfig->setUrl($baseUrl); $liveStreamConfig->setProtocol(PlaybackProtocol::RTMP); return $liveStreamConfig; case PlaybackProtocol::APPLE_HTTP: // TODO pass single tag $liveStreamConfig = new kLiveStreamConfiguration(); $liveStreamConfig->setUrl($this->entry->getHlsStreamUrl()); $liveStreamConfig->setProtocol(PlaybackProtocol::APPLE_HTTP); return $liveStreamConfig; } return null; }
/** * @param string $baseUrl * @return array */ private function buildRtmpLiveStreamFlavorsArray(&$baseUrl) { $streamId = $this->entry->getStreamRemoteId(); $streamUsername = $this->entry->getStreamUsername(); $baseUrl = $this->entry->getStreamUrl(); $baseUrl = rtrim($baseUrl, '/'); $rtmpHost = parse_url($baseUrl, PHP_URL_HOST); $urlManager = $this->getUrlManagerByCdn($rtmpHost); $flavors = $this->entry->getStreamBitrates(); if (count($flavors)) { foreach ($flavors as $index => $flavor) { $brIndex = $index + 1; $flavors[$index]['url'] = str_replace('%i', $brIndex, $this->entry->getStreamName()); } } else { $flavors[0]['url'] = str_replace('%i', '1', $this->entry->getStreamName()); } if (strpos($this->protocol, "rtmp") === 0) { $baseUrl = $this->protocol . '://' . preg_replace('/^rtmp.*?:\\/\\//', '', $baseUrl); } $urlManager->finalizeUrls($baseUrl, $flavors); $this->tokenizer = $urlManager->getTokenizer(); return $flavors; }
private function serveRtmp() { switch ($this->entry->getType()) { case entryType::MEDIA_CLIP: $duration = $this->entry->getDurationInt(); $flavorAssets = array(); if ($this->flavorId) { $flavorAsset = flavorAssetPeer::retrieveById($this->flavorId); if (!$flavorAsset->hasTag(flavorParams::TAG_WEB)) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } if (!$flavorAsset->getStatus() == flavorAsset::FLAVOR_ASSET_STATUS_READY) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } $flavorAssets[] = $flavorAsset; } else { $flavorAssets = flavorAssetPeer::retreiveReadyByEntryIdAndTag($this->entryId, flavorParams::TAG_MBR); if (!count($flavorAssets)) { $flavorAssets = flavorAssetPeer::retreiveReadyByEntryIdAndTag($this->entryId, flavorParams::TAG_WEB); } } $flavorAssets = $this->removeMaxBitrateFlavors($flavorAssets); if (!$this->storageId) { $partner = $this->entry->getPartner(); $finalFlavors = array(); if ($partner->getStorageServePriority() == StorageProfile::STORAGE_SERVE_PRIORITY_KALTURA_FIRST) { foreach ($flavorAssets as $flavorAsset) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $fileSync = kFileSyncUtils::getReadyInternalFileSyncForKey($key); if ($fileSync) { $finalFlavors[] = $flavorAsset; } } } if (!count($finalFlavors) && $partner->getStorageServePriority() && $partner->getStorageServePriority() != StorageProfile::STORAGE_SERVE_PRIORITY_KALTURA_ONLY) { $storages = StorageProfilePeer::retrieveExternalByPartnerId($partner->getId()); if (count($storages) == 1) { $this->storageId = $storages[0]->getId(); } elseif (count($storages)) { $storagesFlavors = array(); foreach ($storages as $storage) { $storagesFlavors[$storage->getId()] = array(); foreach ($flavorAssets as $flavorAsset) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $fileSync = kFileSyncUtils::getReadyExternalFileSyncForKey($key, $storage->getId()); if ($fileSync) { $storagesFlavors[$storage->getId()][] = $flavorAsset; } } } $maxCount = 0; foreach ($storagesFlavors as $storageId => $storageFlavors) { $count = count($storageFlavors); if ($count > $maxCount) { $maxCount = $count; $this->storageId = $storageId; $finalFlavors = $storageFlavors; } } $flavorAssets = $finalFlavors; } else { foreach ($flavorAssets as $flavorAsset) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $fileSync = kFileSyncUtils::getReadyInternalFileSyncForKey($key); if ($fileSync) { $finalFlavors[] = $flavorAsset; } } } } } foreach ($flavorAssets as $flavorAsset) { $mediaInfo = mediaInfoPeer::retrieveByFlavorAssetId($flavorAsset->getId()); if ($mediaInfo && ($mediaInfo->getVideoDuration() || $mediaInfo->getAudioDuration() || $mediaInfo->getContainerDuration())) { $duration = $mediaInfo->getVideoDuration() ? $mediaInfo->getVideoDuration() : ($mediaInfo->getAudioDuration() ? $mediaInfo->getAudioDuration() : $mediaInfo->getContainerDuration()); $duration /= 1000; break; } } $baseUrl = null; $flavors = array(); if ($this->storageId) { $storage = StorageProfilePeer::retrieveByPK($this->storageId); if (!$storage) { die; } $baseUrl = $storage->getDeliveryRmpBaseUrl(); // get all flavors with external urls foreach ($flavorAssets as $flavorAsset) { $key = $flavorAsset->getSyncKey(flavorAsset::FILE_SYNC_FLAVOR_ASSET_SUB_TYPE_ASSET); $fileSync = kFileSyncUtils::getReadyExternalFileSyncForKey($key, $this->storageId); if (!$fileSync) { continue; } $urlManager = kUrlManager::getUrlManagerByStorageProfile($fileSync->getDc()); $urlManager->setClipTo($this->clipTo); $urlManager->setFileExtension($flavorAsset->getFileExt()); $urlManager->setProtocol(StorageProfile::PLAY_FORMAT_RTMP); $url = $urlManager->getFileSyncUrl($fileSync); $url = preg_replace('/^\\//', '', $url); $flavors[] = array('url' => $url, 'bitrate' => $flavorAsset->getBitrate(), 'width' => $flavorAsset->getWidth(), 'height' => $flavorAsset->getHeight()); } } else { $partnerId = $this->entry->getPartnerId(); $subpId = $this->entry->getSubpId(); $partnerPath = myPartnerUtils::getUrlForPartner($partnerId, $subpId); $baseUrl = myPartnerUtils::getRtmpUrl($partnerId); $urlManager = kUrlManager::getUrlManagerByCdn($this->cdnHost); // get all flavors with kaltura urls foreach ($flavorAssets as $flavorAsset) { $urlManager->setClipTo($this->clipTo); $urlManager->setFileExtension($flavorAsset->getFileExt()); $urlManager->setProtocol(StorageProfile::PLAY_FORMAT_RTMP); $url = $urlManager->getFlavorAssetUrl($flavorAsset); $url = preg_replace('/^\\//', '', $url); $flavors[] = array('url' => $url, 'bitrate' => $flavorAsset->getBitrate(), 'width' => $flavorAsset->getWidth(), 'height' => $flavorAsset->getHeight()); } } if (!count($flavors)) { KExternalErrors::dieError(KExternalErrors::FLAVOR_NOT_FOUND); } if (strpos($this->protocol, "rtmp") === 0) { $baseUrl = $this->protocol . '://' . preg_replace('/^rtmp.*?:\\/\\//', '', $baseUrl); } return $this->buildXml(self::PLAY_STREAM_TYPE_RECORDED, $flavors, 'video/x-flv', $duration, $baseUrl); case entryType::LIVE_STREAM: $streamId = $this->entry->getStreamRemoteId(); $streamUsername = $this->entry->getStreamUsername(); $baseUrl = $this->entry->getStreamUrl(); $baseUrl = rtrim($baseUrl, '/'); $flavors = $this->entry->getStreamBitrates(); if (count($flavors)) { foreach ($flavors as $index => $flavor) { $brIndex = $index + 1; $flavors[$index]['url'] = str_replace('%i', $brIndex, $this->entry->getStreamName()); } } else { $flavors[0]['url'] = str_replace('%i', '1', $this->entry->getStreamName()); } if (strpos($this->protocol, "rtmp") === 0) { $baseUrl = $this->protocol . '://' . preg_replace('/^rtmp.*?:\\/\\//', '', $baseUrl); } return $this->buildXml(self::PLAY_STREAM_TYPE_LIVE, $flavors, 'video/x-flv', null, $baseUrl); } KExternalErrors::dieError(KExternalErrors::INVALID_ENTRY_TYPE); }