<?php if (!defined('PmWiki')) exit();
/**
  \file  video5.php
  \brief  HTML5 Video Support for PmWiki
  
  This recipe provides the HTML5 <video> tag for PmWiki. 
  
  Copyright 2012, 2013, 2015, 2022 Tom Gem <tomgem@me.com>, 
    an adaptation of HTML5video.php by GNUZoo, 
    copyright 2007, 2010 GNUZoo <guru@gnuzoo.org>

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published
  by the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  Full documentation: 
    http://www.pmwiki.org/wiki/Cookbook/Video5
  
  Version history:
    2012-11-01 - initial release
    2013-10-22 - added support for the track element (subtitles)
        - removed necessity to use the (:video file:) markup without file extensions
        - video format order is now configurable
        - video5 now shows upload links if no video files are found
        - added php5.2 as a requirement on the recipe page
    2013-10-23 - added support for the srt track format
    2013-12-03 - added support for attachments on other groups/pages (:video group/page/file:)
    2015-10-05 - added support for php 5.5 (replaced Markup with Markup_e) 
    2022-10-28 - update for PHP 8 (Petko Yotov pmwiki.org/petko)
    2022-10-30 - replaced all tabs with spaces
*/

// recipe version
$RecipeInfo['Video5']['Version'] = '2022-10-30';

// get and set defaults
SDV($VideoWidth, '640');     // default video width is 640 (480i 4:3)
SDV($VideoHeight, '480');    // default video height is 480 (480i 4:3)
SDV($VideoPreload, 'auto');  // default is to load video when page loads (auto|metadata|none)
SDV($VideoAutoplay, 0);      // default is not to autoplay video (0|1)
SDV($VideoControls, 1);      // default is a player with controls (0|1)
SDV($VideoLoop, 0);          // default is not to loop video (0|1)
SDV($VideoMuted, 0);         // default is not to mute audio (0|1)
SDVA($VideoExtensions, array('mp4','ogv','webm'));  // default video format order
SDVA($PosterExtensions, array('gif','jpg','png'));  // default poster format order (reverse order)
SDVA($TrackExtensions, array('srt','vtt'));         // default track format order (reverse order)

// text which will be shown in old browsers instead of video
SDV($VideoNotSupportedText, 'Sorry, your browser does not support HTML5 video.'); 

// use this if your videos are not stored as 'attachments' of your wiki pages
// example setting for config.php (note the trailing slash): 
// $VideoUrl = 'http://server.example.com/path/to/videofolder/';
SDV($VideoUrl, 0); 

// get the currently active language. only used by the track (subtitles) element
if (isset($XLLangs['0'])) { $VideoLang = $XLLangs['0']; } else { $VideoLang = 'en'; }

// video markup definition
Markup('Video5', 'fulltext', 
    '/\\(:(video)(\\s.*?)?:\\)/i', 
    "mu_Video5");

function mu_Video5($m) {
  return Video5($m[1],$m[2]);
}

