'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 $form_state * @param $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); } }