GNOME Bugzilla – Bug 345006
Rhythmbox MTP support
Last modified: 2008-11-07 12:12:52 UTC
I've tried to send this to the mailing list a couple of times. I don't know if it came through, but this is probably the right place anyway. Here is a copy of the mail: --- Hello all, I thought I'd share with you the result of my hacking the last days. The attached patch adds support for handling MTP (Microsoft Transfer Protocol) to rhythmbox. I'm not the one who talked about MTP-support a couple of moth ago, that was Steve Fox, but I've talked to him and he hadn't had the time to work on it, but I have :). But since this is my first contribution to rhythmbox, or anything for that part, I probably should introduce myself. My name is Peter Grundström, petgru/pete on irc, I'm 18 years old and I live in Sweden. I've been a user of opensource (linux/gnome/rhythmbox you name it) for quite some time now. The last year or so I've started to develop some useful programming skills. This is my first, but hopefully not my last, "major" contribution to any opensource project. So, back to the thing you probably are more interested in :) The patch adds basic mtp-device handling to rhythmbox. Setup the device, List the songs, Transfer songs and delete songs. It's built in the same way as the ipod support, one mtp-plugin and a mtp-source. It's still not perfect in any way, but it works. What it doesn't do / TODO: * You cant play the songs on the device. (the device never gets mounted, you only access it through the library libmtp.) * you have to run rhythmbox as root, since the libmtp requires root-privileges to access the device through libusb. This should probably be fixed with something like a udev-rule (in libmtp i presume). * the device has to be attached when you start rhythmbox, and the only way to detach it is to close rhythmbox. * I was working with that last thing, but I couldn't get the popup to work, it only says "Couldn't get menu widget for /MTPSourcePopup". Someone who is more experienced with rhythmbox maybe can figure out why. * It is a little delay when you close rythmbox which makes rhythmbox look like it hanged, and the "rhythmbox does not respond" dialog appears. No idea how to fix that. * test it. * find and fix the bugs ---
Created attachment 67419 [details] [review] Version 0.1 of the patch
Now I've a new version of the patch :). New things in this patch: * I figured out how to solv the problem that you only could run it as root. The solution was to install a libmtp.rules file (udev rules) from the libmtp tar that wasn't installed by default. * I use hal to monitor devices added and removed, so now you can add or remove a mtp-device at any time. * Some clean-ups and fixes. The only realy big thing left is playing. Some people have suggested that I write a gstreamer src for it. Is that the way to go? Also, is there a way to disable playing until then? I saw RBSource had a can_pause thing, but no can_play (as far as I could see) feedback is most appreciated.
Created attachment 67543 [details] [review] Version 0.2 of the patch
See also thread on archives: http://mail.gnome.org/archives/rhythmbox-devel/2006-June/thread.html#8 (also obsolete older version of the patch)
To disable playback add "entry_type->get_playback_uri = (RhythmDBEntryStringFunc)rb_null_function;" right after you register the entry type in rb_mtp_source_new. That will cause it to use NULL when trying to start playback, which indicates that there is nothing to play. For Rhythmbox to be able to play back from the device, GStreamer needs to be able to read the data from it. That means either writing a GStreamer source element, or making one of the existing ones be able to do it (e.g. writing a gnome-vfs module).
I was thinking on how to solv the playing problem. Writing a gnome-vfs module is a good idea since MTP in't just for song-transfer. Since MTP devices are accessed through the libmtp, only one program at the time can access a device. There are several programs/plugins that wants to talk to MTP devices. Rhythmbox-plugin, Gnome-VFS module, Gstreamer-src, other music players (like banshee and amorak) and gphoto. If every one of these programs talk to the libmtp directly only one will get the connection and the rest will start spewing out error messages. One solution, that I'm leaning towards right now, is to do like the njbstack[1] project. Create a daemon that talks to libmtp and then let all the programs talk to it through dbus. What do you people think about this? I think it would make handling mtp devices a lot easier and reduce code duplication in many projects. [1] http://sourceforge.net/project/showfiles.php?group_id=89742&package_id=117754
While it will be a bit more work, I think that the mtp-daemon route that would prove to be better in the long run. It means people could write a gnomevfs/kio/fuse/whatever module using it, and let multiple things access the device at once. The code looks okay, apart from a few nitpicks: * variable need to be declared at the start of functions/blocks, not in the middle * don't use C++-style comments (use slash-star not double-slash) * the mtp souce can go in plugins/mtp/ too, the ones used by plugins in sources/ were only there because moving files is a pain with cvs.
Also, it's probably worth discussion with the person/people working on MTP support for Banshee, as it would obviously be useful to both and collaboration would let both players get better support quicker.
Is something still happening regarding MTP support for Banshee or gnome-vfs??Thanks for taking the time to report this bug. This bug report isn't very useful because it doesn't describe the bug well. If you have time and can still reproduce the bug, please read http://bugzilla.gnome.org/bug-HOWTO.html and add a description of how to reproduce this bug. You'll also need to add a stack trace; please see http://live.gnome.org/GettingTraces for more information about how to do so. Thanks in advance! Thanks for taking the time to report this bug. This bug report isn't very useful because it doesn't describe the bug well. If you have time and can still reproduce the bug, please read http://bugzilla.gnome.org/bug-HOWTO.html and add a description of how to reproduce this bug. You'll also need to add a stack trace; please see http://live.gnome.org/GettingTraces for more information about how to do so. Thanks in advance!
I don't know, but I don't think marking the bug NEEDINFO is a good way to find out.
Jonathan, I'm sorry I accidentally hit a wrong link on the page. I was just wanting to ask what the status was.
Hi, I'd be very interested in getting support for mtp devices in rhythmbox. Perhaps the amount of work needed is not that bad as there is already an patch in this bug report (probably very old). There is also a fuse filesystem already for libmtp (mtpfs: http://www.adebenham.com/mtpfs/) maybe that could help. There is also someone working on python bindings if that can be of any help (https://launchpad.net/pylibmtp). I can test but I cannot code. Nic
Ok, I tried to apply the patch, only one change in configure.ac is not made +plugins/mtp/Makefile so I manually added it to the configure.ac file. Unfortunately, the Makefile is still not created in the directory plugins/mtp/ which means the "make" errors out when it can't find it there. It's probably a stupid error to fix. Nic
Created attachment 83802 [details] [review] update Updated to SVN, and had a few minor things fixed. As I don't have a MTP device, I can't guarantee anything about this besides that it compiles and doesn't crash the instant I turn the plugin on.
I've started to update the patch to compensate for changes in rhythmbox and libmtp api and behavior. It's kind of working now, but I've some problems while dragging songs to the mtp-device and the hotplug code is currently broken, haven't looked in to that yet. I don't have a ETA on when it's going to be finished, but I'll hope to squeeze in the time to finish it some time soon.
Peter, Wouldn't it be best to have support for MTP in gnome-vfs. In that way all applications can use it.
Maybe, but, as I said in comment 6, I prefer to solve the problem with a dbus daemon that would allow all programs, including a gnome-vfs module, to access the device(s) simultaneously. However that would take a much greater amount of time than just fixing up the patch that I already have, time that I don't have right now. The daemon approach would also involve getting the guys that develop libmtp and people who have build programs and plug-ins based on it aboard, which also will take a lot of time. If no one has started this project by this summer I'll probably do it my self, but until then I just don't have the time.
Hi all, Thanks a lot Peter for your nice work. Trust me, it is and will be much appreciated by the community. I understand the call for a gnome-vfs thing, but getting the devices to work with rhythmbox should be a priority at this point since no other music management software under gnome (amarok can) can access these very popular devices (all Creatives, irivers, zune, etc). As of now, for some reason the configure script refuses to create the Makefile for the mtp plugin. while running make: Making all in mtp make[3]: Entering directory `/home/nt271/temp/rhythmbox/plugins/mtp' make[3]: *** No rule to make target `all'. Stop. make[3]: Leaving directory `/home/nt271/temp/rhythmbox/plugins/mtp' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory `/home/nt271/temp/rhythmbox/plugins' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/nt271/temp/rhythmbox' make: *** [all] Error 2 Configure run like this (after autogen.sh obviously): ./configure --enable-track-transfer --enable-mtp At the end of configure script i get: configure: creating ./config.status config.status: creating Makefile config.status: creating macros/Makefile config.status: creating lib/Makefile config.status: creating metadata/Makefile config.status: creating rhythmdb/Makefile config.status: creating widgets/Makefile config.status: creating widgets/libsexy/Makefile config.status: creating podcast/Makefile config.status: creating shell/Makefile config.status: creating data/Makefile config.status: creating data/rhythmbox.desktop.in config.status: creating data/ui/Makefile config.status: creating data/art/Makefile config.status: creating data/glade/Makefile config.status: creating sources/Makefile config.status: creating corelib/Makefile config.status: creating plugins/Makefile config.status: creating plugins/sample/Makefile config.status: creating plugins/audiocd/Makefile config.status: creating plugins/audioscrobbler/Makefile config.status: creating plugins/cd-recorder/Makefile config.status: creating plugins/daap/Makefile config.status: creating plugins/ipod/Makefile config.status: creating plugins/iradio/Makefile config.status: creating plugins/lirc/Makefile config.status: creating plugins/lyrics/Makefile config.status: creating plugins/sample-python/Makefile config.status: creating plugins/pythonconsole/Makefile config.status: creating plugins/artdisplay/Makefile config.status: creating plugins/artdisplay/artdisplay/Makefile config.status: creating plugins/magnatune/Makefile config.status: creating plugins/magnatune/magnatune/Makefile config.status: creating plugins/jamendo/Makefile config.status: creating plugins/jamendo/jamendo/Makefile config.status: creating plugins/generic-player/Makefile config.status: creating plugins/rb/Makefile config.status: creating plugins/power-manager/Makefile config.status: creating plugins/visualizer/Makefile config.status: creating plugins/mmkeys/Makefile config.status: creating bindings/Makefile config.status: creating bindings/python/Makefile config.status: creating help/Makefile config.status: creating po/Makefile.in config.status: creating tests/Makefile config.status: creating doc/Makefile config.status: creating doc/reference/Makefile config.status: creating backends/Makefile config.status: creating backends/gstreamer/Makefile config.status: creating remote/Makefile config.status: creating remote/dbus/Makefile config.status: creating config.h config.status: config.h is unchanged config.status: executing depfiles commands config.status: executing intltool commands config.status: executing default-1 commands config.status: executing po/stamp-it commands configure: Rhythmbox was configured with the following options: configure: ** Tree database is enabled configure: ** Tag writing is enabled configure: ** Track transfer is enabled configure: iPod write support is disabled configure: ** Multimedia keys support is enabled configure: ** MusicBrainz support is enabled configure: ** GStreamer 0.10 player is enabled configure: iPod integration disabled configure: ** MTP integration enabled configure: ** CD burning support enabled configure: DAAP (music sharing) support is disabled configure: libnotify support is disabled configure: ** HAL support enabled configure: ** Python support enabled configure: ** gnome-keyring support enabled configure: Audioscrobbler support disabled configure: ** Separate metadata helper process enabled configure: using internal libsexy configure: End options I am attaching my config.log as well just in case it could help. Thanks again. Nic
Created attachment 83962 [details] config log
Hi. I'm a user with an MTP device interested in testing the patch. I have some experience compiling apps from source, downloading from CVS, etc., but not much with applying patches. What should I do? By the way, I really appreciate that someone is working on this problem. MTP media devices are becoming increasingly common... I bought my Creative player as a lower-cost alternative to the iPod, and have several friends who have done the same. Keep up the good work. Bill
Created attachment 84021 [details] [review] Version 0.3 of the patch
Here is a new version of the patch that should apply cleanly against the latest svn. You'll need to at least run ./configure, maybe ./autogen.sh, and then make, make install. For me hotplug is broken in this version and I can't seem to get it working right now, so you'll need to have the device plugged in and turned on when you start rhythmbox. BTW, how do one obsolete a patch in bugzilla?
(In reply to comment #22) > BTW, how do one obsolete a patch in bugzilla? There should be a drop-down box under "Status" for each patch. If you don't have enough bugzilla permissions you'll probably only be able to obsolete your own patches. I obsoleted the earlier version for you.
Hi Peter, the latest patch works very well for me so far. It applies cleanly to the latest svn (Bill: save the patch to a text file, patchmtp in the rhythmbox svn directory, apply with "patch -p0 < patchmtp && ./autogen.sh --with-mtp && make && sudo make install"). I can transfer files to the device but haven't found how to copy files from the device to the hard disk library, maybe a bug? If the device is not connected when starting rhythmbox, it can still be enabled by unchecking and checking again the mtp plugin. The plugin works extremely fast (8 gigs of music read in 30 seconds) and it hasn't crash anything yet! Keep up the good work Peter, very much appreciated. Nic P.S.: I get this error in terminal: Autodetected device "Creative Zen MicroPhoto" (VID=041e,PID=413c) is known. PTP: Opening session Connected to MTP device. sys:1: GtkWarning: gtk_ui_manager_insert_action_group: assertion `g_list_find (self->private_data->action_groups, action_group) == NULL' failed WARNING: LIBMTP_Get_Tracklisting() is deprecated. WARNING: please update your code to use LIBMTP_Get_Tracklisting_With_Callback() when disconnecting: PTP: Closing session rb_mtp_plugin_source_deletedprocess 31176: Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application. sys:1: GtkWarning: gtk_widget_hide: assertion `GTK_IS_WIDGET (widget)' failed
(In reply to comment #24) > (Bill: save the patch to a text file, patchmtp in the rhythmbox svn > directory, apply with "patch -p0 < patchmtp && ./autogen.sh --with-mtp && make > && sudo make install"). I wouldn't suggest installing random snapshots like this, but you can if you want. One alternative is passing "--enable-uninstalled-build" to autogen.sh/configure and then running from within the source tree with "shell/rhythmbox". > I can transfer files to the device but haven't found > how to copy files from the device to the hard disk library, maybe a bug? I imagine you also can't play tracks off your MTP device, since that and copying from it use the same mechanism. As mentioned in earlier comments, this either needs a special GStremer element to be written, or much better getting something like GnomeVFS to be able to read tracks from the device (so we can use the existing GStreamer element).
Thanks James, I'll try your method next time. What works: Plug and unplug via check/uncheck of plugin List music from device (with Control-B, view by artist, etc) Transfer music from computer to device (drag and drop) Delete music from device Disconnects fine What doesn't work for me: Transfer podcast to device, nothing happens when you drag a podcast to the device icon) Music files are transfered into the Music directory on the device but it doesn't create a directory for the artist/album (badly needed) Playing music directly from the device (not a big deal for most people at this point) Thanks again for your work, Nic
(In reply to comment #26) > What doesn't work for me: > > Transfer podcast to device, nothing happens when you drag a podcast to the > device icon) Tried this last time but couldn't get it to work. Will try again. > Music files are transfered into the Music directory on the device but it > doesn't create a directory for the artist/album (badly needed) Does any other program that transfer music with libmtp do this (gnomad or amorak). I don't know if it's the program or libmtp that should control that. > Playing music directly from the device (not a big deal for most people at this > point) As said in earlier comments, this is a bit harder to fix. (In reply to comment #24) > I can transfer files to the device but haven't found > how to copy files from the device to the hard disk library, maybe a bug? Since it's possible to transfer files to the computer with libmtp we could do something like a "Transfer to library"-button. I dont how to do it with drag and drop, since we can't supply a valid url to the file. Another solution would be to use a callback that gets called from the library-source just before the transfer so we could transfer the track and update the entries url. We might even be able to use this method as a hack to get playing to work while waiting for a better solution.
Dear Peter, if I can express myself freely, there seems to be only a handful of issues that need to work before being widely usable by the masses. Transfer back from the device to the hard disk should work (delete already does and transfer music file to the device works), transfer podcasts to the device should work, and create artist/album directories should work. Both gnomad2 and amarok create the right directory structure when transferring files to the device. Actually, there is an option in amarok to change the structure using things like %a - %b to create /Music/Artist - Album/ structure. Short of giving everyone the option to change it, I think a default structure using the artist and album names to create on directory would suffice. e.g. Music/Bob dylan - Blonde on blonde/musicfiles.mp3 In response to your comment on a "Transfer to library" button, perhaps one could find out how this work for the ipod and use a similar system. In the mean time, dragging the files from the device to the the Music tab seemed like the logical thing to do as the transfer from the library to the device works like that. Thanks again! Nic
I downloaded the latest source from Subversion and tried, with my limited knowledge, to apply the patch. This is what happened. It seemed to almost work... any help would be greatly appreciated; I am eager to test this patch. bill@HAL-9000:~/rhythmbox$ patch -i ../mtp-patch-0.3.patch patching file configure.ac patching file Makefile.am Hunk #1 FAILED at 47. 1 out of 1 hunk FAILED -- saving rejects to file Makefile.am.rej patching file rb-mtp-plugin.c patching file rb-mtp-source.h patching file rb-mtp-source.c The next patch would create the file Makefile.am, which already exists! Assume -R? [n] y patching file Makefile.am Hunk #1 FAILED at 1. File Makefile.am is not empty after patch, as expected 1 out of 1 hunk FAILED -- saving rejects to file Makefile.am.rej patching file mtpdevice.rb-plugin.desktop.in patching file mtp-ui.xml
Bill, you might want to remove all the files in your directory (other than the patch i guess) with "rm -fr *", then download svn again "svn update", then apply patch on clean svn. It should apply without problems. Nic
The same problem occurs. Perhaps I did something else wrong? I used the following SVN command to check out: svn co http://svn.gnome.org/svn/rhythmbox/trunk rhythmbox I clicked on the link at the bottom of this page for patch version 0.3, saved it to my home directory, and as detailed above, typed: patch -i ../mtp-patch-0.3.patch I also tried using the -l flag with patch, but that didn't help.
Peter, there is this bit in the amarok MTP plugin where the directory structure is set when sending a track to the device. I thought maybe it could be of some help. The plugin was written by Andy Kelk (<andy@mopoke.co.uk>). You can find this file in the src directory of amarok at amarok/src/mediadevice/mtp/mtpmediadevice.cpp Lines > 275 By the way, I guess the artist and albums have to be replaced by "unknown" if the info is not in the mp3 file though. Also, amarok has problems creating the structure if the artist and album have french accents in them, you might want to keep this in mind. // try and create the requested folder structure uint32_t parent_id = 0; if( !m_folderStructure.isEmpty() ) { parent_id = checkFolderStructure( bundle ); if( parent_id == 0 ) { debug() << "Couldn't create new parent (" << m_folderStructure << ")" << endl; Amarok::StatusBar::instance()->shortLongMessage( genericError, i18n( "Cannot create parent folder. Check your structure." ), KDE::StatusBar::Error ); return 0; } } else { parent_id = getDefaultParentId(); } debug() << "Parent id : " << parent_id << endl; m_critical_mutex.lock(); debug() << "Sending track... " << bundle.url().path().latin1() << endl; int ret = LIBMTP_Send_Track_From_File( m_device, bundle.url().path().latin1(), trackmeta, progressCallback, this, parent_id ); m_critical_mutex.unlock();
Bill, there is no reason you should get an error telling you the Makefile.am already exist if you deleted it. In the rhythmbox directory, run this: rm -fr * svn update copy the patch to the directory and run it with: patch -p0 < patchmtp you should get this: patching file configure.ac patching file plugins/Makefile.am patching file plugins/mtp/rb-mtp-plugin.c patching file plugins/mtp/rb-mtp-source.h patching file plugins/mtp/rb-mtp-source.c patching file plugins/mtp/Makefile.am patching file plugins/mtp/mtpdevice.rb-plugin.desktop.in patching file data/ui/mtp-ui.xml Nic
It compiled! Thank you for your help, Nic. And it works with my Creative Zen V! Glitches: 1. the device shows up as "muu," which I certainly did not name it 2. RB doesn't detect the device at all unless I plug it in and then start the program 3. there is no way to unmount the device 4. as Nic noted, transferring podcasts doesn't work, nor does playing music from the device, nor transferring music from the device But I was able to transfer music to the Zen V, and listen to it. I don't know how important it is for RB to create a directory structure on the device, since--as far as I know--the device uses a proprietary sort of file system which I can't mount or browse. My Zen V gives me the option of creating a FAT32 partition which I can use as a USB flash drive--but this is separate from the music, which seems inaccessible. I was under the impression that MTP devices were set up like iPods, in that the MP3s could have more or less arbitrary filenames, but the device's firmware would keep a database of the music. Bill
Oh, and here's some stdout: Autodetected device "Creative Zen V" (VID=041e,PID=4150) is known. PTP: Opening session Connected to MTP device. sys:1: GtkWarning: gtk_ui_manager_insert_action_group: assertion `g_list_find (self->private_data->action_groups, action_group) == NULL' failed WARNING: LIBMTP_Get_Tracklisting() is deprecated. WARNING: please update your code to use LIBMTP_Get_Tracklisting_With_Callback() (rhythmbox:16919): RhythmDB-WARNING **: attempting to create entry that already exists: 0. World News Bulletin 14_00 GMT.mp3 That "World News Bulletin" file is a podcast that I had previously transferred to the device with Banshee. I guess it gave me that message because there's a similarly named file in the music library on my hard disk. And also, when I closed RB: PTP: Closing session rb_mtp_plugin_source_deletedprocess 16919: Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application. sys:1: GtkWarning: gtk_widget_hide: assertion `GTK_IS_WIDGET (widget)' failed Bill
(In reply to comment #34) > 1. the device shows up as "muu," which I certainly did not name it This was intentional. The api for looking up them name of the device had changed and I just named all 'muu' until I'd the time to look up the new function name. This is fixed now in my repository. > 2. RB doesn't detect the device at all unless I plug it in and then start the > program Known issue. I've some problem with the hal code that I think should work, but it doesn't. If someone is proficient with hal I would really appreciate some help. The code is in rb-mtp-plugin.c > 3. there is no way to unmount the device Haven't got around to fix this, but I do have the context menu working now. > 4. as Nic noted, transferring podcasts doesn't work, nor does playing music > from the device, nor transferring music from the device Podcast transfers are fixed now. Still now transfer back to computer though. Does any other libmtp software than gnomad2 do this? > I don't know how important it is for RB to create a directory structure on the > device, since--as far as I know--the device uses a proprietary sort of file > system which I can't mount or browse. You can tell rhythmbox how to place the files when extracting them from cd and we should probably use the same setting. There is probably a function creating that uri but I'll need to look that up. (In reply to comment #35) > rb_mtp_plugin_source_deletedprocess 16919: Applications must not close shared > connections - see dbus_connection_close() docs. This is a bug in the > application. Fixed now.
Hi Peter, I wonder if this part of the amarok plugin could give you a hand to transfer file from the device to the hard disk: /** * Get a list of selected items, download them to a temporary location and * organize. */ int MtpMediaDevice::downloadSelectedItemsToCollection() { QPtrList<MediaItem> items; m_view->getSelectedLeaves( 0, &items ); KTempDir tempdir( QString::null ); tempdir.setAutoDelete( true ); KURL::List urls; QString genericError = i18n( "Could not copy track from device." ); int total,progress; total = items.count(); progress = 0; if( total == 0 ) return 0; setProgress( progress, total ); for( MtpMediaItem *it = dynamic_cast<MtpMediaItem*>(items.first()); it && !(m_canceled); it = dynamic_cast<MtpMediaItem*>(items.next()) ) { if( it->type() == MediaItem::TRACK ) { QString filename = tempdir.name() + it->bundle()->filename(); int ret = LIBMTP_Get_Track_To_File( m_device, it->track()->id(), filename.utf8(), progressCallback, this ); if( ret != 0 ) { debug() << "Get Track failed: " << ret << endl; Amarok::StatusBar::instance()->shortLongMessage( genericError, i18n( "Could not copy track from device." ), KDE::StatusBar::Error ); } else { urls << filename; progress++; setProgress( progress ); } } else { total--; setProgress( progress, total ); } } hideProgress(); CollectionView::instance()->organizeFiles( urls, i18n( "Move Files To Collection" ), false ); return 0; }
Thank you for your detailed response, Peter--and your continued efforts. Again, I'm glad that work on this patch is proceeding so quickly. I'll continue to monitor this thread and test future updates with my Zen.
Created attachment 84442 [details] [review] Version 0.4 of the patch
It was a while since the last patch, for some strange reason teachers doesn't seam to accept writing code as a legitimate reason to not do ones homework :P. A lot of changes this time. All testing is welcome. Changes from 0.3 to 0.4 * Renamed the plugin folder to mtpdevice. * Moved the mtp-ui.xml file to the plugin folder. * Copy podcasts now works. * Play music from the device works. * Copy music from the device works. * The plugin actually checks if the device can handle the mime-type of a file before transferring it. * The gui-actions works now. * Renaming the device works. * Ejecting the device works. What still doesn't work. * The hotplug code is broken. It worked well when I wrote it originally. If someone with more experience with hal could take a look at this I would appreciate it very much. The problem is that the callbacks I register never gets called. * I tried to add suport for transcoding files if the mimetype isn't supported, but since the RBEncoder is threaded and libmtp and the plugin is very non-threadsafe it's no hit. * When transferring files to the device all files ends up in the root directory. It probably should use the rhythmbox setting on how to organize files copied to the library. Is there a function to get this path from a entry? * Sometimes when on tries to play music from the device the magnatune plugin crashes and make rhythmbox jump to the next song. I think this is a bug in the magnatune source.
Hi Peter, thanks for your amazing work. I have yet to be able to compile the patch though. First, I think there are two extra repeating sections in the patch at the beginning. After removing them, the patch applies cleanly. I then get an error during autogen.sh: Running automake-1.9... cp: cannot stat `INSTALL': No such file or directory configure.ac: installing `./install-sh' configure.ac: installing `./missing' backends/Makefile.am: installing `./depcomp' bindings/python/Makefile.am: installing `./compile' plugins/artdisplay/artdisplay/Makefile.am:4: installing `./py-compile' Makefile.am: installing `./INSTALL' configure.ac:951: required file `plugins/mtpdevice/Makefile.in' not found I can't make any sense of it but using the patch 0.3, I don't get this error. I tried reusing a Makefile.in created with patch 0.3 but then the make borks out when compiling the mtp plugin. Nic
Marking 0.3 of the patch obsolete, as I'm guessing that 0.4 is supposed to obsolete it.
Hi Peter, thanks for the new patch. I just succeeded in patching, compiling and starting rhythmbox. There are a few problems in the patch (not complaining): 1. There are two repeating parts at the top, i removed them 2. There is a part missing to create the /mtpdevice/Makefile.am, I added it by copy and paste from patch 0.3. That probably brings problems later If I remember well, then the patch applies cleanly and the ./autogen.sh --with-mtp does it's thing without error. 3. During make, it couldn't find the rb-encoder.h which had to be changed in the patch to ../../backends/rb-encoder.h instead of straight rb-encoder.h 4. Then the make works but rhythmbox segfaults when it cannot find the mtp-ui.xml at startup. This is probably due to me copy and pasting the /mtpdevice/Makefile.am part of your patch-0.3 to 0.4. The mtp plugins file all end up in the plugins root directory (/usr/local/lib/rhythmbox/plugins/) instead of /usr/local/lib/rhythmbox/plugins/mtpdevice. If I mv the files into the mtpdevice directory as well as the mtp-ui.xml, rhythmbox starts fine. Unfortunately, I forgot my usb cable from home so I cannot test the actual patch. I am uploading the patch I used to compile as patch-0.4b. Thanks again for your work. Nic
Created attachment 84513 [details] [review] patch 0.4b
Created attachment 84599 [details] [review] Version 0.4.1 of the patach Sorry about the last patch, it had some Makefile problems. This one should hopefully fix all of them. Tried it on a fresh checkout of rhythmbox and everything worked.
Hi Peter, thanks again for the latest patch. It works great, your plugin is already ahead of anything else out there. Your work is very much appreciated. I have started a thread in Ubuntu Feisty explaining how to get it working. Hopefully, people with coding experience will step up and give you a hand (http://ubuntuforums.org/showthread.php?t=385371&highlight=mtp). I am still unsure about this, but is seems that segfaulting happens when using the latest libmtp-0.1.4, perhaps you can confirm this. Also, if I try to play a song from the device, it works well sometimes, and some other, it just goes through the playlist, trying every song but without playing them. It works on and off, I can't seem to be able to reproduce the problem reliably, I'll keep trying and I 'll give you the output. Copying files back and forth from the device, including podcasts works flawlessly for me, great! As for the copying the files to a specific directory, couldn 't you use the same method that is used in amarok (see earlier post)? I way to enable and disable the plugin depending is it's connected or not seems necessary but other than that, I find the plugin to be rock solid here (other than some minor playback issues). Hope this makes it into the next rhythmbox release. Nic
If you wanted some more widespread testing, I'd be happy to commit this to svn. I don't have a device to test with, but the code looks okay: Some potential changes: * RBRemovableMediaSource now has some common functionality pushed up to it. by setting impl_can_paste to rb_true_function and implementing impl_get_mime_types, you could implement impl_build_dest_uri to give a temp location, and copy it to the device in impl_track_added then remove the temp file. That means you could remove impl_receive_drag, impl_paste, etc. I think this would work * it looks like there are several memory leaks, e.g. not freeing the result of libhal_get_all_devices() A few other nitpicks * variables should be declared at the start of functions, not half-way though * you've occasionally got four-spaces for indentation, instead of tabs * add a space between opening parenthesises and the bit before, e.g. "LIBMTP_Detect_Descriptor (&vid, &pid);" * use 'rb_debug ("foo")' instead of 'g_print ("foo\n")', you can run "rhythmbox -D mtp" to just get the debug output from your plugin
With 0.4.1, playing from the device, transferring podcasts, and ejecting the device all seem to work. Good job, Peter! However, in the case of songs that were transferred to the device using programs other than RB (most songs, on my Zen), songs would not play from the device if the cover art plugin was enabled. Stdout: /usr/local/lib/rhythmbox/plugins/artdisplay/__init__.py:188: GtkWarning: gdk_pixbuf_composite: assertion `dest_x >= 0 && dest_x + dest_width <= dest->width' failed self.anim.composite (ret, max (x, 0), max (y, 0), w, h, x, y, 1, 1, gtk.gdk.INTERP_BILINEAR, 255) Disabling the art plugin fixed the problem. Also, the list of songs on the device doesn't seem to update after one transfers songs to it. This would be helpful. B.
Good to hear that the plugin is works well for most people. :) Right now I'm in London doing a three week internship at last.fm, so I won't be able to produce any more mtp-plugin code before Easter.
Created attachment 86425 [details] [review] updated patch Updated to svn, and fixed some memory leaks, style things, bugs, etc. I don't have a device to test with, so I may have broken something.
Hi "Doc", thanks for the patch. Unfortunately, it doesn't compile cleanly on my Feisty 7.04 system. I get this: cc1: warnings being treated as errors rb-mtp-plugin.c: In function 'impl_activate': rb-mtp-plugin.c:168: warning: implicit declaration of function 'rb_mtp_plugin_setup_dbus_hal_connection' rb-mtp-plugin.c:168: warning: nested extern declaration of 'rb_mtp_plugin_setup_dbus_hal_connection' rb-mtp-plugin.c:148: warning: unused variable 'devices' rb-mtp-plugin.c:147: warning: unused variable 'i' rb-mtp-plugin.c:147: warning: unused variable 'num' rb-mtp-plugin.c: In function 'impl_deactivate': rb-mtp-plugin.c:204: error: 'DBusError' undeclared (first use in this function) rb-mtp-plugin.c:204: error: (Each undeclared identifier is reported only once rb-mtp-plugin.c:204: error: for each function it appears in.) rb-mtp-plugin.c:204: error: expected ';' before 'error' rb-mtp-plugin.c:217: warning: implicit declaration of function 'dbus_error_init' rb-mtp-plugin.c:217: warning: nested extern declaration of 'dbus_error_init' rb-mtp-plugin.c:217: error: 'error' undeclared (first use in this function) rb-mtp-plugin.c:218: warning: implicit declaration of function 'libhal_ctx_shutdown' rb-mtp-plugin.c:218: warning: nested extern declaration of 'libhal_ctx_shutdown' rb-mtp-plugin.c:218: error: 'RBMtpPlugin' has no member named 'hal_context' rb-mtp-plugin.c:219: warning: implicit declaration of function 'libhal_ctx_free' rb-mtp-plugin.c:219: warning: nested extern declaration of 'libhal_ctx_free' rb-mtp-plugin.c:219: error: 'RBMtpPlugin' has no member named 'hal_context' rb-mtp-plugin.c:220: warning: implicit declaration of function 'dbus_connection_unref' rb-mtp-plugin.c:220: warning: nested extern declaration of 'dbus_connection_unref' rb-mtp-plugin.c:220: error: 'RBMtpPlugin' has no member named 'dbus_connection' rb-mtp-plugin.c:221: warning: implicit declaration of function 'dbus_error_free' rb-mtp-plugin.c:221: warning: nested extern declaration of 'dbus_error_free' make[3]: *** [rb-mtp-plugin.lo] Error 1 make[3]: Leaving directory `/home/nt271/temp/compile/rhythmbox/plugins/mtpdevice' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory `/home/nt271/temp/compile/rhythmbox/plugins' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/nt271/temp/compile/rhythmbox' make: *** [all] Error 2
I get the exact same errors, with Feisty.
Created attachment 86722 [details] [review] fixed for svn trunk There were some HAL-related changes in trunk which broke the patch, this should fix it. Note that MTP support now requires HAL (which shouldn't be a huge problem for anyone).
Applies and builds fine on Feisty. Doesn't show tracks I've transferred to the device that session until I restart rhythmbox, though. And it can't play tracks from the device. Output: Autodetected device "Creative Zen Touch (MTP mode)" (VID=041e,PID=4131) is known. PTP: Opening session Connected to MTP device. (rhythmbox:6987): Gtk-CRITICAL **: gtk_ui_manager_insert_action_group: assertion `g_list_find (self->private_data->action_groups, action_group) == NULL' failed WARNING: LIBMTP_Get_Tracklisting() is deprecated. WARNING: please update your code to use LIBMTP_Get_Tracklisting_With_Callback()
Confirmed, with my Zen V. Playing tracks from the device worked with the patch v0.4....
Hi again, its been a while since the last patch. I've been very busy with my final exams after returning from London, so I haven't had the time to do any work on the plugin. But now at last my final are over over over !!! :D Changes between patch 0.5 and 0.6: * Entries shows up on the device directly after transfer. * Playback from the device works again. * The source now derives from the RBRemovableMediaSource with all the goodies that brings. simpler code, transcoding etc... * Clean-ups. To make it possible to derive from RBRemovableMediaSource I'll needed to modify it. The patch is available here http://bugzilla.gnome.org/show_bug.cgi?id=443367. I also started writing some code to add albumart-transfer support, but I discovered that my device (Creative MicroPhoto) doesn't support that. If someone has a device that supports albumart and want to help out, I could point out what needs to be done. The biggest showstopper right now is the need to have the device plugged in at startup. I'll have a look at that code and try to figure something out. When that is fixed I think it would be a good thing to commit it to HEAD to get a little more testing.
Created attachment 89263 [details] [review] PVersion 0.2 of the patch
Created attachment 89264 [details] [review] Version 0.6 of the patch
If anyone wonder, "PVersion 0.2 of the patch" was my hands slipping on the keyboard. Could someone with bugzilla privileges obsolete that one and the "fixed for svn trunk" one please.
I don't have a MTP device to test with, but it looks okay. If you wanted, I'm happy to commit it to SVN so you can get some more widespread testing.
Hi all, thanks again Peter for your efforts, greatly appreciated once again. The latest patch doesn't seem to compile cleanly for me: rb-mtp-source.c: In function 'impl_get_mime_types': rb-mtp-source.c:792: error: 'ret' undeclared (first use in this function) rb-mtp-source.c:792: error: (Each undeclared identifier is reported only once rb-mtp-source.c:792: error: for each function it appears in.) cc1: warnings being treated as errors rb-mtp-source.c:795: warning: assignment makes pointer from integer without a cast make[3]: *** [rb-mtp-source.lo] Error 1 make[3]: Leaving directory `/home/nt271/temp/compile/rhythmbox/plugins/mtpdevice' make[2]: *** [all-recursive] Error 1 make[2]: Leaving directory `/home/nt271/temp/compile/rhythmbox/plugins' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/nt271/temp/compile/rhythmbox' make: *** [all] Error 2 Nic
Created attachment 89275 [details] [review] Version 0.6.1 of the patch Sry, my fault. This one should work better.
Hi Peter, thanks for the updated patch, it compiles fine. Everything seems to work great, playback, remove/add including podcasts. It also shows the transfer progress which is really nice. Unfortunately, it crashes when transfering a song from a DAAP share directly to the device: (13:34:38) [0x80f8028] [progress_timeout_cb] rb-encoder-gst.c:269: encoding progress at 89 out of 90 (13:34:38) [0x80f8028] [progress_cb] rb-removable-media-manager.c:655: transfer progress 0.988889 (13:34:38) [0x80f8028] [rb_shell_transfer_progress_cb] rb-shell.c:1861: transferred 0 tracks out of 1 (13:34:38) [0x80f8028] [rb_statusbar_sync_status] rb-statusbar.c:417: updating status with: '95 songs, 6 hours and 38 minutes, 587.2 MB', '', 999.000000 (13:34:38) [0x80f8028] [rb_statusbar_sync_status] rb-statusbar.c:417: updating status with: '95 songs, 6 hours and 38 minutes, 587.2 MB', '', 999.000000 (13:34:38) [0x80f8028] [bus_watch_cb] rb-encoder-gst.c:223: received EOS (13:34:38) [0x80f8028] [completed_cb] rb-removable-media-manager.c:665: completed transferring track to file:///tmp/to_mtp_device.mp3 (rhythmbox:10324): GLib-CRITICAL **: g_path_get_basename: assertion `file_name != NULL' failed Segmentation fault (core dumped) Thanks again! Nic
Hi Peter, as for using HAL to connect the device, couldn't you use the implementation written for the ipod plugin? Here are the parts which look relevant: From rb-ipod-source.c LINES 28-34 #ifdef HAVE_HAL #include <libhal.h> #include <dbus/dbus.h> #endif #include <libgnomevfs/gnome-vfs-utils.h> #include <libgnomevfs/gnome-vfs-volume.h> #include <libgnomevfs/gnome-vfs-volume-monitor.h> LINES 63-65 #ifdef HAVE_HAL static gboolean hal_udi_is_ipod (const char *udi); #endif LINES 752-845 #ifdef HAVE_HAL gchar *udi; #endif if (gnome_vfs_volume_get_volume_type (volume) != GNOME_VFS_VOLUME_TYPE_MOUNTPOINT) { return FALSE; } #ifdef HAVE_HAL udi = gnome_vfs_volume_get_hal_udi (volume); if (udi != NULL) { gboolean result; result = hal_udi_is_ipod (udi); g_free (udi); if (result == FALSE) { return FALSE; } } #endif return rb_ipod_volume_has_ipod_db (volume); } #ifdef HAVE_HAL static gboolean hal_udi_is_ipod (const char *udi) { LibHalContext *ctx; DBusConnection *conn; char *parent_udi; char *parent_name; gboolean result; DBusError error; gboolean inited = FALSE; result = FALSE; dbus_error_init (&error); conn = NULL; parent_udi = NULL; parent_name = NULL; ctx = libhal_ctx_new (); if (ctx == NULL) { /* FIXME: should we return an error somehow so that we can * fall back to a check for iTunesDB presence instead ? */ rb_debug ("cannot connect to HAL"); goto end; } conn = dbus_bus_get (DBUS_BUS_SYSTEM, &error); if (conn == NULL || dbus_error_is_set (&error)) goto end; libhal_ctx_set_dbus_connection (ctx, conn); if (!libhal_ctx_init (ctx, &error) || dbus_error_is_set (&error)) goto end; inited = TRUE; parent_udi = libhal_device_get_property_string (ctx, udi, "info.parent", &error); if (parent_udi == NULL || dbus_error_is_set (&error)) goto end; parent_name = libhal_device_get_property_string (ctx, parent_udi, "storage.model", &error); if (parent_name == NULL || dbus_error_is_set (&error)) goto end; if (strcmp (parent_name, "iPod") == 0) result = TRUE; end: g_free (parent_udi); g_free (parent_name); if (dbus_error_is_set (&error)) { rb_debug ("Error: %s\n", error.message); dbus_error_free (&error); dbus_error_init (&error); } if (ctx) { if (inited) libhal_ctx_shutdown (ctx, &error); libhal_ctx_free(ctx); } dbus_error_free (&error); return result; } #endif
Well that code doesn't really do what I want, which is to monitor hal for new devices. But anyway I solved the problem. I had to setup the dbus connection to the gmainloop with dbus_connection_setup_with_g_main, something not needed earlier.
Created attachment 89341 [details] [review] Version 0.7 of the patch Changes between version 0.6.1 and 0.7: * Detection of added and removed devices with hal works now. * Transfer of tracks from a daap source should hopefully work now. (I don't have access to one so I can't test). Even if it don't work it won't crash. * New name "Portable Players - MTP" to be more consistent. If this patch get some positive initial testing I think it's good to go for svn. Is there anything more I need to do before that? Should I add my name to the AUTHORS file?
An easy way to test daap support is with tangerine.
Hi Peter, thanks again for the newest patch. HAL support works great! Really quite amazing. We can plug and unplug the device and it gets picked up everytime, perfect. Podcast, music drag and drop from the local collection or networked DAAP share as well as playback seem to work flawlessly as well. This patch is definitely ready to be included in SVN. Great work! Nic
This might be more of a question for "Doc", but since MTP devices are usually 1gig and higher, it would seem to suggest that the browser view should be used by default for this plugin, perhaps there is a way to do this in gconf? Nic
Since this uses easily predictable filenames in /tmp, we should be very careful to ensure there are no race conditions etc. that could allow the typical /tmp symlink attacks.
Some specific comments: In impl_delete_thyself: + tracks = rb_source_get_entry_view (asource); + rb_entry_view_select_all (tracks); + tem = rb_entry_view_get_selected_entries (tracks); This isn't a very good way of getting a list of all the tracks.. maybe set the value_destroy_func on the hashtable to LIBMTP_destroy_track_t so destroying the hash table cleans up properly. In impl_copy: + for (selected_entries = rb_entry_view_get_selected_entries (rb_source_get_entry_view (source)); + selected_entries != NULL; + selected_entries = g_list_next (selected_entries)) { This leaks the selected_entries list. In rb_mtp_source_transfer_track_to_disk: + if (device == NULL || track == NULL || uri == "") { + return FALSE; + } uri == "" isn't a useful check; should be uri[0] == '\0' or strlen(uri) == 0. + guri = gnome_vfs_uri_new (uri); + if (!check_dir_has_space (gnome_vfs_uri_get_path(gnome_vfs_uri_get_parent (guri)), track->filesize)) { + g_object_unref (guri); + return FALSE; + } + gnome_vfs_uri_unref (guri); The g_object_unref here should be a gnome_vfs_uri_unref.
One potential idea for using a GStreamer pipeline for writing to the device would be to use fdsink, and LIBMTP_Send_Track_From_File_Descriptor. The source could create a pipe and use that function, and then use "fd://%d" with the other end of the pipe as the destination URI. Something similar could probably be done for reading from the device, but it would be a bit more complicated - one way would be to write a custom element which uses GstFdSrc and handles x-rb-mtp:// URIs. Problematic is the fact that it needs a pointer to the device structure and a track id. There are some icky solutions like g_strdup_printf ("x-rb-mtp://%d/%lx", trackid, (long)device), and possibly even a good solution. Also, in rather than mapping the file extension to the filetype we set, mapping the mimetype is probably a better idea.
Created attachment 89444 [details] [review] Version 0.7.1 of the patch Changes between 0.7 and 0.7.1: * (hopefully) Fixed all Jonathan Matthews comments * Now looks up filetype from mimetype instead of extension. * Fixed a bug in impl_track_added that caused a ghost-track and some warnings to the console. * Fixed a bug in rb_mtp_source_get_playback_uri that caused playback to fail every other time. I havnt looked very closely on the idea of using a GstFdSinc for writing, but I think I get it.
From a user perspective (...my perspective), the last basic features needed are: 1. Browser view by default 2. Transfer tracks using a directory structure Music/Artist/Album More advanced features: 3. Playlist support (available in gnomad2 & amarok, thus not badly needed here) 4. AlbumArt support (my player doesn't support it, so probably not needed at all!) Thanks all for your hard work. Nic
Your 1st point is related to bug #420476
Created attachment 89471 [details] [review] 0.7.2 Actually, (1) isn't related to bug 420476 - that bug is about letting you control which of genre/artist/album browser appear per-source (at least, I think that's what it's about). This patch is basically the same as the last one, with a couple of memory leaks, some code-style stuff (spaces between function names and the opening paren, whitespace at end of lines, etc) fixes, fixing a few warnings and the like. Assuming that I haven't broken anything (I can't test more than compiling myself), I'm happy to commit this to trunk.
Second part of bug #420476 is « Also, the state be restored for each source on restart which is currently only true for the Library, Podcast and Internet Radio source. » which I assumed included browser shown/hidden in addition to the visibility of the various browsers, that's why I mentioned it here.
Okay, I hate to bring bad news but there's a new things not working: 1. When I tried to transfer a wma file to the device, it gets re-encoded in mp3, but then doesn't show up on the device... there seems to be two issues here. First it shouldn't get reencoded as my device plays wma files natively, but if it does reencode and transfer it, it should show up in the list. error: (15:59:57) [0x80f8028] [rb_statusbar_sync_status] rb-statusbar.c:417: updating status with: '16 songs, 1 hour and 1 minute, 56.4 MB', '', 999.000000 (15:59:57) [0x80f8028] [rb_statusbar_sync_status] rb-statusbar.c:417: updating status with: '16 songs, 1 hour and 1 minute, 56.4 MB', '', 999.000000 (15:59:57) [0x80f8028] [bus_watch_cb] rb-encoder-gst.c:223: received EOS (15:59:57) [0x80f8028] [completed_cb] rb-removable-media-manager.c:665: completed transferring track to file:///tmp/Bright%20Eyes-Mirrors%20and%20Fevers.mp3 PTP: I/O error LIBMTP_Send_Track_From_File_Descriptor: Could not send object (16:00:09) [0x80f8028] [transfer_track] rb-mtp-source.c:677: Tracktransfer failed (16:00:09) [0x80f8028] [rb_shell_transfer_progress_cb] rb-shell.c:1861: transferred 1 tracks out of 1 I just wanted to add that the plugin works well using the latest libmtp-0.1.5, which will be distributed with Ubuntu Gutsy. Nic
Sometimes (not reproducible) when I press "Eject", i get: PTP: Closing session PTP: request code 0xbfb0eef4 sending req wrote only 12 bytes instead of 148029640 ERROR: Could not close session! File naming problems: Let's say I transfer 1 mp3 file on the device: It's taken from the directory /Jet, The/Shine on/01-Jet-L'esprit D'escalier.mp3 On the device, it is now called: /tmp/The Jet-01 - Jet - L'esprit D'escalier.mp3.mp3 (extra /tmp/The Jet- and extra .mp3) If I copy it back in the library, it becomes The Jet/The Jet - Shine on/00 - 01 - Jet - L'esprit D'escalier.mp3.b-mtp-226576 The way the new directory is created is fine, but the name of the file is totally different, and it lacks the proper extension. Also, the double 00 shouldn't probably be there. Thanks again for your hard work! Nic
I'm going to Copenhagen, Denmark tomorrow and won't be able to do any work until at least Monday. I haven't had the time to test the modified patch, but if it gets ok from someone else that has tested it, then I'm ok with it getting commited to trunk. (In reply to comment #79) > Sometimes (not reproducible) when I press "Eject", i get: > PTP: Closing session > PTP: request code 0xbfb0eef4 sending req wrote only 12 bytes instead of > 148029640 > ERROR: Could not close session! That is most probably a libmtp error. Please report it to the libmtp developers. > File naming problems: <snip> I'll have a look at that when I get back.
I've committed the patch to svn trunk, if there are issues we can fix them there.
Created attachment 89673 [details] [review] use a pipe for transfers I have no idea if it actually works (it almost certainly doesn't), but this is the kind of thing I was thinking of w.r.t. using a pipe to link RBEncoder and libmtp.
I get the principle of what you try to do, but I have a question. Maybe because I don't have any experience of working with pipes. The thing I wonder about is how the track-data would come to the LIBMTP_Send_Track_From_File_Descriptor function when the data is not written to the pipe until the function has exited. Wouldn't the transfer function just fail because it doesn't have any data?
Pipes are a fixed size, and if it tries to read data when there isn't any there, it will wait until something had put some in the other end and then continue. Conversely, if you try to write to a full pipe, it will block until something reads the data already there. It won't stop transferring the track until the other end closes the pipe, to signal the end of the data. Actually, does LIBMTP_Send_Track_From_File_Descriptor() return immediately and run in the background, or does it block until it's finished? If the latter, what I've got won't actually work - since it will block until data arrives, and the data won't start flowing until after it returns.
Peter, this plugin really kicks ass, thanks a lot for doing this! If you need some help or input from libmtp just tell, I think I saw your name on the list some time ago, had no idea you were doing this. Jag tittade på att fixa en Rhythmbox-plugin till vårt förra library "libnjb" för ganska länge sen, men det blev aldrig nåt av det. Om libmtp-pluggen blir schysst kan den nog ganska lätt anpassas till att även hantera libnjb-compliant enheter, men de är kanske redan antika vid det här laget, vad vet jag...
By the way (and sorry for diverging to Swedish for a moment there, I was to exalted) sending files from a pipe will work just as with any file descriptor as long as the final file size is known when beginning the transfer. The reason is that the size has to be known the PTP/MTP protocol mandates that the metadata for the file be sent before the actual file, and this includes the file size. If you don't fill in the metadata with the correct file size (e.g. try something like size 0xffffffff or 0x00000000) the transfer will _FAIL_ on all devices I've seen. We tried this approach in the past when people wanted to use their MTP devices for things like streaming.
More things, this: + return g_strdup_printf ("%2i%2i%2iT0000.0", + g_date_get_year (date), I think you shall use %4i first, the year is four digits. MIME type mappings, there are more of them, see this list based on code from libgphoto2 (which is used as upstream by libmtp): LIBMTP_FILETYPE_UNKNOWN "application/x-unknown" LIBMTP_FILETYPE_WINEXEC "application/octet-stream" LIBMTP_FILETYPE_TEXT "text/plain" {I think you shall use %4i first, the year is four digits. MIME type mappings, there are more of them, see this list based on code from libgphoto2 (which is used as upstream by libmtp): LIBMTP_FILETYPE_UNKNOWN "application/x-unknown" LIBMTP_FILETYPE_WINEXEC "application/octet-stream" LIBMTP_FILETYPE_TEXT "text/plain" LIBMTP_FILETYPE_HTML "text/html" LIBMTP_FILETYPE_WAV "audio/x-wav" LIBMTP_FILETYPE_MP3 "audio/mpeg" LIBMTP_FILETYPE_WMA "audio/x-ms-wma" LIBMTP_FILETYPE_OGG "application/ogg" LIBMTP_FILETYPE_MP4 "video/mp4" LIBMTP_FILETYPE_WMV "video/x-ms-wmv" LIBMTP_FILETYPE_AVI "video/x-msvideo" LIBMTP_FILETYPE_MPEG "video/mpeg" LIBMTP_FILETYPE_ASF "video/x-ms-asf" LIBMTP_FILETYPE_QT "video/quicktime" LIBMTP_FILETYPE_JPEG "image/jpeg" LIBMTP_FILETYPE_JFIF "image/jpeg" LIBMTP_FILETYPE_TIFF "image/tiff" LIBMTP_FILETYPE_BMP "image/bmp" LIBMTP_FILETYPE_GIF "image/gif" LIBMTP_FILETYPE_PICT "image/x-pict" LIBMTP_FILETYPE_PNG "image/png" LIBMTP_FILETYPE_VCALENDAR1 "text/calendar" LIBMTP_FILETYPE_VCALENDAR2 "text/calendar" LIBMTP_FILETYPE_VCARD2 "text/directory" LIBMTP_FILETYPE_VCARD3 "text/directory" LIBMTP_FILETYPE_FIRMWARE "application/octet-stream" LIBMTP_FILETYPE_AAC "audio/MP4A-LATM" LIBMTP_FILETYPE_FLAC "audio/x-flac" LIBMTP_FILETYPE_MP2 "video/mpeg" LIBMTP_FILETYPE_M4A "audio/x-m4a" LIBMTP_FILETYPE_DOC "application/msword" LIBMTP_FILETYPE_XML "text/xml" LIBMTP_FILETYPE_XLS "vnd.ms-excel" LIBMTP_FILETYPE_PPT "vnd.ms-powerpoint" LIBMTP_FILETYPE_JP2 "image/x-jpeg2000bff" LIBMTP_FILETYPE_JPX "image/x-jpeg2000eff" I don't know which of these may be relevant for Rhythmbox, perhaps all, perhaps just the audio ones.
Another not on VFS abstractions and the like mentioned earlier in this bug: libmtp has no intent of providing the abstractions for filesystem emulation of any kind. libgphoto2 (part of gPhoto) already does that, and Marcus Meissner and others have done an excellent job at doing VFS support for PTP which will also handle MTP. This is also what Banshee is currently using, so if a FS-oriented approach to MTP is sought for, libgophoto2 is the way to go. (It's still much the same code.) Then naturally comes the question of why libmtp exist at all (our most common question), so I quote our homepage: ------------ Q: How does libmtp differ from libgphoto2? A: libgphoto2 is very file-listing oriented, everything is a file (the unix way). It abstracts away details of the underlying protocol this way and represent any camera device (MTP devices are regared "cameras" in libgphoto2) this way. libmtp is closer to the actual protocol and does not provide the same abstraction, instead it relies on numeric identifiers for "objects" on the device, 32bit numbers that are unique for each object/file. This has the side effect that libmtp can handle two files with an identical path (folder+filename) whereas libgphoto2 will be confused by this. We hope that all of this will be fixed in libgphoto2 so we can obsolete libmtp some day. BTW: this is not nagging, we work closely with the libgphoto2 guys and love what they do. ------------ As you see the two projects are somewhat orthogonal, if you have a good solution for this that will make everyone happy then I'm happy too, but we haven't found a way yet. Further, MTP devices behave very badly sometimes so that their interior design shines through. Having two files with the same name will work on some devices (those who use a database or similar inside) while it will fail on others (those who just reflect their own internal filesystem through MTP without much thought to it). According to the PTP/MTP spec, "#{//_\\}`'$$%&&.mp3" is a perfectly valid filename. Still very many devices will behave very strangely if you use that filename, while Creative devices will actually survive it. Currently libmtp has some USB low-level workarounds that will make it work better with some devices, but libgphoto2 is getting better every day. This fundamental issue about filesystem abstraction is hard to solve though. Moreover, nothing in the MTP spec require files to be stored to any clever naming scheme at all, or using any directory hierarchies whatsoever. PTP/MTP just supports directories (called associations), but does not encourage its use. However Windows Media player use it so you will see this on many devices, so could be good to have. Some devices require all music to go into a folder like "/Music" or "/My Music" or else it won't play back! (Early Creative devices) this is why libmtp will default to using these directories, if they exist.
(In reply to comment #86) > By the way (and sorry for diverging to Swedish for a moment there, > I was to exalted) sending files from a pipe will work just as with > any file descriptor as long as the final file size is known when > beginning the transfer. > > The reason is that the size has to be known the PTP/MTP protocol > mandates that the metadata for the file be sent before the actual > file, and this includes the file size. If you don't fill in the > metadata with the correct file size (e.g. > try something like size 0xffffffff or 0x00000000) the transfer will > _FAIL_ on all devices I've seen. We tried this approach in the past > when people wanted to use their MTP devices for things like streaming. Ah, we won't be able to use that then, since we don't know how big it will be. From your other comment, we'd have to use libgphoto to do that.
I generally get this output when I try to transfer anything to my Zen Micro: (22:03:30) [0x80fa028] [register_rb_plugin] rb-mtp-plugin.c:95: Registering plugin RBMtpPlugin (22:03:30) [0x80fa028] [rb_mtp_plugin_init] rb-mtp-plugin.c:125: RBMtpPlugin initialising (22:03:30) [0x80fa028] [rb_mtp_plugin_setup_dbus_hal_connection] rb-mtp-plugin.c:379: connected to: :1.285 PTP: Opening session WARNING: LIBMTP_Get_Tracklisting() is deprecated. WARNING: please update your code to use LIBMTP_Get_Tracklisting_With_Callback() Unknown OPFF type 2 This also happens: (22:08:56) [0x80fa028] [transfer_track] rb-mtp-source.c:677: Tracktransfer failed There are plenty of transcoded mp3's sitting around in my /tmp directory, they just don't seem to make it onto the device...
Matt: Try to transfer mp3 files and see if you still get the last error (the Warnings have been there from the beginning and are also found when transferring files from with gnomad2 if i remember well). I also have the same problems with .wma which get transcoded (they shouldn't, my device plays wma natively) and never make it to the device. On a different note, the MTP plugin is now installed by default on the latest Ubuntu Gutsy Gibbons, which means millions will be using it in October. That also means the latest bugs might need some love before then. Will there be a seperate MTP module against which we can report bugs? In the mean time, here's a short list of "major" bugs: 1. wma files get transcoded even if the device plays them natively, they also never make it to the device. 2. Files transfered are not named correctly (see post above) 3. Files transfered back to the disk also get a new name and lack the mp3 extension. Another bug which is far from being major: 4. Music files are not saved on the device using the directory structure (gnomad2 and amarok do that), everything gets saved in /Music on my device instead of /Music/Artist/CD/songs. Good job! Nic
$ rhythmbox -D mtp (12:48:20) [0x80fa028] [register_rb_plugin] rb-mtp-plugin.c:95: Registering plugin RBMtpPlugin (12:48:20) [0x80fa028] [rb_mtp_plugin_init] rb-mtp-plugin.c:125: RBMtpPlugin initialising (12:48:20) [0x80fa028] [rb_mtp_plugin_setup_dbus_hal_connection] rb-mtp-plugin.c:379: connected to: :1.109 PTP: Opening session WARNING: LIBMTP_Get_Tracklisting() is deprecated. WARNING: please update your code to use LIBMTP_Get_Tracklisting_With_Callback() Unknown OPFF type 2 The same thing with mp3's. They just don't seem to make it to the transfer. So, it seems like all of the transcoding (or not transcoding if it's an mp3) works, and that the transfers fail. I only managed to transfer one thing to the player, which was a large mp3 file. That seems to have been a stroke of luck, as I haven't been able to transfer anything since then.
I transferred mp3 files to my device with gnomad2, which removed the tags from the files. When I transfer them back using gnomad2, it reapplies the tags using info from the device, but when I transfer them back with rhythmbox, it doesn't apply any tags and leaves the files with no tags.
Hi, anybody still working on this plugin? There are still a few bugs worth fixing (especially about file naming) which would really make a big difference for end users. Please remember that the plugin will be released with Rhythmbox when Ubuntu Gutsy comes out in October. Thanks again for your work! Nic
Hi, I still work on it, or rather plan to work on it. But I don't have that much spare time at the moment. The problem with unnessicary re-encoding and not being able to transfer tracks probably have something to do with the mimetype stuff, so if everybody having such problems could post the mimetype of those files here it would be good. The other problems I'll have a look at when I've time, but if someone wants to beat me to it, that is ok with me.
Hi all, I have tried the MTP plugin with my Philips HDD085/00 mp3 player. this is on Ubuntu Feisty. I followed Nic's (ntetreau at gmail dot com) approach except that I installed libmtp from source so that I had the 0.1.5 version which was said to have better recognition of Philips mtp type players. I added the rules data into the udev files and ran mtp-detect and it saw it with no problem giving a lot of information about the device. After autogen, make and make install I the opened Rhythmbox and found that I can see the HDD085. After getting Rhythmbox to work with mp3 files I was able to drag and drop mp3 files to the HDD085. When I the ejected the HDD085 I could find the files on it and play them with no problems. However the problem I have found is that when I put the HDD085 back on it is recognised but no files are seen on the player even though they are there. If I now copy one of the same files across to the HDD085 then disconnect I now have two copies of that song file on my HDD085 and again when I reconnect they can not be see. Currently this means that to delete the files I still need to go back to Windows XP to use the Windows Media Player to see all the files and delete them. What could be causing this. Could this be something I have missed in the udev file information or is this a bug in the mtp plugin. One other thing I have found is that when I open Rhythmbox then the little round spinning disc comes up in Gnome and after a while it disappears and goes back to an arrow but Rhythmbox does not open. If I click it again then it opens very quickly. This happens consistently. It did not happen when I had the Ubunty standard Rhythmbox installation. In case it was related to the various hunting around I had to do the first time I did the build I checked it out by removing everything that I had built and doing the whole thing again, including libmtp. Again both above problems occurred the same way. Where would I set up debug logging to record what I happening when I reconnect to the HDD085 and when I start up Rhythmbox. I am willing to explore this if someone can give me some pointers as to where to look for the information so that I can post it on this site. Regards, Adolf.
> I installed libmtp from source so that I had the 0.1.5 version which was > said to have better recognition of Philips mtp type players. Please try the all-new (TM) libmtp 0.2.0. > I added the rules > data into the udev files and ran mtp-detect and it saw it with no problem What is the vendor/product ID of the HDD085? We need this for libmtp.
Hi Linus, Yes after sending my message I noticed that libmtp had gone up to 0.2.0 so was going to give it a try anyway. Don't know if that will get done tonight or not but will try as soon as I can. The vendor id is 0471 and the product id is 014d Regards, Adolf.
Okay, I haven't had the opportunity to do the full compile and make from scratch yet but I have tried using the libmtp command line commands. mtp-detect works okay with 0.1.5 but when I tried mtp-tracks I got the message that there were no tracks. I then uninstalled libmtp 0.1.5 and compiled, make, make installed libmtp 0.2.0 and now mtp-tracks can see all the tracks in my HDD085. Later this week I will rebuild Rhythmbox and see how it then works. Based on the above I am noe hopeful that it will work okay. Will let you all know how it goes. Regards, Adolf.
Hi all, I have downloaded libmtp 0.2.1, compiled installed, then on a fresh svn of rhythmbox, it compiled fine and seems to work properly. I haven't tested everything properly yet, but so far so good. Nic
Hi all, I have also downloaded libmtp 0.2.1, compiled and installed it and then checked out a fresh svn of rhythmbox and compiled and installed that. When I then start Rhythmbox my HDD085 is not being seen in it at all. From the command line mtp-tracks still gives me a full listing of all the tracks on the mp3 player. I changed back to 0.1.5 to check and then I can see the HDD085 in Rhythmbox but there are no tracks visible and from the command line mtp-tracks says there are no tracks. So 0.2.1 is needed for libmtp to be able to see the tracks in the HDD085 but then Rhythmbox does not want to see anything at all. I suspect I am missing something simple somewhere but I can't figure out what it is. Any ideas from anyone. Let me know what info I need to dump from my system and post here and I will do so. Adolf
(In reply to comment #101) > I suspect I am missing something simple somewhere but I can't figure out what > it is. Any ideas from anyone. Are your udev rules in order? I.e. did you run the hotplug.sh script when installing libmtp from source? Linus
Hi, I had copied the libmtp.rules file to my udev rules location but I had not run hotplug.sh. When I read the libmtp Install and Readme files I had interpreted it to be saying that hotplug.sh was only needed for the prior to udev system. Thanks for the input and I will give that a go and feedback the results. Regards, Adolf.
(In reply to comment #103) > Hi, I had copied the libmtp.rules file to my udev rules location but I had not > run hotplug.sh. It should be sort of the same, but the debian package of the libmtp.rules may be tweaked somewhat, especially for fixing up the console permissions. You should inspect the rulesfile that comes with the Debian package and compare to libmtp.rules from the source install, I think there are differences in order to adopt to the Debian architecture.
Okay I tried hotplug.sh but it complained that it could not find the function inmap that is the first function in the script. I Googled but couldn't find anything on it. So I went back to the rules file. When I have copied it I have changed the name to fit the naming convention being used by Ubuntu. The file name starts with 65- but I copied the rest of the file as was. I had kept a copy of the original rules file so I compared that. The mode permissions in the rules file were the same as for the libmtp file from source. The structure of the rules was the same. The only difference I found was in the initial lines at the top of the script before the rules start, so I copied the top of the original file to the one copied from libmtp and restarted udev, then re-did the Rhythmbox configure, compile and install. Exactly the same has happened. I can see nothing in Rhythmbox but when I tail syslog then I can see hal recognising the insertion and removal of the mp3 player and recognising the vendor and device codes (in the usb file name string). That says that the hotplugging operation is working with udev I would presume. mtp-tracks then gives me a listing of what is on the mp3 player. When I use mtp-tracks with Rhythmbox started up then I still get the track listing. When I was running libmtp 0.1.5 then if Rhythmbox was open and had the mp3 player in the left hand pane then I could not use mtp-tracks as another system was accessing it (ie Rhythmbox). This would suggest to me that Rhythmbox is not finding the information on the player at all when I am using libmtp 0.2.1 but can when I use libmtp 0.1.5 but as far as I am aware I am carrying out the configure/compile/install of both libmtp and Rhythmbox the same for both versions. Any other ideas what I should look for. Are there any specific logs or reports from the configs/makes that I should look through or compare between the two situations. Regards, Adolf.
Regarding the hotplug script I found the problem with it. Ubuntu, from Edgy onwards, has symlinked sh to dash instead of bash and dash is limited with scripts and apparently does not recognise the command "function". Anyway I was the able to run the script via bash but all it did was copy the .rules and .fdi to the directories but made them executable and left the names as original. What I have been doing anyway is manually copying the rules file to the correct location and giving it the correct name. I had edited the hal .fdi file to include the HDD085. I just tried also copying the libmtp created fdi file to the correct location but that also made no difference. The HDD085 was still being detected as the same unit as before. Regards, Adolf.
If there is a reason to keep this bug open, it's buried somewhere in 100+ comments and really needs to go into a new bug.