Skip to content

Commit 5f78e21

Browse files
authored
Add videoCodec to/fromJson (#521)
1 parent bd76e10 commit 5f78e21

File tree

10 files changed

+123
-10
lines changed

10 files changed

+123
-10
lines changed

__TESTS_BUNDLE_SIZE__/bundleSizeTestCases.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const bundleSizeTestCases:ITestCase[] = [
7474
},
7575
{
7676
name: 'Import all of the SDK',
77-
sizeLimitInKB: 126,
77+
sizeLimitInKB: 127,
7878
importsArray: [
7979
importFromPackage('* as CloudinaryURLGEN')
8080
]
@@ -88,7 +88,7 @@ const bundleSizeTestCases:ITestCase[] = [
8888
},
8989
{
9090
name: 'Import All Actions',
91-
sizeLimitInKB: 53,
91+
sizeLimitInKB: 54,
9292
importsArray: [
9393
importFromPackage('Actions')
9494
]

__TESTS__/unit/fromJson/transcode.fromJson.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ describe('transcode.fromJson', () => {
1212
{actionType: 'audioCodec', audioCodec: 'aac'},
1313
{actionType: 'audioFrequency', audioFrequencyType: 'freq8000'},
1414
{actionType: 'streamingProfile', profile: 'fullHd'},
15-
{actionType: 'toAnimated', animatedFormat: 'gif', delay: 20, sampling: '4s'}
15+
{actionType: 'toAnimated', animatedFormat: 'gif', delay: 20, sampling: '4s'},
16+
{actionType: 'videoCodec', videoCodec: {videoCodecName: 'auto'}},
17+
{actionType: 'videoCodec', videoCodec: {videoCodecName: 'h264', profile: 'baseline', level: 3.1}}
1618
]});
1719

1820
expect(transformation.toString()).toStrictEqual([
@@ -25,7 +27,9 @@ describe('transcode.fromJson', () => {
2527
'ac_aac',
2628
'af_8000',
2729
'sp_full_hd',
28-
'dl_20,f_gif,fl_animated,vs_4s'
30+
'dl_20,f_gif,fl_animated,vs_4s',
31+
'vc_auto',
32+
'vc_h264:baseline:3.1'
2933
].join('/'));
3034
});
3135
});

__TESTS__/unit/toJson/transcode.toJson.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import {Transcode} from "../../../src/actions/transcode";
33
import {AudioCodec} from "../../../src/qualifiers/audioCodec";
44
import {AudioFrequency} from "../../../src/qualifiers/audioFrequency";
55
import {AnimatedFormat} from "../../../src/qualifiers/animatedFormat";
6+
import {VideoCodec} from "../../../src/qualifiers/videoCodec";
7+
import {VideoCodecProfile} from "../../../src/qualifiers/videoCodecProfile";
8+
import {VideoCodecLevel} from "../../../src/qualifiers/videoCodecLevel";
69

710
describe('Transcode toJson()', () => {
811
it('transcode.keyframeInterval number', () => {
@@ -140,4 +143,44 @@ describe('Transcode toJson()', () => {
140143
]
141144
});
142145
});
146+
147+
it('transcode.videoCodec', () => {
148+
const transformation = new Transformation()
149+
.addAction(Transcode.videoCodec(
150+
VideoCodec.h264()
151+
));
152+
153+
expect(transformation.toJson()).toStrictEqual({
154+
actions: [
155+
{
156+
actionType: 'videoCodec',
157+
videoCodec: {
158+
videoCodecName: 'h264'
159+
}
160+
}
161+
]
162+
});
163+
});
164+
165+
it('transcode.videoCodec advanced', () => {
166+
const transformation = new Transformation()
167+
.addAction(Transcode.videoCodec(
168+
VideoCodec.h264()
169+
.profile(VideoCodecProfile.baseline())
170+
.level(VideoCodecLevel.vcl31())
171+
));
172+
173+
expect(transformation.toJson()).toStrictEqual({
174+
actions: [
175+
{
176+
actionType: 'videoCodec',
177+
videoCodec: {
178+
videoCodecName: 'h264',
179+
profile: 'baseline',
180+
level: 3.1
181+
}
182+
}
183+
]
184+
});
185+
});
143186
});

