' . t('The FlashVideo module for Drupal 5.x is an easy to use module that expands the Upload module by allowing users to upload videos and attach those videos to any content. Even more exciting, is that FlashVideo automatically performs the very common Flash format conversion as well as create an image thumbnail of any newly uploaded video for every cron cycle. Once the video is in Flash format, the video can then be embedded in that node using the very simple [video] tag.') . '

'; $output .= '

' . t('To enable this module for a certain node type, you must first go to the ' . l(t('FlashVideo Settings'), 'admin/settings/flashvideo') . ' and select the FlashVideo settings for any available node type in the Drupal system. Once the FlashVideo module has been enabled for that node type, you will then notice the modified Upload form when you add new content for that node type.') . '

'; $output .= '

' . t('Once a video has been uploaded, it will then have to wait for the next Cron cycle for the conversion to Flash format to begin. You can manually run the cron operation by going to Administer->Logs->Status Report and then click on the link that says run cron manually. After the video has been converted, it will then be available to any node referencing that video. That node can then reference the video by using the [video] tag, and also reference the video thumbnail by providing the [thumbnail] tag.') . '

'; $output .= '

' . t('Parameters for these tags are provided by using a ":" to indicate a new parameter is being provided. The following format should be used for both the [video] and [thumbnail] tags. [video: param=value ] where param is the name of the parameter being passed, and value is the value of the parameter.') . '

'; $output .= '

' . t('The following parameters can be used...') . '

'; $output .= t(''); $output .= '

' . t('The following are examples of using the [video] and [thumbnail] tag system...') . '

'; $output .= t('
'); $output .= '

' . t('Importing Videos') . '

'; $output .= '

' . t('The FlashVideo module has also included a way for someone to import a large number of videos by just placing them in a directory (using FTP or some other means). Here is how it works. Within the files directory, simply create a new directory and name it video_import (or else defined within the FlashVideo Settings page). Then, whatever video files you place within that directory will not only be added to the Drupal Files database, but also be added to the FlashVideo cron cycle conversion queue. This makes it VERY simple for a site administrator to add MANY videos to their site without having to upload them individually to a node.') . '


'; $output .= '

' . t('Using the FlashVideo API') . '

'; $output .= '

' . t('As of version 2.2, FlashVideo has introduced a new API that allows for developers to hook into the FlashVideo system to add specific conversion utilities besides the previous default of FFMPEG. It does this through the use of two new Hooks that can be used to override how the FlashVideo module performs its conversion routine. These hooks are as follows...') . '

'; $header = array(t('Hook Name'), t('Description')); $rows[] = array(t('flashvideo_submit'), t('This hook gets invoked when the user presses the Submit button on a node insertion and update. The default parameters are passed to this hook.') ); $rows[] = array(t('flashvideo_get_params'), t('This hook gets invoked just before the actual conversion is performed allowing you to override any of the default parameters.') ); $rows[] = array(t('flashvideo_save_file'), t('This hook gets invoked when the FlashVideo module has finished converting the FLV video and is saving it in the database.') ); $rows[] = array(t('flashvideo_get_file'), t('This hook allows other modules to catch the FlashVideo module right before it sets the filepath of the video allowing them to override the path of the video. Great for external storage plugins.') ); $rows[] = array(t('flashvideo_delete_file'), t('This hook gets invoked when the FlashVideo module is deleting a file from the database.') ); $output .= '
' . theme('table', $header, $rows) . '
'; $rows = array(); $output .= '

' . t('The following table is a list of all parameters that can be overidden within these hooks.') . '

'; $header = array(t('Parameter Name'), t('Type'), t('Description')); $rows[] = array(t('output_dir'), t('Text'), t('Used to command the output directory. This is relative to the system files directory.') ); $rows[] = array(t('cmd_path'), t('Text'), t(' Used to specify the CWD path to the conversion utility executable. Be sure to include the executable in the path. Example /usr/bin/ffmpeg') ); $rows[] = array(t('video_args'), t('Text'), t('The arguments given to the conversion utility executable to generate a video. The same format should be used as in the FlashVideo Settings.') ); $rows[] = array(t('thumb_args'), t('Text'), t(' The arguments given to the ffmpeg executable to generate a thumbnail. The same format should be used as in the FlashVideo Settings.') ); $rows[] = array(t('thumbsize'), t('Text'), t('The thumbnail size specified in the following format "WIDTH x HEIGHT". Example 130x100') ); $rows[] = array(t('thumbwidth'), t('Integer'), t('The thumbnail width.') ); $rows[] = array(t('thumbheight'), t('Integer'), t('The thumbnail height.') ); $rows[] = array(t('thumbtime'), t('Text'), t('The amount of time to delay before taking a snapshot of the video. Denoted as "00:00:00"') ); $rows[] = array(t('thumbsecs'), t('Integer'), t('The amount of seconds to delay before taking a snapshot of the video.') ); $rows[] = array(t('thumbext'), t('Text'), t('The extension of the output thumbnail. Example: For JPG\'s this would be jpg') ); $rows[] = array(t('videoext'), t('Text'), t('The extension of the output video. Example: For output FLV\'s, this would be flv') ); $rows[] = array(t('videomime'), t('Text'), t('The mime type of the output video.') ); $output .= '
' . theme('table', $header, $rows) . '
'; $output .= '

' . t('Please Refer to the FlashVideo CCK plugin to observe how to utilize this new API.') . '

