Node.js 批量文件合并code

cnblogs @ Orcim   


本 文主要介绍使用 Node 进行 ACB 序列文件(Atom CueSheet Binary,编译 AtomCueSheet 二进制文件)进行合并的方法。

ACB 文件

ACB文件是日本一家叫做 CRI Middleware 的公司开发的音频包文件,包含ADX或ADX2格式的音频流。主要用于游戏中的声音特效以及背景音乐。其广泛用于 Unity 开发的各种游戏之中,游戏厂商将音频转换为这种二进制的音频文件,再将其打包成 Unity 的资源包(Assets),也就是游戏的资源更新包。而游戏厂商有时将一个 ACB 文件分割成多个二进制文件,这样就需要将其先合并。

ACB文件可以用 CRI Atom Craft 进行查看以及编辑,当然,这个软件也是由这家公司所开发。

关于ACB文件以及ADX2的更多详情,参见官方文档。感觉这种音频文件挺有趣的。

对于我为什么想写此篇博文,以及我为什么要用Node来做ACB文件合并这件事,只是因为偶然在提取游戏资源时碰到了ACB音频文件(起初我还并不知道这是音频流)没事干,折腾了一下,撰文记录我一个晚上的研究成果。

以上是这类二进制音频流文件的科普,以下正文。

ACB文件序列一览

下图是我用UnityStudio_x64从某个游戏中的Assets文件中提取出来的ACB源文件:

一段 BGM 被分割成了总共 41 个文件,提取出来的文件后缀是 .txt,文件是二进制的,用记事本打开会乱码。需要将这些文件合并成一个 ACB 文件。文件名是按规律来排列的:bgm133-[ Number ].acb.txt

思路

1)首先先读取这些 .acb.txt 文件的二进制数据,因为文件有按照数字编号排列,所以要按顺序进行读取并合并。

2)接下来就是进行读文件的操作,得到文件的 Buffer,一个类数组的数据

3)然后将这些文件的 Buffer 合并,这一步类似于多个数组进行 concat 的操作

4)最后一步依据合并得到的数组创建一个 Buffer 对象,例:_buf_,NodeJs 中是用 var buf = Buffer.from( _buf_ ),再写文件 fs.writeFileSync("unite.acb", buf)

方案实施

具体流程,详见代码 unite.JS:

 
unite.js
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
var t0 = new Date().valueOf();
const fs = require("fs");
const path = require("path");
const join = path.join;
 
var fNames = getFileNames(__dirname); // 获取当前文件夹
var base = fNames.map(function(item, idx){
    return path.basename(item); // 当前目录下所有文件路径
});
var baseFiles = []; // 用于存储 CAB 文件的文件名队列
for(var _=0; _<base.length; _++){
    if(!path.basename(base[_]).match(/\.acb\.txt/)) continue; // 判断文件名符不符合 *.acb.txt
    baseFiles.push(base[_]); // 如果符合就 push 到队列之中
}
console.log(baseFiles); // ["..001.acb.txt", "..002.acb.txt", ..., "..041.acb.txt"]
var buf = [], a = 0; // var( buf ) -> 用于存储合并后文件的二进制值数组
baseFiles.forEach(function(item, idx){
    var pos_center = item.indexOf("-")+1; // 从 ..001.acb.txt 开始
    // 按照 001 ~ 041 的文件名顺序进行 Buffer 的连接
    var tmpBuf = fs.readFileSync(path.join(__dirname, item.substr(0, pos_center) + to3digit(idx+1) + ".acb.txt"));
    var tmpLength = tmpBuf.length;
    for(var b=0; b<tmpLength; b++){
        buf[a] = tmpBuf[b]; // 类似于数组的 concat 操作
        a++;
    }
});
fs.writeFileSync(__dirname + "\\unite.acb", Buffer.from(buf));
function getFileNames(_path){ // 获取当前目录下所有文件的路径数组
    let jsonFiles = [];
    function findJsonFile(path){
        let files = fs.readdirSync(path);
        files.forEach(function(item){
            let fPath = join(path, item);
            let stat = fs.statSync(fPath);
            if(stat.isDirectory() === true){
                findJsonFile(fPath);
            }
            if(stat.isFile() === true){
                jsonFiles.push(fPath);
            }
        });
    }
    findJsonFile(_path);
    return jsonFiles;
}
function to3digit(num){ // 数字转换为三位的字符串,数字不足三位补0
    return (num<10?"00":(num<100?"0":"")) + num;
}
// console.log(to3digit(1), to3digit(9), to3digit(10), to3digit(99), to3digit(100), to3digit(999), to3digit(1000))
console.info("Bundled \x1B[35m%d\x1B[39m file%s in \x1B[32m%dms\x1B[39m", baseFiles.length, baseFiles.length>1?"s":"", new Date().valueOf() - t0);
 

使用方法

  1. 将unite.js放在ACB序列文件所在的根目录下

  2. 打开命令行工具,运行 unite.js:可以将js文件直接拖到命令行窗口中运行。

  3. 合并成功

  4. 合并后目录下会合并写好一个unite.acb文件,文件可以通过 VGMToolbox 工具进行提取,转换为 .hca 音频,foobar2000 安装 VGMStream Decoder 插件后(点击下载,解压后双击安装),即可播放 .hca 音频或进行格式转换

结束语

使用工具:NodeJS、UnityStudio、VGMToolbox、foobar2000、VGMStream Decoder

