Files
kodi-api-server/src/Streamer/StreamerService/streamer.service.ts
T
2022-12-15 11:00:15 +02:00

56 lines
1.9 KiB
TypeScript

import { ReadStreamCreatable } from '../Interface/read-stream-creatable.interface';
import { RequestRangeService } from '../RequestRange/request-range.service';
import { MimeService } from '../Mime/mime.service';
import { Injectable } from '@nestjs/common';
import { Request, Response } from 'express';
import { ResponseHeadersService } from '../ResponseHeadersService/response-headers.service';
import { ResponseSenderService } from '../ResponseSender/response-sender.service';
import RequestRangeBytes from '../RequestRange/request-range-bytes.class';
@Injectable()
export class StreamerService {
constructor(
private readonly mimeService: MimeService,
private readonly requestRangeService: RequestRangeService,
private readonly responseHeadersService: ResponseHeadersService,
private readonly responseSender: ResponseSenderService,
) {}
stream(
req: Request,
res: Response,
streamCreatable: ReadStreamCreatable,
): void {
const size = streamCreatable.length;
const requestRange = this.getRange(req, size);
if (!this.requestRangeService.isRangeSatisfiable(requestRange, size)) {
return this.handleUnsatisfiable(size, res);
}
const responseHeaders = this.responseHeadersService.createResponseHeaders(
streamCreatable.mimeType,
size,
requestRange,
);
const status = req.headers.range ? 206 : 200;
const readable =
req.method === 'HEAD'
? null
: streamCreatable.createReadStream(requestRange);
return this.responseSender.send(res, status, responseHeaders, readable);
}
private getRange(req: Request, size: number): RequestRangeBytes {
return this.requestRangeService.getRangeFromHeaders(req, size);
}
private handleUnsatisfiable(size: number, res: Response) {
const responseHeaders = { 'Content-Range': 'bytes */' + size };
this.responseSender.send(res, 416, responseHeaders, null);
return;
}
}