'; return $output; case 'admin/settings/modules#description': return t('Allows you to insert videos into nodes.'); } } /** * Implementation of hook_perm(). */ function flashvideo_perm() { return array('administer flashvideo'); } /** * Extracts the [FileType, MimeType, Player] string into an array. */ function flashvideo_get_allowed_filetypes() { // Get the filetype string... $filestring = flashvideo_variable_get(NULL, 'flashvideo_video_filetypes', FLASHVIDEO_FILETYPE_STRING); // Split the file infos. $filetypes = preg_split("/[\n\r]+/", $filestring); // Default our File Array. $filearray = array(); // Make sure that there are filetypes before we iterate. if(count($filetypes)) { // Iterate through our filetypes. foreach($filetypes as $filetype) { // Replace all white space and brackets. $filetype = preg_replace("/[\s\[\]]+/", "", $filetype); // Split the parameters in their own array. $fileinfo = explode(",", $filetype); // Only continue if there three parameters... anything else is not valid. if(count($fileinfo) == 3) { // Set the mime type of the file. $filearray[$fileinfo[0]]['mimetype'] = $fileinfo[1]; // Set the player of the file. $filearray[$fileinfo[0]]['player'] = $fileinfo[2]; } } } // Return the file array return $filearray; } /** * Implementation of hook_theme() */ function flashvideo_theme() { $themes = array(); // Set up the theme for playing the video $themes['flashvideo_play'] = array( 'template' => 'flashvideo-play', 'arguments' => array('video' => NULL, 'url' => NULL, 'text' =>NULL) ); // Set up the theme to show the embed text box. $themes['flashvideo_embed'] = array( 'template' => 'flashvideo-embed', 'arguments' => array('object' => NULL, 'node_type' => NULL) ); // Set up the theme for showing the video thumbnail $themes['flashvideo_thumbnail'] = array( 'template' => 'flashvideo-thumbnail', 'arguments' => array('link' => NULL, 'url' => NULL, 'nid' => NULL, 'width' => NULL, 'height' => NULL) ); // Get all the allowed filetypes. $filetypes = flashvideo_get_allowed_filetypes(); // Iterate through each filetype. foreach($filetypes as $type => $filetype) { // If the filetypes are set and they have a valid player, then we will want to // set up the theme for that player. if(isset($filetypes[$type]) && $filetypes[$type] && $filetypes[$type]['player']) { // Set up the theme for that player. $themes['flashvideo_'.$filetype['player']] = array( 'template' => 'flashvideo-'.$filetype['player'], 'arguments' => array('video' => NULL) ); } } // Return the themes back to the system. return $themes; } /** * Preprocess the variables before being passed to the player specific themes. * * @param $variables * An array of all the variables that will be passed to the player templates. */ function flashvideo_template_preprocess(&$variables) { // Get the node type... $node_type = $variables['video']['node_type']; // Create a variable for the flash players path. $variables['player'] = check_url(file_create_url(flashvideo_variable_get($node_type, 'player', 'Player.swf'))); // Create a variable for the window mode for the player. $variables['wmode'] = flashvideo_variable_get($node_type, 'mode', 'window'); // Create a variable that will be a string of the flashvars to be passed to the flash player. $variables['flashvars'] = flashvideo_get_flashvars($variables['video']); // Create a variable of any extra params. $variables['params'] = _flashvideo_get_parameters($variables['video']); // Switch based off of the type of video. switch($variables['video']['type']) { // For google videos, we need too take out the "google-" at the beginning. case 'googlevideo': $variables['videoid'] = substr($variables['video']['file'], 7); break; // For brightcove videos, we need to take out the "brightcove-" at the beginning. case 'brightcove': $variables['videoid'] = substr($variables['video']['file'], 11); break; // Anything else we will just set the $videoid as if it was a YouTube video. case 'youtube': default: $variables['videoid'] = $variables['video']['file']; break; } } /** * For the template pre-process for the player specific themes, we just want to use a single * method for setting up the variables to be used in that those themes. */ function template_preprocess_flashvideo_flash(&$variables) { flashvideo_template_preprocess($variables); } function template_preprocess_flashvideo_googlevideo(&$variables) { flashvideo_template_preprocess($variables); } function template_preprocess_flashvideo_youtube(&$variables) { flashvideo_template_preprocess($variables); } function template_preprocess_flashvideo_brightcove(&$variables) { flashvideo_template_preprocess($variables); } /** * The main theme for showing a video. It will populate the $video_object variable based on a theme * given by the video type. It will also populate the $video_embed variable based on the theme called * from flashvideo_embed. */ function template_preprocess_flashvideo_play(&$variables) { // Populate the $video_object variable based on the player specific theme. $variables['video_object'] = theme('flashvideo_'. $variables['video']['type'], $variables['video']); // Populate the $video_embed variable based on the theme for "flashvideo_embed" $variables['video_embed'] = theme('flashvideo_embed', $variables['video_object'], $variables['video']['node_type']); } /** * Populates and returns a FlashVars string. * * To allow for custom usage for the FlashVar string, the FlashVideo module has * put into place a method for creating custom FlashVar strings. You can do this two * ways... by either specifying it within the FlashVideo Settings where it says "Custom FlashVars" * which will be used for that node type, or you can be more specific by using the [video] tag * for each video uploaded to that node using the following schema... * * [video:flashvar|param=value] * * where "flashvar" indicates that the parameter is a FlashVar followed by a "|" * and then your FlashVar parameter and value. For example, if I want to set my intro * image for my video as "intro.jpg", my [video] tag would look like the following... * * [video : flashvar|image=intro.jpg] * * If you wish to use the API function call, then all you will need to do then is just * add a sub array under 'flashvars' in the $params array like the following and then pass * that $params array to the "flashvideo_get_video" API call. * * $params['flashvars']['parameter'] = value * * @param $video * An array contining information about the video to be played. * * @return * A string representation of the FlashVars to be passed to the flash player. */ function flashvideo_get_flashvars($video) { // Get the basic FlashVar string... $flashvars = flashvideo_variable_get($video['node_type'], 'flashvars', 'file=@video'); // Boolean to determine if we are using a playlist or not. $playlist = (strpos($video['file'], 'getplaylist') !== FALSE); // Set up the output directory. $output_dir = flashvideo_variable_get($video['node_type'], 'outputdir', ''); $output_dir = ($output_dir == '') ? $output_dir : ($output_dir . '/'); // Determine the intro image for the video... if(!isset($video['flashvars']['image']) && (strpos($flashvars, 'image') === FALSE)) { // If it is a playlist or if they do not want the thumbnail to be used as the intro image. if($playlist || (flashvideo_variable_get($video['node_type'], 'introthumb', 1) == 0)) { // Make sure that the introimg variable is actually valid. if(flashvideo_variable_get($video['node_type'], 'introimg', '') != '') { // Set up the intro image as what they specified in the "introimg" user variable. $video['flashvars']['image'] = check_url(file_create_url($output_dir . flashvideo_variable_get($video['node_type'], 'introimg', '') )); } } else { // They want to use the video thumbnail as the intro image. $video['flashvars']['image'] = check_url(str_replace(".flv", ".jpg", $video['file'])); } } // If they have an intro image set, then we need to figure out how long to show it... if(!isset($video['flashvars']['rotatetime']) && $video['flashvars']['image'] && (strpos($flashvars, 'rotatetime') === FALSE)) { $video['flashvars']['rotatetime'] = flashvideo_variable_get($video['node_type'], 'introtime', '3'); } // Set up the logo image... if(!isset($video['flashvars']['logo']) && (flashvideo_variable_get($video['node_type'], 'logo', '') != '') && (strpos($flashvars, 'logo') === FALSE)) { $video['flashvars']['logo'] = check_url(file_create_url(flashvideo_variable_get($video['node_type'], 'logo', ''))); } // Set up the URL link for the logo image... if(!isset($video['flashvars']['link']) && (flashvideo_variable_get($video['node_type'], 'logolink', '') != '') && (strpos($flashvars, 'link') === FALSE)) { $video['flashvars']['link'] = flashvideo_variable_get($video['node_type'], 'logolink', ''); } // Set up the repeat parameter for the video player. if(!isset($video['flashvars']['repeat']) && (flashvideo_variable_get($video['node_type'], 'repeattype', 'false') != 'false') && (strpos($flashvars, 'repeat') === FALSE)) { $video['flashvars']['repeat'] = flashvideo_variable_get($video['node_type'], 'repeattype', 'false'); } // For reverse functionality... Set up the autostart parameter. if($video['autostart'] && strpos($flashvars, 'autostart') === FALSE) { $video['flashvars']['autostart'] = $video['autostart']; } // If they specify some flashvars, then we want to add them to the FlashVar string. if($video['flashvars'] && (count($video['flashvars']) > 0)) { foreach($video['flashvars'] as $flashvar => $value) { $flashvars .= '&' . $flashvar . '=' . $value; } } // Set up the markup and actual data arrays. $markup = array('@video', '@thumbnail'); $actual = array($video['file'], check_url(str_replace(".flv", ".jpg", $video['file'])) ); return str_replace($markup, $actual, $flashvars); } /** * Gets the HTML representation of the video. * * @param $video * An array of parameters to be used by the shown video. * * @return * String representing the HTML of the video to be displayed. */ function flashvideo_play($video) { // Get the filetype of the video to be shown. $filetype = $video['override'] ? 'flv' : _flashvideo_get_filetype($video['file']); // Get all the allowed filetypes. $filetypes = flashvideo_get_allowed_filetypes(); // If this is a valid filetype and also has a player associated with this file type... if(isset($filetypes[$filetype]) && $filetypes[$filetype] && $filetypes[$filetype]['player']) { // Want to set the type of the video based on the player that will play this video. $video['type'] = $filetypes[$filetype]['player']; // Switch on what player you want to show the video with. switch($video['type']) { case 'flash': return theme('flashvideo_play', $video, t('http://www.macromedia.com/go/getflashplayer'), t('Download latest Flash Player')); case 'youtube': return theme('flashvideo_play', $video, t('http://www.youtube.com/t/help_center'), t('youTube.com')); case 'googlevideo': return theme('flashvideo_play', $video, t('http://video.google.com/support'), t('video.google.com')); default: return theme('flashvideo_play', $video, '', ''); } } else { // Return that the given file type is not supported. return _flashvideo_get_filetype($video['file']) . ' filetypes are not supported'; } } /** * Implementation of hook_form_alter() */ function flashvideo_form_alter(&$form, $form_id) { // Make sure it is a form. if (isset($form['type'])) { // Get the node type from the form being shown. $node_type = $form['type']['#value']; // Make sure that this is actually a form for that node type. if($form['#parameters'][0] == $node_type.'_node_form') { // Check to make sure that they have enabled FlashVideo for this node type. if(flashvideo_variable_get($node_type, 'enable', 0)) { // See if the attachements field is defined in this form. if( isset($form['attachments']) ) { // Change the title based on what they want in the FlashVideo Settings. $form['attachments']['#title'] = flashvideo_variable_get($node_type, 'title', t('Video Upload')); // Expand it so that it is visible. $form['attachments']['#collapsed'] = FALSE; // Set the weight according to what they specified. $form['attachments']['#weight'] = flashvideo_variable_get($node_type, 'weight', -10); // If we don't have any files already, optionally make the 'new' file upload required if (!array_key_exists('files', $form['attachments']['wrapper'])) { $form['attachments']['wrapper']['new']['upload']['#required'] = flashvideo_variable_get($node_type, 'require', 0); } } } } } } /** * Implementation of hook_menu(). */ function flashvideo_menu() { $items = array(); // The Flash Video Settings menu item. $items['admin/settings/flashvideo'] = array( 'title' => t('FlashVideo Settings'), 'description' => t('Administer the FlashVideo module.'), 'page callback' => 'flashvideo_settings', 'access callback' => 'user_access', 'access arguments' => array('administer flashvideo'), 'file' => 'flashvideo.admin.inc' ); // Menu item to get the XML representation for playlists. $items['getplaylist'] = array( 'page callback' => 'flashvideo_getplaylist', 'page arguments' => array(1), 'type' => MENU_CALLBACK, 'access callback' => 'user_access', 'access arguments' => array('access content'), 'file' => 'flashvideo.playlist.inc' ); // Administration settings for a specific node type. $items['admin/settings/flashvideo/edit'] = array( 'title' => t('Edit FlashVideo'), 'page callback' => 'flashvideo_settings_main', 'page arguments' => array(4), 'access callback' => 'user_access', 'access arguments' => array('administer flashvideo'), 'parent' => 'admin/settings/flashvideo', 'file' => 'flashvideo.admin.inc' ); return $items; } /** * Pull the file extension from a filename * * @param $vidfile * string filename to get the filetype from. * * @return * string value of file type or boolean FALSE on error */ function _flashvideo_get_filetype($vidfile) { // Initialize our file type as FALSE. $file_type = FALSE; // They are wanting to show a playlist if (strpos($vidfile, 'getplaylist') !== FALSE) { $file_type = 'playlist'; } // Normal file... just return the extension. else if (strstr($vidfile, '.')) { $file_type = strtolower(get_file_ext($vidfile)); } // See if it is a Google Video else if (strpos($vidfile, 'google-') === 0) { $file_type = 'googlevideo'; } // See if it is a Brightcove video. else if (strpos($vidfile, 'brightcove-') === 0) { $file_type = 'brightcove'; } // See if it is a YouTube video else if (!strpos($vidfile, '.') && !strpos($vidfile, '/') && !strpos($vidfile, '\\') && strlen($vidfile) == 11) { $file_type = 'youtube'; } return $file_type; } /** * Returns the correct video mime-type for the video. Returns false if the file is not a supported video type. * * @param $filename * The name or path of the file you wish to get the mime type of. * * @param $extension * A boolean to indicate whether or not the name is JUST an extension, or is a filetype * * @return Mimetype for known video types, FALSE file is not a supported video type. */ function _flashvideo_get_mime_type($filename, $extension = FALSE) { // Are they providing the extension already? If so, then we don't need to call get_filetype function. $filetype = $extension ? $filename : _flashvideo_get_filetype($filename); // Get all the allowed filetypes. $filetypes = flashvideo_get_allowed_filetypes(); // If this is a valid mime type, then return it, otherwise return FALSE. if(isset($filetypes[$filetype]) && $filetypes[$filetype]['mimetype']) return $filetypes[$filetype]['mimetype']; else return FALSE; } /** * Performs the post operations after a successful conversion. * * @param $oldfile * A Standard Drupal File object of the old file * * @param $newfile * A Standard Drupal File object of the new file * * @param $node_type * The current node type. * * @param $create_thumbnail * Boolean to tell the routine if you just want to create a thumbnail. * */ function _flashvideo_perform_postop($oldfile, $newfile, $node_type, $create_thumbnail = FALSE) { // Create a temporary file for the new file. db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES (%d, '%s', '%s', '%s', %d, %d, %d)", $newfile->uid, $newfile->filename, $newfile->filepath, $newfile->filemime, $newfile->filesize, FILE_STATUS_TEMPORARY, time()); // Get the new File ID $newfile->fid = db_last_insert_id('files', 'fid'); // Look to make sure that the File ID doesn't already exists in the files database. $found = db_result(db_query("SELECT COUNT(*) FROM {files} WHERE filepath='%s' AND status=%d", $newfile->filepath, FILE_STATUS_PERMANENT)); // If the file isn't already in the files database... if($found == 0) { // Insert the new file into the upload database table. db_query("INSERT INTO {upload} (fid, nid, vid, description, list) VALUES (%d, %d, %d, '%s', 0)", $newfile->fid, $newfile->nid, $newfile->vid, $newfile->description); // Set the status of the new file to be a permanent file. file_set_status($newfile, FILE_STATUS_PERMANENT); // Grab the width, height, and video_index from the original video to copy over to the new video, then insert the new video in the flashvideo table. $params = db_fetch_object(db_query("SELECT video_index, width, height FROM {flashvideo} WHERE fid = %d", $oldfile->fid)); // Insert this video into the flashvideo database. db_query("INSERT INTO {flashvideo} (fid, nid, oid, status, video_index, width, height, flags) VALUES (%d, %d, %d, %d, %d, %d, %d, 0)", $newfile->fid, $newfile->nid, $oldfile->fid, FLASHVIDEO_STATUS_CONVERTED, $params->video_index, $params->width, $params->height); // If we are not creating a thumbnail... if(!$create_thumbnail) { // If they wish to delete the original video... if( flashvideo_variable_get($node_type, 'delete', 0) && get_file_ext($oldfile->filepath) != 'flv' ) { // Delete the file from the file system. file_delete($oldfile->filepath); // Delete the file from the files table. db_query("DELETE FROM {files} WHERE fid = %d", $oldfile->fid); // Delete the file from the upload table. db_query("DELETE FROM {upload} WHERE fid = %d", $oldfile->fid); // Delete the file from the flashvideo table. db_query("DELETE FROM {flashvideo} WHERE fid=%d", $oldfile->fid); // Allow other modules do do some delete operations. module_invoke_all('flashvideo_delete_file', $oldfile); } // Now insert this successful conversion into the ffmpeg_data table. db_query("INSERT INTO {ffmpeg_data} (fid, created, input_file, output_file, status) VALUES (%d, NOW(), '%s', '%s', %d)", $oldfile->fid, $oldfile->filepath, $newfile->filepath, 1); } } else { // If the file was found, then all we need to do is just update the database information about that file. db_query("UPDATE {files} SET filepath='%s', filename='%s', filesize=%d WHERE fid=%d", $newfile->filepath, $newfile->filename, $newfile->filesize, $newfile->fid); // Change the filepath in the files table. } // If they opt to change the status of the node. if(flashvideo_variable_get($node_type, 'status', 1)) { // Update the status of the node. db_query("UPDATE {node} SET status = 1 WHERE nid=%d", $oldfile->nid); } // Tell other modules to save this file. module_invoke_all('flashvideo_save_file', $newfile); // Set the status of this video to say it is converted and also set all flags to zero. db_query("UPDATE {flashvideo} SET status=%d, flags=0 WHERE nid=%d AND (oid=fid)", FLASHVIDEO_STATUS_CONVERTED, $newfile->nid); // Set the status to converted. // Empty the cache so your node updates. db_query("TRUNCATE {cache}"); } /** * Gets the default parameters needed to run the conversion. * * @param $node_type * The current node type. * * @return * An array of all the parameters used in the video and thumbnail conversion. */ function flashvideo_get_convert_params($node_type) { // Set the output directory... $params['output_dir'] = flashvideo_variable_get($node_type, 'outputdir', ''); // Sets the original directory... $params['originaldir'] = flashvideo_variable_get($node_type, 'originaldir', ''); // Set the ffmpeg command path. $params['cmd_path'] = flashvideo_variable_get(NULL, 'flashvideo_binpath', '/usr/bin/ffmpeg'); // Set the video command arguments. $params['video_args'] = flashvideo_variable_get($node_type, 'cmd', '-i @input -f flv -acodec mp3 -ar 22050 -ab 64k -ac 1 @output'); // Set the thumbnail command arguments. $params['thumb_args'] = flashvideo_variable_get($node_type, 'thumbcmd', '-y -i @input -vframes 1 -ss @thumbtime -an -vcodec mjpeg -f rawvideo -s @thumbsize @output'); // Set the thumbnail size as a string representation. $params['thumbsize'] = flashvideo_variable_get($node_type, 'thumbsize', '130x100'); // Set the thumbnail size as integer representations by breaking up the string "width x height" $size = explode('x', strtolower($params['thumbsize'])); $params['thumbwidth'] = trim($size[0]); $params['thumbheight'] = trim($size[1]); // Set the thumbtime as a string represation given by "hh:mm:ss" $params['thumbtime'] = flashvideo_variable_get($node_type, 'thumbtime', '00:00:02'); // Set the thumbtime given as a second representation by breaking up the "hh:mm:ss" string. $thumbtimes = explode(":", $params['thumbtime']); array_walk($thumbtimes, create_function('&$n', '$n = intval(trim($n), 10);')); $params['thumbsecs'] = ($thumbtimes[0] * 3600) + ($thumbtimes[1] * 60) + ($thumbtimes[2]); // Set the thumbnail extension as a JPG. $params['thumbext'] = 'jpg'; // Set the video extension as an FLV (flash) file. $params['videoext'] = 'flv'; // Set the video mimetype as the Flash mimetype. $params['videomime'] = 'flv-application/octet-stream'; // Default these variables to true. $params['create_thumb'] = TRUE; $params['create_video'] = TRUE; return $params; } /** * New and improved version of video format conversion. More generic so that it can be easily called outside of Cron Job, and with a different conversion utility. * * @param $file * A Standard Drupal File object * * @param $node_type * The current node type. * * @param $create_thumbnail * Boolean to tell the routine if you want to create a thumbnail. * * @param $params * An array of parameters... Used to override functionality. Leave blank if you wish to use defaults. * - output_dir : The output directory relative to the system files directory. * - originaldir : The output directory to contain the original video after the conversion has been made. * - cmd_path : The path to the ffmpeg executable. Can be overridden with something besides ffmpeg. * - video_args : The command to pass to the ffmpeg executable. * - thumb_args : The thumbnail command to pass to the ffmpeg executable. * - thumbsize : An string spcifying the width and height of the thumbnail denoted as "WIDTH x HEIGHT". * - thumbwidth : An integer representing the thumbnail width. * - thumbheight : An integer representing the thumbnail height. * - thumbtime : A string in the format of "00:00:00" that tells how far to advance the video before taking a snapshot. * - thumbsecs : An integer representing how many seconds to delay before taking a snapshot. * - thumbext : The output thumbnail extension. * - videoext : The output video extension. * - videomime : The output video mime. * * @return * TRUE - conversion was successful. * FALSE - conversion was not succesful. */ function flashvideo_convert($file, $node_type, $create_thumbnail = FALSE, $params = array()) { // Get the default parameters. $default_params = flashvideo_get_convert_params($node_type); /** * If they do not provide a parameter in their overrided $param array, * then we will just use the default instead. */ // Iterate through all default parameters. foreach($default_params as $param => $value) { // If the parameter is not set in the overrided params array. if(!isset($params[$param])) { // Then use the default instead. $params[$param] = $value; } } // Set the new file to equal the old file. $newfile = drupal_clone($file); // Get the CWD filepath. $filepath = getcwd() . '/' . $file->filepath; // Get the file extension. $extension = _flashvideo_get_filetype($file->filepath); // See if they want to use the drupal root path. $useroot = flashvideo_variable_get($node_type, 'userootpath', 0); // Only perform if this is a video. if(_flashvideo_get_mime_type($extension, TRUE)) { // Get the new filename. $newfile->filename = basename($file->filepath, "." . $extension); // Set the extension. $newfile->filename .= $create_thumbnail ? ".{$params['thumbext']}" : ".{$params['videoext']}"; // Set the output directory based on if they want to use the drupal root or not... $output_directory = $useroot ? $params['output_dir'] : file_directory_path() . '/' . $params['output_dir']; // Check the output directory to make sure it exists. Create it if it doesn't. file_check_directory($output_directory, 1); // Add a forward slash only if they have an output directory. $params['output_dir'] = ($params['output_dir'] == '') ? '' : $params['output_dir'] . '/'; // Get the new filepath. $newfile->filepath = $useroot ? $params['output_dir'] . $newfile->filename : file_create_path($params['output_dir'] . $newfile->filename); // Get the output path. $output_path = getcwd() . '/' . $newfile->filepath; // We should only continue if there is an input file. if((file_exists($filepath) && filesize($filepath) > 0)) { $command = ''; // For scope reasons... $ffmpeg_data = ''; // For scope reasons... /* * If the video file is already an FLV extension, and this isn't the pass to create a thumbnail, then we will * just copy the video to the output path and set the status to converted. Otherwise, we will just go ahead and try and convert * the video. */ if(!$create_thumbnail && $extension == 'flv') { // Move the file to the output directory rename($filepath, $output_path); } else { // Set the Status to Converting. db_query("UPDATE {flashvideo} SET status=%d WHERE fid=%d", FLASHVIDEO_STATUS_CONVERTING, $file->fid); /** * If your conversion utility doesn't support the ffmpeg version of "00:00:00" for thumbnail time or * "WIDTH x HEIGHT" for the thumbnail size, then you are more than welcome to unset the $params['thumbtime'] * and $params['thumbsize'] variables and then just use @thumbwidth, @thumbheight, or @thumbsecs in your markup * command. Or, if you require a different string representation, then all you have to do is just overwrite the $params['thumbtime'] * and $params['thumbsize'] variables and then just use @thumbtime and @thumbsize in your markup. */ // Set the String Thumbsize variable. if(isset($params['thumbsecs']) && !isset($params['thumbtime'])) { // Set the Hours section. $params['thumbtime'] = intval($params['thumbsecs'] / 3600) . ':'; // Set the Minutes section. $params['thumbtime'] .= intval($params['thumbsecs'] / 60) . ':'; // Set the Seconds section. $params['thumbtime'] .= intval($params['thumbsecs'] % 60); } // If they didn't provide a thumbsize string, but DID provide the width and height, we can construct the thumbsize string from that. if(isset($params['thumbwidth']) && isset($params['thumbheight']) && !isset($params['thumbsize'])) { // Set the string thumbsize. $params['thumbsize'] = $params['thumbwidth'] . 'x' . $params['thumbheight']; } // Set up the markup and actual data arrays. $markup = array('@input', '@output', '@thumbtime', '@thumbsize', '@thumbsecs', '@thumbwidth', '@thumbheight'); $actual = array('"' . $filepath . '"', // The input file path. '"' . $output_path . '"', // The output file path. '"' . $params['thumbtime'] . '"', // The thumbtime provided as a string. '"' . $params['thumbsize'] . '"', // The thumbsize provided as a string. $params['thumbsecs'], // The thumb time provided as an integer in seconds. $params['thumbwidth'], // The thumb width provided as an integer. $params['thumbheight']); // The thumb height provided as an integer. // Lets check to make sure they have the right audio encoder. if(!$create_thumbnail) { // Get the format string from their ffmpeg installation. $format = shell_exec($params['cmd_path'] . ' -formats'); // If they are using libmp3lame, then we will need to change the command if they have // mp3 as the codec. if(strpos($format, 'EA libmp3lame') !== FALSE) { // Their audio codec is libmp3lame. Lets make sure that we replace the command $params['video_args'] = str_replace('-acodec mp3 ', '-acodec libmp3lame ', $params['video_args']); } } // Set the command. $command = ($create_thumbnail) ? $params['thumb_args'] : $params['video_args']; // Replace all markups with actual data. $command = $params['cmd_path'] . ' ' . str_replace($markup, $actual, $command); // Don't show the command if they opt to convert the videos immediately. if (!flashvideo_variable_get($node_type, 'convert', 0)) { drupal_set_message('Command: ' . $command); } // Convert the video. $ffmpeg_data = shell_exec($command); } // Check to make sure the new file exists. if(file_exists($output_path) && filesize($output_path) > 0) { // Get the new file mimetype $newfile->filemime = $create_thumbnail ? $params['thumbext'] : $params['videomime']; // Get the new file size. $newfile->filesize = filesize($output_path); // If we are not creating a thumbnail, and they want to utilize the original output directory... if(!$create_thumbnail && $params['originaldir'] != '' && $extension != 'flv') { // Get the original directory path. $original_path = $useroot ? $params['originaldir'] : file_directory_path() . '/' . $params['originaldir']; // Check to make sure the directory exists... create it if it doesn't. file_check_directory($original_path, 1); // Add the filename to the path. $original_path .= '/' . basename($file->filepath); // Move the file to the new path. rename(getcwd() . '/' . $file->filepath, getcwd() . '/' . $original_path); $file->filepath = $original_path; // Change the filepath in the files table. db_query("UPDATE {files} SET filepath='%s' WHERE fid=%d", $original_path, $file->fid); } // Sucess! Perform the Post Operations. _flashvideo_perform_postop($file, $newfile, $node_type, $create_thumbnail); // Return TRUE upon success. return TRUE; } else { // So that it will try again later. db_query("UPDATE {flashvideo} SET status=%d, flags=0 WHERE fid=%d" , FLASHVIDEO_STATUS_OK, $file->fid); // If they want to log the data, then we will set up the data field. $data = flashvideo_variable_get(NULL, 'flashvideo_logdata', 0) ? "Command: {$command}\nData: {$ffmpeg_data}" : ''; // Add this failed conversion to the ffmpeg_data table. db_query("INSERT INTO {ffmpeg_data} (fid, created, input_file, output_file, status, data) VALUES (%d, NOW(), '%s', '%s', %d, '%s')", $file->fid, $filepath, $output_path, 0, $data); } } } return FALSE; } /** * Implementation of hook_cron : Now using the new More general flashvideo_perform_ffmpeg routine. */ function flashvideo_cron() { // I will use the Cron task to convert all uploaded video's to Flash file format. $types = node_get_types(); // Iterate through each node type. foreach($types as $type){ // If they have enabled the FlashVideo module for this node type... if(flashvideo_variable_get($type->type, 'enable', 0)) { // Check the import directory and add all files to the queue... flashvideo_import(flashvideo_variable_get(NULL, 'flashvideo_import', 'video_import')); // First we will want to grab all files that have not been processed yet. $files = db_query("SELECT n.nid, u.*, f.*, fv.flags FROM {files} f LEFT JOIN {upload} u ON u.fid=f.fid LEFT JOIN {flashvideo} fv ON f.fid = fv.fid LEFT JOIN {node} n ON fv.nid = n.nid WHERE (n.type = '%s') AND (fv.oid = fv.fid) AND (fv.status <> %d) AND ((fv.status = %d) OR (fv.flags > 0))", $type->type, FLASHVIDEO_STATUS_CONVERTING, FLASHVIDEO_STATUS_OK); $index = 0; // The maximum number of conversions allowed per cron cycle. $max_converts = flashvideo_variable_get(NULL, 'flashvideo_maxconvert', 10); // The maximum number of conversion failures. $max_num_failures = flashvideo_variable_get(NULL, 'flashvideo_maxfail', 5); // Iterate through all the files in the conversion queue. while( ($index < $max_converts) && ($file = db_fetch_object($files)) ) { // See how many failures we have already had with this video... $failures = db_result(db_query("SELECT COUNT(*) FROM {ffmpeg_data} WHERE (fid = %d) AND (status = 0)", $file->fid)); /* * If you wish a file to not convert by uploading... You can simply put NOCONVERT anywhere in the name and the conversion * process will be skipped for that file. */ // Check to see if we are allowed to convert this video. if(!strpos($file->filename, 'NOCONVERT') && (($failures < $max_num_failures) || ($max_num_failures == 0))) { // Get the default parameters. $params = flashvideo_get_convert_params($type->type); // Invoke other modules to allow them to override the conversion parameters. if($override_params = module_invoke_all('flashvideo_get_params', $file, $file->flags, $params)) { if( count( $override_params ) ) { foreach($override_params as $param => $value) { $params[$param] = $value; } } } // If another module chose to override conversion of the thumbnail... if($params['create_thumb']) { // Create the Thumbnail. flashvideo_convert($file, $type->type, TRUE, $params); } // If another module chose to override conversion of the video... if($params['create_video']) { // Create the Flash Video. flashvideo_convert($file, $type->type, FALSE, $params); } // Increment the conversion index. $index++; } else { /* * We are unable to convert the video... Not all is lost. We will just use the original video. * update the status of the file. */ db_query("UPDATE {flashvideo} SET status=%d, flags=0 WHERE fid=%d", FLASHVIDEO_STATUS_CONVERTED, $file->fid); } } } } } /* * This function takes a path as an argument (within the files directory) and will add all video files to the convert queue. * * @param $path * A path within the files directory to be used as the import directory. */ function flashvideo_import($path) { // Scan for all files in the directory $files = file_scan_directory(file_directory_path() . '/' . $path, '.*'); // Only continue if there are files. if(count($files)) { // Iterate through all files in the convert directory. foreach($files as $file) { // Only add if the file is a video and is not already in our flashvideo table. if(($filemime = _flashvideo_get_mime_type($file->filename)) !== FALSE) { // Create a temporary file object. $tempfile->filepath = $file->filename; // Replace the covert directory with blank string so that it will move out of the convert directory. $tempfile->filepath = str_replace($path . '/', '', $tempfile->filepath); // Munge up the filename for security reasons. $tempfile->filepath = file_munge_filename($tempfile->filepath, ''); // Delete potential exploit files for security reasons. if (preg_match('/\.(php|pl|py|cgi|asp|js)$/i', $tempfile->filepath)) { unlink(getcwd() . '/' . $tempfile->filepath); continue; } // Move the file from the old path to the new path. if(file_move($file->filename, $tempfile->filepath)) { // Initialize the node variable. $node = NULL; // Set the node title $node->title = basename($file->filename); // Set the node type. $node->type = flashvideo_variable_get(NULL, 'flashvideo_importtype', 'page'); // Set the status, promote, and sticky booleans. $node->status = 0; $node->promote = 0; $node->sticky = 0; // Create our node to hold the file. node_save($node); // Get the video dimensions. $size = flashvideo_get_size($node->type, $tempfile); // Insert the temporary file into the files database. db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES (%d, '%s', '%s', '%s', %d, %d, %d)", 1, basename($tempfile->filepath), $tempfile->filepath, $filemime, filesize(getcwd() . '/' . $tempfile->filepath), FILE_STATUS_TEMPORARY, time()); // Get the file ID from this insertion. $tempfile->fid = db_last_insert_id('files', 'fid'); // Insert the new file into the upload and flashvideo database tables. db_query("INSERT INTO {upload} (fid, nid, vid, description, list) VALUES (%d, %d, %d, '%s', %d)", $tempfile->fid, $node->nid, $node->nid, '', flashvideo_variable_get($node->type, 'attachment', 0)); db_query("INSERT INTO {flashvideo} (fid, nid, oid, status, video_index, width, height, flags) VALUES (%d, %d, %d, %d, %d, %d, %d, %d)", $tempfile->fid, $node->nid, $tempfile->fid, FLASHVIDEO_STATUS_OK, 0, $size['width'], $size['height'], 0); // Set the files status to permanent. file_set_status($tempfile, FILE_STATUS_PERMANENT); } } } } } /** * Returns the width and height of the given video in pixels. * * @param $node * A standard Drupal node object. * * @param $file * A standard Drupal file object * * @return * An array consisting of the width and height fo the video specified by the file path given. */ function flashvideo_get_size($node, $file = NULL) { // If the file is valid, and they wish to use FFMPEG-PHP to get the dimensions... if($file && flashvideo_variable_get(NULL, 'flashvideo_ffmpegphp', 0)) { // Set up the extension of the FFMPEG-PHP library. $extension = "ffmpeg"; // Get the *.so name of FFMPEG-PHP library. $extension_soname = $extension . "." . PHP_SHLIB_SUFFIX; // Get the full name for the FFMPEG-PHP library. $extension_fullname = PHP_EXTENSION_DIR . "/" . $extension_soname; // Check to see if the extension is loaded. if (!extension_loaded($extension)) { // If not, then load the extension. dl($extension_soname); // Set the CWD filepath of the file to be tested. $filepath = getcwd() . '/' . $file->filepath; // Create the FFMPEG-PHP movie object. $movie = new ffmpeg_movie($filepath); } } // If the file exists and the FFMPEG-PHP movie object exists... if($file && isset($movie)) { // Get the width and height from the $movie object. $width = $movie->getFrameWidth(); $height = $movie->getFrameHeight(); } else { // Otherwise, just extract the width and height from the user variable. $size = explode('x', strtolower(flashvideo_variable_get($node->type, 'size', '450x337'))); $width = trim($size[0]); $height = trim($size[1]); } // Return the width and height of the video. return array('width' => $width, 'height' => $height); } /** * Link into the operations of the upload module for file insertion and deletion. * * @param $node * A standard Drupal node object. */ function _flashvideo_update_files($node) { // Set the video index to zero. $video_index = 0; // Make sure that they uploaded some files. if(isset($node->files) && count($node->files)) { // Iterate through all of the files. foreach ($node->files as $file) { // Convert the file to a file object. $file = (object)$file; // If they wanted to remove the file from the node. if (!empty($file->remove)) { // Find the files referenced by this file being removed. $files = db_query("SELECT * FROM {flashvideo} fv LEFT JOIN {files} f ON f.fid=fv.fid WHERE fv.oid = %d", $file->fid); // Delete the file from the flashvideo database. db_query("DELETE FROM {ffmpeg_data} WHERE fid = %d", $file->fid); db_query("DELETE FROM {flashvideo} WHERE oid = %d", $file->fid); // Iterate through all the files removed from the node. while($oldfile = db_fetch_object($files)) { // Delete that file from the files and upload database as well as from the file system. db_query("DELETE FROM {files} WHERE fid = %d", $oldfile->fid); db_query("DELETE FROM {upload} WHERE fid = %d", $oldfile->fid); file_delete($oldfile->filepath); module_invoke_all('flashvideo_delete_file', $oldfile); } } else { // Is this file already part of the flashvideo database table? $found = db_result(db_query("SELECT count(*) FROM {flashvideo} WHERE fid=%d", $file->fid)); // Only continue if it is a video if(_flashvideo_get_mime_type($file->filepath) !== FALSE) { // Only add if the file is a video and is not already in our flashvideo table. if(!$found) { // Get the size of the video. Width and Height. $size = flashvideo_get_size($node, $file); // Set the list variable dependant on if we wish our video to show up in the files list or not... db_query("UPDATE {upload} SET list=%d WHERE fid=%d", flashvideo_variable_get($node->type, 'attachment', 0), $file->fid); // Now insert our flashvideo into our database. db_query("INSERT INTO {flashvideo} (fid, nid, oid, status, video_index, width, height, flags) VALUES (%d, %d, %d, %d, %d, %d, %d, %d)", $file->fid, $node->nid, $file->fid, FLASHVIDEO_STATUS_OK, $video_index, $size['width'], $size['height'], 0); // If we don't want to wait for cron, call it immediately. if (flashvideo_variable_get($node->type, 'convert', 0)) { flashvideo_cron(); } } // Increment the video index. $video_index++; } } } } } /** * This function will search for a filepath, trying several commons paths. * * @param $filepath * The filepath to use to find the REAL filepath. * * @param $node_type * The node type. * * @return * A string of the REAL filepath of the file... FALSE if it can't find the file. */ function _flashvideo_get_filepath($filepath, $node_type) { // Does the file exist? if( !file_exists(getcwd() . '/' . $filepath) ) { // Try another path... $filepath = file_create_path($filepath); // Does this file exist? if( !file_exists(getcwd() . '/' . $filepath) ) { // Get the base filename. $filename = basename($filepath); // Get the output directory. $output_dir = flashvideo_variable_get($node_type, 'outputdir', ''); $output_dir = ($output_dir == '') ? '' : $output_dir . '/'; // Try another path... $filepath = file_create_path($output_dir . $filename); // Does this file exist? if( !file_exists(getcwd() . '/' . $filepath) ) { // Set the filepath to FALSE. $filepath = FALSE; } } } return $filepath; } /** * Given a node variable, and index, this will return a video thumbnail. * * @param stdObject $node * A standard Drupal node object. * * @param array $params * An array of optional parameters: * index => Integer video index * node => stdObject video node * fids => String of File ID's to play in the format '34-21-35' * file => The file name of the file you wish to show. Path is relative to the system files Directory. * autostart => String 'true' or 'false' to automatically play the video * width => Integer video width in pixels * height => Integer video height in pixels * id => String YouTube or Google Video ID * * @param boolean $file_only * Determine the type of output returned (see below). * * @return String * If $file_only is TRUE, return path to thumbnail file. * If $file_only is FALSE, return HTML code. */ function flashvideo_get_thumbnail($node, $params = array(), $file_only = false) { global $base_url; // Set our Video Index $index = isset($params['index']) ? $params['index'] : 0; // Set our Video Node $nid = (isset($params['node']) && $params['node'] != 0) ? $params['node'] : $node->nid; // Set the File ID's $fids = (isset($params['fids'])) ? $params['fids'] : ''; // Set the File Path. $filepath = (isset($params['file'])) ? $params['file'] : ''; $thumbnail_width = (isset($params['thumbnail_width']) && $params['thumbnail_width'] > 0) ? $params['thumbnail_width'] : ''; $thumbnail_height = (isset($params['thumbnail_height']) && $params['thumbnail_height'] > 0) ? $params['thumbnail_height'] : ''; $url = ''; $image = ''; // Get the node type. $node_type = ($node->type) ? $node->type : db_result(db_query("SELECT type FROM {node} WHERE (nid = %d)", $nid)); // Do they want their thumbnail to be a link? $thumb_link = flashvideo_variable_get($node_type, 'thumblink', 'yes'); $thumb_file = new stdClass(); // If they provided an ID, then we will just need to show the third party thumbnail. if(isset($params['id']) && $params['id'] != '') { // They provided an ID, which means they just want to show a Google or YouTube Video. switch(_flashvideo_get_filetype()) { // A YouTube thumbnail case 'youtube': $url = 'http://img.youtube.com/vi/'. $params['id'] .'/2.jpg'; break; case 'google': break; default: break; } } // If they provided the filepath else if($filepath != '') { // Get the file path and check to make sure it exists. if($filepath = _flashvideo_get_filepath($filepath, $node_type)) { // If so, then set our filepath and break out. $url = check_url(file_create_url($filepath)); } } // If they provided some File ID's to reference the video with. else if($fids != '') { // Extract all the File ID's into an array of ID's. $fids = explode("-", $fids); // Trim all the elements array_walk($fids, create_function('&$n', '$n = trim($n);')); // If they provided only one File ID if(count($fids) == 1) { // Find the thumbnail associated with this file ID. $thumb_file = db_fetch_object(db_query("SELECT filepath,fid FROM {files} WHERE (fid = %d) AND (filemime='jpg')", $fids)); } } else { // They didn't provide any File Name or File ID's. We will use the node, and index to find their video. $thumb_file = db_fetch_object(db_query("SELECT f.filepath,f.fid FROM {flashvideo} fv LEFT JOIN {files} f ON f.fid = fv.fid WHERE (fv.nid = %d) AND (f.filemime='jpg') AND (fv.video_index=%d)", $nid, $index)); } if($thumb_file->filepath) { // Give other modules a chance to overwrite this file... if( !($url = module_invoke_all('flashvideo_get_file', $thumb_file)) ) { $url = check_url(file_create_url($thumb_file->filepath)); } else { $url = $url['file']; } } // Grab the thumbnail from the theme $image = theme('flashvideo_thumbnail', ($thumb_link == 'yes'), $url, $nid, $thumbnail_width, $thumbnail_height ); // Return the thumbnail. if($file_only) { return $url; } else { return $image; } } /* * This will return all accepted mime types for a flash video. * * @return * An array of all accepted mime types. */ function flashvideo_get_mimetypes() { // Get the mime types string. $mimestring = flashvideo_variable_get(NULL, 'flashvideo_mimetypes', FLASHVIDEO_MIMETYPE_STRING); // Split the mimetype phrase into an array. return preg_split("/[\s,]+/", $mimestring); } /* * Given a mime type, this will let you know if the file is a flash file or not. * * @param $filemime * A string of the mime type to check for validity. * * @return * TRUE - The given mimetype is valid. * FALSE - The given mimetype is not valid. */ function flashvideo_is_flash($filemime) { // Get the mimetypes $mimetypes = flashvideo_get_mimetypes(); // If they specified any mimetypes. if(count($mimetypes)) { // Iterate through each of the mimetypes. foreach($mimetypes as $mimetype) { // If the passed mimetype matches the given mimetype. if($filemime == $mimetype) { return TRUE; } } } return FALSE; } /* * This will return the SQL query to determine if the file is a Flash Video. * * @return * SQL chunk query to test for all allowed flash mimetypes. */ function flashvideo_get_flash_query() { // Get the mimetypes. $mimetypes = flashvideo_get_mimetypes(); $index = 0; $query = ""; // If they specified any mimetypes. if(count($mimetypes)) { // Start off the query. $query .= "("; // Iterate through all of the mimetypes. foreach($mimetypes as $mimetype) { // Add an OR statement only if this is not the first one. $query .= ($index > 0) ? "OR " : ""; // Add the SQL mimetype check. $query .= "(f.filemime='{$mimetype}') "; // Increment our index counter. $index++; } // Close off our query. $query .= ")"; } return $query; } /* * Given a node and some parameters, this will return a video object. * * @param stdObject $node * A node object. * * @param array $params * An array of optional parameters: * index => Integer video index * node => stdObject video node * fids => String of File ID's to play in the format '34-21-35' * file => The file name of the file you wish to show. Path is relative to the system files Directory. * autostart => String 'true' or 'false' to automatically play the video * width => Integer video width in pixels * height => Integer video height in pixels * id => String YouTube or Google Video ID * * @param boolean $file_only * Determine the type of output returned (see below). * * @return String * If $file_only is TRUE, return path to video file. * If $file_only is FALSE, return HTML code. * */ function flashvideo_get_video($node, $params = array(), $file_only = false) { global $base_url; // Set our Video Index $index = isset($params['index']) ? $params['index'] : 0; // Set out node ID. $nid = (isset($params['node']) && $params['node']) ? $params['node'] : $node->nid; // Set the File ID's $fids = isset($params['fids']) ? $params['fids'] : ''; // Set the File Path. $filepath = (isset($params['file'])) ? $params['file'] : ''; // Get the flash mime type query. $flashmime = flashvideo_get_flash_query(); $video = array(); $video['node_type'] = ($node->type) ? $node->type : db_result(db_query("SELECT type FROM {node} WHERE (nid = %d)", $nid)); $video['autostart'] = (isset($params['autostart'])) ? $params['autostart'] : flashvideo_variable_get($video['node_type'], 'autostart', 'true'); $video['width'] = (isset($params['width']) && $params['width'] > 0) ? $params['width'] : ''; $video['height'] = (isset($params['height']) && $params['height'] > 0) ? $params['height'] : ''; $video['flashvars'] = $params['flashvars']; $video_file = NULL; // If they want an intro or outro video. $intro_video = flashvideo_variable_get($video['node_type'], 'intro', ''); $outro_video = flashvideo_variable_get($video['node_type'], 'outro', ''); // If they provided an ID. if(isset($params['id']) && $params['id'] != '') { // Set the filepath to the Parameters ID. $video['file'] = $params['id']; } // If they wan't to show all the videos in the node in a playlist fashion... they can say "fids=node"... else if($fids == 'node') { // Set up the fids to be an array. $fids = array(); // Select all File ID's from that node. $result = db_query("SELECT f.fid FROM {flashvideo} fv LEFT JOIN {files} f ON f.fid = fv.fid WHERE {$flashmime} AND (fv.status=%d) AND (f.nid=%d)", FLASHVIDEO_STATUS_CONVERTED, $nid); // Iterate through all of the files and set up the fids array. while($fid = db_fetch_object($result)) { $fids[] = $fid->fid; } } // If they provided some fids. else if($fids != '') { // Set up the file ID array based off the fids string. $fids = (strpos($fids, "-") === FALSE) ? $fids : explode("-", $fids); // If they only provided one File ID. if(count($fids) == 1) { // Find the video file from this one file ID. $video_file = db_fetch_object(db_query("SELECT fv.oid, f.filepath, fv.width, fv.height, f.fid FROM {flashvideo} fv LEFT JOIN {files} f ON f.fid = fv.fid WHERE {$flashmime} AND (fv.status=%d) AND (f.fid = %d)", FLASHVIDEO_STATUS_CONVERTED, $fids)); } } // If they provided the filepath to the video. else if($filepath != '') { // Get the file extension. $extension = _flashvideo_get_filetype($filepath); // See if the filepath exists. $filepath = _flashvideo_get_filepath($filepath, $video['node_type']); // Only continue if they specify an FLV file. if($filepath && $extension == 'flv') { // Find the video file in the flashvideo database table. $video_file = db_fetch_object(db_query("SELECT fv.oid, f.filepath, fv.width, fv.height, f.fid FROM {flashvideo} fv LEFT JOIN {files} f ON f.fid = fv.fid WHERE {$flashmime} AND (fv.status=%d) AND (f.filepath='%s')", FLASHVIDEO_STATUS_CONVERTED, $filepath)); if(!$video_file) { // Fail safe... look for any video. $video_file->filepath = $filepath; } } } // Default case... they provided the node ID and the video index. else { // They didn't provide any File ID's. We will use the node, and index to find their video. $video_file = db_fetch_object(db_query("SELECT fv.oid, f.filepath, fv.width, fv.height, f.fid FROM {flashvideo} fv LEFT JOIN {files} f ON f.fid = fv.fid WHERE {$flashmime} AND (fv.status=%d) AND (fv.nid = %d) AND (fv.video_index=%d)", FLASHVIDEO_STATUS_CONVERTED, $nid, $index)); } // Assign a variable to reference the original video. if(flashvideo_variable_get($video['node_type'], 'downloadfile', 0)) { $video['original_video'] = db_result(db_query("SELECT f.filepath FROM {flashvideo} fv LEFT JOIN {files} f ON f.fid=fv.fid WHERE (f.fid=%d)", $video_file->oid)); } // If no video file was defined... if(!isset($video['file'])) { // Do we need to use the playlist? if( ($intro_video || $outro_video || count($fids) > 1) ) { // Set up our video['file'] $video['file'] = $base_url . '/index.php?q=getplaylist/'; // Get our arguments. $fids = (isset($video_file->fid) && $video_file->fid) ? $video_file->fid : $fids; // If there are some $fids, continue. if($fids) { // Are the fids provided in an array. if(is_array($fids)) { // Trim all the elements. array_walk($fids, create_function('&$n', '$n = trim($n);')); // Append the arguments as a string to the video file playlist path. $video['file'] .= implode("-", $fids); } else { // Trim the fid. $fids = trim($fids); // Set up our arguments. $video['file'] .= $fids; } } } // If a video path was provided. else if(isset($video_file->filepath)) { // Give other modules a chance to override this path... if( !($temp_video = module_invoke_all('flashvideo_get_file', $video_file)) ) { // Set up our video['file'] variable. $video['file'] = check_url(file_create_url($video_file->filepath)); } else { $video['file'] = $temp_video['file']; $video['override'] = true; } } } // If they haven't already provided width and height. if( !($video['width'] && $video['height']) ) { // If the width and height were provided by the $video_file. if(isset($video_file->width) && isset($video_file->height)) { // Set our video['width'] and video['height'] $video['width'] = $video_file->width; $video['height'] = $video_file->height; } // We will just want to use the defaults if none was provided. else { $node->type = $video['node_type']; $size = flashvideo_get_size($node); $video['width'] = $size['width']; $video['height'] = $size['height']; } } // If a video file is defined, return the video object. if(isset($video['file'])) { return ($file_only ? $video['file'] : flashvideo_play($video)); } else { $url = base_path() . drupal_get_path('module', 'flashvideo') . '/video_MIA.png'; return ($file_only ? $url : 'video unavailable'); } } /** * Parses all of the tags, and places them in a parameters array. * * @param $body * The string of the body of the node. * * @param $pos * A reference to the current location of the character pointer in the node body. * * @param $max_params * The maximum amount of allowed parameters. * * @return * An array of the parameters with their associated values. */ function _flashvideo_parse_params($body, &$pos, $max_params = 10) { // If we are able to find the end tag delimiter denoted by "]" if(($endpos = strpos($body, ']', $pos)) !== FALSE) { // Set up an array of charachters to take out from the parameter string. $bad_chars = array("

