Skip to content

Commit ecb16a1

Browse files
committed
feat(av-cliper): add font style support for subtitles
- Add fontWeight and fontStyle options to EmbedSubtitlesClip - Support both string ('bold') and numeric (700) font weights - Support italic and normal font styles - Add test cases for new font style features
1 parent 2e211d9 commit ecb16a1

File tree

3 files changed

+47
-4
lines changed

3 files changed

+47
-4
lines changed

packages/av-cliper/demo/concat-media.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@ document.querySelector('#mp4-srt')?.addEventListener('click', () => {
193193
lineWidth: 20,
194194
lineJoin: 'round',
195195
lineCap: 'round',
196+
fontWeight: 700,
197+
fontStyle: 'italic',
196198
textShadow: {
197199
offsetX: 2,
198200
offsetY: 2,

packages/av-cliper/src/clips/__tests__/embed-subtitles.test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,34 @@ test('split by time', async () => {
9191
preClip.meta.duration + postClip.meta.duration,
9292
);
9393
});
94+
95+
test('EmbedSubtitles with font styles', async () => {
96+
const es = new EmbedSubtitlesClip(txt2, {
97+
videoWidth: 1280,
98+
videoHeight: 720,
99+
fontWeight: 'bold',
100+
fontStyle: 'italic',
101+
});
102+
103+
// Check if the clip is created successfully
104+
expect(es).toBeDefined();
105+
106+
const vf1 = (await es.tick(342000)).video;
107+
expect(vf1?.timestamp).toBe(342000);
108+
expect(vf1?.duration).toBe(3218000 - 342000);
109+
});
110+
111+
test('EmbedSubtitles with numeric font weight', async () => {
112+
const es = new EmbedSubtitlesClip(txt2, {
113+
videoWidth: 1280,
114+
videoHeight: 720,
115+
fontWeight: 700, // Bold weight
116+
fontStyle: 'normal',
117+
});
118+
119+
expect(es).toBeDefined();
120+
121+
const vf1 = (await es.tick(342000)).video;
122+
expect(vf1?.timestamp).toBe(342000);
123+
expect(vf1?.duration).toBe(3218000 - 342000);
124+
});

packages/av-cliper/src/clips/embed-subtitles-clip.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ interface IEmbedSubtitlesOpts {
2121
};
2222
videoWidth: number;
2323
videoHeight: number;
24+
fontWeight?: string | number;
25+
fontStyle?: 'normal' | 'italic';
2426
}
2527

2628
declare global {
@@ -81,6 +83,8 @@ export class EmbedSubtitlesClip implements IClip {
8183
},
8284
videoWidth: 1280,
8385
videoHeight: 720,
86+
fontWeight: 'normal',
87+
fontStyle: 'normal',
8488
};
8589

8690
#cvs: OffscreenCanvas;
@@ -106,15 +110,21 @@ export class EmbedSubtitlesClip implements IClip {
106110
this.#linePadding =
107111
opts.textBgColor == null ? 0 : (opts.fontSize ?? 50) * 0.2;
108112

109-
const { fontSize, fontFamily, videoWidth, videoHeight, letterSpacing } =
110-
this.#opts;
113+
const {
114+
fontSize,
115+
fontFamily,
116+
fontWeight,
117+
fontStyle,
118+
videoWidth,
119+
videoHeight,
120+
} = this.#opts;
111121
this.#lineHeight = fontSize + this.#linePadding * 2;
112122
this.#cvs = new OffscreenCanvas(videoWidth, videoHeight);
113123
this.#ctx = this.#cvs.getContext('2d')!;
114-
this.#ctx.font = `${fontSize}px ${fontFamily}`;
124+
this.#ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`;
115125
this.#ctx.textAlign = 'center';
116126
this.#ctx.textBaseline = 'top';
117-
this.#ctx.letterSpacing = letterSpacing ?? '0px';
127+
this.#ctx.letterSpacing = this.#opts.letterSpacing ?? '0px';
118128

119129
this.#meta = {
120130
width: videoWidth,

0 commit comments

Comments
 (0)