mirror of
https://github.com/OpenCut-app/OpenCut.git
synced 2026-07-13 21:52:53 +02:00
chore: normalize line endings
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import {
|
||||
getHighestImportedVideoFps,
|
||||
getRaisedProjectFpsForImportedMedia,
|
||||
} from "@/lib/project/fps";
|
||||
|
||||
describe("getHighestImportedVideoFps", () => {
|
||||
test("returns the highest valid video fps", () => {
|
||||
expect(
|
||||
getHighestImportedVideoFps({
|
||||
mediaAssets: [
|
||||
{ type: "audio" },
|
||||
{ type: "video", fps: 30 },
|
||||
{ type: "image", fps: 120 },
|
||||
{ type: "video", fps: 60 },
|
||||
],
|
||||
}),
|
||||
).toBe(60);
|
||||
});
|
||||
|
||||
test("ignores missing and invalid fps values", () => {
|
||||
expect(
|
||||
getHighestImportedVideoFps({
|
||||
mediaAssets: [
|
||||
{ type: "video" },
|
||||
{ type: "video", fps: 0 },
|
||||
{ type: "video", fps: -10 },
|
||||
{ type: "audio", fps: 120 },
|
||||
],
|
||||
}),
|
||||
).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe("getRaisedProjectFpsForImportedMedia", () => {
|
||||
test("raises the project fps to match a higher-fps import", () => {
|
||||
expect(
|
||||
getRaisedProjectFpsForImportedMedia({
|
||||
currentFps: 30,
|
||||
importedAssets: [{ type: "video", fps: 60 }],
|
||||
}),
|
||||
).toBe(60);
|
||||
});
|
||||
|
||||
test("does not lower the project fps for lower-fps imports", () => {
|
||||
expect(
|
||||
getRaisedProjectFpsForImportedMedia({
|
||||
currentFps: 60,
|
||||
importedAssets: [{ type: "video", fps: 10 }],
|
||||
}),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
test("ignores non-video imports", () => {
|
||||
expect(
|
||||
getRaisedProjectFpsForImportedMedia({
|
||||
currentFps: 30,
|
||||
importedAssets: [
|
||||
{ type: "image", fps: 60 },
|
||||
{ type: "audio", fps: 120 },
|
||||
],
|
||||
}),
|
||||
).toBeNull();
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { MediaAsset } from "@/lib/media/types";
|
||||
|
||||
type MediaAssetFpsInput = Pick<MediaAsset, "type" | "fps">;
|
||||
|
||||
export function getHighestImportedVideoFps({
|
||||
mediaAssets,
|
||||
}: {
|
||||
mediaAssets: MediaAssetFpsInput[];
|
||||
}): number | null {
|
||||
let highestFps: number | null = null;
|
||||
|
||||
for (const asset of mediaAssets) {
|
||||
const fps = asset.fps ?? Number.NaN;
|
||||
if (asset.type !== "video") continue;
|
||||
if (!Number.isFinite(fps) || fps <= 0) continue;
|
||||
|
||||
highestFps = highestFps === null ? fps : Math.max(highestFps, fps);
|
||||
}
|
||||
|
||||
return highestFps;
|
||||
}
|
||||
|
||||
export function getRaisedProjectFpsForImportedMedia({
|
||||
currentFps,
|
||||
importedAssets,
|
||||
}: {
|
||||
currentFps: number;
|
||||
importedAssets: MediaAssetFpsInput[];
|
||||
}): number | null {
|
||||
const highestImportedVideoFps = getHighestImportedVideoFps({
|
||||
mediaAssets: importedAssets,
|
||||
});
|
||||
|
||||
if (highestImportedVideoFps === null || highestImportedVideoFps <= currentFps) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return highestImportedVideoFps;
|
||||
}
|
||||
@@ -1,53 +1,53 @@
|
||||
import type { TScene } from "@/lib/timeline/types";
|
||||
|
||||
export type TBackground =
|
||||
| {
|
||||
type: "color";
|
||||
color: string;
|
||||
}
|
||||
| {
|
||||
type: "blur";
|
||||
blurIntensity: number;
|
||||
};
|
||||
|
||||
export interface TCanvasSize {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export interface TProjectMetadata {
|
||||
id: string;
|
||||
name: string;
|
||||
thumbnail?: string;
|
||||
duration: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface TProjectSettings {
|
||||
fps: number;
|
||||
canvasSize: TCanvasSize;
|
||||
canvasSizeMode?: "preset" | "custom";
|
||||
lastCustomCanvasSize?: TCanvasSize | null;
|
||||
originalCanvasSize?: TCanvasSize | null;
|
||||
background: TBackground;
|
||||
}
|
||||
|
||||
export interface TTimelineViewState {
|
||||
zoomLevel: number;
|
||||
scrollLeft: number;
|
||||
playheadTime: number;
|
||||
}
|
||||
|
||||
export interface TProject {
|
||||
metadata: TProjectMetadata;
|
||||
scenes: TScene[];
|
||||
currentSceneId: string;
|
||||
settings: TProjectSettings;
|
||||
version: number;
|
||||
timelineViewState?: TTimelineViewState;
|
||||
}
|
||||
|
||||
export type TProjectSortKey = "createdAt" | "updatedAt" | "name" | "duration";
|
||||
export type TSortOrder = "asc" | "desc";
|
||||
export type TProjectSortOption = `${TProjectSortKey}-${TSortOrder}`;
|
||||
import type { TScene } from "@/lib/timeline/types";
|
||||
|
||||
export type TBackground =
|
||||
| {
|
||||
type: "color";
|
||||
color: string;
|
||||
}
|
||||
| {
|
||||
type: "blur";
|
||||
blurIntensity: number;
|
||||
};
|
||||
|
||||
export interface TCanvasSize {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export interface TProjectMetadata {
|
||||
id: string;
|
||||
name: string;
|
||||
thumbnail?: string;
|
||||
duration: number;
|
||||
createdAt: Date;
|
||||
updatedAt: Date;
|
||||
}
|
||||
|
||||
export interface TProjectSettings {
|
||||
fps: number;
|
||||
canvasSize: TCanvasSize;
|
||||
canvasSizeMode?: "preset" | "custom";
|
||||
lastCustomCanvasSize?: TCanvasSize | null;
|
||||
originalCanvasSize?: TCanvasSize | null;
|
||||
background: TBackground;
|
||||
}
|
||||
|
||||
export interface TTimelineViewState {
|
||||
zoomLevel: number;
|
||||
scrollLeft: number;
|
||||
playheadTime: number;
|
||||
}
|
||||
|
||||
export interface TProject {
|
||||
metadata: TProjectMetadata;
|
||||
scenes: TScene[];
|
||||
currentSceneId: string;
|
||||
settings: TProjectSettings;
|
||||
version: number;
|
||||
timelineViewState?: TTimelineViewState;
|
||||
}
|
||||
|
||||
export type TProjectSortKey = "createdAt" | "updatedAt" | "name" | "duration";
|
||||
export type TSortOrder = "asc" | "desc";
|
||||
export type TProjectSortOption = `${TProjectSortKey}-${TSortOrder}`;
|
||||
|
||||
Reference in New Issue
Block a user