Author Topic: "On-the-fly-conversion" settings ignored with Sync_FileStart()  (Read 1536 times)

BoringName

  • Full Member
  • ***
  • Posts: 209
I'm trying to sync a FLAC file to iTunes (it doesn't support FLAC)

It doesn't matter what settings I use, even if I set it to convert all files,  MbApiInterface.Sync_FileStart() doesn't return a converted file. I've tried changing settings in the sync window and in Edit Preferences->Devices->iPod & iPhone Driver->Configure

If I trigger a convert by placing an album cover file in the folder and set it to imbed images, it returns an encoded file but its still a FLAC. Strangely when I set it up this way, it will obey the "convert to" setting but it doesn't actually convert to the specified format. The encoded file just becomes a FLAC file with it's extension changed to whatever is specified in the "convert to" field.  .mp3, m4a etc... and iTunes rejects it.

Ive added ALAC support via ffmpeg in file converter settings and set it to convert to ALAC (m4a) but that behaved the same way as the others.

Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34344
its ages since i looked at this, but i think you need to tell MB via the API what formats are supported on the device - are you doing that already (properties.SupportedFormats = ...)?. Here is a code template i created:
Code
        [StructLayout(LayoutKind.Sequential)]
        public struct DeviceProperties
        {
            private int version;
            public string DeviceName;
            // this should be a 64x64 bitmap
            public Bitmap DeviceIcon64;
            public string Manufacturer;
            public string Model;
            public string FirmwareVersion;
            public int BatteryLevel;
            public ulong FreeSpace;
            public ulong TotalSpace;
            // if yes, a Music node and if enabled Audiobook, Podcast, Video and playlist nodes are displayed in the Devices tree
            public bool ShowCategoryNodes;
            // device supports audio books as a category - if no, the files are synchronised to the music library
            public bool AudiobooksSupported;
            // device supports podcasts as a category - if no, the files are synchronised to the music library
            public bool PodcastsSupported;
            // device supports video as a category - if no, the files are synchronised to the music library
            public bool VideoSupported;
            // device supports a folder structure and allows the user to specify a naming template for the files
            public bool OrganisedFoldersSupported;
            // when enabled you need to query the MetaDataType.Artwork tag which will return null, "embeded" or the file location of the artwork. When not enabled, MusicBee forces the artwork to always be embeded (a temporary file is created if the file does not already have embeded artwork)
            public bool SyncExternalArtwork;
            // allows the user can choose whether files not on the sync list are to be removed from the device. If not enabled, its up to the plugin what to do
            public bool SyncAllowFileRemoval;
            // allows the user to tick 2-way rating sync in the device preferences
            public bool SyncAllowRating2Way;
            // allows the user to tick 2-way play count sync in the device preferences
            public bool SyncAllowPlayCount2Way;
            public SynchronisationSupportedFormats SupportedFormats;
            // allows the user to tick 2-way playlist sync in the device preferences
            public bool SyncAllowPlaylists2Way;
        }

        public bool GetDeviceProperties(IntPtr handle)
        {
            DeviceProperties properties = new DeviceProperties();
            properties.DeviceName = about.TargetApplication;
            properties.ShowCategoryNodes = true;
            properties.AudiobooksSupported = true;
            properties.PodcastsSupported = true;
            properties.DeviceIcon64 = new Bitmap("C:\\Users\\Steven\\Pictures\\34M92.jpg");
            properties.SupportedFormats = SynchronisationSupportedFormats.SyncMp3Supported | SynchronisationSupportedFormats.SyncAacSupported | SynchronisationSupportedFormats.SyncAlacSupported;
            Marshal.StructureToPtr(properties, handle, false);
            return true;
        }


BoringName

  • Full Member
  • ***
  • Posts: 209
its ages since i looked at this, but i think you need to tell MB via the API what formats are supported on the device - are you doing that already

It appears so, below is in the code. But nothing specifically calls/references GetDeviceProperties() if that makes a difference.

