Audioplayer con drPlayer

Para hacer un player de archivos de audio (mp3, etc), ayuda el plugin audio. El problema es que está incompleto (el pase de Drupal 5 a Drupal 6 tiene varios pendientes). Uno puede ir completando las partes que no funcionan, como el playlist, pero es un poco complicado. Además, requiere varios módulos de apoyo. Me dije, a lo mejor, se puede resolver de manera más simple. ¿Cómo lo haría yo?

En este artículo no pretendo instruir sobre la mejor forma de hacer un player de audio. Simplemente, hablaré del camino que voy recorriendo (es un trabajo en marcha) en desarrollar una solución. Tal vez le ayude de algún modo a alguien.

La idea
La idea es poder subir archivos de audio (empecemos con mp3) que puedan ser organizados en playlists, o listas de reproducción.

Un usuario puede subir tantos archivos como quiera y definir sus propias listas.

De preferencia con software que no tenga restricciones de uso comercial, por si acaso.

El método
Empezar con lo imprescindible, lo minimo. Avanzar hacia el siguiente mínimo e imprescindible  paso. Y así sucesivamente. Aplicar la pauta con libertad.

Esbozando la solución
Subir archivos. Se puede usar el módulo filefield.

Playlist. No encontré un módulo para esto, aparte de audio. Busqué en plugins para jQuery. Quiero uno que permita dejar corriendo la lista de canciones. Encontré drplayer y flowplayer, entre otros. Flowplayer se ve muy prometedor. Drplayer es simple de usar. Luego de dar muchas vueltas, me pareció que me estaba distrayendo demasiado en la elección del player, que quizás hasta podría ser intercambiable.

Explorando drPlayer
Hago una demo simple sin usar Drupal, para comprobar lo que requiere:

<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <link rel="stylesheet" href="drplayer.css" type="text/css" />
    <script src="jquery.js" type="text/javascript"></script>
    <script src="drplayer.js" type="text/javascript"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#playlist").playlist(
                {
                    playerurl: "swf/drplayer.swf"
                }
            );
        });
    </script>

</head>
<body>
    <div id="playlist">
        <div href="mp3/cancion-01.mp3" style="width: 400px;" class="item">
            <div>
                <div class="fr duration">03:00</div>
                <div class="btn play"></div>
                <div class="title"><b>Artista 1</b> - Canción 01</div>
            </div>
            <div class="player inactive"></div>
        </div>
        <div class="clear"></div>

        <div href="mp3/cancion-02.mp3" style="width: 400px;" class="item">
            <div>
                <div class="fr duration">04:00</div>
                <div class="btn play"></div>
                <div class="title"><b>Artista 2</b> - Canción 02</div>
            </div>
            <div class="player inactive"></div>
        </div>
        <div class="clear"></div>
        
    </div>
    <div class="clear"></div>
    
    <a href="javascript:void(0);" onClick="$('#playlist').playlist('prev');">Prev</a>
    <a href="javascript:void(0);" onClick="$('#playlist').playlist('next');">Next</a>
 
    <a href="javascript:void(0);" onClick="$('#playlist').playlist('pause');">Pause</a>
    <a href="javascript:void(0);" onClick="$('#playlist').playlist('play');">Play</a>
    
   
</body>
</html>

Es decir, la lista está contenida en un bloque #playlist. Cada item es un bloque .item. El campo de título es un bloque .title y el de duración es un bloque .duration.

Más tarde, encontré que es necesario considerar también un bloque .player .inactive por cada item.

Me parece que se podría usar el módulo views para construir html con esta estructura.

Usando id3
El módulo getid3 para permitir usar getid3 para obtener la metadata de un archivo.

La metadata de un archivo de audio contiene información como el título, el nombre del artista, la duración, el nombre y año del album, etc.

Una vez instalado getid3, los nodos que contengan un archivo subido tendrán un campo $node->field_audiofile[0] conteniendo esa metadata (puede leer un poco más sobre eso en el artículo Resolviendo Filefield Meta y usando Dynamic Field), que se podrán usar para llenar la estructura que se requiere para drplayer. Chévere.

