Lua在Linux上使用Sox进行批量处理MP3音频

首先需要Sox和MP3格式支持

apt install sox
apt install libsox-fmt-mp3

然后是lua程序

主程序 main.lua

local filelist = io.popen('find input -name "*.mp3"')	--扫描MP3
local fileContent = filelist:read("*all")	--读取文字段
filelist:close()	--关闭popen
os.execute("mkdir output")
os.execute("rm -rf SOXLUA")	--移除锁储存的目录
os.execute("mkdir SOXLUA")	--创建锁储存的目录

function split( str,reps )	--字符串分段
    local resultStrList = {}
    string.gsub(str,'[^'..reps..']+',function ( w )
        table.insert(resultStrList,w)
    end)
    return resultStrList
end

function getPart(str)	--大段路径转换成表
	local str,lin = string.gsub(str,"\r","")
	return split(str,"\n")
end
local ret = getPart(fileContent)
local totalLine = #ret	--总行数
local cnt = 0	--当前正在执行

function getPool()	--获取处理池,一旦有空池,立刻返回,否则阻塞主程序
	while(true) do
		os.execute("sleep 0.01")	--防止while造成高cpu使用率
		for i=1,12 do	--一共12个处理程序,循环检测
			local f = io.open("SOXLUA/SOXLUA"..i..".lock")	--检查锁文件是否存在
			if not f then return i end	--不存在则返回id,表示可用
			if f:read(2) == "ad" then	--如果存在,则读取这个锁是否已经被释放
				f:close()	--关闭检查的文件
				return i	--返回id,表示可用
			else
				f:close()	--关闭检查的文件
			end
		end
	end
end

for i,line in ipairs(ret) do	--主循环
	cnt = cnt+1	--每次循环+1表示当前处理进程
	local dir = split(line,"/")	--把路径写成表
	table.remove(dir,1)	--从表中移除"input"
	local fileName = dir[#dir]	--记录文件名
	table.remove(dir,#dir)	--从表中移除文件名
	local path = ""	--最终路径
	for i=1,#dir do	--层层创建路径,并且写入path变量
		path = path.."/"..dir[i]
		os.execute("mkdir 'output"..path.."'")	--创建目录
	end
	print("["..cnt.."/"..totalLine.."]"..line.." --> output"..path.."/"..fileName)	--打印进程数据
	local soxCommand = 'sox '..line..' -C 128 output/'..path..'/'..fileName	--转码的指令,!此处根据实际需求来修改代码!,传递给sox.lua的参数
	local poolID = getPool()	--获取空闲处理程序池
    io.popen("lua sox.lua '"..soxCommand.."' '".."SOXLUA/SOXLUA"..getPool()..".lock".."'")	--不加:close则为异步启动处理程序
end

子程序 sox.lua

local arg = {...}	--获取参数
local file = io.open(arg[2],"w")	--打开锁文件
file:write("a")	--写入a表示该锁已被使用
file:flush()	--立刻保存
io.popen(arg[1]):close()	--运行Sox指令
file:write("d")	--完成后,写入d表示该锁已经被释放
file:close()	--关闭锁

然后要把转码的文件丢到同目录下的input目录(没有自己创建),然后输入lua main.lua运行程序

处理完毕之后,输出在同目录下的output目录,并且保存目录结构

发表评论