Index: audio.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/audio/audio.module,v
retrieving revision 1.90
diff -u -r1.90 audio.module
--- audio.module	13 Dec 2006 18:37:29 -0000	1.90
+++ audio.module	14 Dec 2006 05:42:08 -0000
@@ -83,7 +83,12 @@
       'path' => 'admin/settings/audio/metadata', 'title' => t('Metadata tags'),
       'callback' => 'drupal_get_form',
       'callback arguments' => array('audio_admin_settings_metadata'),
-      'type' => MENU_LOCAL_TASK, 'weight' => '-1');
+      'type' => MENU_LOCAL_TASK,);
+    $items[] = array(
+      'path' => 'admin/settings/audio/players', 'title' => t('Players'),
+      'callback' => 'drupal_get_form',
+      'callback arguments' => array('audio_admin_settings_players'),
+      'type' => MENU_LOCAL_TASK,);
 
     $items[] = array(
       'path' => 'audio/autocomplete',
@@ -1039,6 +1044,90 @@
 }
 
 /**
+ * Format the id3tags settings form as a table.
+ */
+function theme_audio_admin_settings_metadata($form) {
+  $rows = array();
+  foreach (element_children($form['audio_tag_settings']) as $key) {
+    $row = array();
+    if (is_array($form['audio_tag_settings'][$key]['name'])) {
+      $row[] = drupal_render($form['audio_tag_settings'][$key]['name']);
+      $row[] = drupal_render($form['audio_tag_settings'][$key]['autocomplete']);
+      $row[] = drupal_render($form['audio_tag_settings'][$key]['required']);
+      $row[] = drupal_render($form['audio_tag_settings'][$key]['hidden']);
+      $row[] = drupal_render($form['audio_tag_settings'][$key]['browsable']);
+      $row[] = drupal_render($form['audio_tag_settings'][$key]['writetofile']);
+      $row[] = drupal_render($form['audio_tag_settings'][$key]['weight']);
+
+      $row[] = drupal_render($form['delete'][$key]);
+    }
+    $rows[] = $row;
+  }
+  $header = array(t('tag'), t('autocomplete'), t('required'), t('hidden'), t('browsable'),
+    t('written to file'), t('weight'), t('delete'));
+
+  $output = theme('table', $header, $rows);
+  $output .= drupal_render($form);
+  return $output;
+}
+
+function audio_admin_settings_players() {
+  $form = array();
+
+  $options = array();
+  foreach (audio_get_players('formats') as $format => $players) {
+    foreach ($players as $id => $player) {
+      $options[$id] = $player['title'];
+      $form['players'][$format][$id]['description'] = array(
+        '#type' => 'item',
+        '#title' => t('Description'),
+        '#value' => $player['description'],
+      );
+      $form['players'][$format][$id]['url'] = array(
+        '#type' => 'item',
+        '#title' => t('URL'),
+        '#value' => $player['url'],
+      );
+      $form['players'][$format][$id]['preview'] = array(
+        '#type' => 'item',
+        '#title' => t('URL'),
+        '#value' => drupal_get_path('module', $player['module']) .'/'. $player['preview'],
+      );
+    }
+    $form['audio_player_'. $format] = array(
+      '#type' => 'radios',
+      '#title' => t('Player'),
+      '#default_value' => variable_get('audio_player_'. $format, 'xspf_button'),
+      '#options' => $options,
+    );
+  }
+  return system_settings_form($form);
+}
+
+function theme_audio_admin_settings_players($form) {
+  $output = '';
+  $header = array(t('Player'), t('Description'), t('Homepage'));
+  foreach (element_children($form['players']) as $format) {
+    $output .= '<h2>'. t('%format files', array('%format' => $format)) .'</h2>';
+    $rows = array();
+    foreach (element_children($form['players'][$format]) as $name) {
+      $rows[] = array(
+        drupal_render($form['audio_player_'. $format][$name])
+          . theme('image', $form['players'][$format][$name]['preview']['#value'], 'preview', 'preview'),
+        check_plain($form['players'][$format][$name]['description']['#value']),
+        l(t('Link'), $form['players'][$format][$name]['url']['#value']),
+      );
+      unset($form['players'][$format][$name]['description']);
+      unset($form['players'][$format][$name]['url']);
+      unset($form['players'][$format][$name]['preview']);
+    }
+    unset($form['audio_player_'. $format]);
+    $output .= theme('table', $header, $rows);
+  }
+  return $output . drupal_render($form);
+}
+
+/**
  * Get an array of the allowed tags.
  *
  * @return
@@ -1164,24 +1253,99 @@
 }
 
 
+function _audio_player_build_list() {
+  // invoke any modules that implement the hook
+  $players_name = module_invoke_all('audio_player');
+
+  // load all our module's player plugins
+  $path = drupal_get_path('module', 'audio') .'/players';
+  $files = drupal_system_listing('.inc$', $path, 'name', 0);
+  foreach ($files as $file) {
+    require_once('./' . $file->filename);
+    $function = 'audio_' . $file->name . '_audio_player';
+    if (function_exists($function)) {
+      $result = $function();
+      if (isset($result) && is_array($result)) {
+        $players_name = array_merge($players_name, $result);
+      }
+    }
+  }
+
+  // group them by format
+  $players_format = array();
+  foreach ($players_name as $name => $player) {
+    foreach ($player['formats'] as $format) {
+      $players_format[$format][$name] = $player;
+    }
+  }
+
+  return array($players_name, $players_format);
+}
+
+function audio_get_players($op = 'names', $name = '') {
+  static $_player_name, $_player_format;
+
+  if (!isset($_players_format)) {
+    list($_player_name, $_player_format) = _audio_player_build_list();
+  }
+
+  switch ($op) {
+    case 'formats':
+      return $_player_format;
+    case 'format':
+      if (isset($_player_format[$name])) {
+        return $_player_format[$name];
+      }
+      return FALSE;
+    case 'names':
+      return $_player_name;
+    case 'name':
+      if (isset($_player_name[$name])) {
+        return $_player_name[$name];
+      }
+      return FALSE;
+    default:
+      return FALSE;
+  }
+}
+
 /**
  * Build HTML to play an audio node.
  *
+ * @param $node
+ *   node object
  * @return
- *   HTML to play the audio track.
+ *   HTML to play the audio tracks.
  */
