/**
  * Renders an audio or video tag based on the provided media record
  *
  * @param  \WIRO\Html5mediaelements\Domain\Model\Media|int $media              media record or uid of media record
  * @param  boolean|string                                  $flashMediaElement  path to swf file that will be used as flash fallback;
  *                                                                             if set to TRUE the default file will be used; if set
  *                                                                             to FALSE the flash fallback will be disabled
  * @param  array|NULL                                      $priorityFormats    array of MIME types that should be prioritized in the output;
  *                                                                             array order is respected
  * @param  array|NULL                                      $fallbackFormats    array of MIME types that should be used as flash fallback;
  *                                                                             array order is respected
  * @return string                                                              <audio> or <video> tag
  */
 public function render(\WIRO\Html5mediaelements\Domain\Model\Media $media, $flashMediaElement = TRUE, $priorityFormats = NULL, $fallbackFormats = NULL)
 {
     // Fetch media file with provided uid
     if (is_int($media)) {
         $media = $this->mediaRepository->findByUid($media);
     }
     // Validate and store output options
     if ($flashMediaElement !== TRUE) {
         $this->flashMediaElement = $flashMediaElement;
     }
     if (isset($priorityFormats)) {
         $this->priorityFormats = $priorityFormats;
     }
     if (isset($fallbackFormats)) {
         $this->fallbackFormats = $fallbackFormats;
     }
     // Render audio content with <audio> tag
     if ($media->isAudio()) {
         $this->tag->setTagName('audio');
     }
     // Use valid HTML5 boolean attributes
     foreach (array('controls', 'autoplay', 'loop', 'muted') as $attribute) {
         if ($this->tag->hasAttribute($attribute)) {
             $this->tag->addAttribute($attribute, $attribute);
         }
     }
     // Order media sources based on provided priorities
     $orderedMedia = $this->prioritizeMedia($media, $this->priorityFormats);
     // Use source file as fallback if no optimized media is available
     if (empty($orderedMedia)) {
         $orderedMedia = array($media->getSourceFile());
     }
     // Render HTML5 source candidates
     // Attempt to set video dimensions
     $sourceCandidates = $this->renderSources($media, $orderedMedia);
     // Set video poster image
     if ($media->isVideo() && $media->getPoster()) {
         $this->tag->addAttribute('poster', $this->generatePublicUrl($media->getPoster()->getOriginalResource()));
         // Attempt to set video dimensions (if not set already)
         $this->addVideoDimensions($media->getPoster()->getOriginalResource());
     }
     // First try to fetch simple fallback from tag children
     $simpleFallbackSource = $this->renderChildren();
     if (!$simpleFallbackSource) {
         // Render simple fallback (linked poster image or text link)
         $simpleFallbackSource = $this->renderSimpleFallback($media, $orderedMedia);
     }
     // Render Flash fallback (includes simple fallback)
     $fallbackSource = $this->renderFlashFallback($media, $simpleFallbackSource);
     // Add source candidates and fallback to tag
     $this->tag->setContent($sourceCandidates . $fallbackSource);
     return $this->tag->render();
 }
 /**
  * action show
  *
  * @return mixed
  */
 public function showAction()
 {
     // No media provided => Skip
     if (!$this->settings['media']) {
         return '';
     }
     // Fetch media records
     $mediaUids = array_map('intval', explode(',', $this->settings['media']));
     $mediaRecords = $this->mediaRepository->findByUids($mediaUids);
     // Keep original order of items
     $mediaSorted = array();
     foreach ($mediaUids as $uid) {
         foreach ($mediaRecords as $record) {
             if ($record->getUid() === $uid) {
                 $mediaSorted[] = $record;
                 break;
             }
         }
     }
     $this->view->assign('media', $mediaSorted);
 }
 /**
  * Converts source media to configured media formats and references them
  *
  * @param  \WIRO\Html5mediaelements\Domain\Model\Media $media   media record
  * @param  array                                       $config  conversion configuration for media formats
  * @return void
  */
 protected function convertMedia(Media $media, array $config)
 {
     // Create a local file for processing
     $originalFile = $media->getSourceFile()->getOriginalResource()->getOriginalFile();
     $localFile = $originalFile->getForLocalProcessing(FALSE);
     // Prepare for conversion
     if ($media->isAudio()) {
         $source = new \PHPVideoToolkit\Audio($localFile);
     } else {
         $source = new \PHPVideoToolkit\Video($localFile);
     }
     $multiOutput = new \PHPVideoToolkit\MultiOutput();
     $outputContext = array();
     foreach ($config as $formatName => $formatConfig) {
         // Skip files without audio and video
         if ($media->isAudio() && !$formatConfig['audio']['enabled'] || $media->isVideo() && !$formatConfig['audio']['enabled'] && !$formatConfig['video']['enabled']) {
             continue;
         }
         // Generate video file name
         $fileName = $this->generateFilename($originalFile, $formatConfig['filename']);
         $filePath = $this->tempPathFiles . $fileName;
         // Store information about conversion input
         $outputContext[] = array('format' => $formatName, 'path' => $filePath, 'name' => $fileName);
         // Configure output format
         $fallbackFormat = $media->isAudio() ? 'AudioFormat' : 'VideoFormat';
         $className = '\\PHPVideoToolkit\\' . $fallbackFormat . '_' . ucfirst($formatConfig['format']);
         if ($formatConfig['format'] && class_exists($className)) {
             $format = new $className();
         } else {
             $format = \PHPVideoToolkit\Format::getFormatFor($filePath, null, $fallbackFormat);
         }
         // Set format options from configuration
         if ($formatConfig['audio']['enabled']) {
             if ($formatConfig['audio']['codec']) {
                 $format->setAudioCodec($formatConfig['audio']['codec']);
             }
             if ($formatConfig['audio']['bitrate']) {
                 $format->setAudioBitrate((double) $formatConfig['audio']['bitrate']);
             }
             if ($formatConfig['audio']['quality']) {
                 $format->setAudioQuality((double) $formatConfig['audio']['quality']);
             }
             if ($formatConfig['audio']['sampleFrequency']) {
                 $format->setAudioSampleFrequency((int) $formatConfig['audio']['sampleFrequency']);
             }
             if ($formatConfig['audio']['channels']) {
                 $format->setAudioChannels((int) $formatConfig['audio']['channels']);
             }
             if ($formatConfig['audio']['volume']) {
                 $format->setVolume((int) $formatConfig['audio']['volume']);
             }
         } else {
             $format->disableAudio();
         }
         if ($media->isVideo()) {
             if ($formatConfig['video']['enabled']) {
                 if ($formatConfig['video']['codec']) {
                     $format->setVideoCodec($formatConfig['video']['codec']);
                 }
                 if ($formatConfig['video']['width'] && $formatConfig['video']['height']) {
                     $format->setVideoDimensions($formatConfig['video']['width'], $formatConfig['video']['height'], true);
                 }
                 if ($formatConfig['video']['aspectRatio']) {
                     $format->setVideoAspectRatio($formatConfig['video']['aspectRatio'], true);
                 }
                 if ($formatConfig['video']['frameRate']) {
                     $format->setVideoFrameRate((double) $formatConfig['video']['frameRate']);
                 }
                 if ($formatConfig['video']['maxFrames']) {
                     $format->setVideoMaxFrames($formatConfig['video']['maxFrames']);
                 }
                 if ($formatConfig['video']['bitrate']) {
                     $format->setVideoBitrate($formatConfig['video']['bitrate']);
                 }
                 if ($formatConfig['video']['pixelFormat']) {
                     $format->setVideoPixelFormat($formatConfig['video']['pixelFormat']);
                 }
                 if ($formatConfig['video']['quality']) {
                     $format->setVideoQuality((double) $formatConfig['video']['quality']);
                 }
                 if ($formatConfig['video']['h264']['preset']) {
                     $format->setH264Preset($formatConfig['video']['h264']['preset']);
                 }
                 if ($formatConfig['video']['h264']['tune']) {
                     $format->setH264Tune($formatConfig['video']['h264']['tune']);
                 }
                 if ($formatConfig['video']['h264']['profile']) {
                     $format->setH264Profile($formatConfig['video']['h264']['profile']);
                 }
             } else {
                 $format->disableVideo();
             }
         }
         // Add to conversion command
         $multiOutput->addOutput($filePath, $format);
     }
     if (empty($outputContext)) {
         return;
     }
     // TODO make asynchronous
     $process = $source->save($multiOutput, null, \PHPVideoToolkit\Media::OVERWRITE_UNIQUE);
     /*
     // Start conversion
     $progressHandler = new \PHPVideoToolkit\ProgressHandlerNative(null);
     $process = $source->saveNonBlocking($multiOutput, null, \PHPVideoToolkit\Media::OVERWRITE_UNIQUE, $progressHandler);
     
     \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($progressHandler, 'SP');
     return;
     
     // Wait for files being converted
     $lastStatus = null;
     while ($progressHandler->completed !== true) {
     	$probe = $progressHandler->probe(true);
     	if ($probe['status'] !== $lastStatus) {
     		//echo $probe['status'] . PHP_EOL;
     		$lastStatus = $probe['status'];
     	}
     
     	sleep(0.5);
     }
     */
     // Get converted files
     $outputFiles = $process->getAllOutput();
     foreach ($outputContext as $i => $fileOptions) {
         // Add converted file to FAL
         $file = $originalFile->getParentFolder()->addFile($outputFiles[$i], $fileOptions['name'], 'changeName');
         // TODO check for permission of user (_cli_scheduler)
         // Set dimension metadata of converted file
         $this->setFileMetadata($file);
         // Create new optimized media record
         $mediaOptimized = $this->objectManager->get('WIRO\\Html5mediaelements\\Domain\\Model\\MediaOptimized');
         $mediaOptimized->setPid($media->getPid());
         $mediaOptimized->setType($media->isAudio() ? MediaOptimized::TYPE_AUDIO : MediaOptimized::TYPE_VIDEO);
         $mediaOptimized->setFormat($fileOptions['format']);
         // Add reference to media record
         $media->addOptimizedMedium($mediaOptimized);
         $this->mediaRepository->update($media);
         $this->persistenceManager->persistAll();
         // Add reference to converted file
         $this->addFileReference('tx_html5mediaelements_domain_model_mediaoptimized', 'optimized_file', $mediaOptimized, $file);
     }
     // Set converted flag in media record
     $media->setIsConverted(true);
     $this->mediaRepository->update($media);
 }