Alot of misc changes and fixes. Titles with a forward slash are now being corrected for insert in db.

This commit is contained in:
Maximilian Wagner 2023-08-05 15:46:27 +02:00
parent f6eb82ed6a
commit 306d3b6c88
10 changed files with 83 additions and 39 deletions

View File

@ -5,13 +5,12 @@ YouTube Media Library Server aims to make downloading and updating media librari
- Download of channels, playlists and videos in mp3 or mp4
- Download of processed files either individually or entire channels and playlists as a .zip
- Update of channels and playlists from the library
- Watching videos via an embed
# currently not supported
Having the same video in mp3 _and_ mp4 is not possible with how the download process and database work. This includes channels and playlists. The chosen type on initial download dictates what you have.
Deleting files will be added soon:tm:.
# media sources
Currently supported is YouTube but its possible expand since the download itself is handled by yt-dlp.

View File

@ -82,7 +82,10 @@ def process_download(url, ext, parent, query, current_thread):
try:
# this throws KeyError when downloading single file
for video in query['entries']:
if video is not None and check_already_exists(video['id']):
if video is None:
continue
if check_already_exists(video['id']):
add_new_video_to_collection(parent, video['id'])
continue
@ -91,11 +94,14 @@ def process_download(url, ext, parent, query, current_thread):
download=False)
# replace url with name of playlist
queued_downloads[0][0] = parent
queued_downloads[0][0] = parent.replace('/', '')
if max_video_length and video['duration'] > max_video_length:
continue
# add new entry to file_cache
ids.append(video['id'])
titles.append(video['title'])
titles.append(video['title'].replace('/', ''))
urls.append('https://www.youtube.com/watch?v=' + video['id'])
# start download
@ -113,18 +119,24 @@ def process_download(url, ext, parent, query, current_thread):
for tab in query['entries']:
# for every video in their respective tabs
for video in tab['entries']:
if video is not None and check_already_exists(video['id']):
if video is None:
continue
if check_already_exists(video['id']):
add_new_video_to_collection(parent, video['id'])
continue
# replace url with name of channel
queued_downloads[0][0] = parent
queued_downloads[0][0] = parent.replace('/', '')
if max_video_length and video['duration'] > max_video_length:
continue
# there have been cases of duplicate urls or some with '/watch?v=@channel_name'
# but no consistency has been observed
# still works though so will not be checked for now
ids.append(video['id'])
titles.append(video['title'])
titles.append(video['title'].replace('/', ''))
urls.append('https://www.youtube.com/watch?v=' + video['id'])
# start download
@ -141,11 +153,11 @@ def process_download(url, ext, parent, query, current_thread):
# when downloading single files that already exist, there's no need for adjustments in db
if not check_already_exists(query['id']):
ids.append(query['id'])
titles.append(query['title'])
titles.append(query['title'].replace('/', ''))
urls.append('https://www.youtube.com/watch?v=' + query['id'])
# replace url with name of video
queued_downloads[0][0] = query['title']
queued_downloads[0][0] = query['title'].replace('/', '')
# start download
download_all(url, ext=ext)
@ -167,6 +179,9 @@ def process_update(parent, query, current_thread):
try:
# this throws KeyError when downloading single file
for video in query['entries']:
if video is None:
continue
if check_already_exists(video['id']):
add_new_video_to_collection(parent, video['id'])
continue
@ -175,6 +190,9 @@ def process_update(parent, query, current_thread):
ydl.YoutubeDL({'quiet': True}).extract_info('https://www.youtube.com/watch?v=' + video['id'],
download=False)
if max_video_length and video['duration'] > max_video_length:
continue
# add new entry to file_cache
ids.append(video['id'])
titles.append(video['title'])
@ -195,10 +213,16 @@ def process_update(parent, query, current_thread):
for tab in query['entries']:
# for every video in their respective tabs
for video in tab['entries']:
if video is None:
continue
if check_already_exists(video['id']):
add_new_video_to_collection(parent, video['id'])
continue
if max_video_length and video['duration'] > max_video_length:
continue
# there have been cases of duplicate urls or some with '/watch?v=@channel_name'
# but no consistency has been observed
# still works though so will not be checked for now
@ -339,7 +363,7 @@ def yt_download(location, ext='mp3'):
# if videos are wanted, adjust the options
if ext == 'mp4':
opts['format'] = 'bestvideo[height<=1080]+bestaudio/best[height<=1080]'
opts.pop('format')
opts['merge_output_format'] = 'mp4'
opts.pop('postprocessors')
# try to download all new files
@ -455,3 +479,8 @@ def delete_file_or_playlist(file_name):
rmtree(downloads_path() + folder)
return
# checks if file is somewhere in downloads directory and returns true if so
def check_file_path(path):
downloads = downloads_path()
return downloads in os.path.abspath(downloads + path)

View File

@ -3,3 +3,4 @@ titles = []
urls = []
thread_queue = []
queued_downloads = []
max_video_length = 600

View File

