Reputation: 533
How to concat many (say 500) mp3 files into one file (any type) and then extract any specific file as mp3 format?
Currently I get all the files using this code:
int i = 0;
string[] files = new string[500];
foreach (var path in Directory.GetFiles(@"R:\abc\a\"))
{
files[i++] = path;
}
Thanks in advance.
Update: If I can't extract any specific mp3 file then I want to extract all the mp3 files to a specified directory. ZIP, RAR etc aren't enough because I have to prevent humans to extract mp3 files without my program.
Upvotes: 0
Views: 305
Reputation: 22362
If you concat all the bytes together then remember each filename and how many bytes it was you can use that information to find the correct segment of bytes for each music file. Have not tested this but should give you an idea.
IEnumerable<FileInfo> Mp3Files = new DirectoryInfo(dir).GetFiles();
// catalog all names and their length in bytes (you can save this somewhere)
IEnumerable<Mp3File> musicFiles = Mp3Files.Select(o => new Mp3File() { Name = o.Name, Size = o.Length });
// concat all into one
byte[] musicData = files.SelecMany(o => File.ReadAllBytes(o.FullName)).ToArray();
File.WriteAllBytes("allmusic.data", musicData);
byte[] GetSingleMusicFile(string name)
{
// find the music file by name, and get how many bytes it is
int bytesToTake = musicFiles.First(o => o.Name == name).Length;
// count all the music files BEFORE it and add up their bytes to find out how many bytes to skip
int bytesToSkip = musicFiles.TakeWhile(o => o.Name != name).Sum(o => o.Size);
// skip the bytes until you get to your music file then take its bytes
byte[] singleMusicData = musicData.Skip(bytesToSkip).Take(bytesToTake).ToArray();
return singleMusicData[]
}
Upvotes: 1
Reputation: 533
Thank you guys for your afford to help me. I decided to zip them using password protection. So, none can extract my files :)
Upvotes: 0
Reputation: 7551
While a home-brewed container format (such as those suggested in other answers here) might work, I recommend using a well-known container format such as .zip. Although you wouldn't get much benefit out of compression, you'll get the file name, plus the ability for other progs to create/extract your file archive.
If you need help on how to create .zip programmatically, research the web (and particularly StackOverflow), and if you still don't know, ask as a separate question.
Upvotes: 1
Reputation: 38825
Without actually writing the code for you, you could do something like this:
1) Create a file in binary mode.
2) Write an empty Int32 values to the stream.
3) Write the number of mp3 files to the stream.
4) Create an array, the size of the number of mp3 files. We'll store their offsets here.
5) For each file, read it in binary mode. Store the current file position in the aforementioned array, and write the mp3 file out to our output file.
6) Make a note of the output file position once again, and write out the array containing the positions of all the mp3 files.
7) Seek to the beginning of the file and overwrite the value we originally wrote, with the offset of where the file positions are.
8) Close it!
Now, when we want to get a specific MP3, we can open this file, read the first two Int32s which will tell us the offset to our index, and how many there are. You can then seek to the appropriate position and extract the mp3 file.
Upvotes: 2