checkpoint

This commit is contained in:
Christian Benincasa
2025-02-09 12:48:32 -05:00
parent 0cb3689870
commit 2dd67b97a1
8 changed files with 54 additions and 9 deletions

View File

@@ -442,7 +442,7 @@ export class FfmpegStreamFactory extends IFFMPEG {
new FrameState({
isAnamorphic: false,
scaledSize,
paddedSize, // TODO
paddedSize,
videoBitrate: playbackParams.videoBitrate,
videoBufferSize: playbackParams.videoBufferSize,
pixelFormat: playbackParams.pixelFormat, //match(), TODO: Make this customizable...

View File

@@ -0,0 +1,26 @@
import { FilterOption } from './FilterOption.ts';
interface DrawTextOptions {
fontfile: string;
text: string;
border?: {
color: string;
width: number;
};
color: string;
size: string;
position: {
x: string;
y: string;
};
}
export class DrawTextFilter extends FilterOption {
constructor(private opts: DrawTextOptions) {
super();
}
get filter() {
return '';
}
}

View File

@@ -41,6 +41,7 @@ export class SoftwarePipelineBuilder extends BasePipelineBuilder {
currentState = this.setScale(currentState);
currentState = this.setPad(currentState);
currentState = this.setWatermark(currentState);
this.setStillImageLoop();
}
if (!this.hasVideoEncoderPipelineStep()) {

View File

@@ -24,6 +24,7 @@ export const DefaultFrameState: Omit<
deinterlace: false,
pixelFormat: null,
bitDepth: 8,
displayTrackInfo: true,
};
export class FrameState {
@@ -42,6 +43,7 @@ export class FrameState {
frameDataLocation: FrameDataLocation;
deinterlace: boolean;
pixelFormat: Nullable<PixelFormat>;
displayTrackInfo: boolean;
constructor(
fields: MarkOptional<FrameStateFields, keyof typeof DefaultFrameState>,

View File

@@ -133,7 +133,7 @@ export type StreamOptions = {
startTime: Duration;
duration: Duration;
watermark?: Watermark;
realtime?: boolean; // = true,
realtime: boolean;
extraInputHeaders?: Record<string, string>;
outputFormat: OutputFormat;
ptsOffset?: number;

View File

@@ -49,7 +49,7 @@ export abstract class ProgramStream extends (events.EventEmitter as new () => Ty
}
async setup(
opts?: Partial<StreamOptions>,
opts: Partial<StreamOptions> = {},
): Promise<Result<FfmpegTranscodeSession>> {
if (this.isInitialized()) {
return Result.success(this._transcodeSession);
@@ -86,7 +86,7 @@ export abstract class ProgramStream extends (events.EventEmitter as new () => Ty
protected shutdownInternal(): void {}
protected abstract setupInternal(
opts?: Partial<StreamOptions>,
opts: Partial<StreamOptions>,
): Promise<Result<FfmpegTranscodeSession>>;
get transcodeSession() {

View File

@@ -299,8 +299,8 @@ export class PlexStreamDetails {
videoStream.scanType === 'interlaced'
? 'interlaced'
: videoStream.scanType === 'progressive'
? 'progressive'
: 'unknown',
? 'progressive'
: 'unknown',
width: videoStream.width,
height: videoStream.height,
framerate: videoStream.frameRate,
@@ -358,6 +358,14 @@ export class PlexStreamDetails {
audioDetails: isEmpty(audioStreamDetails)
? undefined
: (audioStreamDetails as NonEmptyArray<AudioStreamDetails>),
musicMetadata:
media.type === 'track'
? {
albumName: media.parentTitle ?? '',
artistName: media.grandparentTitle,
trackName: media.title,
}
: undefined,
};
if (

View File

@@ -2,7 +2,7 @@ import type { Nullable } from '@/types/util.js';
import { isNonEmptyString } from '@/util/index.js';
import type { Duration } from 'dayjs/plugin/duration.js';
import { first, isNull, isUndefined } from 'lodash-es';
import type { Dictionary } from 'ts-essentials';
import type { Dictionary, NonEmptyArray } from 'ts-essentials';
import type { PixelFormat } from '../ffmpeg/builder/format/PixelFormat.ts';
import {
KnownPixelFormats,
@@ -11,19 +11,27 @@ import {
PixelFormatYuv420P10Le,
} from '../ffmpeg/builder/format/PixelFormat.ts';
type StreamMusicMetadata = {
artistName: string;
trackName: string;
albumName: string;
};
export type StreamDetails = {
duration?: Duration;
// This is the total bitrate
bitrate?: number;
// If defined, there is at least one video stream
videoDetails?: [VideoStreamDetails, ...VideoStreamDetails[]];
audioDetails?: [AudioStreamDetails, ...AudioStreamDetails[]];
videoDetails?: NonEmptyArray<VideoStreamDetails>;
audioDetails?: NonEmptyArray<AudioStreamDetails>;
audioOnly?: boolean;
placeholderImage?: StreamSource;
serverPath?: string;
directFilePath?: string;
musicMetadata?: StreamMusicMetadata;
};
export type VideoStreamDetails = {