Code
public struct DeviceProperties
        {
            private int version;
            public string DeviceName;
            // this should be a 64x64 bitmap
            public Bitmap DeviceIcon64;
            public string Manufacturer;
            public string Model;
            public string FirmwareVersion;
            public int BatteryLevel;
            public ulong FreeSpace;
            public ulong TotalSpace;
            // if yes, a Music node and if enabled Audiobook, Podcast, Video and playlist nodes are displayed in the Devices tree
            public bool ShowCategoryNodes;
            // device supports audio books as a category - if no, the files are synchronised to the music library
            public bool AudiobooksSupported;
            // device supports podcasts as a category - if no, the files are synchronised to the music library
            public bool PodcastsSupported;
            // device supports video as a category - if no, the files are synchronised to the music library
            public bool VideoSupported;
            // device supports a folder structure and allows the user to specify a naming template for the files
            public bool OrganisedFoldersSupported;
            // when enabled you need to query the MetaDataType.Artwork tag which will return null, "embeded" or the file location of the artwork. When not enabled, MusicBee forces the artwork to always be embeded (a temporary file is created if the file does not already have embeded artwork)
            public bool SyncExternalArtwork;
            // allows the user can choose whether files not on the sync list are to be removed from the device. If not enabled, its up to the plugin what to do
            public bool SyncAllowFileRemoval;
            // allows the user to tick 2-way rating sync in the device preferences
            public bool SyncAllowRating2Way;
            // allows the user to tick 2-way play count sync in the device preferences
            public bool SyncAllowPlayCount2Way;
            public SynchronisationSupportedFormats SupportedFormats;
            // allows the user to tick 2-way playlist sync in the device preferences
            public bool SyncAllowPlaylists2Way;
        }

public bool GetDeviceProperties(IntPtr handle)
        {
            DeviceProperties properties = new DeviceProperties();
            if (!ITunes.IgnoreIPod)
            {
                properties.DeviceName = pluginName;
                properties.FirmwareVersion = ITunes.IPodSource.SoftwareVersion;
                properties.FreeSpace = (ulong)ITunes.IPodSource.FreeSpace;
                properties.TotalSpace = (ulong)ITunes.IPodSource.Capacity;
            }
            else
            {
                properties.DeviceName = pluginName;
            }

            properties.ShowCategoryNodes = true;
            properties.AudiobooksSupported = false;
            properties.PodcastsSupported = false;
            properties.VideoSupported = false;
            properties.Manufacturer = "Apple Inc.";
            properties.SyncExternalArtwork = false;
            properties.SyncAllowFileRemoval = true;
            properties.SyncAllowRating2Way = true;
            properties.SyncAllowPlayCount2Way = true;
            properties.SyncAllowPlaylists2Way = false;

            System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager("MusicBeePlugin.Images", System.Reflection.Assembly.GetExecutingAssembly());
            properties.DeviceIcon64 = (Bitmap)resourceManager.GetObject("iTunes64");

            properties.SupportedFormats = SynchronisationSupportedFormats.SyncMp3Supported | SynchronisationSupportedFormats.SyncAacSupported | SynchronisationSupportedFormats.SyncAlacSupported;
            Marshal.StructureToPtr(properties, handle, false);

            return true;
        }

Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34344
it looks like there is a bug in the code so i will try to fix it over the weekend

BoringName

  • Full Member
  • ***
  • Posts: 209
it looks like there is a bug in the code so i will try to fix it over the weekend

That would be great, thanks.

I believe the following issue is also related so might be worth checking out while your playing around that area. But it's just a visual issue so not a big deal. It appears to not be getting the total number of files being synchronised so it's just displaying "No Files".

Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34344
I have made the sync change but dont have iTunes installed to test it, so are you happy to try it on that understanding? I can send you a PM with a link

For the 2nd issue, do you have a function named "PrepareSynchronise" defined? It looks like i didnt document it, and its needed so you can tell musicbee how many files will be deleted and how many updated before the sync starts
Code
PrepareSynchronise(
SynchronisationSettings settings,  // indicates what type of synchronisation has been requested
KeyValuePair(Of Integer, String()) syncFiles[], // the files that will be sent for synchronisation
List(Of KeyValuePair(Of Integer, String[])) updates, // just add any values to this list - only the count in the list is used to determine the total files that will be sycned
List(Of String) deletes, // just add any values to this list - only the count in the list is used to determine the total files that will be deleted
List(Of String) playlists) // just add any values to this list - only the count in the list is used to determine the total playlists that will be synched
Last Edit: June 19, 2022, 01:24:07 AM by Steven

BoringName

  • Full Member
  • ***
  • Posts: 209
I have a test system setup so I can't trash the main library while I'm playing around so feel free to send a link and I'll give it a shot.

There is no "PrepareSynchonise" in the code so I will have a play around with that as well.

Thanks for getting onto this so quickly.



BoringName

  • Full Member
  • ***
  • Posts: 209
The conversion option seems to be working properly now. Thanks.

