From 2a1aa4036c063c474ef001f3a03f594132999294 Mon Sep 17 00:00:00 2001 From: Isaac Grynsztein Date: Tue, 7 Apr 2020 01:52:59 -0400 Subject: [PATCH 1/3] New checkbox to select streaming only mode when subscribing --- .../dialogs/subscribe-dialog/subscribe-dialog.component.html | 5 ++++- .../dialogs/subscribe-dialog/subscribe-dialog.component.ts | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.html b/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.html index 10f81b7..d82c66d 100644 --- a/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.html +++ b/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.html @@ -29,6 +29,9 @@ +
+ Streaming-only mode +
@@ -36,7 +39,7 @@ - +
diff --git a/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.ts b/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.ts index 14a7621..c850e3d 100644 --- a/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.ts +++ b/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.ts @@ -19,6 +19,9 @@ export class SubscribeDialogComponent implements OnInit { // state subscribing = false; + // no videos actually downloaded, just streamed + streamingOnlyMode = false; + time_units = [ 'day', 'week', From e15141c5e0c44e594af2cfc039f283a63d86c0aa Mon Sep 17 00:00:00 2001 From: Isaac Grynsztein Date: Thu, 9 Apr 2020 23:33:58 -0400 Subject: [PATCH 2/3] Added backend and database support for video streaming Added UI support for video streaming. branch is now feature-complete --- backend/app.js | 19 ++++++++++++-- backend/subscriptions.js | 26 ++++++++++++++++--- .../subscribe-dialog.component.html | 6 +++-- .../subscribe-dialog.component.ts | 3 +-- src/app/posts.services.ts | 4 +-- .../subscription-file-card.component.ts | 6 ++++- .../subscription/subscription.component.ts | 12 ++++++--- 7 files changed, 60 insertions(+), 16 deletions(-) diff --git a/backend/app.js b/backend/app.js index 7f6df42..194dc8b 100644 --- a/backend/app.js +++ b/backend/app.js @@ -1708,11 +1708,13 @@ app.post('/api/subscribe', async (req, res) => { let name = req.body.name; let url = req.body.url; let timerange = req.body.timerange; + let streamingOnly = req.body.streamingOnly; const new_sub = { name: name, url: url, - id: uuid() + id: uuid(), + streamingOnly: streamingOnly }; // adds timerange if it exists, otherwise all videos will be downloaded @@ -1781,7 +1783,7 @@ app.post('/api/getSubscription', async (req, res) => { } // get sub videos - if (subscription.name) { + if (subscription.name && !subscription.streamingOnly) { let base_path = config_api.getConfigItem('ytdl_subscriptions_base_path'); let appended_base_path = path.join(base_path, subscription.isPlaylist ? 'playlists' : 'channels', subscription.name, '/'); let files; @@ -1817,6 +1819,19 @@ app.post('/api/getSubscription', async (req, res) => { parsed_files.push(file_obj); } + res.send({ + subscription: subscription, + files: parsed_files + }); + } else if (subscription.name && subscription.streamingOnly) { + // return list of videos + let parsed_files = []; + if (subscription.videos) { + for (let i = 0; i < subscription.videos.length; i++) { + const video = subscription.videos[i]; + parsed_files.push(new File(video.title, video.title, video.thumbnail, false, video.duration, video.url, video.uploader, video.size, null, null, video.upload_date)); + } + } res.send({ subscription: subscription, files: parsed_files diff --git a/backend/subscriptions.js b/backend/subscriptions.js index 14458b5..24be735 100644 --- a/backend/subscriptions.js +++ b/backend/subscriptions.js @@ -187,6 +187,7 @@ async function getVideosForSub(sub) { resolve(false); return; } + const sub_db = db.get('subscriptions').find({id: sub.id}); const basePath = config_api.getConfigItem('ytdl_subscriptions_base_path'); const useArchive = config_api.getConfigItem('ytdl_subscriptions_use_youtubedl_archive'); @@ -199,10 +200,6 @@ async function getVideosForSub(sub) { let downloadConfig = ['-o', appendedBasePath + '/%(title)s.mp4', '-f', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4', '-ciw', '--write-annotations', '--write-thumbnail', '--write-info-json', '--print-json']; - if (sub.timerange) { - downloadConfig.push('--dateafter', sub.timerange); - } - let archive_dir = null; let archive_path = null; @@ -214,6 +211,15 @@ async function getVideosForSub(sub) { downloadConfig.push('--download-archive', archive_path); } + // if streaming only mode, just get the list of videos + if (sub.streamingOnly) { + downloadConfig = ['-f', 'best', '--dump-json']; + } + + if (sub.timerange) { + downloadConfig.push('--dateafter', sub.timerange); + } + // get videos logger.verbose('Subscribe: getting videos for subscription ' + sub.name); youtubedl.exec(sub.url, downloadConfig, {}, function(err, output) { @@ -236,6 +242,18 @@ async function getVideosForSub(sub) { continue; } + if (sub.streamingOnly) { + if (i === 0) { + sub_db.assign({videos: []}).write(); + } + + // remove unnecessary info + output_json.formats = null; + + // add to db + sub_db.get('videos').push(output_json).write(); + } + // TODO: Potentially store downloaded files in db? } diff --git a/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.html b/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.html index d82c66d..5efbe3f 100644 --- a/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.html +++ b/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.html @@ -29,8 +29,10 @@ -
- Streaming-only mode +
+
+ Streaming-only mode +
diff --git a/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.ts b/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.ts index c850e3d..69f9326 100644 --- a/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.ts +++ b/src/app/dialogs/subscribe-dialog/subscribe-dialog.component.ts @@ -49,8 +49,7 @@ export class SubscribeDialogComponent implements OnInit { if (!this.download_all) { timerange = 'now-' + this.timerange_amount.toString() + this.timerange_unit; } - - this.postsService.createSubscription(this.url, this.name, timerange).subscribe(res => { + this.postsService.createSubscription(this.url, this.name, timerange, this.streamingOnlyMode).subscribe(res => { this.subscribing = false; if (res['new_sub']) { this.dialogRef.close(res['new_sub']); diff --git a/src/app/posts.services.ts b/src/app/posts.services.ts index 1db85c4..ade864a 100644 --- a/src/app/posts.services.ts +++ b/src/app/posts.services.ts @@ -184,8 +184,8 @@ export class PostsService { return this.http.post(this.path + 'deletePlaylist', {playlistID: playlistID, type: type}); } - createSubscription(url, name, timerange = null) { - return this.http.post(this.path + 'subscribe', {url: url, name: name, timerange: timerange}) + createSubscription(url, name, timerange = null, streamingOnly = false) { + return this.http.post(this.path + 'subscribe', {url: url, name: name, timerange: timerange, streamingOnly: streamingOnly}); } unsubscribe(sub, deleteMode = false) { diff --git a/src/app/subscription/subscription-file-card/subscription-file-card.component.ts b/src/app/subscription/subscription-file-card/subscription-file-card.component.ts index 093eb94..43f583c 100644 --- a/src/app/subscription/subscription-file-card/subscription-file-card.component.ts +++ b/src/app/subscription/subscription-file-card/subscription-file-card.component.ts @@ -54,7 +54,11 @@ export class SubscriptionFileCardComponent implements OnInit { } goToFile() { - this.goToFileEmit.emit(this.file.id); + const emit_obj = { + name: this.file.id, + url: this.file.requested_formats ? this.file.requested_formats[0].url : this.file.url + } + this.goToFileEmit.emit(emit_obj); } openSubscriptionInfoDialog() { diff --git a/src/app/subscription/subscription/subscription.component.ts b/src/app/subscription/subscription/subscription.component.ts index 496f2d1..3c7545f 100644 --- a/src/app/subscription/subscription/subscription.component.ts +++ b/src/app/subscription/subscription/subscription.component.ts @@ -84,10 +84,16 @@ export class SubscriptionComponent implements OnInit { }); } - goToFile(name) { + goToFile(emit_obj) { + const name = emit_obj['name']; + const url = emit_obj['url']; localStorage.setItem('player_navigator', this.router.url); - this.router.navigate(['/player', {fileNames: name, type: 'subscription', subscriptionName: this.subscription.name, - subPlaylist: this.subscription.isPlaylist}]); + if (this.subscription.streamingOnly) { + this.router.navigate(['/player', {name: name, url: url}]); + } else { + this.router.navigate(['/player', {fileNames: name, type: 'subscription', subscriptionName: this.subscription.name, + subPlaylist: this.subscription.isPlaylist}]); + } } onSearchInputChanged(newvalue) { From f6f54c0e535cdf1c82061823c22073c208b9c2b9 Mon Sep 17 00:00:00 2001 From: Isaac Grynsztein Date: Thu, 9 Apr 2020 23:41:21 -0400 Subject: [PATCH 3/3] Fixed bug where video infos caused an error for streaming-only subscriptions --- .../video-info-dialog/video-info-dialog.component.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/dialogs/video-info-dialog/video-info-dialog.component.html b/src/app/dialogs/video-info-dialog/video-info-dialog.component.html index 0c0c105..7323385 100644 --- a/src/app/dialogs/video-info-dialog/video-info-dialog.component.html +++ b/src/app/dialogs/video-info-dialog/video-info-dialog.component.html @@ -15,15 +15,15 @@
File size: 
-
{{filesize(file.size)}}
+
{{file.size ? filesize(file.size) : 'N/A'}}
Path: 
-
{{file.path}}
+
{{file.path ? file.path : 'N/A'}}
Upload Date: 
-
{{file.upload_date}}
+
{{file.upload_date ? file.upload_date : 'N/A'}}