You are here

video.module in Video 6.4

File

video.module
View source
<?php

/**
 *
 * @file video.module
 *
 */

/**
 * Implementation of hook_init().
 */
function video_init() {
  drupal_add_css(drupal_get_path('module', 'video') . '/css/video.css');
  drupal_add_js(drupal_get_path('module', 'video') . '/js/video.js');
}

/**
 * Invokes hook_video_*action*() in every module.
 * Eg :
 * hook_video_submit()
 * hook_video_insert()
 * hook_video_preview()
 * hook_video_delete()
 * hook_video_load()
 * hook_video_form() - to show values once upload is completed eg. Resolution, and Convert on Save etc
 *
 * We cannot use module_invoke() for this, because the arguments need to
 * be passed by reference.
 */
function video_module_invoke($action, &$array, &$video = NULL, $other = NULL) {
  foreach (module_list() as $module) {
    $function = $module . '_video_' . $action;
    if (function_exists($function)) {
      $function($array, $video, $other);
    }
  }
}

/**
 * Implementation of hook_perm().
 */
function video_perm() {
  return array(
    'bypass conversion video',
    'convert on submission',
    'override player dimensions',
    'use default thumb',
  );
}

/**
 * Implementation of hook_menu().
 */
function video_menu() {
  $items = array();
  $items['admin/settings/video'] = array(
    'title' => 'Video',
    'description' => 'Configure different aspects of the video module and its plugins',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'video_general_admin_settings',
    ),
    'file' => 'video.admin.inc',
    'access arguments' => array(
      'administer site configuration',
    ),
    'type' => MENU_NORMAL_ITEM,
  );
  $items['admin/settings/video/general'] = array(
    'title' => 'General',
    'type' => MENU_DEFAULT_LOCAL_TASK,
    'weight' => 0,
  );
  $items['admin/settings/video/players'] = array(
    'title' => 'Players',
    'description' => 'Configure your player settings for each video extension.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'video_players_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'video.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 1,
  );
  $items['admin/settings/video/transcoders'] = array(
    'title' => 'Transcoders',
    'description' => 'Configure your transcoder to convert your videos or extra thumbnails.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'video_transcoder_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'video.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 2,
  );
  $items['admin/settings/video/presets'] = array(
    'title' => 'Presets',
    'description' => 'Configure your transcoder presets to convert your videos.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'video_preset_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'video.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 3,
  );
  $items['admin/settings/video/metadata'] = array(
    'title' => 'Metadata',
    'description' => 'Configure your metadata settings.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'video_metadata_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'video.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 4,
  );
  $items['admin/settings/video/filesystem'] = array(
    'title' => 'File System',
    'description' => 'Configure your file system settings.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'video_filesystem_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'video.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 5,
  );
  $items['admin/settings/video/cron'] = array(
    'title' => 'Cron Settings',
    'description' => 'Configure your cron settings.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'video_cron_admin_settings',
    ),
    'access arguments' => array(
      'administer site configuration',
    ),
    'file' => 'video.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => 6,
  );
  return $items;
}

/**
 * Implementation of hook_theme().
 */
