<commit_before>import { Operation } from 'express-openapi';
import { StreamsModelInterface } from '../../../../../Model/Api/StreamsModel';
import factory from '../../../../../Model/ModelFactory';
import { Stream } from '../../../../../Model/Service/Stream/Stream';
import * as api from '../../../../api';

export const get: Operation = async(req, res) => {
    const streams = <StreamsModelInterface> factory.get('StreamsModel');

    try {
        if (req.method === 'HEAD') {
            const header = await streams.getRecordedStreamingMpegTsHEADInfo(
                req.params.id,
                req.query.mode,
                req.query.ss,
                typeof req.headers.range === 'undefined' ? null : req.headers.range,
            );

            res.status(200);
            res.set(header);
            res.end();

            return;
        }

        const info = await streams.getRecordedStreamingMpegTs(
            req.params.id,
            req.query.mode,
            req.query.ss,
            typeof req.headers.range === 'undefined' ? null : req.headers.range,
        );
        const encChild = info.stream.getEncChild();

        const responseInfo = info.stream.getResponseInfo();

        res.set(responseInfo.header);
        res.status(responseInfo.responseCode);

        // 接続切断時
        req.on('close', async() => {
            await streams.stop(info.streamNumber);
        });

        if (encChild !== null) {
            encChild.stdout.pipe(res);

            // enc コマンド終了時
            encChild.on('exit', async() => {
                await streams.stop(info.streamNumber);
                res.end();
            });

            // enc コマンドエラー時
            encChild.on('error', async() => {
                await streams.stop(info.streamNumber);
                res.end();
            });
        } else {
            throw new Error('CreatetRecordedStreamingMpegTsStreamChildError');
        }
    } catch (err) {
        if (err.message === Stream.OutOfRangeError) {
            api.responseError(res, { code: 416,  message: 'out of range' });
        } else if (err.message === Stream.FileIsNotFoundError) {
            api.responseError(res, { code: 404,  message: 'Recorded Id is not Found' });
        } else {
            api.responseServerError(res, err.message);
        }
    }
};

get.apiDoc = {
    summary: '録画済みファイルの mpegts ストリーミング配信',
    tags: ['streams'],
    description: '録画済みファイルの mpegts ストリーミング配信をする',
    parameters: [
        {
            name: 'id',
            in: 'path',
            description: 'recorded id',
            required: true,
            type: 'integer',
        },
        {
            name: 'mode',
            in: 'query',
            description: 'encode mode',
            required: true,
            type: 'integer',
        },<commit_msg>エラー処理を強化<commit_after>import { Operation } from 'express-openapi';
import { StreamsModelInterface } from '../../../../../Model/Api/StreamsModel';
import factory from '../../../../../Model/ModelFactory';
import { Stream } from '../../../../../Model/Service/Stream/Stream';
import * as api from '../../../../api';

export const get: Operation = async(req, res) => {
    const streams = <StreamsModelInterface> factory.get('StreamsModel');
    let stream: Stream | null = null;

    const stop = async() => {
        if (stream === null) { return; }
        await stream.stop()
        .catch(() => {});
    };

    try {
        if (req.method === 'HEAD') {
            const header = await streams.getRecordedStreamingMpegTsHEADInfo(
                req.params.id,
                req.query.mode,
                req.query.ss,
                typeof req.headers.range === 'undefined' ? null : req.headers.range,
            );

            res.status(200);
            res.set(header);
            res.end();

            return;
        }

        const info = await streams.getRecordedStreamingMpegTs(
            req.params.id,
            req.query.mode,
            req.query.ss,
            typeof req.headers.range === 'undefined' ? null : req.headers.range,
        );
        stream = info.stream;
        const encChild = info.stream.getEncChild();

        const responseInfo = info.stream.getResponseInfo();

        res.set(responseInfo.header);
        res.status(responseInfo.responseCode);

        // 接続切断時
        req.on('close', async() => {
            await stop();
        });

        if (encChild !== null) {
            encChild.stdout.pipe(res);

            // enc コマンド終了時
            encChild.on('exit', async() => {
                await stop();
                res.end();
            });

            // enc コマンドエラー時
            encChild.on('error', async() => {
                await stop();
                res.end();
            });
        } else {
            throw new Error('CreatetRecordedStreamingMpegTsStreamChildError');
        }
    } catch (err) {
        await stop();

        if (err.message === Stream.OutOfRangeError) {
            api.responseError(res, { code: 416,  message: 'out of range' });
        } else if (err.message === Stream.FileIsNotFoundError) {
            api.responseError(res, { code: 404,  message: 'Recorded Id is not Found' });
        } else {
            api.responseServerError(res, err.message);
        }
    }
};

get.apiDoc = {
    summary: '録画済みファイルの mpegts ストリーミング配信',
    tags: ['streams'],
    description: '録画済みファイルの mpegts ストリーミング配信をする',
    parameters: [
        {
            name: 'id',
            in: 'path',
            description: 'recorded id',
            required: true,
            type: 'integer',
        },
        {
            name: 'mode',
            in: 'query',
            description: 'encode mode',
            required: true,
            type: 'integer',
        },
{'fraction_non_alphanumeric': 0.14662301860785665, 'fraction_numerical': 0.0031013094417643005, 'mean_word_length': 1.5719982277359326, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1885265', 'n_tokens_mistral': 1716, 'n_tokens_neox': 1677, 'n_words': 339}