View source
<?php
define('VIDEO_RENDERING_PENDING', 1);
define('VIDEO_RENDERING_INQUEUE', 2);
define('VIDEO_RENDERING_ACTIVE', 5);
define('VIDEO_RENDERING_COMPLETE', 10);
define('VIDEO_RENDERING_FAILED', 20);
module_load_include('inc', 'video', 'video.field');
module_load_include('inc', 'video', 'video.features');
module_load_include('inc', 'video', 'video.filters');
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');
}
function video_menu() {
$items = array();
$items['postback/jobs'] = array(
'page callback' => 'video_transcoder_postback_jobs',
'file' => 'video.pages.inc',
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['video/transfer/%file'] = array(
'page callback' => 'video_transfer_file',
'page arguments' => array(
2,
),
'file' => 'video.pages.inc',
'access callback' => 'video_transfer_access',
'access arguments' => array(
2,
),
'type' => MENU_CALLBACK,
);
$items['video/browser'] = array(
'page callback' => 'video_file_browser',
'file' => 'video.pages.inc',
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
$items['video/embed/%/%/%/%/%'] = array(
'page callback' => 'video_file_embed',
'file' => 'video.pages.inc',
'page arguments' => array(
3,
2,
4,
5,
6,
),
'access arguments' => array(
'access content',
),
'type' => MENU_CALLBACK,
);
return $items;
}
function video_transfer_access($file) {
$arguments = array(
':fid' => $file->fid,
':status' => VIDEO_RENDERING_ACTIVE,
);
if (db_query('SELECT f.fid FROM {file_managed} f INNER JOIN {video_queue} q ON f.fid = q.fid WHERE f.fid = :fid AND q.status = :status', $arguments)
->fetchField()) {
$username = variable_get('video_zencoder_http_username', FALSE);
$password = variable_get('video_zencoder_http_password', FALSE);
if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW']) && !empty($username) && !empty($password) && $_SERVER['PHP_AUTH_USER'] == $username && $_SERVER['PHP_AUTH_PW'] == $password) {
return TRUE;
}
else {
drupal_add_http_header('WWW-Authenticate', 'Basic realm="Video transfer"');
drupal_add_http_header('Status', '401 Unauthorized');
print t('Access denied');
drupal_exit();
}
}
return FALSE;
}
function video_permission() {
return array(
'bypass conversion video' => array(
'title' => t('Bypass video conversion'),
'description' => t('Warning: Give to trusted roles only; this permission has security implications.'),
),
'convert on submission' => array(
'title' => t('Convert video on submit'),
'description' => t('Warning: Give to trusted roles only; this permission has security implications.'),
),
'override player dimensions' => array(
'title' => t('Change default player dimensions'),
'description' => t('Warning: Give to trusted roles only; this permission has usability implications.'),
),
'use default thumb' => array(
'title' => t('Use default thumbnail'),
'description' => t('Use the default video thumbnail as the thumbnail for the video.'),
),
're convert video' => array(
'title' => t('Re queue video'),
'description' => t('Convert videos back again if failed or not.'),
),
'administer video presets' => array(
'title' => t('Administer video presets'),
'description' => t('Perform administration tasks for the video presets.'),
),
);
}
function video_theme() {
$theme = array();
$theme['video_formatter_player'] = array(
'variables' => array(
'item' => NULL,
'entity' => NULL,
'entity_type' => NULL,
'field' => NULL,
'instance' => NULL,
'player_dimensions' => NULL,
'poster_image_style' => NULL,
),
'file' => 'video.theme.inc',
);
$theme['video_formatter_thumbnail'] = array(
'variables' => array(
'item' => NULL,
'path' => NULL,
'image_style' => NULL,
'entity' => NULL,
'entity_type' => NULL,
'field' => NULL,
'instance' => NULL,
'colorbox' => NULL,
),
'file' => 'video.theme.inc',
);
$theme['video_widget'] = array(
'render element' => 'element',
'file' => 'video.theme.inc',
);
$theme['video_conversion_failed'] = array(
'variables' => array(),
'file' => 'video.theme.inc',
);
$theme['video_inprogress'] = array(
'variables' => array(),
'file' => 'video.theme.inc',
);
$path = drupal_get_path('module', 'video') . '/theme';
module_load_include('utility.inc', 'video');
$players = array_keys(video_utility::getVideoPlayers());
$players[] = 'video_play_html5_audio';
foreach ($players as $tpl) {
$theme[$tpl] = array(
'variables' => array(
'item' => NULL,
'width' => NULL,
'height' => NULL,
),
'template' => str_replace('_', '-', $tpl),
'path' => $path,
);
}
$theme['video_flv'] = array(
'variables' => array(
'item' => NULL,
'themed_output' => NULL,
),
'file' => 'video.theme.inc',
);
$theme['video_html5'] = array(
'variables' => array(
'item' => NULL,
'width' => NULL,
'height' => NULL,
),
'file' => 'video.theme.inc',
);
$theme['video_dialog_page'] = array(
'render element' => 'page',
'template' => 'templates/video-dialog-page',
'file' => 'video.theme.inc',
);
return $theme;
}
function video_theme_registry_alter(&$registry) {
if (!class_exists('video_utility', TRUE)) {
module_load_include('utility.inc', 'video');
}
$players = video_utility::getVideoPlayers();
$templates = array_keys($players);
$templates[] = 'video_flv';
$templates[] = 'video_html5';
foreach ($templates as $template) {
if (!isset($registry[$template])) {
continue;
}
if (!isset($registry[$template]['preprocess functions'])) {
$registry[$template]['preprocess functions'] = array();
}
$registry[$template]['preprocess functions'][] = 'video_preprocess_video_formatter_player';
}
}
function video_preprocess_video_formatter_player(array &$variables) {
if (!isset($variables['autoplay'])) {
$variables['autoplay'] = (bool) variable_get('video_autoplay', FALSE);
}
if (!isset($variables['autobuffering'])) {
$variables['autobuffering'] = (bool) variable_get('video_autobuffering', TRUE);
}
}
function video_cron() {
if (!variable_get('video_cron', TRUE)) {
return;
}
$videos = video_jobs::loadQueue();
if (!empty($videos)) {
$queue = DrupalQueue::get('video_queue');
foreach ($videos as $video) {
$queue
->createItem($video);
}
}
$transcodetimeout = variable_get('video_transcode_timeout', 5);
if (!empty($transcodetimeout)) {
$limit = time() - $transcodetimeout * 60;
$videos = db_query('SELECT f.fid FROM {video_queue} q INNER JOIN {file_managed} f ON (f.fid = q.fid) WHERE q.statusupdated < ? AND q.status = ?', array(
$limit,
VIDEO_RENDERING_ACTIVE,
))
->fetchAllKeyed(0, 0);
if (!empty($videos)) {
$list = array();
foreach ($videos as $fid) {
$video = video_jobs::load($fid);
video_jobs::setFailed($video);
$entity = video_utility::loadEntity($video->entity_type, $video->entity_id);
$uri = entity_uri($video->entity_type, $entity);
$list[] = l($video->filename, $uri['path'], $uri['options']) . ' (' . t('@status since @datetime', array(
'@status' => t('active'),
'@datetime' => format_date($video->statusupdated),
)) . ')';
}
watchdog('video', 'The following videos were marked as %newstate because they have been in %oldstate state for more than @timeout minutes. To increase this limit, update the Video module scheduling @setting-name setting. !list', array(
'%newstate' => 'failed',
'%oldstate' => 'rendering active',
'@timeout' => $transcodetimeout,
'@setting-name' => t('Video transcode timeout'),
'!list' => theme('item_list', array(
'items' => $list,
)),
), WATCHDOG_WARNING, l(t('configure'), 'admin/config/media/video/scheduling'));
}
}
$queuetimeout = variable_get('video_queue_timeout', 60);
if (!empty($queuetimeout)) {
$limit = time() - $queuetimeout * 60;
$videos = db_query('SELECT f.fid, f.filename, q.entity_type, q.entity_id, q.statusupdated FROM {video_queue} q INNER JOIN {file_managed} f ON (f.fid = q.fid) WHERE q.statusupdated < ? AND q.status = ?', array(
$limit,
VIDEO_RENDERING_INQUEUE,
))
->fetchAllAssoc('fid');
if (!empty($videos)) {
db_update('video_queue')
->condition('fid', array_keys($videos), 'IN')
->fields(array(
'status' => VIDEO_RENDERING_PENDING,
'statusupdated' => time(),
))
->execute();
$list = array();
foreach ($videos as $video) {
$entity = video_utility::loadEntity($video->entity_type, $video->entity_id);
$uri = entity_uri($video->entity_type, $entity);
$list[] = l($video->filename, $uri['path'], $uri['options']) . ' (' . t('@status since @datetime', array(
'@status' => t('queued'),
'@datetime' => format_date($video->statusupdated),
)) . ')';
}
watchdog('video', 'The following videos were marked as %newstate because they have been in %oldstate state for more than @timeout minutes. To increase this limit, update the Video module scheduling @setting-name setting. !list', array(
'%newstate' => 'rendering pending',
'%oldstate' => 'queued',
'@timeout' => $queuetimeout,
'@setting-name' => t('Video queue timeout'),
'!list' => theme('item_list', array(
'items' => $list,
)),
), WATCHDOG_NOTICE, l(t('configure'), 'admin/config/media/video/scheduling'));
}
}
}
function video_cron_queue_info() {
return array(
'video_queue' => array(
'worker callback' => 'video_queue_process',
'time' => 60 * variable_get('video_transcode_timeout', 5) * variable_get('video_ffmpeg_instances', 5),
),
);
}
function video_queue_process(stdClass $video) {
$video_conversion = new Transcoder();
$video_conversion
->executeConversion($video);
}
function video_file_delete(stdClass $file) {
db_delete('video_queue')
->condition('fid', $file->fid)
->execute();
db_delete('video_thumbnails')
->condition('thumbnailfid', $file->fid)
->execute();
db_delete('video_thumbnails')
->condition('videofid', $file->fid)
->execute();
db_delete('video_output')
->condition('output_fid', $file->fid)
->execute();
db_delete('video_output')
->condition('original_fid', $file->fid)
->execute();
}
function video_features_api() {
return array(
'video' => array(
'name' => t('Video presets'),
'default_hook' => 'video_default_presets',
'file' => drupal_get_path('module', 'video') . '/video.features.inc',
),
);
}
function video_views_api() {
return array(
'api' => 3.0,
'path' => drupal_get_path('module', 'video') . '/views',
);
}
function video_views_handlers() {
return array(
'info' => array(
'path' => drupal_get_path('module', 'video') . '/views',
),
'handlers' => array(
'video_handler_field_video_duration' => array(
'parent' => 'views_handler_field',
),
),
);
}
function video_file_download($uri) {
$fileinfo = FALSE;
$extension = video_utility::getExtension($uri);
$isimage = $extension == 'png' || $extension == 'jpg';
if (!$isimage) {
$fileinfo = db_query('SELECT video.uri videouri, converted.* FROM {file_managed} video JOIN {video_output} op ON video.fid = op.original_fid JOIN {file_managed} converted ON converted.fid = op.output_fid WHERE converted.uri = :uri', array(
':uri' => $uri,
))
->fetchObject();
}
if ($fileinfo === FALSE && $isimage) {
$fileinfo = db_query('SELECT video.uri videouri, thumb.* FROM {file_managed} video JOIN {video_thumbnails} tn ON video.fid = tn.videofid JOIN {file_managed} thumb ON thumb.fid = tn.thumbnailfid WHERE thumb.uri = :uri', array(
':uri' => $uri,
))
->fetchObject();
}
if ($fileinfo === FALSE && strpos($uri, '/thumbnails/') !== FALSE) {
$thumbfile = db_query('SELECT thumb.* FROM {file_managed} thumb WHERE thumb.uri = :uri', array(
':uri' => $uri,
))
->fetchObject();
if ($thumbfile != NULL && strncmp($thumbfile->filemime, 'image/', 6) === 0) {
$fields = field_info_fields();
foreach ($fields as $field_name => $file_field) {
if ($file_field['type'] != 'video') {
continue;
}
$query = new EntityFieldQuery();
$references = $query
->fieldCondition($file_field, 'thumbnail', $thumbfile->fid)
->age(FIELD_LOAD_CURRENT)
->execute();
foreach ($references as $entity_type => $type_references) {
foreach ($type_references as $id => $reference) {
$entity = video_utility::loadEntity($entity_type, $id);
if ($entity) {
$field_items = field_get_items($entity_type, $entity, $field_name);
foreach ($field_items as $item) {
if ($item['thumbnail'] == $thumbfile->fid) {
$thumbfile->videouri = $item['uri'];
break 4;
}
}
}
}
}
}
if (isset($thumbfile->videouri)) {
$fileinfo = $thumbfile;
}
}
}
if ($fileinfo != NULL) {
$original_headers = file_download_headers($fileinfo->videouri);
if (empty($original_headers)) {
return -1;
}
return file_get_content_headers($fileinfo);
}
$path = file_uri_target($uri);
if (strpos($path, 'styles/') === 0) {
$args = explode('/', $path);
array_shift($args);
$style_name = array_shift($args);
array_shift($args);
$original_uri = file_uri_scheme($uri) . '://' . implode('/', $args);
if ($info = image_get_info($uri)) {
$headers = module_invoke_all('file_download', $original_uri);
if (!in_array(-1, $headers)) {
return array(
'Content-Type' => $info['mime_type'],
'Content-Length' => $info['file_size'],
'Expires' => gmdate(DATE_RFC1123, REQUEST_TIME + 1209600),
'Cache-Control' => 'max-age=1209600, private, must-revalidate',
);
}
}
return -1;
}
$files = file_load_multiple(array(), array(
'uri' => $uri,
));
if (count($files)) {
$file = reset($files);
if ($file->status) {
return file_file_download($uri, 'video');
}
}
}
function video_page_alter(&$page) {
if (isset($_GET['render']) && $_GET['render'] == 'video-popup') {
$page['#theme'] = 'video_dialog_page';
if (module_exists('admin_menu')) {
admin_menu_suppress();
}
foreach (element_children($page) as $key) {
if ($key != 'content') {
unset($page[$key]);
}
}
}
if (arg(1) == 'embed' && arg(0) == 'video') {
$page['#theme'] = 'video_dialog_page';
if (module_exists('admin_menu')) {
admin_menu_suppress();
}
foreach (element_children($page) as $key) {
if ($key != 'content') {
unset($page[$key]);
}
}
}
}