Compare commits

...

4 Commits

3 changed files with 66 additions and 18 deletions

View File

@@ -1229,7 +1229,7 @@ async function downloadFileByURL_exec(url, type, options, sessionID = null) {
const download = downloads[session][download_uid]; const download = downloads[session][download_uid];
updateDownloads(); updateDownloads();
youtubedl.exec(url, downloadConfig, {}, function(err, output) { youtubedl.exec(url, downloadConfig, {}, async function(err, output) {
download['downloading'] = false; download['downloading'] = false;
download['timestamp_end'] = Date.now(); download['timestamp_end'] = Date.now();
var file_uid = null; var file_uid = null;
@@ -1286,6 +1286,14 @@ async function downloadFileByURL_exec(url, type, options, sessionID = null) {
} }
let success = NodeID3.write(tags, output_json['_filename']); let success = NodeID3.write(tags, output_json['_filename']);
if (!success) logger.error('Failed to apply ID3 tag to audio file ' + output_json['_filename']); if (!success) logger.error('Failed to apply ID3 tag to audio file ' + output_json['_filename']);
} else {
const possible_webm_path = removeFileExtension(output_json['_filename']) + '.webm';
const possible_mkv_path = removeFileExtension(output_json['_filename']) + '.mkv';
const output_file_path = removeFileExtension(output_json['_filename']) + '.mp4';
// check if video file is not mp4
if (fs.existsSync(possible_webm_path)) await convertFileToMp4(possible_webm_path, output_file_path);
else if (fs.existsSync(possible_mkv_path)) await convertFileToMp4(possible_mkv_path, output_file_path);
} }
// registers file in DB // registers file in DB
@@ -1421,9 +1429,18 @@ async function downloadFileByURL_normal(url, type, options, sessionID = null) {
const possible_webm_path = removeFileExtension(video_info['_filename']) + '.webm'; const possible_webm_path = removeFileExtension(video_info['_filename']) + '.webm';
const possible_mp4_path = removeFileExtension(video_info['_filename']) + '.mp4'; const possible_mp4_path = removeFileExtension(video_info['_filename']) + '.mp4';
// check if audio file is webm const output_file_path = removeFileExtension(video_info['_filename']) + '.mp3';
if (fs.existsSync(possible_webm_path)) await convertFileToMp3(possible_webm_path, video_info['_filename']); // check if audio file is not mp3
else if (fs.existsSync(possible_mp4_path)) await convertFileToMp3(possible_mp4_path, video_info['_filename']); if (fs.existsSync(possible_webm_path)) await convertFileToMp3(possible_webm_path, output_file_path);
else if (fs.existsSync(possible_mp4_path)) await convertFileToMp3(possible_mp4_path, output_file_path);
} else {
const possible_webm_path = removeFileExtension(video_info['_filename']) + '.webm';
const possible_mkv_path = removeFileExtension(video_info['_filename']) + '.mkv';
const output_file_path = removeFileExtension(video_info['_filename']) + '.mp4';
// check if video file is not mp4
if (fs.existsSync(possible_webm_path)) await convertFileToMp4(possible_webm_path, output_file_path);
else if (fs.existsSync(possible_mkv_path)) await convertFileToMp4(possible_mkv_path, output_file_path);
} }
// registers file in DB // registers file in DB
@@ -1483,7 +1500,9 @@ async function generateArgs(url, type, options) {
var youtubePassword = options.youtubePassword; var youtubePassword = options.youtubePassword;
let downloadConfig = null; let downloadConfig = null;
let qualityPath = (is_audio && !options.skip_audio_args) ? '-f bestaudio' :'-f best[ext=mp4]';
let qualityPath = (is_audio && !options.skip_audio_args) ? '-f bestaudio' :'-f best';
const is_youtube = url.includes('youtu'); const is_youtube = url.includes('youtu');
if (!is_audio && !is_youtube) { if (!is_audio && !is_youtube) {
// tiktok videos fail when using the default format // tiktok videos fail when using the default format
@@ -1506,7 +1525,7 @@ async function generateArgs(url, type, options) {
if (customOutput) { if (customOutput) {
downloadConfig = ['-o', path.join(fileFolderPath, customOutput) + ".%(ext)s", '--write-info-json', '--print-json']; downloadConfig = ['-o', path.join(fileFolderPath, customOutput) + ".%(ext)s", '--write-info-json', '--print-json'];
} else { } else {
downloadConfig = ['-o', path.join(fileFolderPath, videopath + (is_audio ? '.%(ext)s' : '.mp4')), '--write-info-json', '--print-json']; downloadConfig = ['-o', path.join(fileFolderPath, videopath + '.%(ext)s'), qualityPath, '--write-info-json', '--print-json'];
} }
if (qualityPath) downloadConfig.push(qualityPath); if (qualityPath) downloadConfig.push(qualityPath);
@@ -1569,6 +1588,7 @@ async function generateArgs(url, type, options) {
} }
// downloadConfig.map((arg) => `"${arg}"`); // downloadConfig.map((arg) => `"${arg}"`);
logger.verbose(`Generated args: ${downloadConfig.toString()}`);
resolve(downloadConfig); resolve(downloadConfig);
}); });
} }
@@ -1617,6 +1637,23 @@ async function convertFileToMp3(input_file, output_file) {
}); });
} }
async function convertFileToMp4(input_file, output_file) {
logger.verbose(`Converting ${input_file} to ${output_file}...`);
return new Promise(resolve => {
ffmpeg(input_file).toFormat('mp4')
.on('end', () => {
logger.verbose(`Conversion for '${output_file}' complete.`);
fs.unlinkSync(input_file)
resolve(true);
})
.on('error', (err) => {
logger.error('Failed to convert video file to the correct format.');
logger.error(err);
resolve(false);
}).save(output_file);
});
}
function writeToBlacklist(type, line) { function writeToBlacklist(type, line) {
let blacklistPath = path.join(archivePath, (type === 'audio') ? 'blacklist_audio.txt' : 'blacklist_video.txt'); let blacklistPath = path.join(archivePath, (type === 'audio') ? 'blacklist_audio.txt' : 'blacklist_video.txt');
// adds newline to the beginning of the line // adds newline to the beginning of the line

View File

@@ -27,7 +27,7 @@
</mat-label> </mat-label>
<mat-select [ngModelOptions]="{standalone: true}" [(ngModel)]="selectedQuality"> <mat-select [ngModelOptions]="{standalone: true}" [(ngModel)]="selectedQuality">
<ng-container *ngFor="let option of qualityOptions[(audioOnly) ? 'audio' : 'video']"> <ng-container *ngFor="let option of qualityOptions[(audioOnly) ? 'audio' : 'video']">
<mat-option *ngIf="option.value === '' || url && cachedAvailableFormats[url] && cachedAvailableFormats[url]['formats'] && cachedAvailableFormats[url]['formats'][(audioOnly) ? 'audio' : 'video'][option.value]" [value]="option.value"> <mat-option *ngIf="option.value === '' || url && cachedAvailableFormats[url] && cachedAvailableFormats[url]['formats'] && cachedAvailableFormats[url]['formats'][(audioOnly) ? 'audio' : 'video'][option.note]" [value]="option.note">
{{option.label}} {{option.label}}
</mat-option> </mat-option>
</ng-container> </ng-container>

View File

@@ -108,47 +108,56 @@ export class MainComponent implements OnInit {
{ {
'resolution': null, 'resolution': null,
'value': '', 'value': '',
'label': 'Max' 'label': 'Max',
'note': ''
}, },
{ {
'resolution': '3840x2160', 'resolution': '3840x2160',
'value': '2160', 'value': '2160',
'label': '2160p (4K)' 'label': '2160p (4K)',
'note': '2160p'
}, },
{ {
'resolution': '2560x1440', 'resolution': '2560x1440',
'value': '1440', 'value': '1440',
'label': '1440p' 'label': '1440p',
'note': '1440p'
}, },
{ {
'resolution': '1920x1080', 'resolution': '1920x1080',
'value': '1080', 'value': '1080',
'label': '1080p' 'label': '1080p',
'note': '1080p'
}, },
{ {
'resolution': '1280x720', 'resolution': '1280x720',
'value': '720', 'value': '720',
'label': '720p' 'label': '720p',
'note': '720p'
}, },
{ {
'resolution': '720x480', 'resolution': '720x480',
'value': '480', 'value': '480',
'label': '480p' 'label': '480p',
'note': '480p'
}, },
{ {
'resolution': '480x360', 'resolution': '480x360',
'value': '360', 'value': '360',
'label': '360p' 'label': '360p',
'note': '360p'
}, },
{ {
'resolution': '360x240', 'resolution': '360x240',
'value': '240', 'value': '240',
'label': '240p' 'label': '240p',
'note': '240p'
}, },
{ {
'resolution': '256x144', 'resolution': '256x144',
'value': '144', 'value': '144',
'label': '144p' 'label': '144p',
'note': '144p'
} }
], ],
'audio': [ 'audio': [
@@ -1032,14 +1041,16 @@ export class MainComponent implements OnInit {
} else if (format_obj.type === 'video') { } else if (format_obj.type === 'video') {
// check if video format is mp4 // check if video format is mp4
const key = format.height.toString(); const key = format.height.toString();
if (format.ext === 'mp4') { if (true) {
format_obj['height'] = format.height; format_obj['height'] = format.height;
format_obj['acodec'] = format.acodec; format_obj['acodec'] = format.acodec;
format_obj['format_id'] = format.format_id; format_obj['format_id'] = format.format_id;
format_obj['ext'] = format.ext;
format_obj['note'] = format.format_note;
// no acodec means no overwrite // no acodec means no overwrite
if (!(video_formats[key]) || format_obj['acodec'] !== 'none') { if (!(video_formats[key]) || format_obj['acodec'] !== 'none') {
video_formats[key] = format_obj; video_formats[format_obj['note']] = format_obj;
} }
} }
} }