ffmpegGUI 开发笔记

如何开启硬件加速

注意: 在开启硬件加速时,转码的速度虽然快了,但视频质量会出现大幅下滑,目前解决办法只能通过设置高码率来解决,目前我的做法是在原码率的基础上提高 1.5 倍,基本能保证视频质量,但体积也会增加 1.5 倍(如果有更好的方法请告诉我)

以我这个项目为例,首先通过执行 ffmpeg -hwaccels 来获取当前机器支持哪些硬件加速的方法,不同的平台开启硬件加速的方法不一样

查看机器支持的硬件加速的方法:

1
2
3
4
5
// node子进程的方式
let exec = require("child_process").exec;
exec(`${ffmpegPath} -hwaccels`, (err, stdout, stderr) => {
console.log(stdout); // Hardware acceleration methods: videotoolbox
});
1
2
// 原生ffmpeg的方式
ffmpeg - hwaccels;

查看机器支持的编码器(encoders):

1
2
3
4
5
6
7
8
9
10
// node子进程的方式
let exec = require("child_process").exec;
exec(`${ffmpegPath} -encoders`, (err, stdout, stderr) => {
console.log(stdout);
// 这里会打印出很多信息,只需要找出带有之前带有videotoolbox的就行(这里的 videotoolbox 是上次查到的支持硬件加速的方法)
// ......
// V..... h264_videotoolbox VideoToolbox H.264 Encoder (codec h264)
// V..... hevc_videotoolbox VideoToolbox H.265 Encoder (codec hevc)
// ......
});
1
2
// 原生ffmpeg的方式
ffmpeg - encoders;

把上面查到的结果带到ffmpeg 里执行即可(以下代码是我项目的例子,如果是命令的方式,直接带上这个参数执行就行)

1
2
3
4
ffmpeg()
.input("/dev/video")
.videoCodec("h264_videotoolbox") // H264,hevc_videotoolbox(h265)
.inputFormat("mov");
1
2
// 原生ffmpeg的方式
ffmpeg -vcodec h264_videotoolbox

以上就可以开启硬件加速功能了

打包后 electron 里 asar 不能使用二进制文件的问题

1
2
3
4
5
// 修复 electron asar 不能使用二进制文件的问题
if (process.env.NODE_ENV !== "development") {
ffmpegPath = ffmpegPath.replace("app.asar", "app.asar.unpacked");
ffprobePath = ffprobePath.replace("app.asar", "app.asar.unpacked");
}

在打完包后,会把相关的二进制文件放到app.asar.unpacked里,默认会放到app.asar

screenshot3

如何通过 Webpack 打包不同平台的二进制文件到 APP 里

首先通过 process.platform来判断平台,然后用 CopyWebpackPlugin 插件从 node_modules 把相关平台的的二进制文件复制出来

webpack.renderer.config

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if (process.env.NODE_ENV === "production") {
const ffmpegBasePath = "../node_modules/ffmpeg-static/bin/"; // ffmpeg-static

const { platform } = process;

const ffmpegPathMap = {
darwin: "darwin/x64/ffmpeg",
};

const ffmpegPath = ffmpegBasePath + ffmpegPathMap[platform];

rendererConfig.plugins.push(
new CopyWebpackPlugin([
{
from: path.join(__dirname, ffmpegPath),
to: path.join(__dirname, "../core"),
ignore: [".*"],
},
])
);
}

调整二进制文件的权限,并设置 ffmpeg 的打包后的路径(复制出来的二进制文件似乎有权限问题)

core.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import ffmpeg from "fluent-ffmpeg";
import { resolve } from "path";

// 找出复制出来的路径
let basePath = resolve(__dirname, "../../../core/");

if (process.env.NODE_ENV == "production") {
const fs = require("fs");

let realFfmpegPath = basePath + "/ffmpeg";

fs.stat(realFfmpegPath, (err, stats) => {
if (err) return;
// 如果 ffmpeg、ffprobe 非 777 权限,则设置成 777
if (stats.mode !== 33279) {
fs.chmod(realFfmpegPath, "0777", (err) => {
if (err) {
console.error(err);
return;
}
console.log("ffmpeg 修改权限成功");
});
}
});

ffmpegPath = realFfmpegPath;
}

ffmpeg.setFfmpegPath(ffmpegPath);

把二进制文件打包到 APP 里(通过 electron builderextraResources 把二进制文件拷贝到 APP 里)

package.json

1
2
3
4
5
6
7
"mac": {
"extraResources": {
"from": "./core/",
"to": "./core/",
"filter": ["**/*"]
}
}

screenshot4