[Rhythmbox-devel] iTunes Music Sharing



Hello everyone,

I'm Charlie Schmidt, and I'm adding iTunes Music Sharing (Digitial Audio
Access Protocol [DAAP]) to Rhythmbox.  I was working on this last
October, and some may remember my work at that time
(http://ishamael.inactivex.net/software/daap.html).  I've been chosen by
Google - as part of their Summer of Code deal - to restart and finish
this work.

My first attempt (see uri above) involved writing a GnomeVFS module for
daap:// uris.  The module is written, and I had code interfacing it with
Rhythmbox.  Unfortuantly, the RB code has been lost.  Last October, and
even since then
(http://mail.gnome.org/archives/rhythmbox-devel/2005-June/msg00101.html)
there has been discussion that the virtual file system approach isn't
the way to go.

So, this time, I've written it directly in to Rhythmbox.  I have
browsing other DAAP shares written up to the point of listening to music
(it will find shares and get a list of their songs).  DAAP sits on top
of http.  To listen to a particular file, one needs to establish a DAAP
connection and, among other things, recieve a session-id and revision-id
(in addition to knowing the song's id).  A full uri for a daap song,
after establishing the connection and locating it within the database
is:  http://192.168.0.1:3689/databases/DB-ID/items/SONG-ID.SONG-FORMAT.

So, easy enough, right?  We just pop that uri over to GStreamer's lovely
playbin, which currently uses a gnomevfs source element to handle
http:// uris.  Unfortunatly, it isn't that easy.  The first problem is
that there are several headers that need to be sent when requesting the
file:

Client-DAAP-Version: 3.0
Client-DAAP-Access-Index: 2
Client-DAAP-Request-ID: request-id
Client-DAAP-Validation: special hash of the path, the DAAP version and
the request-id.

The request-id starts at 1, and every time you request another song it
needs to increment one.  The DAAP version can only be determined in the
main DAAP connection, you can't figure it out in the same connection you
ask for the file in (as far as I know).

Additionally, the connection requesting the file needs to be a new http
connection (you cannot re-use the existing one) and can only be used for
1 file (it must send a  Connection: close header).

The gnomevfs source element does not provide any functionality for
additional http headers and if I recall correctly, it caches http
connections.  So, I'm stuck.

As I see it, work can be done to resolve this in one of the following
ways:

1. Write a daap:// uri handler for GnomeVFS that will take specially
formed daap:// uri's providing the request-id and DAAP version, compute
the validation hash, and set up all the extra headers required.  It
could be based on the existing http:// uri for GnomeVFS or my earlier
work.  There would need to be work done (basically someone telling me
where/how) to tell GStreamer's playbin to use the gnomevfs source for
daap:// uris.

2. Write a daap:// uri handling source for GStreamer.  There is an
existing httpclientsrc implentation in bugzilla:
http://bugzilla.gnome.org/show_bug.cgi?id=169125 that could be modified
similar to how I described above.  Again, GStreamer's playbin would need
to know to use it for daap:// uris.

3. Modify the httpclientsrc implementation in bugzilla to have settable
properties for extra headers.  uris would be handed to RBPlayer in the
form of daap://.  RBPlayer would fudge them into http:// uris, force
playbin to use the new httpclientsrc, and add the extra headers to it.

Number 3 is probably the "best" solution:
	It solves multiple problems. Namely: this one and adds a non-gnomevfs
http:// handler for GStreamer.   However, I believe it is the most
challenging, and does end up with some "hackish" code inside RBPlayer.

Numbers 1 & 2 are basically the same, just putting the code in different
places (GnomeVFS or GStreamer).  Between the two, I believe GnomeVFS is
the better and simpler place for it.  However, in both cases, daap://
uris are useless unless a previous DAAP connection has been established.
For example, in #2, the daap:// uris won't work in gst-launch.
Similarly, in #1, they wouldn't work in Nautilus.  Numbers 1 & 2 are
much easier to implement, in my opinion - however, they do lead to some
code duplication unless an entire DAAP library is written.

On that note, I do not think that is a neccessary step.  DAAP has a
specific use: browsing music shares inside a music player like
Rhythmbox.  I cannot see how it would work, for example, in something
like Totem or Muine, where there aren't ideas of separate sources of
music.  If some code duplication is neccessary, it is not the end of the
world, since the code for either the GStreamer element or GnomeVFS
module could exist within the Rhythmbox source tree, and be installed
with RB.

So.  Comments, questions, suggestions and criticsms, please, direct them
my way.  I'm subscribed to the mailing list here, and I'm on IRC as ish
from usually 2pm-3am or 6pm-3am EST.

-
charlie






[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]