docs(download): examples for downloading videos

This commit is contained in:
Daniel Wykerd
2022-06-16 13:34:07 +02:00
committed by LuanRT
parent 60075f8726
commit 418dcac80a
6 changed files with 176 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
# Downloading Videos
With YouTube.js you can consume videos in your applications as Node Streams.
```js
import Innertube from 'youtubei.js';
const yt = await new Innertube();
// Downloading videos returns a Node Stream which you can consume
const stream = yt.download('VIDEO_ID');
// Alternatively you may want more info before downloading
const info = await yt.getInfo('VIDEO_ID');
// Then you may request a download stream
const stream_from_info = yt.download();
```
## Download Methods
There are two options for downloading a video:
- `Innertube.download(video_id: string, options?: DownloadOptions)`
- `VideoInfo.download(options?: DownloadOptions)`
The download methods are identical, but the first one is a convenience method for the second one.
## Download Options
The `DownloadOptions` object is used to choose the format for download
- `format`: The format of the video to download. Use `'any'` to pick any format available. (default: `'mp4'`)
- `quality`: The quality of the video to download. (default: `'360p'`) There's some options:
- `'best'`: The best quality available. Picks the highest dimensions and highest bitrate stream.
- `'bestefficiency'`: The best quality available. Picks the highest dimensions and lowest bitrate stream.
- You may also filter via quality labels such as `'720p'` or `'1080p'`.
- `type`: The type of the video to download. (default: `'videoandaudio'`)
- `'videoandaudio'`: Download both video and audio.
- `'video'`: Download only video.
- `'audio'`: Download only audio.
- `range`: The range of the video to download. (default: `undefined`)
- `range.start`: First byte to download.
- `range.end`: Last byte to download.
## Download Events
In addition to the normal events emitted by Node Streams, YouTube.js also emits the following events on the stream:
- `info`: Emitted when the video metadata is available. (only emiited with `Innertube.download` not with `VideoInfo.download`)
- `progress`: Emitted when the video is downloading.
- `start`: Emitted when the video starts downloading.
```js
stream.on('info', (info) => {
// `info` is an instance of VideoDetails as returned by Innertube.getBasicInfo() and is thus not complete with all the details.
});
stream.on('progress', (progress) => {
// The progress object has the following properties
// progress.size - size of the video in megabytes as string
// progress.percent - percentage of the video downloaded as string
// progress.chunk_size - size of the last chunk downloaded as bytes
// progress.downloaded_size - size of the video downloaded in megabytes as string
// progress.raw_data.chunk_size - size of the last chunk downloaded as bytes
// progress.raw_data.downloaded_size - size of the video downloaded as bytes
// progress.raw_data.size - size of the response range in bytes
});
stream.on('start', () => {
// start does not have any data
});
```
## Aborting Downloads
The download stream may be abotted by calling `stream.cancel()`

View File

@@ -0,0 +1,3 @@
# Basic Video Download Example
Donwload video in 360p quality with both audio and video.

View File

@@ -0,0 +1,20 @@
// import Innertube from 'youtubei.js';
const { createWriteStream } = require('fs');
const Innertube = require('../../../lib/Innertube');
(async () => {
// instantiate the library
const yt = await new Innertube();
// download the video
// the default options are to download with 360p quality
// with both audio and video in an mp4 container
yt.download('bUHZ2k9DYHY')
.pipe(createWriteStream('./stream.mp4'))
.on('progress', progress => {
console.log(`Downloaded ${progress.percent}%`);
})
.on('finish', () => {
console.log('Download finished');
});
})();

View File

@@ -0,0 +1,5 @@
# FFMPEG Download Example
If you want to download vidoes in their best quality, you're going to have to download the audio and video separately. We can use `ffmpeg` to mux the audio and video streams back together.
This example uses `ffmpeg-static` package to provide a static binary of `ffmpeg`.

View File

@@ -0,0 +1,66 @@
/**
* Mux audio and video into a single stream.
*
* This example requires ffmpeg-static package or some other ffmpeg binary installed on your system.
*/
// import Innertube from 'youtubei.js';
const Innertube = require('../../../lib/Innertube');
const ffmpeg = require('ffmpeg-static');
const fs = require('fs');
const cp = require('child_process');
const readline = require('readline');
(async () => {
// instantiate the library
const yt = await new Innertube();
// get video info
const info = await yt.getInfo('bUHZ2k9DYHY');
// get the best video stream
const video = info.download({
quality: 'bestefficiency',
format: 'any',
type: 'video',
});
// get the best audio stream
const audio = info.download({
quality: 'bestefficiency',
format: 'any',
type: 'audio',
});
// create a ffmpeg instance
const ffmpeg_process = cp.spawn(ffmpeg, [
// remove ffmpeg's banner spam
'-hide_banner',
// inputs
'-i', 'pipe:3',
'-i', 'pipe:4',
// map the streams
'-map', '0:a',
'-map', '1:v',
// keep the original encodings
'-c', 'copy',
// output format
'-f', 'matroska',
// force write to file
'-y', 'stream.mkv'
], {
windowsHide: true,
stdio: [
// inherit stdio, stdin and stdout
'inherit', 'inherit', 'inherit',
// pipe:3, pipe:4
'pipe', 'pipe'
]
});
// pipe the streams to ffmpeg
audio.pipe(ffmpeg_process.stdio[3]);
video.pipe(ffmpeg_process.stdio[4]);
})();

View File

@@ -0,0 +1,6 @@
{
"license": "MIT",
"dependencies": {
"ffmpeg-static": "^5.0.0"
}
}