HTML 5 Video tag not working

Im trying to use the video snippet from this Gist and i have it kind of working, but just noticed an issue.

the video is getting rendered on the page, with the poster image just fine, however im seeing multiple source tags for MP4, even though i told it the name of an mp4 file and a webm file. These files do exist, and the video plays.

Looking at the output there seems to be an issue with this part of the video snippet (not the tag code).

  <?php if(method_exists($url,'url')): ?>
  <source src="<?php echo $video->url() ?>" type="<?php echo $video->mime() ?>" />
  <?php else : ?>
  <source src="<?php echo $url ?>" />
  <?php endif ?>
  <?php endforeach ?>

The source tags im getting do not have the mime type on them, which means its falling through to the else and using <source src="<?php echo $url ?>" /> to render the source tags. They both point to mp4 files, when i should have one for mp4 and one for webm.

Im guessing its not seeing the $url passed through from the tag to the snippet:

$video = snippet('video', $args, true);`

This snippet and tag is about 2 years old, so maybe something in Kirby has changed to upset it - does anyone know how to make it work?

$url in this case is just a URL, not an image object, right?

Its set in the tag like this:

$url = $tag->attr('video');
// use the file url if available and otherwise the given url
$url = $file ? $file->url() : url($url);`

Yes, I know, but what do you actually pass to the tag? Could you post what your tag looks like?

Your very quick… i was digging it out… it looks like this…

(video:myvideo.mp4 width:100% height:100% webm:myvideo.webm poster:myvideo.jpg  class:video-post)

Which results in this being generated (edited for brevity):

<figure class="video-post">
<video width="100%" height="100%" class=""  preload="preload" controls="controls" poster="mysite/mypage/myvideo.jpg">
    <source src="mysite/mypage/myvideo.mp4" />
    <source src="mysite/mypage/myvideo.mp4" />
    <a href="mysite/mypage/myvideo.mp4">
      <img src="mysite/mypage/myvideo.jpg" alt="" />

The problem is that the tag code first gets the file object from the tag, but then only passes an array of urls to the snippet. So the first condition will never be true.

Thanks, had a feeling it was something like but have no idea how to fix it :frowning:

Try this:


 * Move this file to /site/snippets/ and rename it video.php
// stop without videos

if(empty($videos)) return;
// set some defaults
if(!isset($width))    $width    = 400;
if(!isset($height))   $height   = 300;
if(!isset($preload))  $preload  = true;
if(!isset($controls)) $controls = true;
// build the html atts for the video element
$preload  = ($preload)  ? ' preload="preload"'   : '';
$controls = ($controls) ? ' controls="controls"' : '';
$poster_attr = ($poster) ? ' poster="'. $poster->url() .'"' : '';
<video width="<?php echo $width ?>" height="<?php echo $height ?>" class="<?php echo $class ?>" <?php echo $preload . $controls . $poster_attr ?>>

  <?php foreach($videos as $video): ?>
  <?php if(is_a($video, 'file')): ?>

  <source src="<?php echo $video->url() ?>" type="<?php echo $video->mime() ?>" />
  <?php else : ?>
  <source src="<?php echo $url ?>" />
  <?php endif ?>
  <?php endforeach ?>

  <a href="<?php echo $url ?>">
  <?php if($poster): ?>
  	<img src="<?php echo $poster->url() ?>" alt="<?php echo $title ?>" />
  <?php else: ?>
  	<?php echo $title ?>
  <?php endif ?>



 * Move this file to /site/tags/ and rename it video.php
// video tag
kirbytext::$tags['video'] = array(
  'attr' => array(
  'html' => function($tag) {
    $url     = $tag->attr('video');
    $alt     = $tag->attr('alt');
    $title   = $tag->attr('title');
    $link    = $tag->attr('link');
    $caption = $tag->attr('caption');
    $file    = $tag->file($url);

    // use the file url if available and otherwise the given url
    $url = $file ? $file  : url($url);
    // alt is just an alternative for text
    if($text = $tag->attr('text')) $alt = $text;
    // try to get the title from the image object and use it as alt text
    if($file) {
      if(empty($alt) and $file->alt() != '') {
        $alt = $file->alt();
      if(empty($title) and $file->title() != '') {
        $title = $file->title();
    if(empty($alt)) $alt = pathinfo($url, PATHINFO_FILENAME);
    $args = array(
      'videos' => array( $file ),
      'width'  => $tag->attr('width'),
      'height' => $tag->attr('height'),
      'class'  => $tag->attr('vidclass'),
      'poster' => $tag->attr('poster'),
      'preload' => $tag->attr('preload'),
      'controls' => $tag->attr('controls'),
      'title'  => html($title),
      'url'    => html($url),
      'alt'    => html($alt));
    if ( $poster = $tag->page()->images()->find($tag->attr('poster'))) {
      $args['poster'] = $poster;
    if ( $webm = $tag->page()->videos()->find($tag->attr('webm'))) {
      $args['videos'][] = $webm;
    if ( $mp4 = $tag->page()->videos()->find($tag->attr('mp4'))) {
      $args['videos'][] = $mp4;
    if ( $ogv = $tag->page()->videos()->find($tag->attr('ogv'))) {
      $args['videos'][] = $ogv;

    $video = snippet('video', $args, true);
    $figure = new Brick('figure');
    if(!empty($caption)) {
      $figure->append('<figcaption>' . html($caption) . '</figcaption>');
    return $figure;

Good work! Worked a treat… thanks a lot :slight_smile: