@pieda/video-dl 1.3.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/types/_func.d.ts +1 -1
- package/dist/types/composables/index.d.ts +2 -0
- package/dist/types/composables/useDownloader.d.ts +4 -2
- package/dist/types/composables/useInstagram.d.ts +7 -0
- package/dist/types/composables/useTiktok.d.ts +7 -0
- package/dist/types/library.d.ts +1 -1
- package/dist/video-dl.cjs +1 -1
- package/dist/video-dl.js +133 -68
- package/package.json +3 -2
package/README.md
CHANGED
package/dist/types/_func.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const importModule: (moduleName: string) => Promise<unknown>;
|
|
2
|
-
export declare const downloadFileFromUrl: (url: string, filename: string) => Promise<void>;
|
|
2
|
+
export declare const downloadFileFromUrl: (url: string, filename: string, headers?: any) => Promise<void>;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { useYoutube } from './useYoutube';
|
|
2
2
|
import { useFacebook } from './useFacebook';
|
|
3
3
|
import { useVimeo } from './useVimeo';
|
|
4
|
+
import { useInstagram } from './useInstagram';
|
|
5
|
+
import { useTiktok } from './useTiktok';
|
|
4
6
|
type TUseDownloader = {
|
|
5
|
-
type: 'youtube' | 'facebook' | 'vimeo';
|
|
7
|
+
type: 'youtube' | 'facebook' | 'vimeo' | 'instagram' | 'yt-short' | 'fb-reel' | 'ig' | 'ig-reel' | 'tiktok' | 'tiktok-reel';
|
|
6
8
|
};
|
|
7
|
-
type TUseDownloaderResponse = typeof useYoutube | typeof useFacebook | typeof useVimeo;
|
|
9
|
+
type TUseDownloaderResponse = typeof useYoutube | typeof useFacebook | typeof useVimeo | typeof useInstagram | typeof useTiktok;
|
|
8
10
|
export declare const useDownloader: ({ type }: TUseDownloader) => TUseDownloaderResponse;
|
|
9
11
|
export {};
|
package/dist/types/library.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { useDownloader, useYoutube, useFacebook, useVimeo } from './composables';
|
|
1
|
+
export { useDownloader, useYoutube, useFacebook, useVimeo, useInstagram, useTiktok, } from './composables';
|
package/dist/video-dl.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=o=>new Promise((t,w)=>{import(o).then(e=>t(e.default)).catch(w)}),d=async(o,t,w)=>{const e=await s("fs"),l=await s("axios");return console.log(`Downloading ${o} to ${t}`),new Promise((n,r)=>{l.get(o,{responseType:"stream",headers:w}).then(g=>{const c=g.data,a=e.createWriteStream(t);c.pipe(a),a.on("finish",function(){a.close(()=>{n()})})}).catch(r)})},p=(o=!1)=>({log:(...t)=>{o&&console.log(...t)},error:(...t)=>{o&&console.error(...t)}}),f=async({videoId:o,dest:t,debug:w=!1})=>{const e=p(w);e.log(`Downloading video: ${o} to: ${t}`);const l=`https://www.youtube.com/watch?v=${o}`,n=await s("fs"),r=await s("path"),g=await s("@distube/ytdl-core");return n.existsSync(r.dirname(t))||n.mkdirSync(r.dirname(t),{recursive:!0},777),new Promise((c,a)=>{try{g(l).on("error",u=>{e.error(u),c([u,null])}).pipe(n.createWriteStream(t)).on("finish",()=>{e.log("Downloading finished."),c([null,!0])})}catch(i){console.log("error"),c([i,null])}})},$=async({videoId:o,dest:t,debug:w=!1})=>{try{const e=p(w);e.log(`Downloading video: ${o} to: ${t}`);const l=`https://m.facebook.com/watch/?v=${o}`,n=await s("fs"),r=await s("path"),g=await s("puppeteer");n.existsSync(r.dirname(t))||(n.mkdirSync(r.dirname(t),{recursive:!0},777),e.log(`建立 ${r.dirname(t)}`));const c=await g.launch();e.log("啟動 puppeteer");const a=await c.newPage();await a.setUserAgent("'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1'"),e.log("開新分頁"),await a.goto(l,{waitUntil:"networkidle0"}),e.log(`前往 ${l}`),await a.waitForSelector("video"),e.log("找到 video 元素");const i=await a.$eval("video",u=>u.getAttribute("src"));return e.log(`取得 video url: ${i}`),await c.close(),e.log("關閉 puppeteer"),await d(i,t),e.log(`下載完成 ${i}`),[null,!0]}catch(e){return[e,null]}},y=async({videoId:o,dest:t,debug:w=!1})=>{const e=p(w);e.log(`Downloading video: ${o} to: ${t}`);const l=await s("fs"),n=await s("path"),r=await s("axios"),g=async()=>{const a=await r.get("https://vimeo.com/_next/viewer",{responseType:"json",headers:{"X-Requested-With":"XMLHttpRequest"}}),{jwt:i}=a.data;return i||""},c=async(a="",i="")=>{const u=await r.get(`https://api.vimeo.com/videos/${a}?&fields=download`,{responseType:"json",headers:{"X-Requested-With":"XMLHttpRequest",Authorization:`jwt ${i}`}}),{download:m=[]}=u.data,h=m[0]||null;return(h==null?void 0:h.link)||""};return l.existsSync(n.dirname(t))||(l.mkdirSync(n.dirname(t),{recursive:!0},777),e.log(`建立 ${n.dirname(t)}`)),new Promise(async(a,i)=>{try{const u=await g();e.log(`取得 jwt ${u}`);const m=await c(o,u);e.log(`取得 videoUrl ${m}`),await d(m,t),e.log(`下載完成 ${t}`),a([null,!0])}catch(u){a([u,null])}})},v=async({videoId:o,dest:t,debug:w=!1})=>{try{const e=p(w);e.log(`Downloading video: ${o} to: ${t}`);const l=`https://www.instagram.com/share/${o}/`,n=await s("fs"),r=await s("path"),g=await s("puppeteer");n.existsSync(r.dirname(t))||(n.mkdirSync(r.dirname(t),{recursive:!0},777),e.log(`建立 ${r.dirname(t)}`));const c=await g.launch();e.log("啟動 puppeteer");const a=await c.newPage();await a.setUserAgent("'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1'"),e.log("開新分頁"),await a.goto(l,{}),e.log(`前往 ${l}`),await a.waitForSelector("video"),e.log("找到 video 元素");const i=await a.$eval("video",u=>u.getAttribute("src"));return e.log(`取得 video url: ${i}`),await c.close(),e.log("關閉 puppeteer"),await d(i,t),e.log(`下載完成 ${i}`),[null,!0]}catch(e){return[e,null]}},k=async({videoLink:o,dest:t,debug:w=!1})=>{try{const e=p(w);e.log(`Downloading video: ${o} to: ${t}`);const l=o,n=await s("fs"),r=await s("path"),g=await s("puppeteer");n.existsSync(r.dirname(t))||(n.mkdirSync(r.dirname(t),{recursive:!0},777),e.log(`建立 ${r.dirname(t)}`));const c=await g.launch({headless:!1});e.log("啟動 puppeteer");const a=await c.newPage();e.log("開新分頁"),await a.goto(l,{}),e.log(`前往 ${l}`),await a.waitForSelector("video"),e.log("找到 video 元素");const i=await a.$eval('video source[src^="https://www.tiktok.com/aweme/v1/play/"]',u=>u.getAttribute("src"));return e.log(`取得 video url: ${i}`),await c.close(),e.log("關閉 puppeteer"),await d(i,t,{"User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",Referer:"https://www.tiktok.com/"}),e.log(`下載完成 ${i}`),[null,!0]}catch(e){return[e,null]}},S=({type:o})=>{switch(o){case"youtube":case"yt-short":return f;case"facebook":case"fb-reel":return $;case"vimeo":return y;case"instagram":case"ig":case"ig-reel":return v;case"tiktok":case"tiktok-reel":return k;default:throw new Error(`Invalid video type: ${o}`)}};exports.useDownloader=S;exports.useFacebook=$;exports.useInstagram=v;exports.useTiktok=k;exports.useVimeo=y;exports.useYoutube=f;
|
package/dist/video-dl.js
CHANGED
|
@@ -1,116 +1,181 @@
|
|
|
1
|
-
const
|
|
2
|
-
import(o).then((
|
|
3
|
-
}),
|
|
4
|
-
const
|
|
5
|
-
return new Promise((
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
const s = (o) => new Promise((t, u) => {
|
|
2
|
+
import(o).then((e) => t(e.default)).catch(u);
|
|
3
|
+
}), m = async (o, t, u) => {
|
|
4
|
+
const e = await s("fs"), l = await s("axios");
|
|
5
|
+
return console.log(`Downloading ${o} to ${t}`), new Promise((n, r) => {
|
|
6
|
+
l.get(o, {
|
|
7
|
+
responseType: "stream",
|
|
8
|
+
headers: u
|
|
9
|
+
}).then((g) => {
|
|
10
|
+
const c = g.data, a = e.createWriteStream(t);
|
|
11
|
+
c.pipe(a), a.on("finish", function() {
|
|
12
|
+
a.close(() => {
|
|
13
|
+
n();
|
|
11
14
|
});
|
|
12
15
|
});
|
|
13
|
-
}).catch(
|
|
16
|
+
}).catch(r);
|
|
14
17
|
});
|
|
15
|
-
},
|
|
16
|
-
log: (...
|
|
17
|
-
o && console.log(...
|
|
18
|
+
}, p = (o = !1) => ({
|
|
19
|
+
log: (...t) => {
|
|
20
|
+
o && console.log(...t);
|
|
18
21
|
},
|
|
19
|
-
error: (...
|
|
20
|
-
o && console.error(...
|
|
22
|
+
error: (...t) => {
|
|
23
|
+
o && console.error(...t);
|
|
21
24
|
}
|
|
22
25
|
}), f = async ({
|
|
23
26
|
videoId: o,
|
|
24
|
-
dest:
|
|
27
|
+
dest: t,
|
|
25
28
|
debug: u = !1
|
|
26
29
|
}) => {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
return
|
|
30
|
+
const e = p(u);
|
|
31
|
+
e.log(`Downloading video: ${o} to: ${t}`);
|
|
32
|
+
const l = `https://www.youtube.com/watch?v=${o}`, n = await s("fs"), r = await s("path"), g = await s("@distube/ytdl-core");
|
|
33
|
+
return n.existsSync(r.dirname(t)) || n.mkdirSync(r.dirname(t), { recursive: !0 }, 777), new Promise((c, a) => {
|
|
31
34
|
try {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}).pipe(
|
|
35
|
-
|
|
35
|
+
g(l).on("error", (w) => {
|
|
36
|
+
e.error(w), c([w, null]);
|
|
37
|
+
}).pipe(n.createWriteStream(t)).on("finish", () => {
|
|
38
|
+
e.log("Downloading finished."), c([null, !0]);
|
|
36
39
|
});
|
|
37
|
-
} catch (
|
|
38
|
-
console.log("error"),
|
|
40
|
+
} catch (i) {
|
|
41
|
+
console.log("error"), c([i, null]);
|
|
39
42
|
}
|
|
40
43
|
});
|
|
41
|
-
},
|
|
44
|
+
}, $ = async ({
|
|
42
45
|
videoId: o,
|
|
43
|
-
dest:
|
|
46
|
+
dest: t,
|
|
44
47
|
debug: u = !1
|
|
45
48
|
}) => {
|
|
46
49
|
try {
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
await
|
|
50
|
+
const e = p(u);
|
|
51
|
+
e.log(`Downloading video: ${o} to: ${t}`);
|
|
52
|
+
const l = `https://m.facebook.com/watch/?v=${o}`, n = await s("fs"), r = await s("path"), g = await s("puppeteer");
|
|
53
|
+
n.existsSync(r.dirname(t)) || (n.mkdirSync(r.dirname(t), { recursive: !0 }, 777), e.log(`建立 ${r.dirname(t)}`));
|
|
54
|
+
const c = await g.launch();
|
|
55
|
+
e.log("啟動 puppeteer");
|
|
56
|
+
const a = await c.newPage();
|
|
57
|
+
await a.setUserAgent(
|
|
55
58
|
"'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1'"
|
|
56
|
-
),
|
|
59
|
+
), e.log("開新分頁"), await a.goto(l, {
|
|
57
60
|
waitUntil: "networkidle0"
|
|
58
|
-
}),
|
|
59
|
-
const
|
|
60
|
-
return
|
|
61
|
-
} catch (
|
|
62
|
-
return [
|
|
61
|
+
}), e.log(`前往 ${l}`), await a.waitForSelector("video"), e.log("找到 video 元素");
|
|
62
|
+
const i = await a.$eval("video", (w) => w.getAttribute("src"));
|
|
63
|
+
return e.log(`取得 video url: ${i}`), await c.close(), e.log("關閉 puppeteer"), await m(i, t), e.log(`下載完成 ${i}`), [null, !0];
|
|
64
|
+
} catch (e) {
|
|
65
|
+
return [e, null];
|
|
63
66
|
}
|
|
64
|
-
},
|
|
67
|
+
}, y = async ({
|
|
65
68
|
videoId: o,
|
|
66
|
-
dest:
|
|
69
|
+
dest: t,
|
|
67
70
|
debug: u = !1
|
|
68
71
|
}) => {
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
const
|
|
72
|
+
const e = p(u);
|
|
73
|
+
e.log(`Downloading video: ${o} to: ${t}`);
|
|
74
|
+
const l = await s("fs"), n = await s("path"), r = await s("axios"), g = async () => {
|
|
75
|
+
const a = await r.get("https://vimeo.com/_next/viewer", {
|
|
73
76
|
responseType: "json",
|
|
74
77
|
headers: {
|
|
75
78
|
"X-Requested-With": "XMLHttpRequest"
|
|
76
79
|
}
|
|
77
|
-
}), { jwt:
|
|
78
|
-
return
|
|
79
|
-
},
|
|
80
|
-
const
|
|
80
|
+
}), { jwt: i } = a.data;
|
|
81
|
+
return i || "";
|
|
82
|
+
}, c = async (a = "", i = "") => {
|
|
83
|
+
const w = await r.get(`https://api.vimeo.com/videos/${a}?&fields=download`, {
|
|
81
84
|
responseType: "json",
|
|
82
85
|
headers: {
|
|
83
86
|
"X-Requested-With": "XMLHttpRequest",
|
|
84
|
-
Authorization: `jwt ${
|
|
87
|
+
Authorization: `jwt ${i}`
|
|
85
88
|
}
|
|
86
|
-
}), { download:
|
|
89
|
+
}), { download: h = [] } = w.data, d = h[0] || null;
|
|
87
90
|
return (d == null ? void 0 : d.link) || "";
|
|
88
91
|
};
|
|
89
|
-
return
|
|
92
|
+
return l.existsSync(n.dirname(t)) || (l.mkdirSync(n.dirname(t), { recursive: !0 }, 777), e.log(`建立 ${n.dirname(t)}`)), new Promise(async (a, i) => {
|
|
90
93
|
try {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
} catch (
|
|
96
|
-
|
|
94
|
+
const w = await g();
|
|
95
|
+
e.log(`取得 jwt ${w}`);
|
|
96
|
+
const h = await c(o, w);
|
|
97
|
+
e.log(`取得 videoUrl ${h}`), await m(h, t), e.log(`下載完成 ${t}`), a([null, !0]);
|
|
98
|
+
} catch (w) {
|
|
99
|
+
a([w, null]);
|
|
97
100
|
}
|
|
98
101
|
});
|
|
99
|
-
}, v = ({
|
|
102
|
+
}, v = async ({
|
|
103
|
+
videoId: o,
|
|
104
|
+
dest: t,
|
|
105
|
+
debug: u = !1
|
|
106
|
+
}) => {
|
|
107
|
+
try {
|
|
108
|
+
const e = p(u);
|
|
109
|
+
e.log(`Downloading video: ${o} to: ${t}`);
|
|
110
|
+
const l = `https://www.instagram.com/share/${o}/`, n = await s("fs"), r = await s("path"), g = await s("puppeteer");
|
|
111
|
+
n.existsSync(r.dirname(t)) || (n.mkdirSync(r.dirname(t), { recursive: !0 }, 777), e.log(`建立 ${r.dirname(t)}`));
|
|
112
|
+
const c = await g.launch();
|
|
113
|
+
e.log("啟動 puppeteer");
|
|
114
|
+
const a = await c.newPage();
|
|
115
|
+
await a.setUserAgent(
|
|
116
|
+
"'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1'"
|
|
117
|
+
), e.log("開新分頁"), await a.goto(l, {
|
|
118
|
+
// waitUntil: 'networkidle0',
|
|
119
|
+
}), e.log(`前往 ${l}`), await a.waitForSelector("video"), e.log("找到 video 元素");
|
|
120
|
+
const i = await a.$eval("video", (w) => w.getAttribute("src"));
|
|
121
|
+
return e.log(`取得 video url: ${i}`), await c.close(), e.log("關閉 puppeteer"), await m(i, t), e.log(`下載完成 ${i}`), [null, !0];
|
|
122
|
+
} catch (e) {
|
|
123
|
+
return [e, null];
|
|
124
|
+
}
|
|
125
|
+
}, k = async ({
|
|
126
|
+
videoLink: o,
|
|
127
|
+
dest: t,
|
|
128
|
+
debug: u = !1
|
|
129
|
+
}) => {
|
|
130
|
+
try {
|
|
131
|
+
const e = p(u);
|
|
132
|
+
e.log(`Downloading video: ${o} to: ${t}`);
|
|
133
|
+
const l = o, n = await s("fs"), r = await s("path"), g = await s("puppeteer");
|
|
134
|
+
n.existsSync(r.dirname(t)) || (n.mkdirSync(r.dirname(t), { recursive: !0 }, 777), e.log(`建立 ${r.dirname(t)}`));
|
|
135
|
+
const c = await g.launch({ headless: !1 });
|
|
136
|
+
e.log("啟動 puppeteer");
|
|
137
|
+
const a = await c.newPage();
|
|
138
|
+
e.log("開新分頁"), await a.goto(l, {
|
|
139
|
+
// waitUntil: 'networkidle0',
|
|
140
|
+
}), e.log(`前往 ${l}`), await a.waitForSelector("video"), e.log("找到 video 元素");
|
|
141
|
+
const i = await a.$eval(
|
|
142
|
+
'video source[src^="https://www.tiktok.com/aweme/v1/play/"]',
|
|
143
|
+
(w) => w.getAttribute("src")
|
|
144
|
+
);
|
|
145
|
+
return e.log(`取得 video url: ${i}`), await c.close(), e.log("關閉 puppeteer"), await m(i, t, {
|
|
146
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
147
|
+
Referer: "https://www.tiktok.com/"
|
|
148
|
+
// 設定 Referer
|
|
149
|
+
}), e.log(`下載完成 ${i}`), [null, !0];
|
|
150
|
+
} catch (e) {
|
|
151
|
+
return [e, null];
|
|
152
|
+
}
|
|
153
|
+
}, S = ({ type: o }) => {
|
|
100
154
|
switch (o) {
|
|
101
155
|
case "youtube":
|
|
156
|
+
case "yt-short":
|
|
102
157
|
return f;
|
|
103
158
|
case "facebook":
|
|
104
|
-
|
|
105
|
-
case "vimeo":
|
|
159
|
+
case "fb-reel":
|
|
106
160
|
return $;
|
|
161
|
+
case "vimeo":
|
|
162
|
+
return y;
|
|
163
|
+
case "instagram":
|
|
164
|
+
case "ig":
|
|
165
|
+
case "ig-reel":
|
|
166
|
+
return v;
|
|
167
|
+
case "tiktok":
|
|
168
|
+
case "tiktok-reel":
|
|
169
|
+
return k;
|
|
107
170
|
default:
|
|
108
171
|
throw new Error(`Invalid video type: ${o}`);
|
|
109
172
|
}
|
|
110
173
|
};
|
|
111
174
|
export {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
175
|
+
S as useDownloader,
|
|
176
|
+
$ as useFacebook,
|
|
177
|
+
v as useInstagram,
|
|
178
|
+
k as useTiktok,
|
|
179
|
+
y as useVimeo,
|
|
115
180
|
f as useYoutube
|
|
116
181
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pieda/video-dl",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/video-dl.cjs",
|
|
7
7
|
"module": "dist/video-dl.js",
|
|
@@ -31,12 +31,13 @@
|
|
|
31
31
|
"build": "vue-tsc && vite build && tsc --declaration --emitDeclarationOnly",
|
|
32
32
|
"preview": "vite preview",
|
|
33
33
|
"prepare": "npm run build",
|
|
34
|
+
"start": "bun demo.ts",
|
|
34
35
|
"version:major": "npm version major",
|
|
35
36
|
"version:minor": "npm version minor",
|
|
36
37
|
"version:patch": "npm version patch"
|
|
37
38
|
},
|
|
38
39
|
"dependencies": {
|
|
39
|
-
"@distube/ytdl-core": "^4.15.
|
|
40
|
+
"@distube/ytdl-core": "^4.15.8",
|
|
40
41
|
"axios": "^1.7.2",
|
|
41
42
|
"puppeteer": "^22.13.1"
|
|
42
43
|
},
|