", "

", "
", "
", "\n", "\r", "\t", " "); // Get our parameter string. $param_string = substr($body, $pos, ($endpos - $pos)); // Replace all bad characters with null chars. $param_string = str_replace($bad_chars, '', $param_string); // Create an array with all parameters. $parts = explode(':', $param_string); // Set the position to the end position. $pos = $endpos + 1; // Remove the first index (it's not a parameter). unset($parts[0]); $parts = array_values($parts); // If there are parameters provided, and they don't exceed the maximum... if((count($parts) > 0) && (count($parts) < $max_params)) { $params = array(); // Loop through all of our parameters. foreach($parts as $part) { // Get the value and parameter for this part. $sub_parts = explode('=', $part); // The parameter needs to be all lower case. $sub_parts[0] = strtolower($sub_parts[0]); // If they actually provided a "param=value" if((strlen($sub_parts[0]) > 0) && (strlen($sub_parts[1]) > 0)) { // Check to see if this is a FlashVar. if(strpos($sub_parts[0], 'flashvar') !== FALSE) { // If so, then split up this parameter based on the "|" $flashvar = explode('|', $sub_parts[0]); // Set the "flashvar" parameter. $params['flashvars'][$flashvar[1]] = $sub_parts[1]; } else { // Set this parameter. $params[$sub_parts[0]] = $sub_parts[1]; } } } // Return the parameters array. return $params; } } // Return no parameters. return array(); } /** * Search and Replace routine. Scans the body of a node and replaces every tag and its parameters with an object. * * @param $node * The node which is being searched * * @param $tag * The tag to search for. * */ function _flashvideo_replace_tags(&$node, $tag) { // The maximum number of parameters allowed. All others will be ignored. $max_num_params = 4; // Set the body to be modified. $body = (isset($node->teaser) && $node->body == '') ? $node->teaser : $node->body; // Search for tags for($pos = 0; (($pos = $startpos = strpos($body, $tag, $pos)) !== FALSE); $pos++) { // We need to check to see if this tag has "!" in front of it, if it does, then we will ignore this tag. if(substr($body, $pos - 1, 1) == '!') { // Replace the body with this with a normal "[video]" or "[thumbnail]" $body = substr_replace($body, $tag, $pos - 1, strlen($tag) + 1); } // This is the real thing... else { // So that it will skip over the "[" $pos++; // Initialize our parameters array. $params = array(); // Parse all the parameters. $params = _flashvideo_parse_params($body, $pos); // Set the object based on the parameters given. $object = ($tag == '[thumbnail') ? flashvideo_get_thumbnail($node, $params) : flashvideo_get_video($node, $params); // Replace this tag with the real object code. $body = substr_replace($body, $object, $startpos, ($pos - $startpos)); // Replace this tag. } // If the position exceeds the body length, then break out of the loop. if($pos >= strlen($body)) break; } // Set the teaser or the body dependant on which one is being shown... if((isset($node->teaser) && $node->body == '')) $node->teaser = $body; else $node->body = $body; } /** * Implementation of hook_nodeapi() */ function flashvideo_nodeapi(&$node, $op, $teaser) { // Only if the node type is enabled. if(flashvideo_variable_get($node->type, 'enable', 0)) { switch ($op) { case 'insert': case 'update': _flashvideo_update_files($node); break; case 'submit': module_invoke_all('flashvideo_submit', $node, flashvideo_get_convert_params($node->type)); break; case 'load': // Get the play counter and increment it... $results = db_fetch_object(db_query("SELECT play_counter FROM {flashvideo} WHERE nid = %d", $node->nid)); if($results) { $node->play_counter = $results->play_counter; } break; // Here we will do a search and replace for anyone who is using the video and thumbnail tags. case 'alter': if(!$teaser) { db_query("UPDATE {flashvideo} SET play_counter = play_counter + 1 WHERE nid = %d", $node->nid); //Increment play counter. } if( (!flashvideo_variable_get($node->type, 'disabletag', 0)) && (!$teaser || flashvideo_variable_get($node->type, 'searchvideo', 0) ) ) _flashvideo_replace_tags($node, '[video'); if( (!flashvideo_variable_get($node->type, 'disabletag', 0)) && ($teaser || flashvideo_variable_get($node->type, 'searchthumb', 0) ) ) _flashvideo_replace_tags($node, '[thumbnail'); break; case 'rss item': // Get the flash mime query. $flashmime = flashvideo_get_flash_query(); // Find the filepath of the first video uploaded to this node. $filepath = db_result(db_query("SELECT f.filepath FROM {flashvideo} fv LEFT JOIN {files} f ON f.fid = fv.fid WHERE (fv.nid = %d) AND {$flashmime} AND (fv.status = %d) AND (fv.video_index = 0)", $node->nid, FLASHVIDEO_STATUS_CONVERTED)); // Set the URL attributes. $attributes['url'] = check_url(file_create_url($filepath)); // Get the filesize and set that in the attributes. $attributes['length'] = filesize(getcwd() . '/' . $filepath); // Get the mime type of this video. $mime_type = _flashvideo_get_mime_type($filepath); // If the mime type was found, then set the attributes. if ($mime_type) { $attributes['type'] = $mime_type; } // Set the URL for the media object. $media['url'] = $attributes['url']; // Set the filesize for the media object. $media['fileSize'] = $attributes['length']; // Set the mime type for the media attribute. $media['type'] = $attributes['type']; // Return an array of what to contribute to this RSS feed. return array(array('key' => 'enclosure', 'attributes' => $attributes), array('key' => 'media', 'value' => '', 'attributes' => $media)); case 'delete': case 'delete revision': // Delete all entries from the flashvideo table. db_query("DELETE FROM {flashvideo} WHERE nid = %d", $node->nid); // If this node had files... if(count($node->files)){ // Iterate through each file and delete them from the ffmpeg_data table. foreach ($node->files as $file) { $file = (object)$file; db_query("DELETE FROM {ffmpeg_data} WHERE fid = %d", $file->fid); module_invoke_all('flashvideo_delete_file', $file); } } break; } } } /** * Generates the HTML for any object parameters in an embedded video. * * @param $video the node which is being played * * @return * string with the parameters in HTML form. */ function _flashvideo_get_parameters(&$video) { // call hook_v_get_params $param_value = module_invoke_all('v_get_params', $video); $output = ''; foreach ($param_value as $param => $value) { $output .= ''; } return $output; } ?>