[ Index ]

PHP Cross Reference of Drupal 6 (gatewave)

title

Body

[close]

/sites/all/modules/audio/getid3/ -> audio_getid3.module (source)

   1  <?php
   2  // $Id: audio_getid3.module,v 1.9 2008/10/02 18:03:44 drewish Exp $
   3  
   4  include_once drupal_get_path('module', 'audio') .'/audio_image.inc';
   5  
   6  /**
   7   * Implementation of hook_nodeapi().
   8   */
   9  function audio_getid3_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
  10    if ($node->type == 'audio') {
  11      if ($op == 'insert' || $op == 'update') {
  12        // update the metadata in the file
  13        _audio_getid3_save_to_file($node);
  14      }
  15    }
  16  }
  17  
  18  /**
  19   * Implements the audio module's hook_audio()
  20   */
  21  function audio_getid3_audio($op, &$node) {
  22    switch ($op) {
  23      case 'upload':
  24        if ($info = audio_read_id3tags($node->audio['file']->filepath, TRUE)) {
  25          $node->audio_tags = $info['tags'];
  26          $node->audio_images = $info['images'];
  27          // use array_merge so that the play count and downloadable settings aren't
  28          // overwritten.
  29          $node->audio = array_merge($node->audio, $info['fileinfo']);
  30        }
  31        break;
  32    }
  33  }
  34  
  35  /**
  36   * Edit the audio node form and insert our file info stuff.
  37   */
  38  function audio_getid3_form_alter(&$form, &$form_state, $form_id) {
  39    // We only alter audio node edit forms with a file attached.
  40    if ($form_id == 'audio_node_form' && !empty($form['#node']->audio['file']->filepath)) {
  41      $form['#submit'][] = 'audio_getid3_node_submit';
  42      $form['audio']['#description'] = t('This file information was loaded from the file by the getID3 library.');
  43  
  44      // Refresh the meta data everytime they display the edit form.
  45      $info = audio_read_id3tags($form['#node']->audio['file']->filepath, FALSE);
  46  
  47      // Overwrite the default audio module fields with a hidden value so that
  48      // so there's something POSTed back for the preview.
  49      $fields = array('format', 'file_size', 'playtime', 'sample_rate', 'channel_mode', 'bitrate', 'bitrate_mode');
  50      foreach ($fields as $key) {
  51        $form['audio'][$key] = array(
  52          '#type' => 'hidden',
  53          '#default_value' => isset($info['fileinfo'][$key]) ? $info['fileinfo'][$key] : '',
  54        );
  55      }
  56  
  57      $form['audio']['display_format'] = array(
  58        '#type' => 'item',
  59        '#title' => t('Format'),
  60        '#value' => $info['fileinfo']['format'],
  61      );
  62      $form['audio']['display_file_size'] = array(
  63        '#type' => 'item',
  64        '#title' => t('File Size'),
  65        '#value' => t('@filesize bytes', array('@filesize' => number_format($info['fileinfo']['file_size']))),
  66      );
  67      $form['audio']['display_playtime'] = array(
  68        '#type' => 'item',
  69        '#title' => t('Length'),
  70        '#value' => $info['fileinfo']['playtime'],
  71      );
  72      $form['audio']['display_sample_rate'] = array(
  73        '#type' => 'item',
  74        '#title' => t('Sample rate'),
  75        '#value' => t('@samplerate Hz', array('@samplerate' => number_format($info['fileinfo']['sample_rate']))),
  76      );
  77      $form['audio']['display_channel_mode'] = array(
  78        '#type' => 'item',
  79        '#title' => t('Channel mode'),
  80        '#value' => ucfirst($info['fileinfo']['channel_mode']),
  81      );
  82      $form['audio']['display_bitrate'] = array(
  83        '#type' => 'item',
  84        '#title' => t('Bitrate'),
  85        '#value' => t('@bitrate bytes/second', array('@bitrate' => number_format($info['fileinfo']['bitrate']))),
  86      );
  87      $form['audio']['display_bitrate_mode'] = array(
  88        '#type' => 'item',
  89        '#title' => t('Bitrate mode'),
  90        '#value' => strtoupper($info['fileinfo']['bitrate_mode']),
  91      );
  92  
  93      // Check that the audio is compatible with Flash (MP3 with sample rate of
  94      // 11, 22, or 44 kHz). Display a warning if it is not.
  95      switch ($info['fileinfo']['sample_rate']) {
  96        case '44100': case '22050': case '11025':
  97          if ($info['fileinfo']['format'] == 'mp3') {
  98            break;
  99          }
 100        default:
 101          drupal_set_message(t('This file is not compatible with the Flash audio player. Flash can only play MP3 files with a sample rate of 11, 22 or 44KHz.'), 'status');
 102      }
 103    }
 104  }
 105  
 106  function audio_getid3_node_submit($form, &$form_state) {
 107  
 108  }
 109  
 110  /**
 111   * Build a getID3 object.
 112   *
 113   * @return
 114   *   a getID3 object.
 115   */
 116  function _audio_getid3_load() {
 117    if (!getid3_load(TRUE)) {
 118      return NULL;
 119    }
 120  
 121    $getid3 = new getID3;
 122    $getid3->encoding         = 'UTF-8';
 123    $getid3->encoding_id3v1   = 'ISO-8859-1';
 124    $getid3->option_tags_html = FALSE;
 125  
 126    return $getid3;
 127  }
 128  
 129  /**
 130   * Uses getID3 to get information about an audio file...
 131   *
 132   * @param $filepath
 133   *   string full path to audio file to examine
 134   * @param $load_pics
 135   *   boolean indicating if embedded images should be saved to temp files and
 136   *   returned in a sub array 'images'.
 137   * @return
 138   *   array with two sub arrays keyed to 'tags' and 'fileinfo', or FALSE if
 139   *   there's an error.
 140   */
 141  function audio_read_id3tags($filepath, $load_pics = FALSE) {
 142    $getid3 = _audio_getid3_load();
 143    if (!$getid3) {
 144      // getid3 isn't setup correctly. an error should have already been printed
 145      // so just return.
 146      return FALSE;
 147    }
 148  
 149    // Analyze file
 150    $info = $getid3->analyze($filepath);
 151  
 152    // copy out the basic file info
 153    $ret = array(
 154      'tags' => array(),
 155      'images' => array(),
 156      'fileinfo' => array(
 157        'format'  => $info['fileformat'],
 158        'file_size'    => $info['filesize'],
 159        'filemime'     => $info['mime_type'],
 160        'playtime'     => $info['playtime_string'],
 161        'bitrate'      => $info['audio']['bitrate'],
 162        'bitrate_mode' => $info['audio']['bitrate_mode'],
 163        'channel_mode' => $info['audio']['channelmode'],
 164        'sample_rate'  => $info['audio']['sample_rate'],
 165      ),
 166    );
 167  
 168    // First read in the id3v1 tags then overwrite them with the v2 tags.
 169    foreach (array('id3v1', 'id3v2') as $format) {
 170      if (isset($info['tags'][$format])) {
 171        foreach ((array) $info['tags'][$format] as $key => $value ) {
 172          $ret['tags'][$key] = trim(array_pop($value));
 173        }
 174      }
 175    }
 176  
 177    // copy the images
 178    if ($load_pics) {
 179      // check both flavors id3v2 image tags
 180      foreach (array('PIC', 'APIC') as $type) {
 181        if (isset($info['id3v2'][$type])) {
 182          foreach ((array)$info['id3v2'][$type] as $image) {
 183            // Save it to a temp file
 184            $file = audio_image_save_data(basename($filepath), $image['data'], $image['image_mime'], $image['picturetypeid']);
 185            $ret['images'][$file->pictype .'-'. $file->fid] = $file;
 186          }
 187        }
 188      }
 189    }
 190  
 191    // warnings
 192    if (!empty($info['warning']) && variable_get('audio_getid3_show_warnings', FALSE)) {
 193      $warning = t('While reading the ID3 tags, the following warnings were encountered:');
 194      $warning .= '<ul><li>'. implode('</li><li>', $info['warning']) .'</li></ul>';
 195      drupal_set_message($warning, 'error');
 196    }
 197    // report errors and then exit
 198    if (isset($info['error'])) {
 199      $error = t("The following errors where encountered while reading the file's ID3 tags: ");
 200      $error .= '<ul><li>'. implode('</li><li>', $info['error']) .'</li></ul>';
 201      form_set_error('', $error);
 202    }
 203  
 204    return $ret;
 205  }
 206  
 207  /**
 208   * Uses the getID3 library to write updated ID3 tag information back to the
 209   * actual audio file. This function will write over any exisitng ID3 tag
 210   * information contained in the file, and this function does not make a copy of
 211   * this information anywhere...
 212   * @param $filepath
 213   *   Path to the audio file where the tags should be written.
 214   * @param $tags
 215   *   Array of metadata tags to write.
 216   * @param $images
 217   *   Array of image objects from the audio_images.module.
 218   * @param $tagformats
 219   *   Array of the names of tag formats to write.
 220   * @return
 221   *   FALSE on error.
 222   */
 223  function audio_write_id3tags($filepath, $tags, $images = array(), $tagformats = array('id3v1', 'id3v2.3')) {
 224    $getid3 = _audio_getid3_load();
 225    if (!$getid3) {
 226      // getid3 isn't setup correctly. an error should have already been printed
 227      // so just return.
 228      return FALSE;
 229    }
 230  
 231    $tagwriter = new getid3_writetags;
 232    $tagwriter->filename          = $filepath;
 233    $tagwriter->tagformats        = $tagformats;
 234    $tagwriter->tag_encoding      = 'UTF-8';
 235    $tagwriter->overwrite_tags    = TRUE;
 236    $tagwriter->remove_other_tags = TRUE;
 237  
 238    // to prevent annoying warning/errors, add in empty id3v1 tags. see
 239    // http://drupal.org/node/56589 or http://drupal.org/node/84029 for details.
 240    $tagwriter->tag_data = array(
 241      'title' => array(),
 242      'artist' => array(),
 243      'album' => array(),
 244      'track' => array(),
 245      'genre' => array(),
 246      'year' => array(),
 247      'comment' => array(),
 248    );
 249  
 250    // copy our tag data ...
 251    foreach ($tags as $tag => $value) {
 252      $tagwriter->tag_data[$tag][] = $value;
 253    }
 254  
 255    // ... and images to the writer.
 256    foreach ((array) $images as $image) {
 257      $image = (object) $image;
 258      // Skip images that have/are going to be deleted.
 259      if (empty($image->delete)) {
 260        $tagwriter->tag_data['attached_picture'][] = array(
 261          'data' => file_get_contents($image->filepath),
 262          'picturetypeid' => $image->pictype,
 263          'description' => audio_image_type_dirty_array($image->pictype),
 264          'mime' => $image->filemime,
 265        );
 266      }
 267    }
 268  
 269    $tagwriter->WriteTags();
 270  
 271    // check for and display errors
 272    if (!empty($tagwriter->warnings) && variable_get('audio_getid3_show_warnings', FALSE)) {
 273      $warning = t('While writing the ID3 tags, the following warnings were encountered:');
 274      $warning .= '<ul><li>'. implode('</li><li>', $tagwriter->warnings) .'</li></ul>';
 275      drupal_set_message($warning, 'error');
 276    }
 277    if (!empty($tagwriter->errors)) {
 278      $error = t('The following errors were encountered, preventing the ID3 tags from being saved:');
 279      $error .= '<ul><li>'. implode('</li><li>', $tagwriter->errors) .'</li></ul>';
 280      form_set_error('', $error);
 281      return FALSE;
 282    }
 283  }
 284  
 285  /**
 286   * Save the node's ID3 tags to the file. The tags will be saved and then
 287   * reloaded so that the node reflects the allowed values.
 288   */
 289  function _audio_getid3_save_to_file(&$node) {
 290    $settings = audio_get_tag_settings();
 291  
 292    if (preg_match('/\.ogg$/i', $node->audio['file']->filepath)) {
 293      $tagformats = array('vorbiscomment');
 294    }
 295    else {
 296      $tagformats = array('id3v1', 'id3v2.3');
 297    }
 298  
 299    // Determine which tags should be written to the file.
 300    $tags = array();
 301    if (isset($node->audio_tags)) {
 302      foreach ($node->audio_tags as $tag => $value) {
 303        if (isset($settings[$tag]) && $settings[$tag]['writetofile']) {
 304          $tags[$tag] = $value;
 305        }
 306      }
 307    }
 308  
 309    $images = array();
 310    if (isset($node->audio_images)) {
 311      $images = $node->audio_images;
 312    }
 313  
 314    // If there are any writable tags or image, update the file.
 315    if ($tags || $images) {
 316      audio_write_id3tags($node->audio['file']->filepath, $tags, $images, $tagformats);
 317    }
 318  
 319    // then reload them so that the node is in sync with the file/database...
 320    $info = audio_read_id3tags($node->audio['file']->filepath);
 321    // ...merge so that any non-written tags will be preserved...
 322    $node->audio_tags = array_merge($node->audio_tags, $info['tags']);
 323    // ...merge so that the playcount and downloadable options aren't overwritten.
 324    $node->audio = array_merge($node->audio, $info['fileinfo']);
 325  }


Generated: Thu Mar 24 11:18:33 2011 Cross-referenced by PHPXref 0.7