From 690731ff818bda276dde288cbda846ecda4543b5 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Sat, 1 Jan 2022 21:18:26 +0300 Subject: [PATCH] Added download and reencoding progress to mongo --- package-lock.json | 19 ++++++++++++++++++ package.json | 1 + src/index.ts | 40 ++++++++++++++++++------------------- src/interfaces.ts | 4 ++++ src/processDownloaded.ts | 43 ++++++++++++++++++++++++++++++---------- 5 files changed, 76 insertions(+), 31 deletions(-) diff --git a/package-lock.json b/package-lock.json index 0911fb0..ac1ee51 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,6 +22,7 @@ "webtorrent": "^1.5.8" }, "devDependencies": { + "@types/handbrake-js": "^5.0.1", "@types/koa": "^2.13.4", "@types/koa__cors": "^3.1.1", "@types/koa-bodyparser": "^4.3.5", @@ -290,6 +291,15 @@ "@types/range-parser": "*" } }, + "node_modules/@types/handbrake-js": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/handbrake-js/-/handbrake-js-5.0.1.tgz", + "integrity": "sha512-e9hUk3kSYYGeUCE4VjMPI6SKHUF3Y43PVPNwGgBhDcRJBFokhdx9YiHEgt28krJfb7pnerReasObRzHP0qI4vA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/http-assert": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz", @@ -7008,6 +7018,15 @@ "@types/range-parser": "*" } }, + "@types/handbrake-js": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/handbrake-js/-/handbrake-js-5.0.1.tgz", + "integrity": "sha512-e9hUk3kSYYGeUCE4VjMPI6SKHUF3Y43PVPNwGgBhDcRJBFokhdx9YiHEgt28krJfb7pnerReasObRzHP0qI4vA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/http-assert": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/@types/http-assert/-/http-assert-1.5.3.tgz", diff --git a/package.json b/package.json index 6bd5381..5ecad1c 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "webtorrent": "^1.5.8" }, "devDependencies": { + "@types/handbrake-js": "^5.0.1", "@types/koa": "^2.13.4", "@types/koa__cors": "^3.1.1", "@types/koa-bodyparser": "^4.3.5", diff --git a/src/index.ts b/src/index.ts index 2a61fa7..ad572bf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -34,11 +34,22 @@ router.post('/room', async (ctx) => { syncedAt: new Date(), }; const doc = new RoomModel(room); + + async function setDownloadProg() { + await RoomModel.updateOne({ id: room.id }, { + downloadedProg: torrent.progress, + }); + } - torrent.on('done', function () { - torrent.destroy(); - processDownloaded(torrent, room.id); - }); + torrent + .on('download', async () => { + setDownloadProg(); + }) + .on('done', async () => { + setDownloadProg(); + torrent.destroy(); + processDownloaded(torrent, room.id); + }); await doc.save(); ctx.body = room; @@ -84,22 +95,11 @@ router.get('/status', async (ctx) => { const room = await RoomModel.findOne({ id: ctx.request.query.id }).exec(); if (room) { - if (room.downloaded) { - ctx.body = { - progress: 1, - downloaded: room.downloaded, - }; - } else { - const torrent = tCli.get(room.magnet); - if (torrent) { - ctx.body = { - progress: (torrent as WebTorrent.Torrent).progress, - downloaded: room.downloaded, - }; - } else { - ({ status: ctx.status, body: ctx.body } = errorResponse('status-00', 'No torrent found')); - } - } + ctx.body = { + downloadedProg: room.downloadedProg, + reencodedProg: room.reencodedProg, + downloaded: room.downloaded, + }; } else { ({ status: ctx.status, body: ctx.body } = errorResponse('status-01', 'No room found')); } diff --git a/src/interfaces.ts b/src/interfaces.ts index b105d79..b497585 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -6,6 +6,8 @@ export interface Room { createdAt: Date; movie?: string; filename?: string; + downloadedProg?: number; + reencodedProg?: number; downloaded?: boolean; downloadedAt?: Date; position: number; @@ -19,6 +21,8 @@ export const roomSchema = new Schema({ movie: { type: String, required: false }, filename: { type: String, required: false }, downloaded: { type: Boolean, required: false }, + downloadedProg: { type: Number, required: false }, + reencodedProg: { type: Number, required: false }, downloadedAt: { type: Date, required: false }, position: { type: Number, required: true }, syncedAt: { type: Date, required: true }, diff --git a/src/processDownloaded.ts b/src/processDownloaded.ts index 7b39236..4eaac64 100644 --- a/src/processDownloaded.ts +++ b/src/processDownloaded.ts @@ -1,5 +1,6 @@ import fs from 'fs'; import mv from 'mv'; +import { spawn } from 'handbrake-js'; import type short from 'short-uuid'; import type WebTorrent from 'webtorrent'; import { model } from 'mongoose'; @@ -8,18 +9,38 @@ import { Room, roomSchema } from './interfaces'; const RoomModel = model('Room', roomSchema); +function deleteTemp(torrent: WebTorrent.Torrent) { + fs.rmSync(__dirname + '/../' + torrent.path + '/' + torrent.name, { recursive: true }); +} + export default function (torrent: WebTorrent.Torrent, id: short.SUUID) { - const extensionsRegEx = /(\.mp4|\.mkv)$/; - findInDir(torrent.path, extensionsRegEx, (filename: string) => { - const extension = filename.split('.').pop(); - mv(`./${filename}`, `${process.env.FILES}/${id}.${extension}`, async () => { - await RoomModel.updateOne({ id: id }, { - filename: id + '.' + extension, - downloaded: true, - downloadedAt: new Date(), + const extensionsRegEx = /(\.mp4|\.mkv|\.avi)$/; + findInDir(torrent.path, extensionsRegEx, async (filename: string) => { + const originalExtension = filename.split('.').pop(); + const extension = '.mp4'; + const outputLocation = `${process.env.FILES}/${id}.${extension}`; + + if (originalExtension !== 'mp4') { + spawn({ input: filename, output: outputLocation }) + .on('error', console.error) + .on('progress', async (progress) => { + await RoomModel.updateOne({ id: id }, { + reencodedProg: progress.percentComplete / 100, + }); + }) + .on('complete', () => { + deleteTemp(torrent); + }); + } else { + mv(filename, outputLocation, async () => { + await RoomModel.updateOne({ id: id }, { + filename: id + '.' + extension, + downloaded: true, + downloadedAt: new Date(), + }); + + deleteTemp(torrent); }); - - fs.rmSync(__dirname + '/../' + torrent.path + '/' + torrent.name, { recursive: true }); - }); + } }); }