Currently, the playlist.module only implements audio playlists. I would like to make it easier to make new types of playlists such as podcast, video, image, collaborative and mixed media playlists. I also think this will simplify the playlist.module to its core functions.

An example workflow for creating a new playlist would be:

  1. Create a new playlist node (SEPARATE MODULE)
  2. Define what node types can be added to this new playlist (SEPARATE MODULE)
  3. A common management/sort system for re-ordering, deleting, adding items (PLAYLIST MODULE)
  4. Allow new, pluggable XML feed definitions (SEPARATE MODULE)

I would eventually like to create #1, #2, #3, #4 in such a way that you wouldn't have to know PHP to create and define a new playlist. But at this point, probably creating a toolkit of base functions is more helpful, and will satisfy #3. The rest can be handled by a node module.

Building a Toolkit or API of playlist functions

Most playlists will need something like:

  • A table to keep track of the relationships
  • A set of functions to interact with the database
  • A theme_sort function that allows for easy re-ordering of playlist items
  • A hook or way to define new XML feeds based on playlist data/metadata

Database Schema

Add an extra column defining the playlist type in the playlist_relate table

CREATE TABLE `playlist_relate` (
  `rid` int(11) NOT NULL auto_increment,
   'type' varchar(255) NOT NULL default '',
  `parent_id` int(11) NOT NULL default '0',
  'child_id` int(11) NOT NULL default '0',
  `weight` int(11) default '0',
  PRIMARY KEY  (`rid`)
);

The addition of adding a new relationship type column has been brought up in other relationship API threads and is used by the clipper module. Same argument. However, the relationship API in my opinion might be a bit weighty for what the playlist module needs. All the playlist module needs is something like:

46

46

78

78

rid type parent_id child_id weight
1 audio 45 357 0
2 audio 72 568 1
3 video 679 99 0
4 video 35 679 1

Just a basic node relationship table.

Functions to get data in and out of the database

Having basic functions like:

playlist_relate_add($parent_id, $child_id, $weight, $type);
playlist_delete_parent($parent_id);
playlist_delete_child($child_id);
playlist_delete_type($type);
playlist_sort($playlist_id);
etc...

Theme_sort() to handle managing and ordering the playlist items

The playlist sort would be based on the playlist sort function now (up/down arrows, drag and drop sort). It would basically allow for moving the weights around in the table. This is probably the most useful function that the playlist module could offer. Whether it uses prototype.js or a home-brewed function is still up for debate.

Extensible XML Feeds

I'm thinking at this point, that the playlist node type should define this. It can use hook_link and a menu callback, with the functions above, to handle creating a new feed. Or other modules could use nodeapi to define new feeds for other nodes.

CommentFileSizeAuthor
#17 playlist.diff329 bytesRyanbach
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Ryanbach’s picture

What are the names of the modules except for the third (3) one? Also which of them is going to have the module.install file?

-Ryan

zirafa’s picture

Ryan, for #1,#2,#4, those would be defined by another *.module file. For our purposes, we'll define them in an audio_playlist.module file. Later on, if someone else wants to make a video_playlist.module or something, they can just plug in the same helper files again.

I imagine there'd be something like:

  • playlist.install (creates the database table)
  • playlist.inc (a file with all the helper functions)
  • playlist.theme (theme_sort, theme_playlist, theme_manage)
  • playlist.css (a css file for the themes)

those are the core files, then I'll probably include an audio playlist module to start:

  • audio_playlist.module (creates an audio playlist using the files above)

So altogether, the playlist tarball package would contain 5 or so files.

zirafa’s picture

Ok finished the playlist.install file thanks to Ryan. Ryan I just took what you submitted in the other thread and just added the extra 'type' column. I also think I'm near done with playlist.inc (might become playlist.module). Having it as a helper module would mean other modules could share the functions once it is turned on instead of having to worry about including it, or wondering which module has already included it.

zirafa’s picture

Ok, finished playlist.theme and playlist.module I think. Basic toolkit is working, now to make an audio_playlist.module. I'm developing in my sandbox on CVS, if you are intersted in following or testing.

drewish’s picture

this sounds very exciting! when i get some time (tomorrow?) i'll grab a copy from your sandbox and give it a whirl.

zirafa’s picture

ok, audio_playlist.module is nearing completion. I still have to port over the feed functions, however. I also would like to incorporate a theme function to display a flash player with a select box for which playlist to listen to...

also, since the playlist.module uses generic theme functions, i have to think of some way for modules to send additional data for display, like the xspf player, or additional metadata. that way the same theme function can be used across the board by playlists.

zirafa’s picture

Ryanbach’s picture

