feat:完成文档
This commit is contained in:
parent
612677195e
commit
fee2f3100e
19
README.md
19
README.md
@ -1,3 +1,20 @@
|
||||
# h264-to-h265
|
||||
|
||||
使用ffmpeg将264视频转换为h265视频
|
||||
使用 ffmpeg 将 264 视频转换为 h265 视频,支持 intel qsv 加速,nvdia cuda 加速。
|
||||
|
||||
选择文件夹后,会递归处理此文件夹,子文件夹中的视频也会被处理。
|
||||
|
||||
本人实测速度如下:
|
||||
|
||||
- qsv: 10 倍速(使用 uhd750)
|
||||
- cuda: 16 倍速(使用 3060ti)
|
||||
|
||||
## 使用方法
|
||||
|
||||
前置条件:需要安装 ffmpeg,如需要硬件加速还要安装对应的显卡驱动。可参考[安装文档](https://juejin.cn/post/7034411980316213256)
|
||||
|
||||
### node 代码执行。支持 windows/linux
|
||||
|
||||
1. 安装 node 环境
|
||||
2. 修改 index.js 中要处理文件夹路径。
|
||||
3. 执行 node index.js 即可
|
||||
|
40
index.js
40
index.js
@ -2,16 +2,37 @@ const fs = require('fs-extra');
|
||||
const path = require('path');
|
||||
|
||||
const cmd = require('child_process');
|
||||
const hardTypeSet = new Set("none", "qsv", "cuda");
|
||||
const supportVideoTypeSet = new Set("mkv", "mp4");
|
||||
|
||||
async function deal (basePath) {
|
||||
/**
|
||||
*
|
||||
* @param {*} basePath 处理路径
|
||||
* @param {int} maxBitRate 最大码率,默认2500
|
||||
* @param {boolean} changeName 是否改名(true会将h264,x264变更为h265,或者在文件结尾插入h265,其他名称相同额文件也会处理)
|
||||
* @param {*} hardType 硬件加速类型,空/none:不使用加速;qsv:使用intel核显qsv加速;cuda:使用nvdia cuda加速
|
||||
* @returns
|
||||
*/
|
||||
async function deal (basePath, maxBitRate = 2500, changeName = false, hardType) {
|
||||
let hwType = hardType == 'qsv' ? "-hwaccel qsv" : hardType == 'cuda' ? "-hwaccel cuda" : "";
|
||||
let decodeType = hardType == 'qsv' ? "-c:v h264_qsv" : hardType == 'cuda' ? "-c:v hevc_qsv" : "";
|
||||
let encodeType = hardType == 'qsv' ? "-c:v h264_cuvid" : hardType == 'cuda' ? "-c:v hevc_nvenc" : "";
|
||||
|
||||
if (!hardType && !hardTypeSet.has(hardType)) {
|
||||
throw new Error("不支持的加速方案:" + hardType + ",仅支持:空," + JSON.stringify(hardTypeSet));
|
||||
}
|
||||
let fileList = fs.readdirSync(basePath);
|
||||
for (let i in fileList) {
|
||||
let name = fileList[i];
|
||||
if (!name.endsWith('.mkv') && !name.endsWith('.mp4')) {
|
||||
let filePath = path.join(basePath, name);
|
||||
if (fs.statSync(filePath).isDirectory) {
|
||||
//如果为文件夹递归处理
|
||||
deal(filePath, maxBitRate, hardType);
|
||||
}
|
||||
if (!supportVideoTypeSet.has(name.substring(name.lastIndexOf(".") + 1))) {
|
||||
continue;
|
||||
}
|
||||
console.log("---------开始处理:" + name);
|
||||
let filePath = path.join(basePath, name);
|
||||
let res = JSON.parse(cmd.execSync(`ffprobe.exe "${filePath}" -show_streams -select_streams v -show_format -print_format json`, { encoding: 'utf-8' }));
|
||||
if (!res.format || !res.streams || res.streams.length == 0) {
|
||||
console.log("无法识别的格式:" + JSON.stringify(res));
|
||||
@ -28,7 +49,7 @@ async function deal (basePath) {
|
||||
continue;
|
||||
}
|
||||
bitRate = Math.round(parseInt(bitRate) / 1000);
|
||||
bitRate = bitRate > 2500 ? 2500 : bitRate;
|
||||
bitRate = bitRate > maxBitRate ? maxBitRate : bitRate;
|
||||
let newName;
|
||||
if (name.indexOf("h264") > -1) {
|
||||
newName = name.replace('h264', 'h265');
|
||||
@ -39,7 +60,7 @@ async function deal (basePath) {
|
||||
newName = name.substr(0, index) + ".h265" + name.substr(index);
|
||||
}
|
||||
let newFilePath = path.join(basePath, newName);
|
||||
let cmdStr = `ffmpeg.exe -hwaccel cuda -c:v h264_cuvid -i "${filePath}" -c:v hevc_nvenc -maxrate ${bitRate}K -c:a copy "${newFilePath}"`;
|
||||
let cmdStr = `ffmpeg.exe ${hwType} ${decodeType} -i "${filePath}" ${encodeType} -maxrate ${bitRate}K -c:a copy "${newFilePath}"`;
|
||||
console.log(cmdStr);
|
||||
let changeRes = cmd.execSync(cmdStr, { encoding: 'utf-8' });
|
||||
console.log(changeRes);
|
||||
@ -47,6 +68,7 @@ async function deal (basePath) {
|
||||
console.log("未知错误,文件转换失败");
|
||||
return;
|
||||
}
|
||||
if (changeName) {
|
||||
//字幕,nfo文件重命名
|
||||
let namePart1 = name.substr(0, name.lastIndexOf('.'));
|
||||
let newNamePart1 = newName.substr(0, newName.lastIndexOf('.'));
|
||||
@ -58,12 +80,14 @@ async function deal (basePath) {
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
fs.removeSync(filePath);
|
||||
if (!changeName) {
|
||||
fs.moveSync(newFilePath, filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
(async () => {
|
||||
await deal("Z:/无耻之徒.Shameless.美版/season 09");
|
||||
await deal("Z:/无耻之徒.Shameless.美版/season 10");
|
||||
await deal("Z:/无耻之徒.Shameless.美版/season 11");
|
||||
await deal("要处理的文件夹", 2500, true, "cuda");
|
||||
})();
|
||||
|
||||
|
2
run.bat
2
run.bat
@ -1,2 +0,0 @@
|
||||
@REM 核显解码,nv独显编码,平均码率2.5m
|
||||
ffmpeg.exe -hwaccel cuda -c:v h264_cuvid -i ./Shameless.1080p.h264.s11e01.mkv -c:v hevc_nvenc -maxrate 2500K -c:a copy ./newShameless1.1080p.h264.s11e01.mkv
|
@ -1,2 +0,0 @@
|
||||
ffmpeg.exe -i "./Shameless.1080p.h264.s11e01.mkv" -c:v hevc_qsv -c:a copy "./newQsvShameless.1080p.h264.s11e01.mkv" -x265-params lossless=1
|
||||
ffmpeg.exe -hwaccel cuvid -c:v h263_cuvid -i ./Shameless.1080p.h264.s11e01.mkv -c:v hevc_nvenc -b:v 2548k ./newShameless.1080p.h264.s11e01.mkv
|
Loading…
x
Reference in New Issue
Block a user