Home > Software engineering >  Node js - send and receive a video
Node js - send and receive a video

Time:06-20

I want to send a YouTube video which is converted in my API node js with ytdl-core to my client for downloading it. It works if I use a navigator for ask to my API but I can't download when I use my client.

The two way I tried:

video.pipe(reponse);

I receive something like that:
§W��JXIn�!�↓#�▲If�Z2��Y�F∟��6� ♠♂4�o�C4�-KeoX�@↔;#%◄Z↔¶������cl�N♦�5Z8��Ζ��↓��fƦ�P¤�{P�◄�ټ�֩��S��ŗ�Z�↑����.�☻j��G�▬�\L�2�ލ▬�|�T�w<�¶☺�☼!zTMʌ��� L# n=♠V♣nMT�֑zr☺��o�l���↕�iʮ��♫�3���W�lK���x}��7↨4q �zV��5kB��a�m��∟y◄��Xx5�l�OYkFX?�9s��g�♫���0St��#$4#4� �J���♂U◄Ĺ;Á�♀Qž? R߈/��˽}KeoX�@↔�!b�k�u�RhĀR▼$��b�0�ɉIi %�Es�&�u���dvK♥g→E☻ .��ݒ����}�[∟��♣;☼=f� .... or

reponse.status(200).send(video);

I receive that:

{
  _readableState: {
    objectMode: false,
    highWaterMark: 524288,
    buffer: { head: null, tail: null, length: 0 },
    length: 0,
    pipes: [],
    flowing: null,
    ended: false,
    endEmitted: false,
    reading: false,
    constructed: true,
    sync: false,
    needReadable: false,
    emittedReadable: false,
    readableListening: false,
    resumeScheduled: false,
    errorEmitted: false,
    emitClose: true,
    autoDestroy: true,
    destroyed: false,
    errored: null,
    closed: false,
    closeEmitted: false,
    defaultEncoding: 'utf8',
    awaitDrainWriters: null,
    multiAwaitDrain: false,
    readingMore: false,
    dataEmitted: false,
    decoder: null,
    encoding: null
  },
  _events: {},
  _eventsCount: 1,
  _writableState: {
    objectMode: false,
    highWaterMark: 524288,
    finalCalled: false,
    needDrain: false,
    ending: false,
    ended: false,
    finished: false,
    destroyed: false,
    decodeStrings: true,
    defaultEncoding: 'utf8',
    length: 0,
    writing: false,
    corked: 0,
    sync: true,
    bufferProcessing: false,
    writecb: null,
    writelen: 0,
    afterWriteTickInfo: null,
    buffered: [],
    bufferedIndex: 0,
    allBuffers: true,
    allNoop: true,
    pendingcb: 0,
    constructed: true,
    prefinished: false,
    errorEmitted: false,
    emitClose: true,
    autoDestroy: true,
    errored: null,
    closed: false,
    closeEmitted: false
  },
  allowHalfOpen: true
}
[nodemon] restarting due to changes...
[nodemon] starting `node index.js`
server started ! : port 5000
{
  _readableState: {
    objectMode: false,
    highWaterMark: 524288,
    buffer: { head: null, tail: null, length: 0 },
    length: 0,
    pipes: [],
    flowing: null,
    ended: false,
    endEmitted: false,
    reading: false,
    constructed: true,
    sync: false,
    needReadable: false,
    emittedReadable: false,
    readableListening: false,
    resumeScheduled: false,
    errorEmitted: false,
    emitClose: true,
    autoDestroy: true,
    destroyed: false,
    errored: null,
    closed: false,
    closeEmitted: false,
    defaultEncoding: 'utf8',
    awaitDrainWriters: null,
    multiAwaitDrain: false,
    readingMore: false,
    dataEmitted: false,
    decoder: null,
    encoding: null
  },
  _events: {},
  _eventsCount: 1,
  _writableState: {
    objectMode: false,
    highWaterMark: 524288,
    finalCalled: false,
    needDrain: false,
    ending: false,
    ended: false,
    finished: false,
    destroyed: false,
    decodeStrings: true,
    defaultEncoding: 'utf8',
    length: 0,
    writing: false,
    corked: 0,
    sync: true,
    bufferProcessing: false,
    writecb: null,
    writelen: 0,
    afterWriteTickInfo: null,
    buffered: [],
    bufferedIndex: 0,
    allBuffers: true,
    allNoop: true,
    pendingcb: 0,
    constructed: true,
    prefinished: false,
    errorEmitted: false,
    emitClose: true,
    autoDestroy: true,
    errored: null,
    closed: false,
    closeEmitted: false
  },
  allowHalfOpen: true
}

