0

I have a folder filled with hundreds of .aac files, and I'm trying to "pack" them into one file in the most efficient way that I can.

I have tried the following, but only end up with a file that's only a few bytes long or audio that sounds warbled and distorted heavily.

// Now we want to get all of the files in the folder and then repack them into an aac file as fast as possible
void Repacker(string FileName)
{
    string data;
    boost::filesystem::path p = "./tmp/";
    boost::filesystem::ofstream aacwriter;
    aacwriter.open("./" + FileName + ".aac", ios::app);

    boost::filesystem::ifstream aacReader;
    boost::filesystem::directory_iterator it{ p };
    cout << "Repacking File!" << endl;
    while (it != boost::filesystem::directory_iterator{}) {
        aacReader.open(*it, std::ios::in | ios::binary);
        cout << "Writing " << *it << endl;
        aacReader >> data;
        ++it;
        aacwriter << data;
        aacReader.close();
    }
    aacwriter.close();
}

I have looked at the following questions to try and help solve this issue

Merging two files together

Merge multiple txt files into one

How do I read an entire file into a std::string in C++?

Read whole ASCII file into C++ std::string

Merging Two Files Into One

However unfortunately, none of these answer my question.

They all either have to do with text files, or functions that don't deal with hundreds of files at once.

I am trying to write Binary data, not text. The audio is either all warbled or the file is only a few bytes long.

If there's a memory efficent method to do this, please let me know. I am using C++ 20 and boost. Thank you.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • 1
    You can suck the guts out of a `rdbuf` and stream it into a file open for writing. `out << in.rdbuf();` might be all you need. – user4581301 Mar 25 '22 at 23:43
  • you need an inner loop, calling `ifstream.readsome` until you have read all the data from one file, then move onto the next one (you dont need boost io) – pm100 Mar 25 '22 at 23:45
  • 1
    Note that I'm not familiar with the aac format and it probably won't be as simple as concatenating files.. Likely you'll have to set up an output file with the appropriate header information, read the files, parse the data and insert it in the output file. When done, all the files read and all the data is in place, you'll probably have to update the output file header with the correct length, etc... – user4581301 Mar 25 '22 at 23:48
  • 2
    Took a quick look at AAC, and simple binary file copies won't be enough. It's a pretty complicated format. You can't simply glue the files together. – user4581301 Mar 25 '22 at 23:53
  • Ditto. Attempting to produce together a single AAC file simply by concatenated a bunch of smaller files is like attempting to build a big airplane, like an Airbus A380 by bolting together a dozen Cessnas. – Sam Varshavchik Mar 26 '22 at 00:10
  • 1
    You will definitely want to use a pre-written media file library to do this job. Writing this from scratch would be a time-consuming challenge for an experienced programmer. Not my field, so I can't offer any suggestions that you wouldn't find with the same amount of time spent Googling. – user4581301 Mar 26 '22 at 00:18
  • 1
    @JacobJohnson "*I'm trying to "pack" them into one file in the most efficient way that I can*" - for what purpose, exactly? You won't be able to *play* such a file in any media player. Are you perhaps wanting to transport the files somewhere in one big data chunk, and then later you will "unpack" the individual files? – Remy Lebeau Mar 26 '22 at 00:40
  • 1
    If Remy's suspicion is correct, you might as well use a pre-existing archiving utility or virtual file system. – user4581301 Mar 26 '22 at 00:42

1 Answers1

1

These files have an internal structure: header, blocks/frames, etc. and the simple presence of multiple headers within the concatenated file will mess up the expected result.

Take a look at the AAC file format structure, you'll see that it's not so simple.

Your best try should be to use FFMPEG, since it has a feature to concatenate media files without being forced to reencode data. It's a bit complex because FFMPEG's command line is quite complex and not always extremely intuitive, but it should works as long as all AAC files uses the same encoding and characteristics. Otherwise, you'll need to re-encode them - but it can be done automatically, too. Check this web research to get some base informations.

Otherwise, you may use the base libraries used by FFMPEG, for example libavcodec (available at ffmpeg.org), Fraunhofer FDK AAC, etc. but you'll have way, way more work to do and, finally, you'll do exactly what FFMPEG already do, since it relies on these libraries. Other AAC libraries won't be really easier to use.

Obviously, you can also "embed" FFMPEG within your application, call tools like ffprobe to analyze files and call ffmpeg executable automatically, as a child process.

CAUTION: Take a GREAT care about licensing if you plan to distribute your program. FFMPEG licensing is really not simple, most of the time it's distributed as sources to avoid vicious cases.

Wisblade
  • 1,483
  • 4
  • 13
  • I program as a hobby, so Licensing isn't something I want to deal with. I'm using multithreading to download all of the chunks from an m3u8 and then I'm looking for a way to put all of those chunks into a single file. – Jacob Johnson Mar 26 '22 at 19:13
  • Then, definitively, you should look for doing it with FFMPEG, driven by your application in order to manage threads and sequencing. Finding the "good" command line won't take more than half a day, let's say another half to connect it properly to your app, and it's near done. Doing it "manually", through `libav` or similar, is a task that will requires **weeks**. The whole "packing" of AAC files can even be done in a background task of your application... – Wisblade Mar 26 '22 at 23:56
  • @JacobJohnson a single file that is one long, playable audio file? If so, Wisblade has the right idea. – user4581301 Mar 27 '22 at 00:13
  • @user4581301 Quoting the op: _"The audio is either all warbled or the file is only a few bytes long."_ So it looks like it was the intend, at least it's how I understood the initial question. – Wisblade Mar 27 '22 at 00:27
  • That's how I interpret it as well, but Stack Overflow can be a wacky place. – user4581301 Mar 28 '22 at 00:35
  • 1
    +1, I really appreciate the help. For anyone else who is trying to do the same, I suggest you look into Boost.process [Docs](http://www.highscore.de/boost/process/) [Git](https://github.com/boostorg/process) for the child process. – Jacob Johnson Mar 29 '22 at 03:06