fix: update GOP parameters for mediaAnalyzerGOP and transcode2PassX265 to enhance encoding efficiency and documentation
Build / Lint & Test (push) Successful in 16s
Build / Lint & Test (push) Successful in 16s
This commit is contained in:
1 parent
36184fbf32
commit
3f0b38d513
7 files changed
+38
-19
No files matched your search
@@ -6,7 +6,9 @@
|
||||
* mediaAnalyzerGOP
|
||||
* Analyzes the video stream and populates args.variables with encoding
|
||||
* parameters consumed by downstream plugins:
|
||||
* gopKeyint / gopMinKeyint -> 2 x FPS (rounded)
|
||||
* gopKeyint -> 4 x FPS (rounded; maximum 4-second GOP)
|
||||
* gopMinKeyint -> 1 x FPS (rounded; permits scene cuts)
|
||||
* gopSceneCut -> x265 scene-cut threshold (40)
|
||||
* isAnimation -> detected from animeSeries path list
|
||||
* isMovie -> detected from moviePathPatterns
|
||||
* vBitrate / vMaxRate / vBufSize
|
||||
@@ -17,7 +19,7 @@
|
||||
const details = () => ({
|
||||
name: 'Media Analyzer & GOP Calculator',
|
||||
description:
|
||||
'Analyzes video metadata, calculates GOP keyint (2xFPS), target bitrate '
|
||||
'Analyzes video metadata, calculates a streaming-friendly 4-second GOP, target bitrate '
|
||||
+ 'and VBV parameters based on content type (film/series/anime). '
|
||||
+ 'Exports all values to args.variables for downstream plugins.',
|
||||
style: { borderColor: '#2196F3' },
|
||||
@@ -123,8 +125,13 @@ const plugin = async (args) => {
|
||||
}
|
||||
jobLog(`[mediaAnalyzerGOP] FPS: ${fps.toFixed(3)}\n`);
|
||||
|
||||
const gopKeyint = String(Math.round(fps * 2));
|
||||
jobLog(`[mediaAnalyzerGOP] keyint=${gopKeyint}\n`);
|
||||
// A four-second maximum GOP is a compromise for remote streaming: it
|
||||
// reduces regular I-frame overhead while keeping seek recovery short.
|
||||
// A one-second minimum leaves x265 free to insert an I-frame at a real cut.
|
||||
const gopKeyint = String(Math.round(fps * 4));
|
||||
const gopMinKeyint = String(Math.round(fps));
|
||||
const gopSceneCut = '40';
|
||||
jobLog(`[mediaAnalyzerGOP] keyint=${gopKeyint} min-keyint=${gopMinKeyint} scenecut=${gopSceneCut}\n`);
|
||||
|
||||
// Normalize to forward slashes for cross-platform path matching
|
||||
const normalizedPath = filePath.replace(/\\/g, '/');
|
||||
@@ -149,7 +156,8 @@ const plugin = async (args) => {
|
||||
jobLog(`[mediaAnalyzerGOP] vBitrate=${vBitrate} vMaxRate=${vMaxRate} vBufSize=${vBufSize}\n`);
|
||||
|
||||
variables.gopKeyint = gopKeyint;
|
||||
variables.gopMinKeyint = gopKeyint;
|
||||
variables.gopMinKeyint = gopMinKeyint;
|
||||
variables.gopSceneCut = gopSceneCut;
|
||||
variables.isAnimation = String(isAnimation);
|
||||
variables.isMovie = String(isMovie);
|
||||
variables.vBitrate = vBitrate;
|
||||
|
||||
@@ -166,8 +166,9 @@ const plugin = async (args) => {
|
||||
|
||||
// ── Read variables ────────────────────────────────────────────────────────
|
||||
const {
|
||||
gopKeyint = '48',
|
||||
gopMinKeyint = '48',
|
||||
gopKeyint = '96',
|
||||
gopMinKeyint = '24',
|
||||
gopSceneCut = '40',
|
||||
vBitrate = '3000k',
|
||||
vMaxRate = '6000k',
|
||||
vBufSize = '12000k',
|
||||
@@ -189,7 +190,8 @@ const plugin = async (args) => {
|
||||
|
||||
jobLog(
|
||||
`[transcode2PassX265] Params: bitrate=${vBitrate} maxrate=${maxRateNum}k `
|
||||
+ `bufsize=${bufSizeNum}k keyint=${gopKeyint} tune=${x265Tune || 'none'} preset=${x265Preset}\n`,
|
||||
+ `bufsize=${bufSizeNum}k keyint=${gopKeyint} min-keyint=${gopMinKeyint} scenecut=${gopSceneCut} `
|
||||
+ `tune=${x265Tune || 'none'} preset=${x265Preset}\n`,
|
||||
);
|
||||
const sourceBitrateKbps = getVideoBitrateKbps(videoStream, streams, format).toFixed(0);
|
||||
jobLog(
|
||||
@@ -219,7 +221,7 @@ const plugin = async (args) => {
|
||||
const x265ParamsBase = [
|
||||
`keyint=${gopKeyint}`,
|
||||
`min-keyint=${gopMinKeyint}`,
|
||||
`scenecut=0`,
|
||||
`scenecut=${gopSceneCut}`,
|
||||
`open-gop=0`,
|
||||
`vbv-maxrate=${maxRateNum}`,
|
||||
`vbv-bufsize=${bufSizeNum}`,
|
||||
|
||||
Reference in new issue
Block a user