Working with Media Mover

Submitted by robin on October 21, 2007 - 10:54pm.

Are you interested in Media Mover? It is a new framework available for your file processing pleasure. Developed by Arthur Foelesche, Media Mover allows site administrators to manage and process media files like images, video, and audio. Media Mover provides an API, so developers can easily write modules which hook into the Media Mover system.

I recently finished the Exif Removal Media Mover Module (mm_exif). This module uses Media Mover hooks to remove Exif data from jpeg files. Learning to work with a new API always takes time, so here are some steps to consider when you start working with the Media Mover API.

The Goal: create a new module which uses Media Mover's API to provide extra processing of media files.

  • Read the Media Mover project page.
  • Read the media_mover README (in Media Mover's tar.gz).
  • Figure out your configuration.
  • For example, the Exif removal module only processes the files. I was able to take advantage of existing harvests like "Media Mover node module: Select drupal uploaded files". This harvest configuration lists available content types, and you can choose which content types whose uploaded files you want to process. The Exif removal module needed to overwrite the existing files, so there was no need to setup 'storage' and 'complete' configurations.

  • Check other modules.
    When you install Media Mover, it comes with some of its own modules which rely on the Media Mover API. Check other modules which are similar to what you want your module to do. For example, mm_ffmpeg is also a process-only configuration. Reviewing it helped a lot.

  • Start creating a new module.
    In your .module file, use hook_media_mover(): mm_exif_media_mover()

    You really need cases for 'name', 'process', 'actions', and 'admin' in the switch statement in hook_media_mover().

    Name is easy enough, it is a short name of your module:

  •     case 'name':
          return "EXIF module";
          break;

  • By creating the 'process' array in case 'actions', then you use a switch in case 'process' to inform Media Mover of which functions to call.

    For example, '1' represents the action to remove Exif data in the 'process' array:

  •     case 'actions':
          return array(
            'process' => array( 1 => t('Find and remove EXIF data')),
          );
          break;

  • Now in case 'process', case '1' specifies (and yes, $action_id is a string) what function to call in the Exif module which actually removes Exif data:
  •     case 'process':
          switch($action_id) {
          case '1': 
              return _mm_exif_remove($file,$configuration);
            break;

  • Write the process functions.
    Pass the $file array to your process functions (it is the file that you want to process). $configuration gives you access to the configuration-specific settings which you may use to change how the file is processed.

    If your processing takes you to the command line, be sure to watchdog() the results. You will want to track any unexpected behavior (especially since Media Mover usually relies on cron to do its job).

  • Make sure your process functions return an array representing the file.

I found it useful to create an 'admin' case. For mm_exif, it provides a default path to the executable (jhead), but an administrator can change this path via Media Mover settings (admin/media_mover/settings).

In addition, you can allow the administrator to setup configuration-specific settings. In that case, add case 'config' to your hook_media_mover(). For an example, check out mm_ffmpeg.

When testing, make sure your test configuration (which you create through the Media Mover GUI), actually harvests files; otherwise it will not run your new module. This may seem obvious, but I just wanted to get to my code and sort of ignored how to properly define a configuration in the first place...darn laziness.

Have fun!