Title: Re-writing the playlist module as a relationship toolkit for 4.7 » playlist.install

I think you may need to add this to the playlist.install

function playlist_update_1() {
  return _system_update_utf8(array('node_playlist', 'node_playlist_item', 'table3'));
}

See this: http://drupal.org/node/51220 and this: http://drupal.org/node/22218#utf8_sql for more info.

Ryanbach’s picture

Remove 'table3' there isn't a table3, sorry my mistake.

zirafa’s picture

Title: playlist.install » Re-writing the playlist module as a relationship toolkit for 4.7

Ah, please don't change the title ;)

Yeah, the playlist.install needs some work. I'm not quite sure what you posted though. I'm not sure how to update from playlist 4.6 to this version since the schema is different. hmm....

drewish’s picture

looked through the code but didn't have a chance to run it. i made a few notes of things that i wanted to ask about:

  • in the table you've got an rid? what is that used for? it would seem like a joint key between parent and child would be fine...
  • not a big deal but, in _playlist_save_order() for security clarity, you might want to cast the values from $_REQUEST to integers before passing them into playlist_set_weight().
  • i'd like to see the following functions renamed
    • playlist_delete_parent() -> playlist_remove()
    • playlist_delete_child() -> playlist_remove_child()
    • playlist_delete_type() -> playlist_remove_type()
  • i think remove is a better word than delete because neither the child or parent nodes are being deleted, they're being removed from the playlist. there's probably a better name than playlist_remove_type(), maybe playlist_remove_by_type(), something like that.
  • this is totally nit picky but the indenting/white space is really inconsistant, maybe you could tweak the tab/spaces settings in your editor.

sorry i haven't had a chance to go into it in more depth.

i hope this html is correct, the preview isn't working at all.

zirafa’s picture

Thanks for the comments, Drewish.

" in the table you've got an rid? what is that used for? it would seem like a joint key between parent and child would be fine..."
I guess I was thinking that a parent could potentially have multiple playlists. Don't know if this makes sense yet. But like if you have:

TYPE 'audio playlist' has parent 243 and child 65
TYPE 'audio and video playlist' has parent 243 and child 65

Currently the table is not used this way (and maybe shouldn't be)...especially if the rule is that a parent must be a unique playlist. But thinking in a broader relationship table sense it helps. Hmm I'll have to think about this...

"not a big deal but, in _playlist_save_order() for security clarity, you might want to cast the values from $_REQUEST to integers before passing them into playlist_set_weight()."

Would this work? Not sure if I can cast the entire array at once.

  $playlist_items = $_REQUEST['list'];
  foreach ($playlist_items as $child_id) {
  	playlist_set_weight($parent_id, (int)$child_id, $i++); 

  }

" i think remove is a better word than delete because neither the child or parent nodes are being deleted, they're being removed from the playlist. there's probably a better name than playlist_remove_type(), maybe playlist_remove_by_type(), something like that."

Good point. Remove makes more sense than delete.

"this is totally nit picky but the indenting/white space is really inconsistant, maybe you could tweak the tab/spaces settings in your editor."

True, I use Notepad2 ;) Any other editors you suggest? Notepad2 has a bizarre tab setting which I need to change.
But I'm also not sure what the spacing standards are so I end up doing willy nilly spacing.

Farsheed

zirafa’s picture

Ok, I made the above changes as suggested by Drewish, except for getting rid of RID in the table...

Fixed formatting, changed playlist_delete -> playlist_remove, cast (int) on $_REQUEST['list']

I also fixed some bad SQL commands.

I plan on moving playlist_page back out of playlist.module, I don't think it belongs there because I can't generalize it enough and it has bad SQL.

I plan on merging Narkoba's podcast.module with audio_playlist.module.

Other things to do:

For audio_playlist.module:

  • make the node name and description configurable (people have different names for the same thing, podcasts, audio playlists, music playlists, song playlists, albums)
  • configure which feed links to display (m3u, pls, podcast, xspf)
  • custom theme functions for displaying either an XSPF or RSS flash player
  • blocks and pop-out flash players
coupet’s picture

Interested in image playlist.

Also, dopry started an an interesting thread on File Handling in Drupal's future.... at http://drupal.org/node/52791

your comments would be appreciated.

drewish’s picture

To follow up on coupet's comment, there's a lot of ideas/discussion on what the 4.8/5.0 FileAPI should look like. The best place to be having that discussion is probably here: http://groups.drupal.org/groups/fileapi

Ryanbach’s picture

Ryanbach’s picture

FileSize
329 bytes

Here is the correct update for the install.module file.

Ryanbach’s picture