function video_theme() {
  $theme = array();
  $theme['video_thumbnails'] = array(
    'arguments' => array(
      'file' => NULL,
      'alt' => '',
      'title' => '',
      'attributes' => NULL,
      'getsize' => TRUE,
    ),
    'file' => 'video.theme.inc',
  );
  $theme['video_widget_preview'] = array(
    'arguments' => array(
      'item' => TRUE,
    ),
    'file' => 'video.theme.inc',
  );
  $theme['video_image'] = array(
    'arguments' => array(
      'file' => NULL,
      'alt' => '',
      'title' => '',
      'attributes' => NULL,
      'getsize' => TRUE,
      'imagecache' => NULL,
    ),
    'file' => 'video.theme.inc',
  );
  $theme['video_widget_video_thumb'] = array(
    'arguments' => array(
      'item' => TRUE,
    ),
    'file' => 'video.theme.inc',
  );
  $theme['video_formatter_video_plain'] = array(
    'arguments' => array(
      'element' => NULL,
    ),
    'file' => 'video_formatter.inc',
  );
  $theme['video_formatter_video_nodelink'] = array(
    'arguments' => array(
      'element' => NULL,
      'imagecache' => NULL,
    ),
    'file' => 'video_formatter.inc',
  );
  $theme['video_formatter_video_thumbnail'] = array(
    'arguments' => array(
      'element' => NULL,
      'imagecache' => NULL,
    ),
    'file' => 'video_formatter.inc',
  );
  $theme['video_formatter_video_nonodelink'] = array(
    'arguments' => array(
      'element' => NULL,
      'imagecache' => NULL,
    ),
    'file' => 'video_formatter.inc',
  );

  //$theme['video_formatter_video_colorbox'] = array(

  //  'arguments' => array('element' => NULL, 'imagecache' => NULL),
  //  'file' => 'video_formatter.inc',

  //);
  $theme['video_formatter_video_media_js'] = array(
    'arguments' => array(
      'element' => NULL,
    ),
    'file' => 'video_formatter.inc',
  );
  $theme['video_encoding_failed'] = array(
    'arguments' => array(),
    'file' => 'video_formatter.inc',
  );
  $theme['video_inprogress'] = array(
    'arguments' => array(),
    'file' => 'video_formatter.inc',
  );
  $path = drupal_get_path('module', 'video') . '/theme';

  //Lets setup our themes for our players
  $players = video_video_players();
  foreach ($players as $tpl => $value) {
    $theme[$tpl] = array(
      'arguments' => array(
        'video' => NULL,
        'node' => NULL,
        'themed_output' => NULL,
      ),
      //#843368 fix

      //      'file' => 'video_formatter.inc',
      'template' => str_replace('_', '-', $tpl),
      'path' => $path,
    );
  }

  //We need to add an flv theme buffer to allow users to override in their own module to add in extra parameters before

  //calling our flv template file.
  $theme['video_flv'] = array(
    'arguments' => array(
      'video' => NULL,
      'node' => NULL,
    ),
    'file' => 'video_formatter.inc',
  );
  $theme['video_html5'] = array(
    'arguments' => array(
      'video' => NULL,
      'node' => NULL,
    ),
    'file' => 'video_formatter.inc',
  );

  //setup our imagecache presets
  if (module_exists('imagecache')) {

    //we need formatters for each of our thumbnails.

    //@todo create a function to check for our colorbox module and only add theme elements that could be used.
    $thumb_types = array(
      'video_nodelink',
      'video_thumbnail',
      'video_nonodelink',
    );

    //array('video_colorbox', 'video_nodelink');
    foreach ($thumb_types as $types) {
      foreach (imagecache_presets() as $preset) {
        $theme['video_formatter_' . $preset['presetname'] . '__' . $types] = array(
          'arguments' => array(
            'element' => NULL,
          ),
          'function' => 'theme_video_formatter_imagecache',
          'file' => 'video_formatter.inc',
        );
      }
    }
  }
  return $theme;
}

/**
 * Implementation of CCK's hook_field_formatter_info().
 */
function video_field_formatter_info() {
  $formatters = array(
    'video_plain' => array(
      'label' => t('Video'),
      'field types' => array(
        'filefield',
      ),
      'description' => t('Displays video files with player embedded.'),
    ),
    'video_nodelink' => array(
      'label' => t('Video Thumbnail linked to node'),
      'field types' => array(
        'filefield',
      ),
      'description' => t('Displays the video thumbnail and links to the node.'),
    ),
    'video_thumbnail' => array(
      'label' => t('Video Thumbnail'),
      'field types' => array(
        'filefield',
      ),
      'description' => t('Displays the video thumbnail.'),
    ),
    'video_nonodelink' => array(
      'label' => t('Video Thumbnail'),
      'field types' => array(
        'filefield',
      ),
      'description' => t('Displays the video thumbnail (no link to node).'),
    ),
    //'video_colorbox' => array(

    //  'label' => t('Video Thumbnail to Colorbox'),
    //  'field types' => array('filefield'),
    //  'description' => t('Displays the video thumbnail and adds colorbox support.'),

    //),
    'video_media_js' => array(
      'label' => t('Video inject with jMedia'),
      'field types' => array(
        'filefield',
      ),
      'description' => t('Displays the video by using jmedia javascript.'),
    ),
  );

  //setup our imagecache presets
  if (module_exists('imagecache')) {

    //we need formatters for each of our thumbnails.
    $thumb_types = array(
      'video_nodelink',
      'video_thumbnail',
      'video_nonodelink',
    );

    //array('video_colorbox', 'video_nodelink');
    foreach ($thumb_types as $types) {
      foreach (imagecache_presets() as $preset) {
        $formatters[$preset['presetname'] . '__' . $types] = array(
          'label' => t('@preset @label', array(
            '@preset' => $preset['presetname'],
            '@label' => $formatters[$types]['label'],
          )),
          'field types' => array(
            'filefield',
          ),
        );
      }
    }
  }
  return $formatters;
}

