Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
hls-dash-dl
Advanced tools
HLS(.m3u8
) and DASH(.mpd
) video streaming download tool.
Supports multiple audio tracks and multiple subtitle tracks.
npm install hls-dash-dl
const HLS = "https://cdn.theoplayer.com/video/elephants-dream/playlist-single-audio.m3u8";
const DASH = "https://dash.akamaized.net/akamai/test/caption_test/ElephantsDream/elephants_dream_480p_heaac5_1_https.mpd";
const Downloader = require("hls-dash-dl");
const dl = new Downloader({
ffmpegPath: "./bin/ffmpeg.exe",
// quality: "highest", // "highest" | "medium" | "lowest"
// concurrency: 5,
// videoCodec: "copy",
// audioCodec: "copy",
// subtitleCodec: "srt",
// clean: true,
});
dl.download(DASH, "./DASH.mkv").then((video_info) => {
console.log(video_info);
});
dl.parse(HLS, "./HLS.mkv").then((video_info) => {
console.log(video_info);
});
// decrypt example
const dl = new Downloader({
ffmpegPath: "./bin/ffmpeg.exe",
gpacPath: "C:/Program Files/GPAC/gpac.exe",
});
dl.download(
{
url: "https://cdn.bitmovin.com/content/assets/art-of-motion_drm/mpds/11331.mpd",
keys: [
"ccbf5fb4c2965be7aa130ffb3ba9fd73:9cc0c92044cb1d69433f5f5839a159df",
"9bf0e9cf0d7b55aeb4b289a63bab8610:90f52fd8ca48717b21d0c2fed7a12ae1",
"eb676abbcb345e96bbcf616630f1a3da:100b6c20940f779a4589152b57d2dacb",
"0294b9599d755de2bbf0fdca3fa5eab7:3bda2f40344c7def614227b9c0f03e26",
"639da80cf23b55f3b8cab3f64cfa5df6:229f5f29b643e203004b30c4eaf348f4",
],
},
"./bitmovin.mkv"
);
// handler example
let childProcess;
dl.download(DASH, "./DASH.mkv", (event, data) => {
if (event === "video_info") {
const { video_info } = data;
} else if (event === "child_process_spawn") {
const { process, cwd, command, args } = data;
childProcess = process;
} else if (event === "child_process_close") {
const { code } = data;
childProcess = null;
} else if (event === "child_process_error") {
const { error } = data;
childProcess = null;
}
});
// logger example
const fs = require("node:fs");
const logFile = "./log.txt";
const dl = new Downloader({
ffmpegPath: "./bin/ffmpeg.exe",
// logger: console, // default
// logger: null, // silence
logger: {
indentSize: 2,
indent: 0,
group(...args) {
this.indent += 1;
fs.appendFileSync(logFile, args.join(" ") + "\n");
},
groupEnd() {
this.indent -= 1;
},
log(...args) {
fs.appendFileSync(logFile, " ".repeat(this.indent * this.indentSize) + args.join(" ") + "\n");
},
error(...args) {
this.log(...args);
},
},
});
new Downloader(config?)
config
ffmpegPath?
string - FFmpeg executable file path (download here). Default by ffmpeg
(in the Path
of the system environment variables). For decrypting and muxing tracks.gpacPath?
string - GPAC executable file path (download here). Default by gpac
(in the Path
of the system environment variables). For extracting WVTT/TTML subtitle tracks.outDir?
string - Default output directory. Default by Downloads
directory.quality?
string - Quality of video to download, can be highest
| medium
| lowest
. Default by highest
.concurrency?
number - Number of concurrent downloads of segments. Default by 5
.videoCodec?
string - Video Codec. Default by copy
.audioCodec?
string - Audio Codec. Default by copy
.subtitleCodec?
string - Subtitle Codec. Default by srt
.clean?
boolean - Clear temporary files after download is complete. Default by true
.logger?
console - Custom logger. Default by console
. Set to null
for silence.downloader.download(manifest, outFile, handler?): Promise
manifest
- HLS(.m3u8
) or DASH(.mpd
) manifest info.
url?
string - Manifest url.text?
string - Manifest content text.keys?
string | string[] - Decryption key(s).outFile
string - Output file path.handler(event, data)?
Function - Event handler.
"video_info"
, { video_info }
) - Manifest parsed."child_process_spawn"
, { process, cwd, command, args }
) - Spawn child process (FFmpeg or GPAC)."child_process_close"
, { code }
) - child process closed."child_process_error"
, { error }
) - child process error."child_process_stdout"
, { data }
) - child process stdout data."child_process_stderr"
, { data }
) - child process stderr data.Resolves with video_info
.
downloader.parse(manifest, outFile): Promise
manifest
string | { url?, text?, keys? } - HLS(.m3u8
) or DASH(.mpd
) manifest info.outFile
string - Output file path.Resolves with video_info
.
video_info
{
// config
ffmpegPath: './bin/ffmpeg.exe',
gpacPath: 'C:/Program Files/GPAC/gpac.exe',
outDir: 'C:\\Users\\ssnangua\\Downloads',
quality: 'highest',
concurrency: 5,
videoCodec: 'copy',
audioCodec: 'copy',
subtitleCodec: 'srt',
clean: true,
logger: { /*...*/ },
// manifest
url: 'https://.../*.mpd',
text: '/*...*/', // *.mpd file content
keys: [/*...*/], // decryption keys
manifest: { /*...*/ }, // dasha library Manifest object
// output
dir: 'E:\\GitHub\\hls-dash-dl',
name: 'DASH',
ext: '.mkv',
file: 'E:\\GitHub\\hls-dash-dl\\DASH.mkv'
tmpDir: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH',
handler: (event, data) => { /*...*/ },
// tracks
video: [
{
// attributes
type: 'video',
codec: 'H.264',
bitrate: { /*...*/ },
quality: '480p',
language: '',
label: undefined,
fps: 24,
defaultKeyId: '9eb4050de44b4802932e27d75083e266',
// segments
segments: [
{
url: 'https://.../*.mp4',
tmpDir: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH',
name: 'video0_Segment0',
ext: '.mp4',
file: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH\\video0_Segment0.mp4',
stat: 'waiting',
},
/*...*/
],
// output
tmpDir: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH',
name: 'video0_1080p_H.264', // [type][index]_[quality]_[codec]
ext: '.mp4',
file: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH\\video0_1080p_H.264.mp4',
}
],
audio: [
{
// attributes
type: 'audio',
codec: 'AAC',
bitrate: { /*...*/ },
quality: undefined,
language: 'en',
label: undefined,
defaultKeyId: "9eb4050de44b4802932e27d75083e266",
// segments
segments: [
{
url: 'https://.../*.mp4',
tmpDir: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH',
name: 'audio0_Segment0',
ext: '.mp4',
file: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH\\audio0_Segment0.mp4',
stat: 'waiting',
},
/*...*/
],
// output
tmpDir: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH',
name: 'audio0_en_AAC', // [type][index]_[language]_[codec]
ext: '.mp4',
file: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH\\audio0_en_AAC.mp4',
},
/*...*/
],
subtitle: [
{
// attributes
type: 'subtitle',
codec: 'VTT',
bitrate: { /*...*/ },
quality: undefined,
language: 'en',
label: undefined,
// segments
segments: [
{
url: 'https://.../*.vtt',
tmpDir: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH',
name: 'subtitle0_Segment0',
ext: '.vtt',
file: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH\\subtitle0_Segment0.vtt',
stat: 'waiting',
},
/*...*/
],
// output
tmpDir: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH',
name: 'subtitle0_en_VTT', // [type][index]_[language]_[codec]
ext: '.vtt',
file: 'E:\\GitHub\\hls-dash-dl\\tmp-DASH\\subtitle0_en_VTT.vtt',
},
/*...*/
]
}
FAQs
HLS(.m3u8) and DASH(.mpd) video streaming download tool.
The npm package hls-dash-dl receives a total of 25 weekly downloads. As such, hls-dash-dl popularity was classified as not popular.
We found that hls-dash-dl demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.