mirror of
https://github.com/chrisbenincasa/tunarr.git
synced 2026-04-18 09:03:35 -04:00
ffmpeg stream test util
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
import { FileStreamSource } from '../../../../stream/types.ts';
|
||||
import {
|
||||
FfmpegStateVersion702,
|
||||
h2641080pVideoStream,
|
||||
} from '../../../../testing/ffmpegTestUtil.ts';
|
||||
import { FfmpegCapabilities } from '../../capabilities/FfmpegCapabilities.ts';
|
||||
import { NvidiaHardwareCapabilities } from '../../capabilities/NvidiaHardwareCapabilities.ts';
|
||||
import { PixelFormatYuv420P } from '../../format/PixelFormat.ts';
|
||||
@@ -11,6 +15,7 @@ import {
|
||||
SubtitleMethods,
|
||||
VideoStream,
|
||||
} from '../../MediaStream.ts';
|
||||
import { KnownFfmpegFilters } from '../../options/KnownFfmpegOptions.ts';
|
||||
import { FfmpegState } from '../../state/FfmpegState.ts';
|
||||
import { FrameState } from '../../state/FrameState.ts';
|
||||
import { FrameSize } from '../../types.ts';
|
||||
@@ -103,14 +108,7 @@ describe('NvidiaPipelineBuilder', () => {
|
||||
|
||||
const video = VideoInputSource.withStream(
|
||||
videoSource,
|
||||
VideoStream.create({
|
||||
codec: 'h264',
|
||||
displayAspectRatio: '16:9',
|
||||
frameSize: FrameSize.FHD,
|
||||
index: 0,
|
||||
pixelFormat: new PixelFormatYuv420P(),
|
||||
sampleAspectRatio: null,
|
||||
}),
|
||||
h2641080pVideoStream(),
|
||||
);
|
||||
|
||||
const watermark = new WatermarkInputSource(
|
||||
@@ -144,19 +142,8 @@ describe('NvidiaPipelineBuilder', () => {
|
||||
),
|
||||
);
|
||||
|
||||
const state = FfmpegState.create({
|
||||
version: {
|
||||
versionString: 'n7.0.2-15-g0458a86656-20240904',
|
||||
majorVersion: 7,
|
||||
minorVersion: 0,
|
||||
patchVersion: 2,
|
||||
isUnknown: false,
|
||||
},
|
||||
// start: +dayjs.duration(0),
|
||||
});
|
||||
|
||||
const out = builder.build(
|
||||
state,
|
||||
FfmpegStateVersion702(),
|
||||
new FrameState({
|
||||
isAnamorphic: false,
|
||||
scaledSize: video.streams[0].squarePixelFrameSize(FrameSize.FHD),
|
||||
@@ -168,4 +155,64 @@ describe('NvidiaPipelineBuilder', () => {
|
||||
|
||||
console.log(out.getCommandArgs().join(' '));
|
||||
});
|
||||
|
||||
test('updates pixel format when overlaying subtitles after a scale', () => {
|
||||
const capabilities = new NvidiaHardwareCapabilities('RTX 2080 Ti', 75);
|
||||
const binaryCapabilities = new FfmpegCapabilities(
|
||||
new Set(),
|
||||
new Map(),
|
||||
new Set([KnownFfmpegFilters.ScaleNpp]),
|
||||
);
|
||||
|
||||
const videoSource = new FileStreamSource('/path/to/video.mkv');
|
||||
|
||||
const video = VideoInputSource.withStream(
|
||||
videoSource,
|
||||
h2641080pVideoStream(),
|
||||
);
|
||||
|
||||
const watermark = new WatermarkInputSource(
|
||||
new FileStreamSource('/path/to/watermark.jpg'),
|
||||
StillImageStream.create({
|
||||
frameSize: FrameSize.withDimensions(800, 600),
|
||||
index: 0,
|
||||
}),
|
||||
{
|
||||
duration: 5,
|
||||
enabled: true,
|
||||
horizontalMargin: 5,
|
||||
opacity: 100,
|
||||
position: 'bottom-right',
|
||||
verticalMargin: 5,
|
||||
width: 10,
|
||||
},
|
||||
);
|
||||
|
||||
const builder = new NvidiaPipelineBuilder(
|
||||
capabilities,
|
||||
binaryCapabilities,
|
||||
video,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new SubtitlesInputSource(
|
||||
videoSource,
|
||||
[new EmbeddedSubtitleStream('pgs', 5, SubtitleMethods.Burn)],
|
||||
SubtitleMethods.Burn,
|
||||
),
|
||||
);
|
||||
|
||||
const out = builder.build(
|
||||
FfmpegStateVersion702(),
|
||||
new FrameState({
|
||||
isAnamorphic: false,
|
||||
scaledSize: video.streams[0].squarePixelFrameSize(FrameSize.FourK),
|
||||
paddedSize: FrameSize.FourK,
|
||||
pixelFormat: new PixelFormatYuv420P(),
|
||||
deinterlace: false,
|
||||
}),
|
||||
);
|
||||
|
||||
console.log(out.getCommandArgs().join(' '));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -179,7 +179,7 @@ export class NvidiaPipelineBuilder extends SoftwarePipelineBuilder {
|
||||
!isNil(currentState.pixelFormat) &&
|
||||
!desiredPixelFormat.equals(currentState.pixelFormat)
|
||||
) {
|
||||
this.logger.trace('adding pixel filter format for watermark!!!');
|
||||
this.logger.trace('adding pixel filter format for overlay!!!');
|
||||
if (currentState.frameDataLocation === FrameDataLocation.Software) {
|
||||
const pixelFormatFilter = new PixelFormatFilter(desiredPixelFormat);
|
||||
currentState = pixelFormatFilter.nextState(currentState);
|
||||
|
||||
11
server/src/testing/bun-test.d.ts
vendored
11
server/src/testing/bun-test.d.ts
vendored
@@ -1,11 +0,0 @@
|
||||
import type { PixelFormat } from '@/ffmpeg/builder/format/PixelFormat.js';
|
||||
import 'vitest';
|
||||
|
||||
interface CustomMatchers<R = unknown> {
|
||||
toMatchPixelFormat: (expected: PixelFormat) => R;
|
||||
}
|
||||
|
||||
declare module 'bun:test' {
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-object-type
|
||||
interface Matchers<R = unknown> extends CustomMatchers<R> {}
|
||||
}
|
||||
37
server/src/testing/ffmpegTestUtil.ts
Normal file
37
server/src/testing/ffmpegTestUtil.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { PixelFormatYuv420P } from '../ffmpeg/builder/format/PixelFormat.ts';
|
||||
import { VideoStream } from '../ffmpeg/builder/MediaStream.ts';
|
||||
import { FfmpegState } from '../ffmpeg/builder/state/FfmpegState.ts';
|
||||
import { FrameSize } from '../ffmpeg/builder/types.ts';
|
||||
|
||||
export const FfmpegStateVersion702 = () =>
|
||||
FfmpegState.create({
|
||||
version: {
|
||||
versionString: 'n7.0.2-15-g0458a86656-20240904',
|
||||
majorVersion: 7,
|
||||
minorVersion: 0,
|
||||
patchVersion: 2,
|
||||
isUnknown: false,
|
||||
},
|
||||
});
|
||||
|
||||
export const h2641080pVideoStream = () =>
|
||||
VideoStream.create({
|
||||
codec: 'h264',
|
||||
displayAspectRatio: '16:9',
|
||||
frameSize: FrameSize.FHD,
|
||||
index: 0,
|
||||
pixelFormat: new PixelFormatYuv420P(),
|
||||
sampleAspectRatio: '1:1',
|
||||
frameRate: '23.98',
|
||||
});
|
||||
|
||||
export const h264FourKVideoStream = () =>
|
||||
VideoStream.create({
|
||||
codec: 'h264',
|
||||
displayAspectRatio: '16:9',
|
||||
frameSize: FrameSize.FourK,
|
||||
index: 0,
|
||||
pixelFormat: new PixelFormatYuv420P(),
|
||||
sampleAspectRatio: '1:1',
|
||||
frameRate: '23.98',
|
||||
});
|
||||
Reference in New Issue
Block a user