src/actions/transcode/VideoCodecAction.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import {Action} from "../../internal/Action.js";
22
import {AdvVideoCodecType, VideoCodecType} from "../../qualifiers/videoCodecType/VideoCodecType.js";
3+
import {IVideoCodecActionModel} from "../../internal/models/ITranscodeActionModel.js";
4+
import {IActionModel} from "../../internal/models/IActionModel.js";
5+
import {VIDEO_CODEC_TO_TRANSFORMATION} from "../../qualifiers/videoCodec.js";
36

47
/**
58
* @extends SDK.Action
@@ -8,9 +11,37 @@ import {AdvVideoCodecType, VideoCodecType} from "../../qualifiers/videoCodecType
811
* @see Visit {@link Actions.Transcode|Transcode} for an example
912
*/
1013
class VideoCodecAction extends Action {
14+
protected _actionModel : IVideoCodecActionModel = {actionType: 'videoCodec'};
1115
constructor(videoCodecTypeQualifier : VideoCodecType | AdvVideoCodecType) {
1216
super();
17+
this._actionModel.videoCodec = {videoCodecName: videoCodecTypeQualifier.getType()};
18+
19+
if(videoCodecTypeQualifier instanceof AdvVideoCodecType) {
20+
if(videoCodecTypeQualifier.getProfile()) {
21+
this._actionModel.videoCodec = {profile: videoCodecTypeQualifier.getProfile(), ...this._actionModel.videoCodec};
22+
}
23+
24+
if(videoCodecTypeQualifier.getLevel()){
25+
this._actionModel.videoCodec = {level: videoCodecTypeQualifier.getLevel(), ...this._actionModel.videoCodec};
26+
}
27+
}
28+
1329
this.addQualifier(videoCodecTypeQualifier);
1430
}
31+
32+
static fromJson(actionModel: IActionModel): VideoCodecAction {
33+
const {videoCodec} = (actionModel as IVideoCodecActionModel);
34+
35+
// We are using this() to allow inheriting classes to use super.fromJson.apply(this, [actionModel])
36+
// This allows the inheriting classes to determine the class to be created
37+
const result = new this(VIDEO_CODEC_TO_TRANSFORMATION[videoCodec.videoCodecName]);
38+
//@ts-ignore
39+
videoCodec.profile && new this(VIDEO_CODEC_TO_TRANSFORMATION[videoCodec.videoCodecName].profile(videoCodec.profile));
40+
41+
//@ts-ignore
42+
videoCodec.level && new this(VIDEO_CODEC_TO_TRANSFORMATION[videoCodec.videoCodecName].level(videoCodec.level));
43+
44+
return result;
45+
}
1546
}
1647
export {VideoCodecAction};

src/assets/CloudinaryMedia.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import {CloudinaryTransformable} from "./CloudinaryTransformable.js";
2-
import {Action} from "../internal/Action.js";
32
import {videoEditType} from "../actions/videoEdit.js";
43
import {LayerAction} from "../actions/layer/LayerAction.js";
54
import {Transformation} from "../transformation/Transformation.js";
65
import ICloudConfig from "../config/interfaces/Config/ICloudConfig.js";
76
import IURLConfig from "../config/interfaces/Config/IURLConfig.js";
87
import { cloneDeep } from '../internal/utils/cloneDeep.js';
8+
import {ITranscodeAction} from "../actions/transcode.js";
99

1010