I mean playlist.install

zirafa’s picture

Hi ryan, could you explain what this patch does? I'm a bit confused by node_playlist and node_playlist_item.

Ryanbach’s picture

The function function playlist_update_1() uses _system_update_utf8 to update the old arrays database tables (if you upgraded from 4.6->4.7) to the utf8 format that Drupal 4.7 uses.

You also may need to add the dBase tables for node_playlist and node_playlist_item for the new 4.7 install. I assume that you use those as well, if not sorry.

Ryanbach’s picture

Here is some more info about the .install files: http://drupal.org/node/51220

zirafa’s picture

Thanks Ryan, I think I understand. I believe we would only need something like:

function playlist_update_1() {
   return _system_update_utf8(array('playlist_relate'));
}

It might be a good idea, when altering the 4.6 playlist table, to insert audio_playlist under the column, 'type'.

zirafa’s picture

Coupet, Drewish, thanks for the File API links. I'll definitely be looking at how to integrate with these new ideas.

I also was thinking of some other ideas for modules that could build off the playlist.module. Since parent and child are just numbered values, we could have the parent id be an nid, but have the children be taxonomy term ids. Then, the playlist module would grab all nodes associated with those TIDs when generating a feed or displaying the feed. This way it could be used to make a smart playlist, so you just tag stuff and then it gets auto-added to a playlist and generates the desired feed or feeds. Maybe views could be incorporated with this.

ANYWAY! Back to getting this to work as is... ;)

zirafa’s picture

Just some updates....

Got XSPF, PLS, M3U working great for audio playlist. I am finding having Narkoba's and Colin's album modules are great references and resources. I'm basically trying to combine and refine the best parts of everyone's code into one module. I'm also finding that having all the playlist_relate stuff in a separate module makes my life 10x easier and the code much easier to read through;)

Really the iTunes RSS specific stuff is what is holding me back. I am going to have to implement some extra node fields and a database schema to hold the iTunes metadata. Not really too difficult, but I've just been wading through the iTunes spec to make sure I get it right. Because of this, I'm planning on releasing the audio_playlist module as a separate module from playlist.module. It is getting much too big anyway and I don't want to clutter up playlist.module since it serves a more general purpose anyhow.

After I get the iTunes metadata in, the only thing left will be implementing some custom theme functions. That will be the really cool part, having pop-up flash players load in your playlist(s), or loading it up in a block.

drewz’s picture

Awesome! Exactly, what i was looking for. Great progress so far. I'm grabbing a cut now to try it out :)

drewish’s picture

regarding the itunes specific tags, please feel free to push any relevant stuff down into the audio module. those sort of general improvments would be much apprecitated. eventually we'll get the q0rban's image code committed and it'll do wonders for the the itunes feeds.

zirafa’s picture

OK! I'm finally done integrating everything I was hoping to for this release:

1) iTunes podcast/xspf/m3u/pls feeds generated on the fly, with full metadata support
2) album artwork can now be integrated (through URL)
3) xspf flash players for each feed, including popup players for each
4) audio browser, similar to iTunes, used to search audio tags and find the audio to add to playlists
5) upload new audio files to playlists on the fly with an inline uploader
6) listening station: an xspf flash player block that has a dropdown select to listen to different playlists on the site
7) Cut n' paste HTML and javascript includes for integrating the flash player on other sites

I will be uploading to to the main CVS repository soon and tagging it as 4.7. It still needs loads of testing, which by tagging it as 4.7 I hope will encourage people to try it out.

Farsheed

drewz’s picture

nice work man! I'm logging bugs as you can see. One question... is the album art url suppose to be relative to the root? absolute?

Once in awhile, i'm getting an error with the album art:

getimagesize(/podcast.gif) [function.getimagesize]: failed to open stream: No such file or directory in /home/.carmen/drewz/tapestry/modules/playlist/audio_playlist/audio_playlist.module on line 629.

But I just want to know if it's because of the url i'm feeding it? It happens only intermittently, which is bizarre. I'll log it as a bug once you confirm the album art url.

Thanks for all the work! It's a great module.

zirafa’s picture

Hi Drewz,

Thanks for the bug reports!

The album art is supposed to be an absolute URL. It probably won't work with relative URLs. Eventually I'm thinking about integrating image_attach so that if an image is attached to the playlist it uses that as the album artwork instead of the URL.

I've only tested it with external images with absolute URLs.

Farsheed

zirafa’s picture

Status: Active » Fixed

Marking this as fixed. If you have any issues with the new 4.7 version of this module please file a separate bug report.

Anonymous’s picture

Status: Fixed » Closed (fixed)