As for the second part, I'm not 100% sure how to implement that. I get how to call it from my code but not sure how to add it into MusicBeeInterface.cs

I added  the following at line 261
public PrepareSynchroniseDelegate PrepareSynchronise;

And I assume I need to add something like -
public delegate void PrepareSynchronise(SynchronisationSettings settings, KeyValuePair(Of Integer, String()) syncFiles[], List(Of KeyValuePair(Of Integer, String[])) updates, List(Of String) deletes, List(Of String) playlists)

But obviously it doesn't like that and I don't know what I'm doing.

I'm also not 100% on the first field. "What type of synchronisation has been requested". Is this just expecting "Music", "Playlist", "Video" etc... or something else?





Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34344
the SynchronisationSettings parameter will be set by MB and you could probably ignore it
Code
        [Flags()]
        public enum SynchronisationSettings
        {
            None = 0,
            SyncRemoveMissingFiles = 0x1,
            SyncRating2Way = 0x2,
            SyncPlayCount2Way = 0x4,
            SyncConfirmRemoveFiles = 0x8,
            SyncPlaylists2Way = 0x10
        }
syncFiles will be set by MB and just telling you what the candidate files would be for the actual sync
the last 3 you need to add a list of filenames but in the current implementation, MB only uses the count from the list to work out the total file operations.
For the update parameter i dont recall why it wasnt just a list of string, so just use FilePropertyType.Url, and the filename


BoringName

  • Full Member
  • ***
  • Posts: 209
Sorry, I probably didn't explain myself properly. At the moment if I compile the code I get an error
'MusicBeePlugin.Plugin.MusicBeeApiInterface' does not contain a definition for 'PrepareSynchronise'

I just need to know how to add the PrepareSynchonise definition into MusicBeeInterface.cs

Thanks.

Steven

  • Administrator
  • Sr. Member
  • *****
  • Posts: 34344
dont add it to the api interface. Just create the function in the .cs file similar to "public bool Synchronise(SynchronisationSettings flags, KeyValuePair<int, string[]>[] files)"
MB will look at the .dll and find the function if its defined

BoringName

  • Full Member
  • ***
  • Posts: 209
dont add it to the api interface. Just create the function in the .cs file similar to "public bool Synchronise(SynchronisationSettings flags, KeyValuePair<int, string[]>[] files)"
MB will look at the .dll and find the function if its defined

Right... I'm an idiot. Thanks.

BoringName

  • Full Member
  • ***
  • Posts: 209
Forgot to mention. Before I changed anything with PrepareSynchronise the new version you gave me already changed the "No Files" problem to match the track number currently being synchronised.
eg) instead of -
1 of No files
2 of No files
3 of No files
It changed to -
1 of 1 files
2 of 2 files
3 of 3 files

Since adding PrepareSynchronise that behaviour hasn't changed so good chance I've got it wrong.

Here is the code I figured out after a bit of trial and error....
Code
		public bool PrepareSynchronise(SynchronisationSettings settings, KeyValuePair<int, string[]>[] syncFiles, List<KeyValuePair<int, string[]>> updates, List<string> deletes, List<string> playlists)
{
foreach (KeyValuePair<int, string[]> item in syncFiles)
{
Plugin.syncUpdates.Add(new KeyValuePair<int, string[]>(0,new string[]{item.Value[0]}));
}
settings = Plugin.SynchronisationSettings.None;
updates = Plugin.syncUpdates;
deletes = Plugin.syncDeletes;
playlists = Plugin.syncPlaylists;
MessageBox.Show(updates.Count.ToString());
return true;
}
I know the foreach loop is dodgy, I'm just using that for now to populate the updates . I couldn't get the FilePropertyType.Url to work as it kept telling me it couldn't convert it so I just put a zero in there for now.
When the messagebox pops up it does list the correct number of songs to be synced (well one extra because one is a playlist). So it must be working to some degree if syncFiles is populated.
syncDeletes and syncPlaylists are currently empty lists while I test it out.

Sorry for the hassle.


BoringName

  • Full Member
  • ***
  • Posts: 209
I found a consistency issue. Sorry I don't know if you want these in different threads. It all seems related though.

What displays in the sync window is inconsistent between Sync_FileStart and Sync_FileDeleteStart
eg)
filename = "C:\Users\User\Music\iTunes\iTunes Media\Music\abba\Unknown Album\dancing queen.mp3"
Sync_FileStart(filename); //displays as <Artist> - <Track Title>
Sync_FileDeleteStart(filename) //displays as the filename without the extension - "dancing queen"