1111
/**
@@ -24,7 +24,7 @@ class CloudinaryMedia extends CloudinaryTransformable {
2424
* @param {Actions.Transcode} action
2525
* @return {this}
2626
*/
27-
transcode(action: Action): this {
27+
transcode(action: ITranscodeAction): this {
2828
this.transformation.transcode(action);
2929
return this;
3030
}

src/assets/CloudinaryVideo.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import IURLConfig from "../config/interfaces/Config/IURLConfig.js";
2-
import {Action} from "../internal/Action.js";
32
import {CloudinaryTransformable} from "./CloudinaryTransformable.js";
43
import ICloudConfig from "../config/interfaces/Config/ICloudConfig.js";
54
import {videoEditType} from "../actions/videoEdit.js";
65
import {VideoTransformation} from "../transformation/VideoTransformation.js";
6+
import {ITranscodeAction} from "../actions/transcode.js";
77

88

99
/**
@@ -23,7 +23,7 @@ class CloudinaryVideo extends CloudinaryTransformable {
2323
* @param {Actions.Transcode} action
2424
* @return {this}
2525
*/
26-
transcode(action: Action): this {
26+
transcode(action: ITranscodeAction): this {
2727
this.transformation.transcode(action);
2828
return this;
2929
}

src/internal/fromJson.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import StreamingProfileAction from "../actions/transcode/StreamingProfile.js";
5555
import ToAnimatedAction from "../actions/transcode/ToAnimatedAction.js";
5656
import {FadeInEffectAction} from "../actions/effect/leveled/FadeIn.js";
5757
import {FadeOutEffectAction} from "../actions/effect/leveled/FadeOut.js";
58+
import {VideoCodecAction} from "../actions/transcode/VideoCodecAction.js";
5859

5960
const ActionModelMap: Record<string, IHasFromJson> = {
6061
scale: ResizeScaleAction,
@@ -120,7 +121,8 @@ const ActionModelMap: Record<string, IHasFromJson> = {
120121
streamingProfile: StreamingProfileAction,
121122
toAnimated: ToAnimatedAction,
122123
fadeIn: FadeInEffectAction,
123-
fadeOut: FadeOutEffectAction
124+
fadeOut: FadeOutEffectAction,
125+
videoCodec: VideoCodecAction
124126
};
125127

126128
/**

src/internal/models/ITranscodeActionModel.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ interface IToAnimatedActionModel extends IActionModel{
3535
delay?: number;
3636
}
3737

38+
interface IVideoCodecActionModel extends IActionModel{
39+
videoCodec?: {videoCodecName?: string; profile?: string; level?: string | number}
40+
}
41+
3842
export {
3943
IKeyframeIntervalsActionModel,
4044
IFPSActionModel,
@@ -43,5 +47,6 @@ export {
4347
IAudioCodecActionModel,
4448
IAudioFrequencyActionModel,
4549
IStreamingProfileActionModel,
46-
IToAnimatedActionModel
50+
IToAnimatedActionModel,
51+
IVideoCodecActionModel
4752
};

src/qualifiers/videoCodec.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,15 @@ function vp9():VideoCodecType {
7777
return new VideoCodecType('vp9');
7878
}
7979

80+
export const VIDEO_CODEC_TO_TRANSFORMATION: Record<string, VideoCodecType | AdvVideoCodecType> = {
81+
'auto': auto(),
82+
'h264': h264(),
83+
'h265': h265(),
84+
'prores': proRes(),
85+
'theora': theora(),
86+
'vp8': vp8(),
87+
'vp9': vp9()
88+
};
89+
8090
const VideoCodec = { auto, h264, h265, proRes, theora, vp8, vp9};
8191
export {VideoCodec, auto, h264, h265, proRes, theora, vp8, vp9};

src/qualifiers/videoCodecType/VideoCodecType.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,16 @@ import {Qualifier} from "../../internal/qualifier/Qualifier.js";
66
* @memberOf Qualifiers.VideoCodec
77
*/
88
class VideoCodecType extends Qualifier {
9+
private _type: string;
910
constructor(type: string) {
1011
super('vc');
12+
this._type = type;
1113
this.addValue(type);
1214
}
15+
16+
getType(): string {
17+
return this._type;
18+
}
1319
}
1420

1521
/**
@@ -26,6 +32,10 @@ class AdvVideoCodecType extends Qualifier{
2632
this._type = type;
2733
}
2834

35+
getType(): string{
36+
return this._type;
37+
}
38+
2939
/**
3040
* @description Specifies the profile to use with the h264 codec.
3141
* @param {Qualifiers.VideoCodecProfile | string} profile Sets the profile of the video codec
@@ -37,6 +47,10 @@ class AdvVideoCodecType extends Qualifier{
3747
return this;
3848
}
3949

50+
getProfile(): string {
51+
return this._prof;
52+
}
53+
4054
/**
4155
* @description Specifies the level to use with the h264 codec and specified profile.
4256
* @param {Qualifiers.VideoCodecLevel | number | string} lvl
@@ -48,6 +62,10 @@ class AdvVideoCodecType extends Qualifier{
4862
return this;
4963
}
5064

65+
getLevel(): number | string {
66+
return this._lvl;
67+
}
68+
5169
/**
5270
* @description returns a toString representation of this qualifier
5371
* @return string;

0 commit comments

Comments
 (0)