mirror of
https://github.com/immich-app/immich.git
synced 2026-06-12 19:11:52 -07:00
use zod
This commit is contained in:
@@ -4734,6 +4734,16 @@
|
||||
"maximum": 9007199254740991,
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "x-immich-hls-msn",
|
||||
"required": false,
|
||||
"in": "header",
|
||||
"schema": {
|
||||
"minimum": 0,
|
||||
"maximum": 9007199254740991,
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
|
||||
@@ -227,7 +227,6 @@ export const HLS_LEASE_DURATION_MS = 30 * 60 * 1000;
|
||||
export const HLS_PLAYLIST_CONTENT_TYPE = 'application/vnd.apple.mpegurl';
|
||||
export const HLS_SEGMENT_DURATION = 2;
|
||||
export const HLS_SEGMENT_FILENAME_REGEX = /^seg_(\d+)\.m4s$/;
|
||||
export const HLS_TARGET_SEGMENT_HEADER = 'x-immich-hls-msn';
|
||||
export const HLS_VARIANTS = [
|
||||
{ resolution: 480, codec: VideoCodec.Av1, bitrate: 1_000_000, codecString: 'av01.0.04M.08' },
|
||||
{ resolution: 480, codec: VideoCodec.Hevc, bitrate: 1_200_000, codecString: 'hvc1.1.6.L90.B0' },
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { Controller, Delete, Get, Header, Headers, HttpCode, HttpStatus, Next, Param, Res } from '@nestjs/common';
|
||||
import { ApiProduces, ApiTags } from '@nestjs/swagger';
|
||||
import { NextFunction, Response } from 'express';
|
||||
import { HLS_PLAYLIST_CONTENT_TYPE, HLS_TARGET_SEGMENT_HEADER } from 'src/constants';
|
||||
import { HLS_PLAYLIST_CONTENT_TYPE } from 'src/constants';
|
||||
import { Endpoint, HistoryBuilder } from 'src/decorators';
|
||||
import { AuthDto } from 'src/dtos/auth.dto';
|
||||
import { HlsSegmentParamDto, HlsSessionParamDto, HlsVariantParamDto } from 'src/dtos/streaming.dto';
|
||||
import { ApiTag, Permission, RouteKey } from 'src/enum';
|
||||
import {
|
||||
HlsSegmentHeaderDto,
|
||||
HlsSegmentParamDto,
|
||||
HlsSessionParamDto,
|
||||
HlsVariantParamDto,
|
||||
} from 'src/dtos/streaming.dto';
|
||||
import { ApiTag, ImmichHeader, Permission, RouteKey } from 'src/enum';
|
||||
import { Auth, Authenticated, FileResponse } from 'src/middleware/auth.guard';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { HlsService } from 'src/services/hls.service';
|
||||
@@ -59,21 +64,14 @@ export class VideoStreamController {
|
||||
async getSegment(
|
||||
@Auth() auth: AuthDto,
|
||||
@Param() { id, sessionId, variantIndex, filename }: HlsSegmentParamDto,
|
||||
// Allows the client to hint at which segment will be loaded after init.mp4
|
||||
@Headers(HLS_TARGET_SEGMENT_HEADER) targetSegment: string | undefined,
|
||||
@Headers() { [ImmichHeader.HlsTargetSegment]: targetSegment }: HlsSegmentHeaderDto,
|
||||
@Res() res: Response,
|
||||
@Next() next: NextFunction,
|
||||
) {
|
||||
const target = targetSegment === undefined ? undefined : Number.parseInt(targetSegment);
|
||||
if (target !== undefined && (!Number.isFinite(target) || target < 0)) {
|
||||
res.status(HttpStatus.BAD_REQUEST).send('Invalid target segment');
|
||||
return;
|
||||
}
|
||||
|
||||
await sendFile(
|
||||
res,
|
||||
next,
|
||||
() => this.service.getSegment(auth, id, sessionId, variantIndex, filename, target),
|
||||
() => this.service.getSegment(auth, id, sessionId, variantIndex, filename, targetSegment),
|
||||
this.logger,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { createZodDto } from 'nestjs-zod';
|
||||
import { ImmichHeader } from 'src/enum';
|
||||
import z from 'zod';
|
||||
|
||||
const HlsSessionParamSchema = z.object({
|
||||
@@ -24,3 +25,10 @@ const HlsSegmentParamSchema = z.object({
|
||||
});
|
||||
|
||||
export class HlsSegmentParamDto extends createZodDto(HlsSegmentParamSchema) {}
|
||||
|
||||
const HlsSegmentHeaderSchema = z.object({
|
||||
// Lets the client hint at which segment will be loaded after init.mp4.
|
||||
[ImmichHeader.HlsTargetSegment]: z.coerce.number().int().min(0).optional(),
|
||||
});
|
||||
|
||||
export class HlsSegmentHeaderDto extends createZodDto(HlsSegmentHeaderSchema) {}
|
||||
|
||||
@@ -24,6 +24,7 @@ export enum ImmichHeader {
|
||||
SharedLinkSlug = 'x-immich-share-slug',
|
||||
Checksum = 'x-immich-checksum',
|
||||
CorrelationId = 'X-Correlation-ID',
|
||||
HlsTargetSegment = 'x-immich-hls-msn',
|
||||
}
|
||||
|
||||
export enum ImmichQuery {
|
||||
|
||||
Reference in New Issue
Block a user