/** * Append recorded video to live entry * * @action appendRecording * @param string $entryId Live entry id * @param string $assetId Live asset id * @param KalturaMediaServerIndex $mediaServerIndex * @param KalturaDataCenterContentResource $resource * @param float $duration in seconds * @param bool $isLastChunk Is this the last recorded chunk in the current session (i.e. following a stream stop event) * @return KalturaLiveEntry The updated live entry * * @throws KalturaErrors::ENTRY_ID_NOT_FOUND */ function appendRecordingAction($entryId, $assetId, $mediaServerIndex, KalturaDataCenterContentResource $resource, $duration, $isLastChunk = false) { $dbEntry = entryPeer::retrieveByPK($entryId); if (!$dbEntry || !$dbEntry instanceof LiveEntry) { throw new KalturaAPIException(KalturaErrors::ENTRY_ID_NOT_FOUND, $entryId); } $dbAsset = assetPeer::retrieveById($assetId); if (!$dbAsset || !$dbAsset instanceof liveAsset) { throw new KalturaAPIException(KalturaErrors::ASSET_ID_NOT_FOUND, $assetId); } $lastDuration = 0; $recordedEntry = null; if ($dbEntry->getRecordedEntryId()) { $recordedEntry = entryPeer::retrieveByPK($dbEntry->getRecordedEntryId()); if ($recordedEntry) { if ($recordedEntry->getReachedMaxRecordingDuration()) { KalturaLog::err("Entry [{$entryId}] has already reached its maximal recording duration."); throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_EXCEEDED_MAX_RECORDED_DURATION, $entryId); } // if entry is in replacement, the replacement duration is more accurate if ($recordedEntry->getReplacedEntryId()) { $replacementRecordedEntry = entryPeer::retrieveByPK($recordedEntry->getReplacedEntryId()); if ($replacementRecordedEntry) { $lastDuration = $replacementRecordedEntry->getLengthInMsecs(); } } else { $lastDuration = $recordedEntry->getLengthInMsecs(); } } } $liveSegmentDurationInMsec = (int) ($duration * 1000); $currentDuration = $lastDuration + $liveSegmentDurationInMsec; $maxRecordingDuration = (kConf::get('max_live_recording_duration_hours') + 1) * 60 * 60 * 1000; if ($currentDuration > $maxRecordingDuration) { if ($recordedEntry) { $recordedEntry->setReachedMaxRecordingDuration(true); $recordedEntry->save(); } KalturaLog::err("Entry [{$entryId}] duration [" . $lastDuration . "] and current duration [{$currentDuration}] is more than max allwoed duration [{$maxRecordingDuration}]"); throw new KalturaAPIException(KalturaErrors::LIVE_STREAM_EXCEEDED_MAX_RECORDED_DURATION, $entryId); } $kResource = $resource->toObject(); $filename = $kResource->getLocalFilePath(); if (!$resource instanceof KalturaServerFileResource) { $filename = kConf::get('uploaded_segment_destination') . basename($kResource->getLocalFilePath()); kFile::moveFile($kResource->getLocalFilePath(), $filename); chgrp($filename, kConf::get('content_group')); chmod($filename, 0640); } if ($dbAsset->hasTag(assetParams::TAG_RECORDING_ANCHOR) && $mediaServerIndex == KalturaMediaServerIndex::PRIMARY) { $dbEntry->setLengthInMsecs($currentDuration); // Extract the exact video segment duration from the recorded file $mediaInfoParser = new KMediaInfoMediaParser($filename, kConf::get('bin_path_mediainfo')); $recordedSegmentDurationInMsec = $mediaInfoParser->getMediaInfo()->videoDuration; $currentSegmentVodToLiveDeltaTime = $liveSegmentDurationInMsec - $recordedSegmentDurationInMsec; $recordedSegmentsInfo = $dbEntry->getRecordedSegmentsInfo(); $recordedSegmentsInfo->addSegment($lastDuration, $recordedSegmentDurationInMsec, $currentSegmentVodToLiveDeltaTime); $dbEntry->setRecordedSegmentsInfo($recordedSegmentsInfo); if ($isLastChunk) { // Save last elapsed recording time $dbEntry->setLastElapsedRecordingTime($currentDuration); } $dbEntry->save(); } kJobsManager::addConvertLiveSegmentJob(null, $dbAsset, $mediaServerIndex, $filename, $currentDuration); if ($mediaServerIndex == KalturaMediaServerIndex::PRIMARY) { if (!$dbEntry->getRecordedEntryId()) { $this->createRecordedEntry($dbEntry, $mediaServerIndex); } $recordedEntry = entryPeer::retrieveByPK($dbEntry->getRecordedEntryId()); if ($recordedEntry) { $this->ingestAsset($recordedEntry, $dbAsset, $filename); } } $entry = KalturaEntryFactory::getInstanceByType($dbEntry->getType()); $entry->fromObject($dbEntry, $this->getResponseProfile()); return $entry; }