【m】修改为服务器录屏
This commit is contained in:
85
test/recording-composer.test.ts
Normal file
85
test/recording-composer.test.ts
Normal file
@@ -0,0 +1,85 @@
|
||||
import { buildFfmpegCompositionArgs } from '../src/recording/composer';
|
||||
import { ServerTrackRecordingFile } from '../src/recording/storage';
|
||||
|
||||
function file(filename: string, trackKind: string, participantId: string, role = 'participant'): ServerTrackRecordingFile {
|
||||
return {
|
||||
meetingId: 'room-1',
|
||||
directory: 'recordings/room-1',
|
||||
filename,
|
||||
filePath: `recordings/room-1/${filename}`,
|
||||
metadataPath: `recordings/room-1/${filename}.json`,
|
||||
recordingId: 'recording-1',
|
||||
participantId,
|
||||
trackId: `${participantId}-${trackKind}`,
|
||||
trackKind,
|
||||
uploadedAt: '2026-06-01T00:00:00.000Z',
|
||||
metadata: { role }
|
||||
};
|
||||
}
|
||||
|
||||
describe('recording composer', () => {
|
||||
test('builds ffmpeg args for host-led video layout and mixed audio', () => {
|
||||
const args = buildFfmpegCompositionArgs({
|
||||
videoInputs: [
|
||||
file('p1-video.webm', 'video', 'p1', 'host'),
|
||||
file('p2-video.webm', 'video', 'p2')
|
||||
],
|
||||
audioInputs: [
|
||||
file('p1-audio.webm', 'audio', 'p1'),
|
||||
file('p2-audio.webm', 'audio', 'p2')
|
||||
],
|
||||
outputPath: 'recordings/room-1/output.webm',
|
||||
format: 'webm'
|
||||
});
|
||||
|
||||
expect(args).toContain('-filter_complex');
|
||||
expect(args.join(' ')).toContain('xstack=inputs=2');
|
||||
expect(args.join(' ')).toContain('scale=1280:540');
|
||||
expect(args.join(' ')).toContain('scale=1280:180');
|
||||
expect(args.join(' ')).toContain('layout=0_0|0_540');
|
||||
expect(args.join(' ')).toContain('amix=inputs=2');
|
||||
expect(args).toContain('libvpx-vp9');
|
||||
expect(args).toContain('libopus');
|
||||
expect(args[args.length - 1]).toBe('recordings/room-1/output.webm');
|
||||
});
|
||||
|
||||
test('places host in the first row even when host input is not first', () => {
|
||||
const args = buildFfmpegCompositionArgs({
|
||||
videoInputs: [
|
||||
file('p1-video.webm', 'video', 'p1'),
|
||||
file('host-video.webm', 'video', 'host', 'host'),
|
||||
file('p2-video.webm', 'video', 'p2')
|
||||
],
|
||||
audioInputs: [],
|
||||
outputPath: 'recordings/room-1/output.webm',
|
||||
format: 'webm'
|
||||
});
|
||||
|
||||
const filter = args[args.indexOf('-filter_complex') + 1];
|
||||
expect(args.slice(0, 7)).toEqual([
|
||||
'-y',
|
||||
'-i',
|
||||
'recordings/room-1/host-video.webm',
|
||||
'-i',
|
||||
'recordings/room-1/p1-video.webm',
|
||||
'-i',
|
||||
'recordings/room-1/p2-video.webm'
|
||||
]);
|
||||
expect(filter).toContain('scale=1280:540');
|
||||
expect(filter).toContain('scale=640:180');
|
||||
expect(filter).toContain('layout=0_0|0_540|640_540');
|
||||
});
|
||||
|
||||
test('builds mp4 encoder args', () => {
|
||||
const args = buildFfmpegCompositionArgs({
|
||||
videoInputs: [file('p1-video.webm', 'video', 'p1')],
|
||||
audioInputs: [],
|
||||
outputPath: 'recordings/room-1/output.mp4',
|
||||
format: 'mp4'
|
||||
});
|
||||
|
||||
expect(args).toContain('libx264');
|
||||
expect(args).toContain('-pix_fmt');
|
||||
expect(args).not.toContain('libopus');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user