@ -1,5 +1,7 @@
from __future__ import unicode_literals
import os.path
from flask import (
Blueprint,
request,
@ -14,7 +16,8 @@ from backend import (
zip_folder_not_in_directory,
enqueue_download,
internet_available,
delete_file_or_playlist
delete_file_or_playlist,
check_file_path
)
from forms.download import DownloadForm
from db_tools import query_db
@ -50,7 +53,7 @@ def downloader():
# if there has been a problem with the form (empty or error) or the link is not valid
if not form.validate_on_submit() or not valid_link:
valid_link = True if url == 'None' else False # if url is empty, don't show error
return render_template('downloader.html', form=form, ytLink=valid_link, amount=len(urls))
return render_template('downloader.html', form=form, amount=len(urls))
if not internet_available():
flash('No internet connection available.', 'danger')
@ -113,7 +116,6 @@ def download():
# else a directory is requested
else:
zip_path, zip_name = zip_folder(file_path)
print(zip_path, zip_name)
zip_folder_not_in_directory(zip_path + zip_name)
# zip and send
@ -155,23 +157,25 @@ def update():
# todo: add functionality to library
@frontend.route('/player', methods=['GET'])
def player():
return render_template('video-player.html')
return render_template('player.html', file=request.args.get('file'))
@frontend.route('/serve', methods=['GET'])
def serve():
file = request.args.get('file', None)
if 'audio' in file:
file = r'downloads\\CptCatman\\my vital organs all lift together.mp3'
file = request.args.get('file').replace('/', '').replace('\\', '')
if not check_file_path(file):
flash('Video not found', 'danger')
return render_template('flash-message.html')
if 'mp3' in file:
return send_file(
file,
downloads_path() + file,
'audio/mpeg',
True
)
else:
file = r'downloads\\Rick Astley - Never Gonna Give You Up (Official Music Video).webm'
elif 'mp4' in file:
return send_file(
file,
downloads_path() + file,
'video/webm',
True
)

View File

@ -1,9 +1,11 @@
from waitress import serve
from app import create_app
import file_cache
import os
PORT = 5000
MAX_VIDEO_DOWNLOAD_LENGTH_MINUTES = 10
os.chdir(os.path.dirname(os.path.abspath(__file__)))
file_cache.max_video_length = MAX_VIDEO_DOWNLOAD_LENGTH_MINUTES * 60
serve(create_app(), port=PORT)

View File

@ -15,7 +15,7 @@
<tbody>
{% for video in videos %}
<tr>
<td class="text-center">{{ video['name'] }}</td>
<td class="text-center"><a class="btn btn-link" href="/player?file={{ video['path'] + video['name'] + video['ext'] }}">{{ video['name'] }}</a></td>
<td class="text-center"><a class="btn btn-link" href="/download?file={{ video['path'] + video['name'] + video['ext'] }}" download>Download</a></td>
</tr>
{% endfor %}

View File

@ -16,7 +16,7 @@
<tbody>
{% for entry in running_downloads %}
<tr>
<td class="text-center"><a href="{{ entry[0] }}" target="_blank">{{ entry[0] }}</a></td>
<td class="text-center">{{ entry[0] }}</td>
<td class="text-center">{{ entry[1] }}</td>
</tr>
{% endfor %}
@ -33,7 +33,7 @@
<table class="table">
<thead>
<tr>
<th scope="col" class="text-center">Currently processing</th>
<th scope="col" class="text-center">New downloads in {{ running_downloads[0][0] }}</th>
</tr>
</thead>
<tbody>

View File

@ -43,7 +43,7 @@
{% for video in videos %}
{% if 'mp3' in video['ext'] %}
<tr>
<td class="text-center align-middle">{{ video['name'] }}</td>
<td class="text-center align-middle"><a class="btn btn-link" href="/player?file={{ video['path'] + video['name'] + video['ext'] }}">{{ video['name'] }}</a></td>
<td class="text-center align-middle"><a class="btn btn-link" href="/download?file={{ video['path'] + video['name'] + video['ext'] }}" download>Download</a></td>
<td class="text-center align-middle"><a class="btn btn-danger" href="/delete?file={{ video['path'] + video['name'] + video['ext'] }}&from=/library"> </a></td>
</tr>

21
templates/player.html Normal file
View File

@ -0,0 +1,21 @@
{%- extends "base.html" %}
{% block content %}
{{ super() }}
<div class="container-fluid">
{% if 'mp4' in file %}
<div class="section d-flex justify-content-center embed-responsive embed-responsive-16by9" style="padding: 1.5%">
<video class="embed-responsive-item" style="width: 100%; height: auto" controls>
<source src="serve?file={{ file }}" type="video/webm">
</video>
</div>
{% endif %}
{% if 'mp3' in file %}
<div class="section d-flex justify-content-center embed-responsive" style="padding: 1.5%">
<audio class="embed-responsive-item" controls>
<source src="serve?file={{ file }}" type="audio/mpeg">
</audio>
</div>
{% endif %}
</div>
{%- endblock %}

View File

@ -1,12 +0,0 @@
{%- extends "base.html" %}
{% block content %}
{{ super() }}
<div class="container-fluid">
<div id="trailer" class="section d-flex justify-content-center embed-responsive embed-responsive-16by9">
<video class="embed-responsive-item" style="width: 100%; padding: 1.5%; height: auto" controls>
<source src="serve?file=video" type="video/webm">
</video>
</div>
</div>
{%- endblock %}