// main (and only) function
function Video5($name, $args) {  
  // those are needed here
  global  $pagename, $PageUrl, $UploadDir, $UploadPrefixFmt, $UploadUrlFmt, $EnableDirectDownload, 
      $VideoWidth, $VideoHeight, $VideoAutoplay, $VideoControls, $VideoLoop, $VideoMuted, $VideoPreload, 
      $VideoExtensions, $PosterExtensions, $TrackExtensions, $VideoNotSupportedText, $VideoLang, $VideoUrl;
    
  // a little helper
  $nl = "\n";
  
  // parse arguments
  $args = ParseArgs($args);
  
  // get video file basename and dirname
  $VideoFile = pathinfo($args[''][0], PATHINFO_FILENAME);
  $VideoDirName = pathinfo($args[''][0], PATHINFO_DIRNAME);
  
  // get the path to the upload dir
  if ($VideoDirName == ".") {
    // the attachment can be found on the same group/page 
    $VideoDir = FmtPageName($UploadDir.$UploadPrefixFmt, $pagename);
  } else { 
    // the attachment can be found on another group/page 
    $VideoDirUnix = str_replace('.', '/', $VideoDirName);
    $VideoDir = $UploadDir.'/'.$VideoDirUnix;
  }
  
  // get video src url
  $VideoAttached = 0;
  if (empty($VideoUrl)) {
    // respect setting of $EnableDirectDownload 
    // please note, video playback does not work with most browsers if $EnableDirectDownload=0; is set 
    if (IsEnabled($EnableDirectDownload, 1)) {
      if ($VideoDirName == ".") {
        // the attachment can be found on the same group/page 
        $VideoUrl = FmtPageName($UploadUrlFmt.$UploadPrefixFmt.'/', $pagename);
      } else { 
        // the attachment can be found on another group/page 
        $VideoUrl = $UploadUrlFmt.'/'.$VideoDirUnix.'/';
      }
    } else {
      // note, attachments on other groups/pages will not work if $EnableDirectDownload=0 is set
      $VideoUrl = FmtPageName('$PageUrl?action=download&upname=', $pagename);
    }
    $VideoAttached = 1;
  }
  
  // assemble complete video source url
  $VideoSrc = $VideoUrl.$VideoFile;
  
  // get and set video resolution
  if (isset($args['width'])) { $VideoWidth = $args['width']; } 
  if (isset($args['height'])) { $VideoHeight = $args['height']; } 

  // start gathering video options
  $VideoOpt = ' width="'.$VideoWidth.'" height="'.$VideoHeight.'" ';

  // get and set preload behaviour
  if (isset($args['preload'])) { $VideoPreload = $args['preload']; }
  $VideoOpt = $VideoOpt.'preload="'.$VideoPreload.'" ';

  // get and set boolean video attributes
  if (isset($args['autoplay'])) {
    if (!empty($args['autoplay'])) { $VideoOpt = $VideoOpt.'autoplay="autoplay" '; }
  } else {
    if (!empty($VideoAutoplay)) { $VideoOpt = $VideoOpt.'autoplay="autoplay" '; }
  }
  if (isset($args['controls'])) {
    if (!empty($args['controls'])) { $VideoOpt = $VideoOpt.'controls="controls" '; }
  } else {
    if (!empty($VideoControls)) { $VideoOpt = $VideoOpt.'controls="controls" '; }
  }
  if (isset($args['loop'])) {
    if (!empty($args['loop'])) { $VideoOpt = $VideoOpt.'loop="loop" '; }
  } else {
    if (!empty($VideoLoop)) { $VideoOpt = $VideoOpt.'loop="loop" '; }
  }
  if (isset($args['muted'])) {
    if (!empty($args['muted'])) { $VideoOpt = $VideoOpt.'muted="muted" '; }
  } else {
    if (!empty($VideoMuted)) { $VideoOpt = $VideoOpt.'muted="muted" '; }
  }
    
  // search for existing video files and add them to the <video> tag if they do
  $Videos = '';
  $VideoFound = 0;
  
  foreach ($VideoExtensions as $Extension) {
    $VideoPath = $VideoDir.'/'.$VideoFile.'.'.$Extension;
    
    // can't check if videos exist if $VideoUrl was set manually - if so, just add them all
    if (file_exists($VideoPath) || empty($VideoAttached)) {
      if ($Extension == 'ogv') { $VideoType = 'type="video/ogg"'; } 
      else { $VideoType = 'type="video/'.$Extension.'"'; }
      
      $Videos = $Videos.'<source src="'.$VideoSrc.'.'.$Extension.'" '.$VideoType.' />'.$nl;
      $VideoFound = 1;
    }
  }
  
  // search for existing poster files and add the last match to the <video> tag
  $PosterAttribute = '';
  $PosterImg = '';
  
  foreach ($PosterExtensions as $Extension) {
    $PosterPath = $VideoDir.'/'.$VideoFile.'.'.$Extension;
    
    // can't check if a poster file exists if $VideoUrl was set manually - if so, just add it
    if (file_exists($PosterPath) || empty($VideoAttached)) {
      $PosterSrc = $VideoSrc.'.'.$Extension;
      $PosterAttribute = 'poster="'.$PosterSrc.'"';
      $PosterImg = '<img src="'.$PosterSrc.'" width="'.$VideoWidth.'" height="'.$VideoHeight.'" alt="'.$VideoFile.'" />';
    }
  }

  // search for existing track files (subtitles) and add the last match to the <video> tag
  $TrackAttribute = '';
  $TrackFile = '';
  
  foreach ($TrackExtensions as $Extension) {
    $TrackPath = $VideoDir.'/'.$VideoFile.'.'.$Extension;
    
    // can't check if a track file exists if $VideoUrl was set manually - if so, just add it
    if (file_exists($TrackPath) || empty($VideoAttached)) {
      $TrackSrc = $VideoSrc.'.'.$Extension;
      $TrackAttribute = 'poster="'.$TrackSrc.'"';
      $TrackFile = '<track src="'.$TrackSrc.'" kind="subtitles" srclang="'.$VideoLang.'" label="'.$VideoFile.'" default />';
    }
  }
  
  // generate and return html for the wiki page
  if ($VideoFound == 1) {
    return Keep('<video'.$VideoOpt.$PosterAttribute.'>'.$nl.$Videos.$PosterImg.$nl.$TrackFile.$nl.'<p class="novideo">'.$VideoNotSupportedText.'</p>'.$nl.'</video>');
  } else {
    // show upload links if no video files can be found
    $VideoUpload = '';
    $VideoUploadlink = FmtPageName('$PageUrl?action=upload&upname=', $pagename);
    
    foreach ($VideoExtensions as $Extension) {
      $VideoUpload = $VideoUpload.'<a rel="nofollow" class="createlinktext" href="'.$VideoUploadlink.$VideoFile.'.'.$Extension.'">'.$VideoFile.'.'.$Extension.'</a>';
      $VideoUpload = $VideoUpload.'<a rel="nofollow" class="createlink" href="'.$VideoUploadlink.$VideoFile.'.'.$Extension.'">&nbsp;&Delta;&nbsp;</a>';
    }
    return Keep('<p class="novideo">No video files ('.$VideoUpload.') found.</p>');
  }
}