-function audio_get_player($node) {
+function audio_get_node_player($node) {
+  $output = '';
+
   // if we've got a URL, setup a player
   if (_audio_allow_play($node)) {
-    // try to find one that's type specific...
     $format = $node->audio_fileinfo['fileformat'];
-    if (!$player = theme('audio_'. $format .'_player', $node)) {
+    $playername = variable_get('audio_player_'. $format, 'xspf_button');
+    $player = audio_get_players('name', $playername);
+    // try to use the requested player...
+    $output = theme($player['theme_node'], $node);
+    if (!$output) {
       // ...if that doesn't work out, use the generic one
-      $player = theme('audio_player', $node);
+      $output = theme('audio_default_node_player', $nodes);
     }
-    return $player;
   }
-  return NULL;
+  return $output;
+}
+
+/**
+ * This is the default player... a link!
+ *
+ * @param $node
+ */
+function theme_audio_default_node_player($node) {
+  $output = '<span class="audio">';
+  // we can't use l() because the url is absolute
+  $output .= '<a href="'. check_url($node->url_play) .'">'. t('Click to play') .'</a>';
+  $output .= "</span>\n";
+  return $output;
 }
 
 /**
@@ -1413,3 +1577,44 @@
   }
 }
 
+function audio_is_flash_playable($node) {
+    // flash only supports a limited range of sample rates.
+  switch ($node->audio_fileinfo['sample_rate']) {
+    case '44100': case '22050': case '11025':
+      return TRUE;
+    default:
+      return FALSE;
+  }
+}
+
+/**
+ * Generate a XSPF playlist
+ */
+function audio_xspf_playlist($title, $nodes) {
+  drupal_set_header('Content-Type: text/xml; charset=utf-8');
+  $output = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+  $output .= "<playlist version=\"1\" xmlns=\"http://xspf.org/ns/0/\">\n";
+  $output .= "  <title>" . $title . "</title>\n";
+  $output .= "  <trackList>\n";
+  foreach ($nodes as $n) {
+    $node = node_load($n->nid);
+    $output .= theme('audio_views_xspf_playlist_track', $node);
+  }
+  $output .= "  </trackList>\n";
+  $output .= "</playlist>\n";
+  print $output;
+  exit;
+}
+
+function theme_audio_views_xspf_playlist_track($node) {
+  $output .= "    <track>\n";
+  $output .= "      <annotation>" . check_plain($node->title) . "</annotation>\n";
+  $output .= "      <title>" . check_plain($node->audio_tags['title']) . "</title>\n";
+  $output .= "      <track>" . check_plain($node->audio_tags['track']) . "</track>\n";
+  $output .= "      <album>" . check_plain($node->audio_tags['album']) . "</album>\n";
+  $output .= "      <location>" . check_url($node->url_play) . "</location>\n";
+  $output .= "      <info>" . url("node/$node->nid", NULL, NULL, TRUE) . "</info>\n";
+  $output .= "      <identifier>" . $node->nid . "</identifier>\n";
+  $output .= "    </track>\n";
+  return $output;
+}
Index: audio_theme.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/audio/audio_theme.inc,v
retrieving revision 1.2
diff -u -r1.2 audio_theme.inc
--- audio_theme.inc	11 Oct 2006 15:52:12 -0000	1.2
+++ audio_theme.inc	14 Dec 2006 05:38:08 -0000
@@ -2,17 +2,6 @@
 // $Id: audio_theme.inc,v 1.2 2006/10/11 15:52:12 drewish Exp $
 
 /**
- * Format an array of nodes for display in a block.
- */
-function theme_audio_block($nodes){
-  $items = array();
-  foreach ((array)$nodes as $node) {
-    $items[] = l($node->title, 'node/'. $node->nid);
-  }
-  return theme('item_list', $items);
-}
-
-/**
  * Format the teaser for an audio node.
  */
 function theme_audio_teaser($node){
@@ -22,7 +11,7 @@
   }
   $params['!filelength'] = theme('audio_format_filelength', $node->audio_fileinfo);
   $params['!fileformat'] = theme('audio_format_fileformat', $node->audio_fileinfo);
-  $params['!player'] = audio_get_player($node);
+  $params['!player'] = audio_get_node_player($node);
   $params['!play_count'] = check_plain($node->audio_fileinfo['play_count']);
   $params['!download_count'] = check_plain($node->audio_fileinfo['download_count']);
 
@@ -41,8 +30,8 @@
   $output .= theme('audio_images', $node->audio_images);
 
   $output .= "<ul class='audio-info'>\n";
-  if ($player = audio_get_player($node)) {
-    $output .= '<li><b>'. t('Play') .':</b>&nbsp;'. $player ."&nbsp;</li>\n";
+  if ($player = audio_get_node_player($node)) {
+    $output .= '<li>'. $player ."</li>\n";
   }
 
   foreach (audio_get_tag_settings() as $tag => $setting) {
@@ -117,94 +106,3 @@
   return check_plain($output);
 }
 
-/**
- * The default mp3 player is the flash XSPF player. If you want to override
- * this behavior you can do so at the theme level.
- *
- * A couple of options that may be of interest:
- * - backgroud color. If it's not specified, it'll default to transparent.
- *    'b_bgcolor' => "000000"
- * - foregroung (border and icon) color.
- *    'b_fgcolor' => "ffffff"
- * - foreground color by state. The order is: connecting (spinner),
- *   ready (arrow), playing (square), and ??? (not sure). The b_fgcolor value
- *   will be used for any ommitted values.
- *    'b_colors' => "ff0000,,00000ff,000000",
- *
- * @param $node
- *   node object
- * @param $options
- *   array of options to pass to the player. This allows you to override the
- *   any parameter passed to the player including colors, title,
- * @return
- *   HTML string with a flash player
- */
-function theme_audio_mp3_player($node, $options = array()) {
-  global $base_url;
-
-  // flash only supports a limited range of sample rates.
-  switch ($node->audio_fileinfo['sample_rate']) {
-    case '44100': case '22050': case '11025':
-      break;
-    default:
-      return;
-  }
-
-  $options = array_merge((array) $options, array(
-    'song_url' => check_url($node->url_play),
-    'song_title' => check_plain($node->audio_tags['title']),
-  ));
-
-  $url = $base_url .'/'. drupal_get_path('module', 'audio') .'/players/mp3.swf';
-  if ($options) {
-    $url .= '?'. drupal_query_string_encode($options);
-  }
-
-  $output = '<object type="application/x-shockwave-flash" data="'. $url .'" width="17" height="17">';
-  $output .= '<param name="movie" value="'. $url .'" />';
-  $output .= '<param name="wmode" value="transparent" />';
-  $output .= '</object>';
-
-  return $output;
-}
-
-/**
- * This is the default player... a link!
- *
- * @param $node
- */
-function theme_audio_player($node) {
-  $output = '<span class="audio">';
-  // we can't use l() because the url is absolute
-  $output .= '<a href="'. check_url($node->url_play) .'">'. t('Click to play') .'</a>';
-  $output .= "</span>\n";
-  return $output;
-}
-
-/**
- * Format the id3tags settings form as a table.
- */
-function theme_audio_admin_settings_metadata($form) {
-  $rows = array();
-  foreach (element_children($form['audio_tag_settings']) as $key) {
-    $row = array();
-    if (is_array($form['audio_tag_settings'][$key]['name'])) {
-      $row[] = drupal_render($form['audio_tag_settings'][$key]['name']);
-      $row[] = drupal_render($form['audio_tag_settings'][$key]['autocomplete']);
-      $row[] = drupal_render($form['audio_tag_settings'][$key]['required']);
-      $row[] = drupal_render($form['audio_tag_settings'][$key]['hidden']);
-      $row[] = drupal_render($form['audio_tag_settings'][$key]['browsable']);
-      $row[] = drupal_render($form['audio_tag_settings'][$key]['writetofile']);
-      $row[] = drupal_render($form['audio_tag_settings'][$key]['weight']);
-
-      $row[] = drupal_render($form['delete'][$key]);
-    }
-    $rows[] = $row;
-  }
-  $header = array(t('tag'), t('autocomplete'), t('required'), t('hidden'), t('browsable'),
-    t('written to file'), t('weight'), t('delete'));
-
-  $output = theme('table', $header, $rows);
-  $output .= drupal_render($form);
-  return $output;
-}
Index: views_audio.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/audio/views_audio.inc,v
retrieving revision 1.4
diff -u -r1.4 views_audio.inc
--- views_audio.inc	3 Nov 2006 22:16:38 -0000	1.4
+++ views_audio.inc	14 Dec 2006 04:35:20 -0000
@@ -141,3 +141,27 @@
   }
   return $tags;
 }
+
+
+function audio_views_style_plugins() {
+  $items = array();
+  $items['audio_xspf_playlist'] = array(
+    'name' => t('Audio: XSPF Playlist'),
+    'theme' => 'audio_views_xspf_playlist',
+    'summary_theme' => 'views_summary',
+  );
+  return $items;
+}
+
+
+function theme_audio_views_xspf_playlist($view, $nodes, $type) {
+  if (isset($_GET['playlist'])) {
+    return audio_xspf_playlist(views_get_title($view, $type), $nodes);
+  }
+  else {
+    $player = audio_get_players('name', 'xspf_extended');
+    $playlist_url = url($view->real_url, 'playlist', NULL, TRUE);
+    return theme($player['theme_xspf'], $playlist_url);
+  }
+}
+

