Add video thumbnails
This commit is contained in:
parent
9fb560fc9a
commit
c3314c440a
BIN
database.sqlite3
BIN
database.sqlite3
Binary file not shown.
23
index.js
23
index.js
@ -172,24 +172,31 @@ app.post("/api/upload_video", authorized(), fileUpload({ limits: { fileSize: 2 *
|
|||||||
const id = randomString(4);
|
const id = randomString(4);
|
||||||
const tempPath = req.files.video.tempFilePath;
|
const tempPath = req.files.video.tempFilePath;
|
||||||
const newPath = path.join(dirname(), "videos", `${id}.mp4`);
|
const newPath = path.join(dirname(), "videos", `${id}.mp4`);
|
||||||
|
const thumbnailPath = path.join(dirname(), "videos", `${id}.png`);
|
||||||
|
|
||||||
console.log(newPath);
|
console.log(newPath);
|
||||||
|
|
||||||
const exitCode = await new Promise((resolve, _reject) => {
|
let exitCode = await new Promise(resolve => {
|
||||||
const process = childProcess.spawn("ffmpeg", ["-i", tempPath, "-b:v", "1M", "-b:a", "192k", newPath]);
|
const process = childProcess.spawn("ffmpeg", ["-i", tempPath, "-b:v", "1M", "-b:a", "192k", newPath]);
|
||||||
process.stderr.on("data", (data) => {
|
process.stderr.on("data", (data) => console.error(data.toString()));
|
||||||
console.error(data.toString());
|
process.on("close", resolve);
|
||||||
});
|
|
||||||
process.on("close", (code) => {
|
|
||||||
resolve(code);
|
|
||||||
})
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
throw new Error("ffmpeg failed");
|
throw new Error("ffmpeg failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
await dbRun("INSERT INTO videos (id, user_id, title, path) VALUES (?, ?, ?, ?)", id, userId, title, newPath);
|
exitCode = await new Promise(resolve => {
|
||||||
|
const process = childProcess.spawn("ffmpeg", ["-i", tempPath, "-ss", "00:00:01.000", "-vframes", "1", thumbnailPath]);
|
||||||
|
process.stderr.on("data", (data) => console.error(data.toString()));
|
||||||
|
process.on("close", resolve);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (exitCode !== 0) {
|
||||||
|
throw new Error("thumbnail generation failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
await dbRun("INSERT INTO videos (id, user_id, title) VALUES (?, ?, ?)", id, userId, title);
|
||||||
|
|
||||||
return res.status(200).json({ ok: true });
|
return res.status(200).json({ ok: true });
|
||||||
})
|
})
|
||||||
|
@ -8,7 +8,6 @@ CREATE TABLE videos (
|
|||||||
id TEXT PRIMARY KEY NOT NULL,
|
id TEXT PRIMARY KEY NOT NULL,
|
||||||
user_id INTEGER,
|
user_id INTEGER,
|
||||||
title TEXT NOT NULL,
|
title TEXT NOT NULL,
|
||||||
path TEXT NOT NULL,
|
|
||||||
FOREIGN KEY(user_id) REFERENCES users(id)
|
FOREIGN KEY(user_id) REFERENCES users(id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -24,7 +24,18 @@ function displayResponse(response) {
|
|||||||
+ videos
|
+ videos
|
||||||
.map(v => {
|
.map(v => {
|
||||||
console.log(v);
|
console.log(v);
|
||||||
return `<li><p><a href="/watch?id=${v.id}">${v.title}</a> - ${v.author}</p></li>`
|
return `
|
||||||
|
<li>
|
||||||
|
<p class="video-item">
|
||||||
|
<img src="/videos/${v.id}.png" alt="">
|
||||||
|
<span class="video-info">
|
||||||
|
<a href="/watch?id=${v.id}">${v.title}</a>
|
||||||
|
<br>
|
||||||
|
by ${v.author}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
</li>
|
||||||
|
`;
|
||||||
})
|
})
|
||||||
.join("")
|
.join("")
|
||||||
+ "</ul>";
|
+ "</ul>";
|
||||||
|
@ -62,12 +62,41 @@ body {
|
|||||||
ul#video-list {
|
ul#video-list {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#video-player {
|
#video-player {
|
||||||
max-height: 80vh;
|
max-height: 80vh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.video-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 2em;
|
||||||
|
text-align: left;
|
||||||
|
background-color: rgba(255, 255, 255, 0.3);
|
||||||
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-item img {
|
||||||
|
width: 200px;
|
||||||
|
height: 100px;
|
||||||
|
object-fit: contain;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-item .video-info {
|
||||||
|
padding-top: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-item a {
|
||||||
|
font-size: 1.4em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
Loading…
Reference in New Issue
Block a user