I don't know how to down load it because pipe don't work when I receive the 2 answers.

CodePudding user response:

you can use gstream nodejs/npm integration

sudo apt-get install gstreamer-tools
npm install gstreamer
var gstreamer = require("../");
 
gstreamer.start({
    url: "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov?random="   Math.random(),
    //url: "rtsp://192.168.1.92:554//1",
    port: 80,
    quiet: false
});

CodePudding user response:

then, try the following:

$ npm init

$ sudo apt install youtube-dl
$ sudo apt install ffmpeg

$ npm install shelljs;
$ npm install -g shelljs;
&lt;!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Video Streaming With Node</title>
        <style>
            body {
                margin: 5% auto;
                max-width: 100%;
                background-color: rgb(14, 14, 14);
                padding-top: 10%;
                padding-left: 35%;
            }
        </style>
    </head>
    <body>
        <video id="videoPlayer" width="50%" controls muted="muted" autoplay>
            <source src="/video" type="video/mp4" />
        </video>
    </body>
</html>

const shx = require('shelljs');

shx.exec("youtube-dl rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov?random="   Math.random());

// *********************************************** //

const express = require("express");
const app = express();
const fs = require("fs");

app.get("/", function (req, res) {
    res.sendFile(__dirname   "/index.html");
});

 // more code will go in here just befor the listening function

app.listen(8000, function () {
    console.log("Listening on port 8000!");
});

// *********************************************** //

app.get("/video", function (req, res) {
    const range = req.headers.range;
    if (!range) {
        res.status(400).send("Requires Range header");
    }
});

// *********************************************** //

const videoPath = "Chris-Do.mp4";
const videoSize = fs.statSync("Chris-Do.mp4").size;

// *********************************************** //

const express = require("express");
const app = express();
const fs = require("fs");

app.get("/", function (req, res) {
    res.sendFile(__dirname   "/index.html");
});
app.get("/video", function (req, res) {
    const range = req.headers.range;
    if (!range) {
        res.status(400).send("Requires Range header");
    }
    const videoPath = "Chris-Do.mp4";
    const videoSize = fs.statSync("Chris-Do.mp4").size;
});

app.listen(8000, function () {
    console.log("Listening on port 8000!");
});

// *********************************************** //

const CHUNK_SIZE = 10 ** 6; // 1MB
const start = Number(range.replace(/\D/g, ""));

// *********************************************** //

const start = Number(range.replace(/\D/g, ""));

// *********************************************** //

const end = Math.min(start   CHUNK_SIZE, videoSize - 1);

// *********************************************** //

const headers = {
    "Content-Range": `bytes ${start}-${end}/${videoSize}`,
    ... // this ... just indicates that there is more code here. 
        // it is not part of code.
}

// *********************************************** //

const headers = {
    "Content-Range": `bytes ${start}-${end}/${videoSize}`,
    "Accept-Ranges": "bytes",
    "Content-Length": contentLength,
    "Content-Type": "video/mp4",
};

// *********************************************** //

// HTTP Status 206 for Partial Content
res.writeHead(206, headers);

// *********************************************** //

const videoStream = fs.createReadStream(videoPath, { start, end });

// *********************************************** //

videoStream.pipe(res);

// *********************************************** //

    const end = Math.min(start   CHUNK_SIZE, videoSize - 1);
    const contentLength = end - start   1;
    const headers = {
        "Content-Range": `bytes ${start}-${end}/${videoSize}`,
        "Accept-Ranges": "bytes",
        "Content-Length": contentLength,
        "Content-Type": "video/mp4",
    };
    res.writeHead(206, headers);
    const videoStream = fs.createReadStream(videoPath, { start, end });
    videoStream.pipe(res);
});

app.listen(8000, function () {
    console.log("Listening on port 8000!");
});
    const end = Math.min(start   CHUNK_SIZE, videoSize - 1);
    const contentLength = end - start   1;
    const headers = {
        "Content-Range": `bytes ${start}-${end}/${videoSize}`,
        "Accept-Ranges": "bytes",
        "Content-Length": contentLength,
        "Content-Type": "video/mp4",
    };
    res.writeHead(206, headers);
    const videoStream = fs.createReadStream(videoPath, { start, end });
    videoStream.pipe(res);
});

app.listen(8000, function () {
    console.log("Listening on port 8000!");
});

// *********************************************** //

"scripts": {
      "start": "nodemon index.js" //this is the main line you need to add
},

//note that the index.js is just the name of my file. yours might be named differently

if you want the full reply, here you have it:

  • Related