NodeJS二进制合并的更多相关文章

  1. NodeJS二进制包安装和快捷键配置(适用于U盘版安装配置)

    首先下载NodeJS二进制安装包:https://nodejs.org/dist/v10.15.3/node-v10.15.3-win-x64.zip 在D盘新建NodeJS文件夹,解压node-v1 ...

  2. centos安装nodejs二进制包

    1.下载nodejs的二进制包 wget https://nodejs.org/dist/v6.3.1/node-v6.3.1-linux-x64.tar.xz 2.解压下载的安装包 tar xf n ...

  3. centos7 nodejs二进制安装

    1.安装文件下载 1.下载地址:http://nodejs.cn/download/ 2.选择一个合适的版本下载 2.安装步骤 1.将安装包上传到指定位置(我习惯放到:/usr/local/appli ...

  4. C# 版 flvmerge:快速合并多个flv文件

    网上的视频很多都是分片的flv文件,怎么把他们合为一体呢?GUI工具就不考虑了,不适合批量执行,不适合在后台运行.有没有命令行工具或库可以实现呢? ffmpeg 提供了一个方法: (1)先把flv文件 ...

  5. AngularJS结合RequireJS做文件合并压缩的那些坑

    我在项目使用了AngularJS框架,用RequireJS做异步模块加载(AMD),在做文件合并压缩时,遇到了一些坑,有些只是解决了,但不明白原因. 那些坑 1. build.js里面的paths必须 ...

  6. 安装nodejs搭建ghost个人博客

    记录一下今天在linux下折腾nodejs的过程,相互学习: (不知道为什么用源代码安装,调用npm的时候老是会出现找不到npmlog的 错误,后来换用下了个二进制 来搞,假设那个牛牛知道为什么.希望 ...

  7. Linux_CentOS软件安装调试 源代码包编译安装和 二进制包配置

    Linux 下源代码(C 语言)如何编译(安装) 1. 先安装源代码编译的软件 gcc,make,openssl 如下: yum install -y gcc make gcc-c++ openssl ...

  8. CentOS7编译安装NodeJS

    概述 在CentOS7下采用编译NodeJS二进制源码包的方式安装NodeJS 下载NodeJS安装包 你可以先下载NodeJS二进制源码安装包文件然后上传到CentOS系统,也可以通过wget命令直 ...

  9. Linux系统下安装NodeJS

    下载NodeJS二进制压缩包 去NodeJS官网https://nodejs.org/zh-cn/,下载二进制压缩包,进入下载页面之后你将看到很多下载选项: 源码不包含bin目录,不是可运行的应用程序 ...

随机推荐

  1. 深圳做假证h

    深圳做假证[电/薇:187ヘ1184ヘ0909同号]办各类证件-办毕业证-办离婚证,办学位证书,办硕士毕业证,办理文凭学历,办资格证,办房产证不. 这是一个简单的取最大值程序,可以用于处理 i32 数 ...

  2. 长沙做假证u

    长沙做假证[电/薇:187ヘ1184ヘ0909同号]办各类证件-办毕业证-办离婚证,办学位证书,办硕士毕业证,办理文凭学历,办资格证,办房产证不. 这是一个简单的取最大值程序,可以用于处理 i32 数 ...

  3. kotlin 作用域函数 : let、run、with、apply、 also、takeIf、takeUnless

    1.官方文档 英文: https://kotlinlang.org/docs/reference/scope-functions.html 中文: https://www.kotlincn.net/d ...

  4. Mac本地生成SSHKey的方法

    1. 查看秘钥是否存在 打开终端查看是否已经存在SSH密钥:cd ~/.ssh 如果没有密钥则不会有此文件夹,有则备份删除,   也可以直接删除, 2.生成新的秘钥, 命令如下 $ssh-keygen ...

  5. Codeforces 1321C Remove Adjacent

    题意 给你一个字符串,字符\(s_i\)可以被伤处当且仅当\(s_{i-1}=s_i-1\)或\(s_{i+1}=s_i-1\).问最多能删几个字符. 解题思路 其实,有个很简单的做法就是从\(z\) ...

  6. 聊聊redis单线程为什么能做到高性能和io多路复用到底是个什么鬼

    1:io多路复用epoll  io多路复用简单来说就是一个线程处理多个网络请求 我们知道epoll in 的事件触发是可读了,这个比较好理解,比如一个连接过来,或者一个数据发送过来了,那么in事件就触 ...

  7. 【CF】Sereja and Arcs

    #include <bits/stdc++.h> #define llong long long using namespace std; const int N = 1e5; const ...

  8. 原生JDK网络编程- NIO之Reactor模式

    “反应”器名字中”反应“的由来: “反应”即“倒置”,“控制逆转”,具体事件处理程序不调用反应器,而向反应器注册一个事件处理器,表示自己对某些事件感兴趣,有时间来了,具体事件处理程序通过事件处理器对某 ...

  9. 10行实现最短路算法——Dijkstra

    今天是算法数据结构专题的第34篇文章,我们来继续聊聊最短路算法. 在上一篇文章当中我们讲解了bellman-ford算法和spfa算法,其中spfa算法是我个人比较常用的算法,比赛当中几乎没有用过其他 ...

  10. jmeter(一)

    一.首先是下载:下载地址为:http://jmeter.apache.org/download_jmeter.cgi选择Binaries下的相应压缩包.ps:jmeter是开源项目,一般这种开源项目B ...