Skip to content

Commit

Permalink
feat: aws pipeline qvbr job
Browse files Browse the repository at this point in the history
  • Loading branch information
oshinongit committed Aug 12, 2024
1 parent f858bc6 commit 18c72f7
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 20 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,23 @@ by insterting `%VARIABLENAME%`. This string will then be substituted with a valu
be set to avoid injecting bitrate options to ffmpeg. Also note that the cli needs to be run with the `--probe-bitrate`
option to get the correct bitrate from the transcoded files.

It is also possible to use pipelineVariables with the AWSPipeline. The following example will run transcode and vmaf analysis using the AWS MediaCOnvert QVBR levels 6, 7, 8 and 9.

```yaml
name: job-name
pipeline: pipeline.yml
encodingProfile: encoding-profile.json
reference: reference.mp4
models:
- HD
pipelineVariables:
QVBR:
- 6
- 7
- 8
- 9
```

### Generate VMAF measurements example

```bash
Expand Down
12 changes: 12 additions & 0 deletions examples/aws/aws-job-qvbr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: job-name
pipeline: pipeline.yml
encodingProfile: encoding-profile.json
reference: reference.mp4
models:
- HD
pipelineVariables:
QVBR:
- 6
- 7
- 8
- 9
45 changes: 45 additions & 0 deletions examples/aws/encoding-profile-qvbr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
{
"Inputs": [
{
"TimecodeSource": "ZEROBASED",
"VideoSelector": {},
"FileInput": "$INPUT"
}
],
"OutputGroups": [
{
"Name": "File Group",
"OutputGroupSettings": {
"Type": "FILE_GROUP_SETTINGS",
"FileGroupSettings": {
"Destination": "$OUTPUT"
}
},
"Outputs": [
{
"VideoDescription": {
"CodecSettings": {
"Codec": "H_264",
"H264Settings": {
"RateControlMode": "QVBR",
"QvbrSettings": {
"QvbrQualityLevel": "$QVBR"
},
"CodecProfile": "HIGH"
}
},
"Width": "$WIDTH",
"Height": "$HEIGHT"
},
"ContainerSettings": {
"Container": "MP4",
"Mp4Settings": {}
}
}
]
}
],
"TimecodeConfig": {
"Source": "ZEROBASED"
}
}
19 changes: 8 additions & 11 deletions src/analysis/brute-force.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,15 +83,14 @@ export default async function analyzeBruteForce(
// Create all combinations of bitrate, resolution, and variables
Object.entries(options.pipelineVariables).forEach(
([variableName, values]) => {
//console.log(`variableName: ${variableName}`);
pairs = pairs.flatMap(
(pair) =>
values.map((value) => {
const variables = pair.ffmpegOptionVariables
? { ...pair.ffmpegOptionVariables }
const variables = pair.pipelineVariables
? { ...pair.pipelineVariables }
: {};
variables[variableName] = value;
return { ...pair, ffmpegOptionVariables: variables };
return { ...pair, pipelineVariables: variables };
}) as BitrateResolutionPair[]
);
}
Expand All @@ -100,12 +99,10 @@ export default async function analyzeBruteForce(

const analyzePair = async (pair: BitrateResolutionPair) => {
let outFile = `${directory}/${pair.resolution.width}x${pair.resolution.height}_${pair.bitrate}`;
if (pair.ffmpegOptionVariables) {
Object.entries(pair.ffmpegOptionVariables).forEach(
([variable, value]) => {
outFile = outFile + `_${variable}_${value}`;
}
);
if (pair.pipelineVariables) {
Object.entries(pair.pipelineVariables).forEach(([variable, value]) => {
outFile = outFile + `_${variable}_${value}`;
});
}
outFile = outFile + '.mp4';
const skip =
Expand All @@ -122,7 +119,7 @@ export default async function analyzeBruteForce(
pair.resolution,
pair.bitrate,
outFile,
pair.ffmpegOptionVariables
pair.pipelineVariables
);

if (variant === '') {
Expand Down
6 changes: 3 additions & 3 deletions src/create-job.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,13 @@ export type JobDescription = {
/** The method to use when analyzing the videos. Either `bruteForce` or `walkTheHull`. By default `bruteForce`. NOTE: `walkTheHull` is not implemented at the moment. */
method?: 'bruteForce' | 'walkTheHull';

/** Values that will be substituted into the encoding options. Currently only supported for local pipeline */
/** Values that will be substituted into the encoding options. */
pipelineVariables?: { [key: string]: string[] };

/** Skip transcode and run analysis only, files are assumed to be already present */
/** Skip transcode and run analysis only, files are assumed to be already present. */
skipTranscode?: boolean;

/** Skip transcode if outfile already exists */
/** Skip transcode if outfile already exists. */
skipExisting?: boolean;
};

Expand Down
2 changes: 1 addition & 1 deletion src/models/bitrate-resolution-pair.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ import { Resolution } from './resolution';
export type BitrateResolutionPair = {
resolution: Resolution;
bitrate: number;
ffmpegOptionVariables?: { [key: string]: string };
pipelineVariables?: { [key: string]: string };
};
20 changes: 15 additions & 5 deletions src/pipelines/aws/aws-pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,18 +158,28 @@ export default class AWSPipeline implements Pipeline {
'$HEIGHT',
targetResolution.height.toString()
);
settingsStr = this.stringReplacement(
settingsStr,
'$BITRATE',
targetBitrate.toString()
);
if (settingsStr.includes('$BITRATE')) {
settingsStr = this.stringReplacement(
settingsStr,
'$BITRATE',
targetBitrate.toString()
);
}

// HEVC specific settings
settingsStr = this.stringReplacement(
settingsStr,
'$HRDBUFFER',
(targetBitrate * 2).toString()
);

//Handle pipelineVariables given in the JobDescription
if (variables) {
Object.entries(variables).forEach(([key, value]) => {
settingsStr = this.stringReplacement(settingsStr, `$${key}`, value);
});
}

const settings = JSON.parse(settingsStr);
logger.debug('Settings Json: ' + JSON.stringify(settings));

Expand Down

0 comments on commit 18c72f7

Please sign in to comment.