Media Device Syncing - One more time now .. (we have a volunteer)

Bart Cerneels bart.cerneels at kde.org
Fri May 28 21:43:41 CEST 2010


On Wed, May 26, 2010 at 09:55, Bart Cerneels <bart.cerneels at kde.org> wrote:
> On Tue, May 25, 2010 at 23:55, Casey Link <unnamedrambler at gmail.com> wrote:
>> He folks,
>>
>> Introducing Amitav here.. he has volunteered to work on iPod syncing
>> for Summer of KDE.. something I've been trying to do and failing to do
>> for awhile.
>>
>> As he is knew to the Amarok codebase I suggested he should work on the
>> easiest task first, which AFAIK is extending parts podcast/playlist
>> stuff to work on ipods. Bart, can you comment on what exactly needs to
>> be done (with a few references to actually classes)?
>
> For the regular playlists: implement UserPlaylistProvider and
> iPodPlaylist class. Though I think this is already implemented
> indirectly though MediaDevicePlaylistProvider, which is a problem I'll
> describe below.
>
> Podcasts on iPod are definitely not implemented yet and you'll be able
> to do it similarly like I did for USB Mass Storage.
> What is needed is a PodcastProvider and the Podcast classes:
> PodcastChannel and PodcastEpisode for iPod. In practice the episodes
> will be a proxy for the itunes-db tracks that are the episodes. You'll
> probably have to generate the PodcastChannels based on the metadata of
> these episodes. Again, UMS is the best inspiration.
>
> Once the podcast provider is registered with
> PlaylistManager::addProvider() it will automatically show up in the
> podcast section.
>
> In order to support copying playlists and adding podcast channels
> you'll need to implement PlaylistProvider::addPlaylist() and
> Playlist::addTrack(), Playlist::removeTrack(). This is all that is
> needed to enable drag and drop copying in the browsers.
>
> Both UserPlaylist and Podcasts share the same synchronization logic,
> it uses the add and remove functions above to get playlists to the
> same state meaning both the tracks and their order. Note that playlist
> synchronization does not directly handle copying over the actual
> tracks.
>
> The steps of synchronization:
> 1) PlaylistProvider A is registered with PlaylistManager.
> 2) PlaylistProvider B is registered with PlaylistManager.
>  * Playlists B.1 is to be synchronized with A.5.
>  * Playlist A.5 and B.1 are added to a SyncedPlaylist
>   - the synchronization logic iterates over all track positions of
> A.5 and adds the track at that position in B.1 if it's not already
> there. Once the end off A.5 is reached all tracks beyond that position
> are removed from B.1.
> (see http://gitorious.org/~Stecchino/amarok/stecchinos-amarok/blobs/playlist_sync/src/playlistmanager/SyncedPlaylist.cpp
> )
> This algorithm is optimized for situations where most of the time one
> or a few tracks are inserted. It preforms badly when the playlist is
> reordered because the playlist could double in length before the
> second step removes the "down shifted" tracks. It does always ensure
> that at least one copy of a track is present during the
> synchronization, this is beneficial for track copying because never
> will a track be completely removed only to be added again right after.
>
> 3) Now that the copies are in sync any changes to the playlist by the
> user are applied to both by the SyncedPlaylist proxy.
> 4) Any event driven changes in one copy (like a podcast updating) are
> applied to the other copies immediately.
>
>>
>> Alejandro, Bart, and Jeff: We had a conversation on IRC a few months
>> back regarding the Media Device API and whether it was worth it to do
>> things the "proper" way -- that is, writing all the code abstractly
>> using Alejandro's media device API from the get go versus skipping
>> that (like Bart did for UMS) and implementing on the device directly.
>> What did we decide?
>>
>> I am trying to give Amitav here some pointers and guidance, but this
>> is definitely not my area of expertise in Amarok.. as much as I would
>> like it to be.
>>
>> Casey
>>
>
> The mediadevice framework has a good design goal: make it easier to
> implement support for players by limiting the amount of code that
> needs to be written. In practice though it has prevented me from
> extending the playlist support to allow playlist synchronization and
> podcast support on iPods. In fact, the only way I could make it work
> on UMS is by sidestepping MD altogether.
>
> It's not uncommon to have well meant API layers get in the way of
> features. In fact, I would say most of my day job involves hacking
> around the unflexible top-down design.
> When implementing some framework from scratch I thus try to work
> bottom up. This means the support needs to be implemented completely
> at the user-level API. This does mean more coding work for the
> implementer but by providing a lot of tools for common functions this
> can be reduced to an absolute minimum. In practice the code is rarely
> from scratch anyway, being able to copy previous implementations and
> adapt in small ways.
> This approach doesn't limit the flexibility of implementations and new
> features are limited to one API level and if done right, without
> impacting more code then required to introduce the feature.
>
> I would define the API to be implemented by mediadevices to be:
> Minimum: Collection, QueryMaker & Meta
> If the player support copying: CollectionLocation (can't think of one
> that doesn't in practice)
> Player has playlist support: UserPlaylistProvider and
> Playlists::Playlist (and this implies tracks added to a playlist are
> also copied to the device)
> Player has Podcast support: PodcastProvider and
> Podcast(Channel|Episode). (If a player can download episodes itself,
> like an iPhone, this can be triggered with an action).
>
> Actually, the same is true for internet services and local collections
> but in practice services also has an extra API and local is several
> classes that use sqlStorage or file storage that can not be considered
> one entity similar to a mediadevice plug-in.
>
> Bart
>

Some follow up.

Casey and I have discussed a way to set up a syncing relationship by
drag and drop and the context menu (and thus including PUD), so no
need for a dialog.

We already support copy/move to collections, though this does not work
via drag and drop yet. That will be added this development cycle.
There is a problem with reaching the drop target when entries in the
collection browser are expanded. You need to wait to scroll to the
root element of the collection you want to add tracks to. And when
merged view is enabled these are not even available to begin with.
So we'll fade in the root element at one end of the collection browser
itemview to make an easy drop zone. These will be the same elements as
the regular collection root's except some background and/or
transparency/glow to make them stand out as drop targets.

Sync will be set up the same way as copy/move. If you want to have all
tracks of an artist, everything of a certain genre, the entire
entirety of music released in 2006, just select sync instead.

We'll reuse a concept in KDE with modifiers to move or sync instead of
the default drop action, which should be to copy.

We can create a querymaker based playlist very easily that would
always contain the required tracks. From there on the syncing logic
will do it's magic.

Bart


More information about the Amarok-devel mailing list