diff --git a/backend/app.js b/backend/app.js index 4c5f42e..db20c35 100644 --- a/backend/app.js +++ b/backend/app.js @@ -173,7 +173,7 @@ function getVideoFormatID(name) } function deleteAudioFile(name) { - var jsonPath = audioFolderPath+name+'.info.json'; + var jsonPath = audioFolderPath+name+'.mp3.info.json'; var audioFilePath = audioFolderPath+name+'.mp3'; fs.unlinkSync(audioFilePath); @@ -192,15 +192,22 @@ app.post('/tomp3', function(req, res) { var url = req.body.url; var date = Date.now(); var path = audioFolderPath; - var audiopath = '%(title)s.%(ext)s'; + var audiopath = '%(title)s'; youtubedl.exec(url, ['--get-filename', '-o', audiopath], {}, function(err_getting_name, output) { if (err_getting_name) { res.sendStatus(500); throw err_getting_name; } - var output_string = output[0]; - audiopath = output_string.substring(0, output_string.lastIndexOf('.')) + '.mp3'; + var file_names = []; + for (let i = 0; i < output.length; i++) { + var modified_file_name = output[i]; + file_names.push(modified_file_name); + } + + var is_playlist = file_names.length > 1; + if (!is_playlist) audiopath = file_names[0]; + youtubedl.exec(url, ['--external-downloader', 'aria2c', '-o', path + audiopath + ".mp3", '-x', '--audio-format', 'mp3', '--write-info-json'], {}, function(err, output) { if (err) { audiopath = "-1"; @@ -208,9 +215,10 @@ app.post('/tomp3', function(req, res) { throw err; } else if (output) { var completeString = "done"; - var audiopathEncoded = encodeURIComponent(audiopath); + var audiopathEncoded = encodeURIComponent(file_names[0]); res.send({ - audiopathEncoded: audiopathEncoded + audiopathEncoded: audiopathEncoded, + file_names: is_playlist ? file_names : null }); } }); @@ -221,15 +229,23 @@ app.post('/tomp4', function(req, res) { var url = req.body.url; var date = Date.now(); var path = videoFolderPath; - var videopath = '%(title)s.%(ext)s'; + var videopath = '%(title)s'; youtubedl.exec(url, ['--get-filename', '-o', videopath], {}, function(err_getting_name, output) { if (err_getting_name) { res.sendStatus(500); throw err_getting_name; } - var output_string = output[0]; - videopath = output_string.substring(0, output_string.lastIndexOf('.')) + '.mp4'; + + var file_names = []; + for (let i = 0; i < output.length; i++) { + var modified_file_name = output[i]; + file_names.push(modified_file_name); + } + + var is_playlist = file_names.length > 1; + if (!is_playlist) videopath = file_names[0]; + youtubedl.exec(url, ['--external-downloader', 'aria2c', '-o', path + videopath + ".mp4", '-f', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/mp4', '--write-info-json'], {}, function(err, output) { if (err) { videopath = "-1"; @@ -237,9 +253,10 @@ app.post('/tomp4', function(req, res) { throw err; } else if (output) { var completeString = "done"; - var videopathEncoded = encodeURIComponent(videopath); + var videopathEncoded = encodeURIComponent(file_names[0]); res.send({ - videopathEncoded: videopathEncoded + videopathEncoded: videopathEncoded, + file_names: is_playlist ? file_names : null }); res.end("yes"); } @@ -403,6 +420,7 @@ app.post('/deleteMp4', function(req, res) { app.post('/downloadFile', function(req, res) { let fileName = req.body.fileName; + let is_playlist = req.body.is_playlist; let type = req.body.type; let file = null; if (type === 'audio') { diff --git a/src/app/app.component.ts b/src/app/app.component.ts index f2b4e9b..3e1ba0e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -29,6 +29,9 @@ export class AppComponent implements OnInit { percentDownloaded: number; fileManagerEnabled = false; downloadOnlyMode = false; + baseStreamPath; + audioFolderPath; + videoFolderPath; mp3s: any[] = []; mp4s: any[] = []; @@ -45,6 +48,9 @@ export class AppComponent implements OnInit { this.topBarTitle = result['YoutubeDLMaterial']['Extra']['title_top']; this.fileManagerEnabled = result['YoutubeDLMaterial']['Extra']['file_manager_enabled']; this.downloadOnlyMode = result['YoutubeDLMaterial']['Extra']['download_only_mode']; + this.baseStreamPath = result['YoutubeDLMaterial']['Downloader']['path-base']; + this.audioFolderPath = result['YoutubeDLMaterial']['Downloader']['path-audio']; + this.videoFolderPath = result['YoutubeDLMaterial']['Downloader']['path-video']; this.postsService.path = backendUrl; this.postsService.startPath = backendUrl; @@ -83,9 +89,9 @@ export class AppComponent implements OnInit { public goToFile(name, isAudio) { if (isAudio) { - this.downloadHelperMp3(name, true); + this.downloadHelperMp3(name, false, true); } else { - this.downloadHelperMp4(name, true); + this.downloadHelperMp4(name, false, true); } } @@ -114,7 +120,8 @@ export class AppComponent implements OnInit { // download helpers - downloadHelperMp3(name: string, forceView = false) { + downloadHelperMp3(name, is_playlist = false, forceView = false) { + /* this.postsService.getFileStatusMp3(name).subscribe(fileExists => { const exists = fileExists; this.exists = exists[0]; @@ -125,35 +132,39 @@ export class AppComponent implements OnInit { this.determinateProgress = true; this.percentDownloaded = percent * 100; } - setTimeout(() => this.downloadHelperMp3(name), 500); + setTimeout(() => this.downloadHelperMp3(name, is_playlist, forceView), 500); } else { + */ this.downloadingfile = false; // if download only mode, just download the file. no redirect if (forceView === false && this.downloadOnlyMode && !this.iOS) { - this.postsService.downloadFileFromServer(name, 'audio').subscribe(res => { - const blob: Blob = res; - saveAs(blob, name + '.mp3'); - - // tell server to delete the file once downloaded - this.postsService.deleteFile(name, true).subscribe(delRes => { - - }); - }); + if (is_playlist) { + for (let i = 0; i < name.length; i++) { + this.downloadAudioFile(name[i]); + } + } else { + this.downloadAudioFile(name); + } } else { - window.location.href = this.exists; + if (is_playlist) { + window.location.href = this.baseStreamPath + this.audioFolderPath + name[0]; + } else { + window.location.href = this.baseStreamPath + this.audioFolderPath + name; + } } // reloads mp3s if (this.fileManagerEnabled) { this.getMp3s(); } - } - }); + /* } + });*/ } - downloadHelperMp4(name: string, forceView = false) { + downloadHelperMp4(name, is_playlist = false, forceView = false) { + /* this.postsService.getFileStatusMp4(name).subscribe(fileExists => { const exists = fileExists; this.exists = exists[0]; @@ -163,30 +174,36 @@ export class AppComponent implements OnInit { this.determinateProgress = true; this.percentDownloaded = percent * 100; } - setTimeout(() => this.downloadHelperMp4(name), 500); + setTimeout(() => this.downloadHelperMp4(name, is_playlist, forceView), 500); } else { + */ this.downloadingfile = false; // if download only mode, just download the file. no redirect if (forceView === false && this.downloadOnlyMode) { - this.postsService.downloadFileFromServer(name, 'video').subscribe(res => { - const blob: Blob = res; - saveAs(blob, name + '.mp4'); - - // tell server to delete the file once downloaded - this.postsService.deleteFile(name, false).subscribe(delRes => { - }); - }); + if (is_playlist) { + for (let i = 0; i < name.length; i++) { + this.downloadVideoFile(name[i]); + } + } else { + this.downloadVideoFile(name); + } } else { - window.location.href = this.exists; + if (is_playlist) { + window.location.href = this.baseStreamPath + this.videoFolderPath + name[0]; + } else { + window.location.href = this.baseStreamPath + this.videoFolderPath + name; + } } // reloads mp4s if (this.fileManagerEnabled) { this.getMp4s(); } + /* } }); + */ } @@ -199,9 +216,10 @@ export class AppComponent implements OnInit { if (this.audioOnly) { this.downloadingfile = true; this.postsService.makeMP3(this.url).subscribe(posts => { - this.path = posts['audiopathEncoded']; + const is_playlist = !!(posts['file_names']); + this.path = is_playlist ? posts['file_names'] : posts['audiopathEncoded']; if (this.path !== '-1') { - this.downloadHelperMp3(this.path); + this.downloadHelperMp3(this.path, is_playlist); } }, error => { // can't access server this.downloadingfile = false; @@ -210,9 +228,10 @@ export class AppComponent implements OnInit { } else { this.downloadingfile = true; this.postsService.makeMP4(this.url).subscribe(posts => { - this.path = posts['videopathEncoded']; + const is_playlist = !!(posts['file_names']); + this.path = is_playlist ? posts['file_names'] : posts['videopathEncoded']; if (this.path !== '-1') { - this.downloadHelperMp4(this.path); + this.downloadHelperMp4(this.path, is_playlist); } }, error => { // can't access server this.downloadingfile = false; @@ -224,6 +243,30 @@ export class AppComponent implements OnInit { } } + downloadAudioFile(name) { + this.postsService.downloadFileFromServer(name, 'audio').subscribe(res => { + const blob: Blob = res; + saveAs(blob, name + '.mp3'); + + // tell server to delete the file once downloaded + this.postsService.deleteFile(name, true).subscribe(delRes => { + + }); + }); + } + + downloadVideoFile(name) { + this.postsService.downloadFileFromServer(name, 'video').subscribe(res => { + const blob: Blob = res; + saveAs(blob, name + '.mp4'); + + // tell server to delete the file once downloaded + this.postsService.deleteFile(name, false).subscribe(delRes => { + + }); + }); + } + // checks if url is a valid URL ValidURL(str) { // tslint:disable-next-line: max-line-length