Compare commits
5 Commits
2f3d0568c9
..
v2
| Author | SHA1 | Date | |
|---|---|---|---|
| 1987330aa7 | |||
| 5ba0447644 | |||
| 5b3181669d | |||
| 710ea0d79f | |||
| 621a260b88 |
@@ -1,3 +1,4 @@
|
|||||||
|
.git
|
||||||
node_modules
|
node_modules
|
||||||
downloads
|
downloads
|
||||||
metadata
|
metadata
|
||||||
+9
-7
@@ -1,13 +1,15 @@
|
|||||||
FROM alpine:3.20
|
FROM node:20-bookworm
|
||||||
RUN adduser -S ytdl
|
ENV LANG=C.UTF-8 LC_ALL=C.UTF-8
|
||||||
RUN apk add --no-cache nodejs npm python3 py3-pip ffmpeg mediainfo make g++
|
RUN useradd -r -m -s /bin/bash -u 369 ytdl
|
||||||
|
RUN apt update; apt install -y python3-pip ffmpeg mediainfo make g++ iproute2
|
||||||
ADD . /app
|
ADD . /app
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
RUN npm ci
|
RUN npm ci
|
||||||
ENV DOWNLOADS=/downloads
|
ADD ./gai.conf /etc/gai.conf
|
||||||
RUN mkdir -p $DOWNLOADS/metadata; chown -R ytdl $DOWNLOADS
|
ENV DOWNLOADS=/downloads META_DIR=/metadata
|
||||||
|
RUN mkdir $DOWNLOADS $META_DIR; chown -R ytdl $DOWNLOADS $META_DIR
|
||||||
USER ytdl
|
USER ytdl
|
||||||
ENV PATH="/home/ytdl/.local/bin:$PATH"
|
ENV PATH="/home/ytdl/.local/bin:$PATH"
|
||||||
VOLUME $DOWNLOADS
|
VOLUME $DOWNLOADS $META_DIR
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
CMD ["sh", "-c", "pip install --break-system-packages --upgrade yt-dlp; exec node ."]
|
CMD ["sh", "-c", "pip install --break-system-packages --upgrade yt-dlp[default]; exec node ."]
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
# prefer ipv6 ULA over ipv4 because docker uses NATed ULA
|
||||||
|
|
||||||
|
# Configuration for getaddrinfo(3).
|
||||||
|
#
|
||||||
|
# So far only configuration for the destination address sorting is needed.
|
||||||
|
# RFC 3484 governs the sorting. But the RFC also says that system
|
||||||
|
# administrators should be able to overwrite the defaults. This can be
|
||||||
|
# achieved here.
|
||||||
|
#
|
||||||
|
# All lines have an initial identifier specifying the option followed by
|
||||||
|
# up to two values. Information specified in this file replaces the
|
||||||
|
# default information. Complete absence of data of one kind causes the
|
||||||
|
# appropriate default information to be used. The supported commands include:
|
||||||
|
#
|
||||||
|
# reload <yes|no>
|
||||||
|
# If set to yes, each getaddrinfo(3) call will check whether this file
|
||||||
|
# changed and if necessary reload. This option should not really be
|
||||||
|
# used. There are possible runtime problems. The default is no.
|
||||||
|
#
|
||||||
|
# label <mask> <value>
|
||||||
|
# Add another rule to the RFC 3484 label table. See section 2.1 in
|
||||||
|
# RFC 3484. The default is:
|
||||||
|
#
|
||||||
|
label ::1/128 0
|
||||||
|
label ::/0 1
|
||||||
|
label 2002::/16 2
|
||||||
|
label ::/96 3
|
||||||
|
label ::ffff:0:0/96 4
|
||||||
|
#label fec0::/10 5
|
||||||
|
#label fc00::/7 6
|
||||||
|
#label 2001:0::/32 7
|
||||||
|
#
|
||||||
|
# This default differs from the tables given in RFC 3484 by handling
|
||||||
|
# (now obsolete) site-local IPv6 addresses and Unique Local Addresses.
|
||||||
|
# The reason for this difference is that these addresses are never
|
||||||
|
# NATed while IPv4 site-local addresses most probably are. Given # *NEVER* NATed huh? You CLUELESS FUCKING RETARDS
|
||||||
|
# the precedence of IPv6 over IPv4 (see below) on machines having only
|
||||||
|
# site-local IPv4 and IPv6 addresses a lookup for a global address would
|
||||||
|
# see the IPv6 be preferred. The result is a long delay because the
|
||||||
|
# site-local IPv6 addresses cannot be used while the IPv4 address is
|
||||||
|
# (at least for the foreseeable future) NATed. We also treat Teredo
|
||||||
|
# tunnels special.
|
||||||
|
#
|
||||||
|
# precedence <mask> <value>
|
||||||
|
# Add another rule to the RFC 3484 precedence table. See section 2.1
|
||||||
|
# and 10.3 in RFC 3484. The default is:
|
||||||
|
#
|
||||||
|
#precedence ::1/128 50
|
||||||
|
#precedence ::/0 40
|
||||||
|
#precedence 2002::/16 30
|
||||||
|
#precedence ::/96 20
|
||||||
|
#precedence ::ffff:0:0/96 10
|
||||||
|
#
|
||||||
|
# For sites which prefer IPv4 connections change the last line to
|
||||||
|
#
|
||||||
|
#precedence ::ffff:0:0/96 100
|
||||||
|
|
||||||
|
#
|
||||||
|
# scopev4 <mask> <value>
|
||||||
|
# Add another rule to the RFC 6724 scope table for IPv4 addresses.
|
||||||
|
# By default the scope IDs described in section 3.2 in RFC 6724 are
|
||||||
|
# used. Changing these defaults should hardly ever be necessary.
|
||||||
|
# The defaults are equivalent to:
|
||||||
|
#
|
||||||
|
#scopev4 ::ffff:169.254.0.0/112 2
|
||||||
|
#scopev4 ::ffff:127.0.0.0/104 2
|
||||||
|
#scopev4 ::ffff:0.0.0.0/96 14
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
process.env.DOWNLOADS ||= "downloads";
|
process.env.DOWNLOADS ||= "downloads";
|
||||||
|
process.env.META_DIR ||= "metadata";
|
||||||
process.env.PORT ||= 8080;
|
process.env.PORT ||= 8080;
|
||||||
|
|
||||||
require("./web.js")
|
require("./web.js");
|
||||||
require("./wss.js")
|
require("./wss.js");
|
||||||
+2
-2
@@ -18,7 +18,7 @@ async function generateList() {
|
|||||||
var files = fs.readdirSync(process.env.DOWNLOADS, {withFileTypes: true}).filter(f => f.isFile()).map(f => f.name);
|
var files = fs.readdirSync(process.env.DOWNLOADS, {withFileTypes: true}).filter(f => f.isFile()).map(f => f.name);
|
||||||
var list = await Promise.all(files.map(async name => {
|
var list = await Promise.all(files.map(async name => {
|
||||||
var filepath = path.join(process.env.DOWNLOADS, name);
|
var filepath = path.join(process.env.DOWNLOADS, name);
|
||||||
var metapath = path.join(process.env.DOWNLOADS, "metadata", name) + ".json";
|
var metapath = path.join(process.env.META_DIR, name) + ".json";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var metadata = JSON.parse(fs.readFileSync(metapath, "utf8"));
|
var metadata = JSON.parse(fs.readFileSync(metapath, "utf8"));
|
||||||
@@ -26,7 +26,7 @@ async function generateList() {
|
|||||||
var metadata = {};
|
var metadata = {};
|
||||||
try {
|
try {
|
||||||
metadata.duration = await getVideoLength(filepath);
|
metadata.duration = await getVideoLength(filepath);
|
||||||
} catch(error) {console.error(error.message)};
|
} catch(error) {console.error(error.stack)};
|
||||||
fs.writeFileSync(metapath, JSON.stringify(metadata));
|
fs.writeFileSync(metapath, JSON.stringify(metadata));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
docker build -t ytdl-server .
|
docker build -t ytdl-server .
|
||||||
|
|
||||||
docker run -d --restart=unless-stopped --name ytdl-server -p 8660:8080 -v "/zpool1/fungible/ytdls:/downloads" ytdl-server
|
docker run -d --restart=unless-stopped --name ytdl-server -p 8660:8080 -v "/zpool1/ytdls:/downloads" -v "./metadata/:/metadata" ytdl-server
|
||||||
|
|
||||||
docker ipv6 required
|
docker ipv6 required
|
||||||
@@ -27,7 +27,7 @@ wss.on("connection", function(ws, req) {
|
|||||||
} else next();
|
} else next();
|
||||||
|
|
||||||
function next() {
|
function next() {
|
||||||
var cp = makeCp("yt-dlp", ["--no-mtime", "--no-playlist", "-6", "--progress-delta", "1", url], {cwd: process.env.DOWNLOADS, shell: false});
|
var cp = makeCp("yt-dlp", ["--js-runtimes", "node", "--no-mtime", "--no-playlist", "--progress-delta", "1", url], {cwd: process.env.DOWNLOADS, shell: false});
|
||||||
cp.on("close", (code, signal) => {
|
cp.on("close", (code, signal) => {
|
||||||
uncacheList();
|
uncacheList();
|
||||||
ws.close();
|
ws.close();
|
||||||
|
|||||||
Reference in New Issue
Block a user