This post has been imported from the old blog and has not yet been converted to the new syntax yet.
Yesterday I explained how you could manage your iPod through Windows Explorer. Having this ability opens up more powerful ways of managing your iPod. One of these ways for example is the ability to automatically sync your master archive stored on your computer, with your iPod. In my case it's stored in FLAC format to retain all it's quality, since FLAC is a lossless format.
Armed with TagLib#, LAME, FLAC and a nice function to recursively search through a directory for files, I slapped together a small synchronization application for myself.
On my iPod I have the following batch file, EncodeLibrary.bat, stored:
[code]@ECHO OFF
ECHO Running: '%~d0\LibrarySync.exe %~d0\ C:\Media\Music %~d0\Music'
ECHO Encodes to MP3 with: -V 4 --vbr-new
%~d0\LibrarySync.exe %~d0\ C:\Media\Music %~d0\Music
ECHO Done.[/code]
This file simply calls my utility, LibrarySync.exe, and passes in the drive it is running on (%~d0), The Archive and the target directory. In my application I then simply scan for all available FLAC files, through a wildcard search, in the archive and trigger an action whenever a file is found.
[csharp]static void Main(string[] args)
{
/* Note to blog reader: These used to be constants, never properly refactored it since it was a quick and dirty personal app. */
DRIVE = args[0];
FROMDIR = args[1];
TODIR = args[2];
ScanDirectory scanDirectory = new ScanDirectory();
scanDirectory.FileEvent += new ScanDirectory.FileEventHandler(scanDirectory_FileEvent);
scanDirectory.SearchPattern = "*.flac";
scanDirectory.WalkDirectory(FROMDIR);
}
[/csharp]
Whenever a FLAC file is found, I check if the target MP3 already exists, and in case it doesn't exist yet, I call a Convert.bat file. I've chosen to use an external batch file to handle the copying, this way I can simply open it up in a text editor and change the encoding quality or the paths to the encoder.
After encoding the file, I take the meta data from the original FLAC file and place it in the target MP3 ID3v1 and ID3v2 tags. This way my iPod can read out the file details and organize it easily in it's catalog.
[csharp]static void scanDirectory_FileEvent(object sender, FileEventArgs e)
{
string from = e.Info.FullName;
string to = TODIR + e.Info.FullName.Remove(0, FROMDIR.Length).Replace(".flac", ".mp3");
string toDir = TODIR + e.Info.DirectoryName.Remove(0, FROMDIR.Length);
if (!IO.File.Exists(to))
{
if (!IO.Directory.Exists(toDir))
{
IO.Directory.CreateDirectory(toDir);
}
Console.WriteLine("Writing " + to);
Process convertFile = new Process();
convertFile.StartInfo.UseShellExecute = false;
convertFile.StartInfo.RedirectStandardOutput = false;
convertFile.StartInfo.FileName = DRIVE + "Convert.bat";
convertFile.StartInfo.Arguments = "\"" + from + "\" \"" + to + "\"";
convertFile.Start();
convertFile.WaitForExit();
Flac.File flacFile = new Flac.File(from);
TagLib.Tag flacTag = flacFile.GetTag(TagLib.TagTypes.FlacMetadata, false);
TagLib.File mp3File = TagLib.File.Create(to);
MP3.Tag mp3Tag = mp3File.GetTag(TagLib.TagTypes.Id3v2) as TagLib.Id3v2.Tag;
MP3Old.Tag mp3OldTag = mp3File.GetTag(TagLib.TagTypes.Id3v1) as TagLib.Id3v1.Tag;
if (flacTag.Album != null) { mp3Tag.Album = flacTag.Album; }
if (flacTag.FirstPerformer != null) { mp3Tag.Performers = new string [] { flacTag.FirstPerformer }; }
if (flacTag.Title != null) { mp3Tag.Title = flacTag.Title; }
if (flacTag.Year != 0) { mp3Tag.Year = flacTag.Year; }
if (flacTag.FirstGenre != null) { mp3Tag.Genres = new string [] { flacTag.FirstGenre }; }
if (flacTag.Track != 0) { mp3Tag.Track = flacTag.Track; }
if (flacTag.Album != null) { mp3OldTag.Album = flacTag.Album; }
if (flacTag.FirstPerformer != null) { mp3OldTag.Performers = new string [] { flacTag.FirstPerformer }; }
if (flacTag.Title != null) { mp3OldTag.Title = flacTag.Title; }
if (flacTag.Year != 0) { mp3OldTag.Year = flacTag.Year; }
if (flacTag.FirstGenre != null) { mp3OldTag.Genres = new string [] { flacTag.FirstGenre }; }
if (flacTag.Track != 0) { mp3OldTag.Track = flacTag.Track; }
mp3File.Save();
Console.WriteLine();
}
}[/csharp]
The content of my Convert.bat file looks like this:
[code]@ECHO OFF
"%~d0\Tools\FLAC\flac.exe" --decode --stdout --silent %1 | "%~d0\Tools\LAME\latest\lame.exe" -V 4 --vbr-new - %2[/code]
It simply encodes the FLAC file to a VBR MP3 with a target bitrate of 165kbps.
All said and done, this is how the tool looks like in action:
When I connect my iPod, I usually follow these steps from now on:
I created a small zip file for anyone who would like to set something like this up for himself as well. To use it, simply follow the following steps:
Do you know of other cool things I could create for my iPod? Comment and let me know!
Armed with TagLib#, LAME, FLAC and a nice function to recursively search through a directory for files, I slapped together a small synchronization application for myself.
On my iPod I have the following batch file, EncodeLibrary.bat, stored:
[code]@ECHO OFF
ECHO Running: '%~d0\LibrarySync.exe %~d0\ C:\Media\Music %~d0\Music'
ECHO Encodes to MP3 with: -V 4 --vbr-new
%~d0\LibrarySync.exe %~d0\ C:\Media\Music %~d0\Music
ECHO Done.[/code]
This file simply calls my utility, LibrarySync.exe, and passes in the drive it is running on (%~d0), The Archive and the target directory. In my application I then simply scan for all available FLAC files, through a wildcard search, in the archive and trigger an action whenever a file is found.
[csharp]static void Main(string[] args)
{
/* Note to blog reader: These used to be constants, never properly refactored it since it was a quick and dirty personal app. */
DRIVE = args[0];
FROMDIR = args[1];
TODIR = args[2];
ScanDirectory scanDirectory = new ScanDirectory();
scanDirectory.FileEvent += new ScanDirectory.FileEventHandler(scanDirectory_FileEvent);
scanDirectory.SearchPattern = "*.flac";
scanDirectory.WalkDirectory(FROMDIR);
}
[/csharp]
Whenever a FLAC file is found, I check if the target MP3 already exists, and in case it doesn't exist yet, I call a Convert.bat file. I've chosen to use an external batch file to handle the copying, this way I can simply open it up in a text editor and change the encoding quality or the paths to the encoder.
After encoding the file, I take the meta data from the original FLAC file and place it in the target MP3 ID3v1 and ID3v2 tags. This way my iPod can read out the file details and organize it easily in it's catalog.
[csharp]static void scanDirectory_FileEvent(object sender, FileEventArgs e)
{
string from = e.Info.FullName;
string to = TODIR + e.Info.FullName.Remove(0, FROMDIR.Length).Replace(".flac", ".mp3");
string toDir = TODIR + e.Info.DirectoryName.Remove(0, FROMDIR.Length);
if (!IO.File.Exists(to))
{
if (!IO.Directory.Exists(toDir))
{
IO.Directory.CreateDirectory(toDir);
}
Console.WriteLine("Writing " + to);
Process convertFile = new Process();
convertFile.StartInfo.UseShellExecute = false;
convertFile.StartInfo.RedirectStandardOutput = false;
convertFile.StartInfo.FileName = DRIVE + "Convert.bat";
convertFile.StartInfo.Arguments = "\"" + from + "\" \"" + to + "\"";
convertFile.Start();
convertFile.WaitForExit();
Flac.File flacFile = new Flac.File(from);
TagLib.Tag flacTag = flacFile.GetTag(TagLib.TagTypes.FlacMetadata, false);
TagLib.File mp3File = TagLib.File.Create(to);
MP3.Tag mp3Tag = mp3File.GetTag(TagLib.TagTypes.Id3v2) as TagLib.Id3v2.Tag;
MP3Old.Tag mp3OldTag = mp3File.GetTag(TagLib.TagTypes.Id3v1) as TagLib.Id3v1.Tag;
if (flacTag.Album != null) { mp3Tag.Album = flacTag.Album; }
if (flacTag.FirstPerformer != null) { mp3Tag.Performers = new string [] { flacTag.FirstPerformer }; }
if (flacTag.Title != null) { mp3Tag.Title = flacTag.Title; }
if (flacTag.Year != 0) { mp3Tag.Year = flacTag.Year; }
if (flacTag.FirstGenre != null) { mp3Tag.Genres = new string [] { flacTag.FirstGenre }; }
if (flacTag.Track != 0) { mp3Tag.Track = flacTag.Track; }
if (flacTag.Album != null) { mp3OldTag.Album = flacTag.Album; }
if (flacTag.FirstPerformer != null) { mp3OldTag.Performers = new string [] { flacTag.FirstPerformer }; }
if (flacTag.Title != null) { mp3OldTag.Title = flacTag.Title; }
if (flacTag.Year != 0) { mp3OldTag.Year = flacTag.Year; }
if (flacTag.FirstGenre != null) { mp3OldTag.Genres = new string [] { flacTag.FirstGenre }; }
if (flacTag.Track != 0) { mp3OldTag.Track = flacTag.Track; }
mp3File.Save();
Console.WriteLine();
}
}[/csharp]
The content of my Convert.bat file looks like this:
[code]@ECHO OFF
"%~d0\Tools\FLAC\flac.exe" --decode --stdout --silent %1 | "%~d0\Tools\LAME\latest\lame.exe" -V 4 --vbr-new - %2[/code]
It simply encodes the FLAC file to a VBR MP3 with a target bitrate of 165kbps.
All said and done, this is how the tool looks like in action:
When I connect my iPod, I usually follow these steps from now on:
- Run reTune to manage my songs in Windows Explorer.
- Run EncodeLibrary to encode possible missing songs.
- Run reTune to organize them back into my iPod.
- Disconnect and listen to music.
I created a small zip file for anyone who would like to set something like this up for himself as well. To use it, simply follow the following steps:
- Extract the zip file to the root of your iPod.
- Edit EncodeLibrary.bat to point to your master archive, and the target folder.
- Get the FLAC and LAME files and place them in a folder called Tools. Look at Convert.bat to determine the exact paths.
- Run EncodeLibrary.bat from a command prompt, and with a bit of luck it'll work for you. If not, leave a comment and I'll see what I can do for you.
Do you know of other cool things I could create for my iPod? Comment and let me know!
Can I use this without an iPod? I need to sync a FLAC and MP3 library
Yes you can, just run EncodeLibrary to sync the flac files to MP3.
Be sure to enter the correct paths however.
Ta.
I get the following error
C:\Documents and Settings\Chilcott>C:\librarysync\EncodeLibrary.bat
Running: 'C:\librarysync\LibrarySync.exe C: c:\FLAC C:\MP3'
Encodes to MP3 with: -V 4 --vbr-new
Writing C:\MP3\Zoso1 Black Dog.mp3
Unhandled Exception: System.ComponentModel.Win32Exception: The system cannot fin
d the file specified
at System.Diagnostics.Process.StartWithCreateProcess(ProcessStartInfo startIn
fo)
at System.Diagnostics.Process.Start()
at LibrarySync.Program.scanDirectory_FileEvent(Object sender, FileEventArgs e
)
at ScanDirectoryDemo.ScanDirectory.RaiseFileEvent(FileInfo fileInfo)
at ScanDirectoryDemo.ScanDirectory.ProcessFile(FileInfo fileInfo)
at ScanDirectoryDemo.ScanDirectory.WalkFilesInDirectory(DirectoryInfo directo
ry)
at ScanDirectoryDemo.ScanDirectory.WalkDirectories(DirectoryInfo directory)
at ScanDirectoryDemo.ScanDirectory.WalkDirectory(DirectoryInfo directory)
at ScanDirectoryDemo.ScanDirectory.WalkDirectories(DirectoryInfo directory)
at ScanDirectoryDemo.ScanDirectory.WalkDirectory(DirectoryInfo directory)
at ScanDirectoryDemo.ScanDirectory.WalkDirectory(String path)
at LibrarySync.Program.Main(String[] args)
Done.
Is there a Convert.bat file at C:\Convert.bat on your computer?
That worked. Thanks. Now I am having trouble with paths containing spaces. e.g. "C:\Documents and Settings\All Users\Documents\My Music"
Tried putting double quotes around it?
eg:
%~d0\LibrarySync.exe %~d0\ "C:\Media\Music" "%~d0\Music"
Should do the trick normally.
That worked, thanks. Presumably it will only work with FLACs (my source library also contains MP3s and OGGs.
The current source only converts *.flac indeed, you'll have to modify it yourself if you want more information.
Or contact me to create something for you against a small price :-)
I just love this idea, a one click method to sync a FLAC folder into a MP3 Folder..
However, I've been (unsuccessfully) searching for a C# compiler to try to resolve "LibrarySync has encountered a problem and needs to close."
Has anyone else seen this issue?
OOPs, User Error! What a surpirse!
I had erronorusly edited the encodlibrary.bat to not have 3 arguments.
THANKS DAVE! THIS PROGRAMS IS PERFECT!
Ok, kinda newb question, but how to I "extract it to the root"? The rest of the directions I can understand but from what I've seen on other sites you have to install linux on your ipod? Or do you just plug it in and go to it?
@Dagda,
You don't need to install linux.
You plug it on, make sure you can access the filesystem like a regular USB memory stick (I belief in iTunes you have to enabled a check box to enable that), and then you just unzip it to the drive letter (also called, the root)
This rocks! Thanks a lot for all your hard work!
I've been playing with batch files for a time (to do something similar) since I have zero other coding skills. One thing I was playing with was using multi-cores for this. I used psexec to launch each to a specific core, speeding up my encoding. Humbly requesting this feature. (something like having a convert_a.bat and convert_bat)
I'm trying it now, with two batch files:
convert_cpu1.cmd
psexec -a 0 "EncodeLibrary.bat"
convert_cpu2.cmd
psexec -a 1 -belownormal "EncodeLibrary.bat"
Since your app checks to see if the mp3 is already there, it "seems" to not fight over who's converting what....
Hi, i was just wondering about tagging support in #taglib...
does it support custom FLAC tags as i have a load of other tags i'd like to support such as ARTISTSORT, ENSEMBLE etc.
do you know whether the support exists for these tags?
This sounds excellent.
Is it able to create gapless MP3s (such as you would need on a DJ mix CD)?