PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/package/app/app/batch/batches/PostConvert/KAsyncPostConvert.class.php

https://bitbucket.org/pandaos/kaltura
PHP | 275 lines | 170 code | 49 blank | 56 comment | 21 complexity | ac517e7b1913f86c2a9a832898aae4f4 MD5 | raw file
Possible License(s): AGPL-3.0, GPL-3.0, BSD-3-Clause, LGPL-2.1, GPL-2.0, LGPL-3.0, JSON, MPL-2.0-no-copyleft-exception, Apache-2.0
  1. <?php
  2. /**
  3. * @package Scheduler
  4. * @subpackage Post-Convert
  5. */
  6. require_once ("bootstrap.php");
  7. /**
  8. * Will convert a single flavor and store it in the file system.
  9. * The state machine of the job is as follows:
  10. * get the flavor
  11. * convert using the right method
  12. * save recovery file in case of crash
  13. * move the file to the archive
  14. * set the entry's new status and file details
  15. *
  16. *
  17. * @package Scheduler
  18. * @subpackage Post-Convert
  19. */
  20. class KAsyncPostConvert extends KBatchBase
  21. {
  22. /* (non-PHPdoc)
  23. * @see KBatchBase::getType()
  24. */
  25. public static function getType()
  26. {
  27. return KalturaBatchJobType::POSTCONVERT;
  28. }
  29. /* (non-PHPdoc)
  30. * @see KBatchBase::getJobType()
  31. */
  32. public function getJobType()
  33. {
  34. return self::getType();
  35. }
  36. /* (non-PHPdoc)
  37. * @see KBatchBase::exec()
  38. */
  39. protected function exec(KalturaBatchJob $job)
  40. {
  41. return $this->postConvert($job, $job->data);
  42. }
  43. // TODO remove run, updateExclusiveJob and freeExclusiveJob
  44. public function run($jobs = null)
  45. {
  46. KalturaLog::info("Post convert batch is running");
  47. if($this->taskConfig->isInitOnly())
  48. return $this->init();
  49. if(is_null($jobs))
  50. $jobs = $this->kClient->batch->getExclusivePostConvertJobs($this->getExclusiveLockKey(), $this->taskConfig->maximumExecutionTime, 1, $this->getFilter());
  51. KalturaLog::info(count($jobs) . " post convert jobs to perform");
  52. if(!count($jobs))
  53. {
  54. KalturaLog::info("Queue size: 0 sent to scheduler");
  55. $this->saveSchedulerQueue(self::getType());
  56. return null;
  57. }
  58. foreach($jobs as &$job) {
  59. $job = $this->postConvert($job, $job->data);
  60. }
  61. return $jobs;
  62. }
  63. /**
  64. * extractMediaInfo extract the file info using mediainfo and parse the returned data
  65. *
  66. * @param string $mediaFile file full path
  67. * @return KalturaMediaInfo or null for failure
  68. */
  69. private function extractMediaInfo($mediaFile)
  70. {
  71. KalturaLog::debug("extractMediaInfo($mediaFile)");
  72. $mediaParser = new KMediaInfoMediaParser($mediaFile, $this->taskConfig->params->mediaInfoCmd);
  73. return $mediaParser->getMediaInfo();
  74. }
  75. /**
  76. * extractFfmpegInfo extract the file info using FFmpeg and parse the returned data
  77. *
  78. * @param string $mediaFile file full path
  79. * @return KalturaMediaInfo or null for failure
  80. */
  81. private function extractFfmpegInfo($mediaFile)
  82. {
  83. KalturaLog::debug("extractFfmpegInfo($mediaFile)");
  84. $mediaParser = new KFFMpegMediaParser($mediaFile, $this->taskConfig->params->FFMpegCmd);
  85. return $mediaParser->getMediaInfo();
  86. }
  87. private function postConvert(KalturaBatchJob $job, KalturaPostConvertJobData $data)
  88. {
  89. KalturaLog::debug("postConvert($job->id)");
  90. try
  91. {
  92. $mediaFile = trim($data->srcFileSyncLocalPath);
  93. if(!file_exists($mediaFile))
  94. return $this->closeJob($job, KalturaBatchJobErrorTypes::APP, KalturaBatchJobAppErrors::NFS_FILE_DOESNT_EXIST, "Source file $mediaFile does not exist", KalturaBatchJobStatus::RETRY);
  95. if(!is_file($mediaFile))
  96. return $this->closeJob($job, KalturaBatchJobErrorTypes::APP, KalturaBatchJobAppErrors::NFS_FILE_DOESNT_EXIST, "Source file $mediaFile is not a file", KalturaBatchJobStatus::FAILED);
  97. KalturaLog::debug("mediaFile [$mediaFile]");
  98. $this->updateJob($job,"Extracting file media info on $mediaFile", KalturaBatchJobStatus::QUEUED, 1);
  99. }
  100. catch(Exception $ex)
  101. {
  102. return $this->closeJob($job, KalturaBatchJobErrorTypes::RUNTIME, $ex->getCode(), "Error: " . $ex->getMessage(), KalturaBatchJobStatus::FAILED);
  103. }
  104. $mediaInfo = null;
  105. try
  106. {
  107. // if($this->taskConfig->params->useMediaInfo)
  108. $mediaInfo = $this->extractMediaInfo(realpath($mediaFile));
  109. }
  110. catch(Exception $ex)
  111. {
  112. KalturaLog::err("Error: " . $ex->getMessage());
  113. $mediaInfo = null;
  114. }
  115. try
  116. {
  117. // if(is_null($mediaInfo) && $this->taskConfig->params->useFFMpeg)
  118. // $mediaInfo = $this->extractFfmpegInfo(realpath($mediaFile));
  119. if(is_null($mediaInfo))
  120. {
  121. return $this->closeJob($job, KalturaBatchJobErrorTypes::APP, KalturaBatchJobAppErrors::EXTRACT_MEDIA_FAILED, "Failed to extract media info: $mediaFile", KalturaBatchJobStatus::FAILED);
  122. }
  123. KalturaLog::debug("flavorAssetId [$data->flavorAssetId]");
  124. $mediaInfo->flavorAssetId = $data->flavorAssetId;
  125. $createdMediaInfo = $this->getClient()->batch->addMediaInfo($mediaInfo);
  126. // must save the mediaInfoId before reporting that the task is finished
  127. $this->updateJob($job, "Saving media info id $createdMediaInfo->id", KalturaBatchJobStatus::PROCESSED, 50, $data);
  128. $data->thumbPath = null;
  129. if(!$data->createThumb)
  130. return $this->closeJob($job, null, null, "Media info id $createdMediaInfo->id saved", KalturaBatchJobStatus::FINISHED, $data);
  131. // creates a temp file path
  132. $rootPath = $this->taskConfig->params->localTempPath;
  133. if(! is_dir($rootPath))
  134. {
  135. if(file_exists($rootPath))
  136. return $this->closeJob($job, KalturaBatchJobErrorTypes::APP, KalturaBatchJobAppErrors::CANNOT_CREATE_DIRECTORY, "Cannot create temp thumbnail directory [$rootPath] due to an error", KalturaBatchJobStatus::FAILED, $data);
  137. KalturaLog::info("Creating temp thumbnail directory [$rootPath]");
  138. mkdir($rootPath);
  139. }
  140. // creates the path
  141. $uniqid = uniqid('thumb_');
  142. $thumbPath = realpath($rootPath) . "/$uniqid";
  143. $videoDurationSec = floor($mediaInfo->videoDuration / 1000);
  144. $data->thumbOffset = max(0 ,min($data->thumbOffset, $videoDurationSec));
  145. if($mediaInfo->videoHeight)
  146. $data->thumbHeight = $mediaInfo->videoHeight;
  147. if($mediaInfo->videoBitRate)
  148. $data->thumbBitrate = $mediaInfo->videoBitRate;
  149. // $width = $mediaInfo->videoWidth;
  150. // $height = $mediaInfo->videoHeight;
  151. // generates the thumbnail
  152. $thumbMaker = new KFFMpegThumbnailMaker($mediaFile, $thumbPath, $this->taskConfig->params->FFMpegCmd);
  153. // $created = $thumbMaker->createThumnail($data->thumbOffset, $width, $height);
  154. $created = $thumbMaker->createThumnail($data->thumbOffset);
  155. if(!$created || !file_exists($thumbPath))
  156. {
  157. $data->createThumb = false;
  158. return $this->closeJob($job, KalturaBatchJobErrorTypes::APP, KalturaBatchJobAppErrors::THUMBNAIL_NOT_CREATED, 'Thumbnail not created', KalturaBatchJobStatus::FINISHED, $data);
  159. }
  160. $data->thumbPath = $thumbPath;
  161. $job = $this->moveFile($job, $data);
  162. if($this->checkFileExists($job->data->thumbPath))
  163. return $this->closeJob($job, null, null, null, KalturaBatchJobStatus::FINISHED, $data);
  164. $data->createThumb = false;
  165. return $this->closeJob($job, KalturaBatchJobErrorTypes::APP, KalturaBatchJobAppErrors::NFS_FILE_DOESNT_EXIST, 'File not moved correctly', KalturaBatchJobStatus::FINISHED, $data);
  166. }
  167. catch(Exception $ex)
  168. {
  169. return $this->closeJob($job, KalturaBatchJobErrorTypes::RUNTIME, $ex->getCode(), "Error: " . $ex->getMessage(), KalturaBatchJobStatus::FAILED);
  170. }
  171. }
  172. /**
  173. * @param KalturaBatchJob $job
  174. * @param KalturaPostConvertJobData $data
  175. * @return KalturaBatchJob
  176. */
  177. private function moveFile(KalturaBatchJob $job, KalturaPostConvertJobData $data)
  178. {
  179. KalturaLog::debug("moveFile($job->id, $data->thumbPath)");
  180. // creates a temp file path
  181. $rootPath = $this->taskConfig->params->sharedTempPath;
  182. if(! is_dir($rootPath))
  183. {
  184. if(! file_exists($rootPath))
  185. {
  186. KalturaLog::info("Creating temp thumbnail directory [$rootPath]");
  187. mkdir($rootPath);
  188. }
  189. else
  190. {
  191. // already exists but not a directory
  192. $err = "Cannot create temp thumbnail directory [$rootPath] due to an error. Please fix and restart";
  193. throw new Exception($err, -1);
  194. }
  195. }
  196. $uniqid = uniqid('thumb_');
  197. $sharedFile = realpath($rootPath) . "/$uniqid";
  198. clearstatcache();
  199. $fileSize = filesize($data->thumbPath);
  200. rename($data->thumbPath, $sharedFile);
  201. if(!file_exists($sharedFile) || filesize($sharedFile) != $fileSize)
  202. {
  203. $err = 'moving file failed';
  204. throw new Exception($err, -1);
  205. }
  206. @chmod($sharedFile, 0777);
  207. $data->thumbPath = $sharedFile;
  208. $job->data = $data;
  209. return $job;
  210. }
  211. protected function updateExclusiveJob($jobId, KalturaBatchJob $job)
  212. {
  213. return $this->kClient->batch->updateExclusivePostConvertJob($jobId, $this->getExclusiveLockKey(), $job);
  214. }
  215. protected function freeExclusiveJob(KalturaBatchJob $job)
  216. {
  217. $resetExecutionAttempts = false;
  218. if($job->status == KalturaBatchJobStatus::ALMOST_DONE)
  219. $resetExecutionAttempts = true;
  220. $response = $this->kClient->batch->freeExclusivePostConvertJob($job->id, $this->getExclusiveLockKey(), $resetExecutionAttempts);
  221. KalturaLog::info("Queue size: $response->queueSize sent to scheduler");
  222. $this->saveSchedulerQueue(self::getType(), $response->queueSize);
  223. return $response->job;
  224. }
  225. }
  226. ?>