如何在 C++ 中将数百个二进制文件合并为一个输出文件?
How do I combine hundreds of binary files to a single output file in c++?
我有一个包含数百个 .aac
文件的文件夹,我正在尝试以最有效的方式将它们“打包”到一个文件中。
我已经尝试了以下方法,但最终得到的文件只有几个字节长,或者音频听起来非常失真。
// 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();
}
我查看了以下问题以尝试帮助解决此问题
Merging two files together
How do I read an entire file into a std::string in C++?
Read whole ASCII file into C++ std::string
然而不幸的是,其中 none 个回答了我的问题。
它们要么与文本文件有关,要么与不能同时处理数百个文件的函数有关。
我正在尝试写入 二进制 数据,而不是文本。音频要么全部失真,要么文件只有几个字节长。
如果有有效的内存方法可以做到这一点,请告诉我。我正在使用 C++ 20 和 boost。
谢谢。
这些文件具有内部结构:header、blocks/frames 等,并且在串联文件中简单地存在多个 header 会打乱预期的结果。
看看AAC file format structure,你会发现事情并没有那么简单。
您最好的尝试应该是使用 FFMPEG,因为它具有连接媒体文件的功能 ,而不会 被迫重新编码数据。它有点复杂,因为 FFMPEG 的命令行非常复杂并且并不总是非常直观,但只要所有 AAC 文件使用相同的编码和特征,它就应该可以工作。否则,您将需要 re-encode 它们 - 但它也可以自动完成。
检查此 web research 以获取一些基本信息。
否则,您可以使用 FFMPEG 使用的基础库,例如 libavcodec (available at ffmpeg.org), Fraunhofer FDK AAC 等。但是您还有更多的工作要做,最后,您将完全按照 FFMPEG 的方式进行操作已经这样做了,因为它依赖于这些库。其他 AAC 库不会真的更容易使用。
显然,您也可以在您的应用程序中“嵌入”FFMPEG,调用 ffprobe
等工具来分析文件并自动调用 ffmpeg
可执行文件,作为一个 child 进程。
注意:如果您打算分发您的程序,请非常注意许可。 FFMPEG licensing 真的不简单,大部分时候都是作为源码分发,避免恶性案件。
我有一个包含数百个 .aac
文件的文件夹,我正在尝试以最有效的方式将它们“打包”到一个文件中。
我已经尝试了以下方法,但最终得到的文件只有几个字节长,或者音频听起来非常失真。
// 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();
}
我查看了以下问题以尝试帮助解决此问题
Merging two files together
How do I read an entire file into a std::string in C++?
Read whole ASCII file into C++ std::string
然而不幸的是,其中 none 个回答了我的问题。
它们要么与文本文件有关,要么与不能同时处理数百个文件的函数有关。
我正在尝试写入 二进制 数据,而不是文本。音频要么全部失真,要么文件只有几个字节长。
如果有有效的内存方法可以做到这一点,请告诉我。我正在使用 C++ 20 和 boost。 谢谢。
这些文件具有内部结构:header、blocks/frames 等,并且在串联文件中简单地存在多个 header 会打乱预期的结果。
看看AAC file format structure,你会发现事情并没有那么简单。
您最好的尝试应该是使用 FFMPEG,因为它具有连接媒体文件的功能 ,而不会 被迫重新编码数据。它有点复杂,因为 FFMPEG 的命令行非常复杂并且并不总是非常直观,但只要所有 AAC 文件使用相同的编码和特征,它就应该可以工作。否则,您将需要 re-encode 它们 - 但它也可以自动完成。 检查此 web research 以获取一些基本信息。
否则,您可以使用 FFMPEG 使用的基础库,例如 libavcodec (available at ffmpeg.org), Fraunhofer FDK AAC 等。但是您还有更多的工作要做,最后,您将完全按照 FFMPEG 的方式进行操作已经这样做了,因为它依赖于这些库。其他 AAC 库不会真的更容易使用。
显然,您也可以在您的应用程序中“嵌入”FFMPEG,调用 ffprobe
等工具来分析文件并自动调用 ffmpeg
可执行文件,作为一个 child 进程。
注意:如果您打算分发您的程序,请非常注意许可。 FFMPEG licensing 真的不简单,大部分时候都是作为源码分发,避免恶性案件。