mirror of
https://github.com/LuanRT/YouTube.js.git
synced 2026-06-13 09:32:12 +00:00
docs(download): examples for downloading videos
This commit is contained in:
76
examples/download/README.md
Normal file
76
examples/download/README.md
Normal 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()`
|
||||
3
examples/download/basic/README.md
Normal file
3
examples/download/basic/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Basic Video Download Example
|
||||
|
||||
Donwload video in 360p quality with both audio and video.
|
||||
20
examples/download/basic/index.js
Normal file
20
examples/download/basic/index.js
Normal 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');
|
||||
});
|
||||
})();
|
||||
5
examples/download/ffmpeg/README.md
Normal file
5
examples/download/ffmpeg/README.md
Normal 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`.
|
||||
66
examples/download/ffmpeg/index.js
Normal file
66
examples/download/ffmpeg/index.js
Normal 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]);
|
||||
})();
|
||||
6
examples/download/ffmpeg/package.json
Normal file
6
examples/download/ffmpeg/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ffmpeg-static": "^5.0.0"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user