[Express][TypeScript] 파일 다운로드

15135 단어 nodetypescriptexpress

소개



이번에는 파일을 다운로드 해보도록 하겠습니다.


  • 스트림으로 파일 다운로드



    아래와 같이 fs로 파일을 다운로드 할 수 있습니다.

    fileDonwloader.ts




    import fs from 'fs';
    
    export function loadFile(): fs.ReadStream {
        return fs.createReadStream('tmp/region.png');
    }
    


    index.ts




    import express from 'express';
    ...
    import * as downloader from './files/fileDownloader';
    
    const port = 3000;
    const app = express();
    ...
    app.get('/files/download', (req, res) => {
        const stream = downloader.loadFile();
        // download file as "hello.png"
        res.writeHead(200, {
            "Content-Type": "image/png",
            "Content-Disposition": "attachment; filename=hello.png",
        });
        stream.on('open', () => {
            console.log('Opened');
            stream.pipe(res);
        });
        stream.on('close', () => {
            console.log('Closed');
        });
    });
    app.listen(port, () => {
        console.log(`Example app listening at http://localhost:${port}`)
    });
    


    매우 간단합니다.
    스트림을 연 후 파일 다운로드가 시작됩니다.
    다운로드가 끝나면 스트림이 닫힙니다.


  • How to use fs.createReadStream? | Node.js
  • Content-Disposition - HTTP | MDN

  • 비디오 재생



    비디오를 재생하는 것은 어떻습니까?

    먼저 동영상 요소의 "src"로 URL을 설정해 봅니다.

    [클라이언트] index.html




    <!DOCTYPE html>
    <html lang='en'>
        <head>
            <title>Hello</title>
            <meta charset="utf8">
        </head>
        <body>
    ...
            <video muted controls autoplay src="/files/video"></video>
            <script src="./js/main.page.js"></script>
            <script>Page.init()</script>
        </body>
    </html>
    


    [서버] index.ts




    app.get('/files/video', (req, res) => {
        const stream = downloader.loadVideo();
        stream.on('open', () => {
            console.log('Opened');
    
            stream.pipe(res);
        });
        stream.on('close', () => {
            console.log('Closed');
        });
    });
    


    [서버] fileDownloader.ts




    import fs from 'fs';
    ...
    export function loadVideo(): fs.ReadStream {
        return fs.createReadStream('tmp/sample.mp4');
    }
    


    동영상을 재생할 수 있습니다.
    하지만 문제가 있습니다.

    페이지를 로드한 후 비디오를 시작하기 전에 먼저 데이터 다운로드를 기다려야 합니다.
    다운로드 후 비디오 재생이 시작됩니다.
    그러나 데이터는 첫 번째 데이터가 아닙니다.



    플레이 준비를 위해 영상 정보를 얻기 위함인 것 같습니다.
    첫 번째 다운로드를 피하거나 더 빨리 완료할 수 있습니까?

    TypeScript로 비디오 다운로드



    비디오를 다운로드하고 TypeScript로 비디오 요소로 설정하는 것은 어떻습니까?

    [클라이언트] index.html




    ...
            <video id="video_sample"></video>
            <script src="./js/main.page.js"></script>
            <script>Page.init()</script>
        </body>
    </html>
    


    [클라이언트] main.page.ts




    ...
    export function init() {
        const targetVideo = document.getElementById('video_sample') as HTMLVideoElement;
        targetVideo.muted = true;
        targetVideo.controls = true;
        targetVideo.autoplay = true;
    
        fetch('files/video', {
            method: 'GET',
            mode: 'cors'
        })
        .then(res => res.blob())
        .then(data => {
            targetVideo.src = URL.createObjectURL(data);
        })
        .catch(err => console.error(err));
    }
    


    대부분의 결과는 첫 번째 예와 동일했습니다.
    또한 모든 비디오 데이터를 먼저 다운로드하기를 기다리기 때문입니다.

    차이점은 비디오 데이터를 캐싱하기 때문에 첫 번째 재생을 마치고 비디오를 다시 재생하더라도 데이터를 다시 다운로드하지 않습니다.

    Stream API를 비디오 요소의 소스로 설정할 수 있습니까?
    나는 그것을하는 방법을 찾지 못했습니다 :(

    ReadableStream에서 "MediaStream"또는 "MediaSource"를 생성할 수 있으면 비디오 요소의 "srcObject"로 설정할 수 있습니다...

    WebSocket 또는 WebRTC를 사용해야 합니까?

    자원


  • 4.8.9 The video element - HTML Standard
  • video: The Video Embed element - HTML: HyperText Markup Language | MDN
  • Live streaming web audio and video - Developer guides | MDN
  • 좋은 웹페이지 즐겨찾기