/**
  * 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();
 }