/**
 * Implmentation of hook_cron().
 */
function video_cron() {
  if (variable_get('video_cron', TRUE)) {

    // This is a hack to execute S3 uploads before Zencoder
    $filesystem = variable_get('vid_filesystem', 'drupal');
    $transcoder = variable_get('vid_convertor', 'video_ffmpeg');
    if ($filesystem == 'video_s3' && $transcoder == 'video_zencoder') {
      video_s3_cron();
    }
    module_load_include('inc', 'video', '/includes/conversion');
    $video_conversion = new video_conversion();
    $video_conversion
      ->run_queue();
  }
}

/**
 * Implementation of hook_form_alter()
 * @param string $form
 * @param <type> $form_state
 * @param <type> $form_id 
 */
function video_form_alter(&$form, &$form_state, $form_id) {
  if (isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
    $form['buttons']['submit']['#submit'][] = 'video_node_update_submit';
    $form['#validate'][] = 'video_add_adminjs';

    // Make sure the js is loaded even when the form is cached
    video_add_adminjs();
  }
}
function video_node_update_submit($form, &$form_state) {

  //lets update our video rending table to include the node id created
  if (isset($form_state['nid']) && isset($form_state['values']['video_id']) && is_array($form_state['values']['video_id'])) {
    foreach ($form_state['values']['video_id'] as $fid) {

      // @TODO : check for enable trancoder
      module_load_include('inc', 'video', '/includes/transcoder');
      $transcoder = new video_transcoder();
      $video = array(
        'nid' => $form_state['nid'],
        'fid' => $fid,
      );
      $transcoder
        ->update_job($video);

      // Lets other module to know to update
      video_module_invoke('update', $form, $form_state);
    }
  }
}

/**
 * Implementation of hook_file_delete().
 */
function video_file_delete($file) {
  if (empty($file->fid)) {
    watchdog('video', 'video_file_delete called with empty argument', array(), WATCHDOG_ERROR);
    return;
  }

  // TODO: only execute this method if the file was uploaded by this module.
  // Let other modules to know about the file delete
  // before we delete the file, so the module has access to information in the database.
  video_module_invoke('delete', $file);

  // @TODO : check for enable trancoder
  // delete the transcoder job
  module_load_include('inc', 'video', '/includes/transcoder');
  $transcoder = new video_transcoder();
  $transcoder
    ->delete_job($file);

  // TODO: Move this to the file system class
  // Now lets delete our video thumbnails and folder.
  $video_thumb_path = variable_get('video_thumb_path', 'video_thumbs');
  $thumb_folder = file_directory_path() . '/' . $video_thumb_path . '/' . $file->fid . '/';

  // Recursively delete our folder and files.
  if (is_dir($thumb_folder)) {
    rmdirr($thumb_folder);

    // Delete any entries in the files table that may refer to the above path.
    // TODO: this is a slow query
    db_query('DELETE FROM {files} WHERE filepath LIKE "%b%%"', strtr(db_escape_string($thumb_folder), array(
      '%' => '\\%',
      '_' => '\\_',
    )));
  }
}

/**
 * Implementation of hook_views_api().
 */
function video_views_api() {
  return array(
    'api' => 2.0,
    'path' => drupal_get_path('module', 'video') . '/views',
  );
}

/**
 * Returns the width/height and aspect ratio of the video
 * 
 * @todo: move this to the transcoder class instead?
 */
function _video_aspect_ratio($video) {

  //lets get our video dimensions from the file
  module_load_include('inc', 'video', '/includes/transcoder');
  $transcoder = new video_transcoder();
  $wxh = $transcoder
    ->get_dimensions($video);
  if (empty($wxh) || empty($wxh['width']) || empty($wxh['height'])) {

    // No width and height found. This may be because the transcoder does not support retrieving dimensions.
    return null;
  }
  return array(
    'width' => $wxh['width'],
    'height' => $wxh['height'],
    'ratio' => number_format($wxh['width'] / $wxh['height'], 4),
  );
}

/**
 * Default video dimensions.
 */
function video_default_dimensions() {
  return "176x144\n352x288\n704x576\n1408x1152\n128x96\n160x120\n320x240\n640x480\n800x600\n1024x768\n1600x1200\n2048x1024\n1280x1024\n2560x2048\n5120x4096\n852x480\n1366x768\n1600x1024\n1920x1200\n2560x1600\n3200x2048\n3840x2400\n6400x4096\n7680x4800\n320x200\n640x350\n852x480\n1280x720\n1920x1080";
}

/**
 * Return our list of video extensions and their associated player.
 */