Tipo de contenido Audio
Defino el tipo de contenido Audio (audio) con el campo Archivo (field_audio_file) de tipo File.

Indico además que no usará el campo Body (dejando en blanco el nombre de ese campo).

Para facilitar el llenado del campo Title, es útil el módulo auto_nodetitle, que se configura en la misma pestaña de edición del tipo de contenido. Allí, indico que el título se genere automáticamente si se deja en blanco (dando la opción al usuario de poner otra cosa, si desea). Teniendo además instalado el módulo token, indiqué que el patrón de los títulos automáticos fuera:

[field_audiofile-filefield-filename]

Es decir, el nombre del archivo subido.

Lista de audios
Defino la vista audios, que muestra nodos de tipo audio y los campos Nodo: Titulo, Contenido: Archivo. Para obtener la duración, requiero algo de código php que ingreso con ayuda del módulo views_customfield, permite usar php para generar el contenido de un campo.

Al comienzo, dejé a un lado el asunto de la duración e intenté proseguir con el nombre de archivo únicamente.

Intenté usar templates para crear la estructura que requería para drplayer. Con los view-xxx.tpl.php pude dar a cada bloque el id y la clase que requerían. #playlist conteniendo .item que contiene .title y .duration. Sin embargo, la estructura requiere que el nombre del archivo esté como href del elemento .item y no se me ocurría un modo de lograr eso con los templates, ya que el template que me permite personalizar el bloque .item no tiene disponible una variable con el nombre del archivo.

Supongo que hay algún modo de usar template.php para publicar la variable que necesita en ese caso, pero no domino mucho los hooks de la vista y se me hizo más natural imaginar que podría usar un Customfield: PHP para generar todo el html que se requiere a partir del $data->nid disponible:

<?php
echo misc_get_drplayer_html_audio($data->nid);
?>

La función misc_get_drplayer_html_audio la defino en el módulo misc:

function misc_get_drplayer_html_audio($nid) {
  $node = node_load($nid);
  $audiofile = $node->field_audiofile[0];
  $filename = base_path().$audiofile['filepath'];
  $duration = $audiofile['data']['duration'];
  $duration_h = sprintf('%02d:%02d', $duration/60, $duration%60);
  $artist = $audiofile['data']['tags']['artist'];
  $title = $audiofile['data']['tags']['title'];
  $html = '
'.$duration_h.'
'.$artist.' - '.$title.'
'; return $html; }

Lo bueno de usar este método es que me permitió acceder con más comodidad a la metadata del archivo, que no estaba directamente disponible en la vista.

Con esto, se puede conseguir que una vista que muestre las canciones con la estructura requerida por drplayer.

Módulo drPlayer
Para incorporar drPlayer a drupal, cree el módulo drplayer, vacío, simplemente para contener los archivos de esa biblioteca, en el subdirectorio modules/drplayer/drplayer/.

Luego, en la vista audios, en el display que muestra los archivos del playlist, Basic settings, Encabezado, indico el siguiente contenido php:

<?php
drupal_add_css(drupal_get_path('module', 'drplayer').'/drplayer/drplayer.css', 'module');
drupal_add_js(drupal_get_path('module', 'drplayer').'/drplayer/drplayer.js', 'module');
drupal_add_js('$(document).ready(function() {
    $("#playlist").playlist(
        {
            playerurl: "'.base_path().drupal_get_path('module', 'drplayer').'/drplayer/swf/drplayer.swf"
        }
    );
});', 'inline');
?>

Esto invoca a drplayer al momento de mostrar la vista.

Siguiente paso
Que el usuario pueda definir sus propios playlist.

Referencias

Comentarios

Entradas populares de este blog

Debug con Xdebug y Aptana (y Notepad++)

Drupal sí, drupal no

CSS3 para mejorar el breadcrumb de un tema Zen