function video_video_extensions() {
  return array(
    'divx' => 'video_play_divx',
    'mkv' => 'video_play_divx',
    'mov' => 'video_play_quicktime',
    '3gp' => 'video_play_quicktime',
    '3g2' => 'video_play_quicktime',
    'mp4' => 'video_play_quicktime',
    'rm' => 'video_play_realmedia',
    'f4v' => 'video_play_flv',
    'flv' => 'video_play_flv',
    'swf' => 'video_play_flash',
    'dir' => 'video_play_dcr',
    'dcr' => 'video_play_dcr',
    'asf' => 'video_play_windowsmedia',
    'wmv' => 'video_play_windowsmedia',
    'avi' => 'video_play_windowsmedia',
    'mpg' => 'video_play_windowsmedia',
    'mpeg' => 'video_play_windowsmedia',
    'ogg' => 'video_play_theora',
    'ogv' => 'video_play_theora',
    'webm' => 'video_play_theora',
  );
}

/**
 * Return our supported video players.
 */
function video_video_players() {
  return array(
    'video_play_html5' => t('HTML5 Player'),
    'video_play_divx' => t('Divx Player'),
    'video_play_quicktime' => t('Quicktime'),
    'video_play_realmedia' => t('Real Media Player'),
    'video_play_flv' => t('FLV Flash Players'),
    'video_play_flash' => t('SWF Flash Player'),
    'video_play_dcr' => t('Director/Shockwave'),
    'video_play_windowsmedia' => t('Windows Media Player'),
    'video_play_theora' => t('Theora Player'),
  );
}

/**
 * Utility function to remove all files and directories recursively.
 */
function rmdirr($dir) {
  if ($objs = glob($dir . "/*")) {
    foreach ($objs as $obj) {
      is_dir($obj) ? rmdirr($obj) : unlink($obj);
    }
  }
  @rmdir($dir);
}
function video_thumb_path($video = NULL, $checkexistence = TRUE) {
  $dir = $basedir = file_directory_path() . '/' . variable_get('video_thumb_path', 'video_thumbs');
  if (is_array($video)) {
    $dir .= '/' . $video['fid'];
  }
  elseif (is_object($video)) {
    $dir .= '/' . $video->fid;
  }
  elseif ($video > 0) {
    $dir .= '/' . intval($video);
  }
  elseif ($video != NULL) {
    return NULL;
  }
  if ($checkexistence) {
    field_file_check_directory(file_directory_path(), FILE_CREATE_DIRECTORY);
    field_file_check_directory($basedir, FILE_CREATE_DIRECTORY);
    if ($dir != $basedir) {
      field_file_check_directory($dir, FILE_CREATE_DIRECTORY);
    }
  }
  return $dir;
}
function video_add_adminjs() {
  drupal_add_js(drupal_get_path('module', 'video') . '/js/video.admin.js');
}

/**
 * Increase the database timeout in preparation for long time
 * operations, such as S3 uploads and local transcoding.
 * 
 * Reconnecting to the database after this operation is not possible
 * due to the way db_set_active stores the connection identifiers.
 * 
 * At this moment, only mysqli and mysql are handled. The timeout is
 * set to 1 day
 */
function _video_db_increase_timeout() {
  global $db_type;
  if ($db_type === 'mysqli' || $db_type === 'mysql') {
    $timeout = 24 * 60 * 60;

    // one day
    db_query('SET SESSION wait_timeout = %d', $timeout);
  }
}

Functions

Namesort descending Description
rmdirr Utility function to remove all files and directories recursively.
video_add_adminjs
video_cron Implmentation of hook_cron().
video_default_dimensions Default video dimensions.
video_field_formatter_info Implementation of CCK's hook_field_formatter_info().
video_file_delete Implementation of hook_file_delete().
video_form_alter Implementation of hook_form_alter()
video_init Implementation of hook_init().
video_menu Implementation of hook_menu().
video_module_invoke Invokes hook_video_*action*() in every module. Eg : hook_video_submit() hook_video_insert() hook_video_preview() hook_video_delete() hook_video_load() hook_video_form() - to show values once upload is completed eg. Resolution, and Convert on Save etc
video_node_update_submit
video_perm Implementation of hook_perm().
video_theme Implementation of hook_theme().
video_thumb_path
video_video_extensions Return our list of video extensions and their associated player.
video_video_players Return our supported video players.
video_views_api Implementation of hook_views_api().
_video_aspect_ratio Returns the width/height and aspect ratio of the video
_video_db_increase_timeout Increase the database timeout in preparation for long time operations, such as S3 uploads and local transcoding.