145 lines
4.6 KiB
Python
145 lines
4.6 KiB
Python
import os
|
|
import sqlite3
|
|
import tinytag
|
|
import yt_dlp
|
|
from urllib.parse import urlparse
|
|
|
|
def initialize_database():
|
|
conn = sqlite3.connect('music.db')
|
|
c = conn.cursor()
|
|
c.execute('''CREATE TABLE IF NOT EXISTS music
|
|
(listmusicname TEXT, listvideoid TEXT, listprovider TEXT,
|
|
filelocation TEXT, fileartistname TEXT, filealbumname TEXT,
|
|
filemusictitle TEXT, fileduration REAL)''')
|
|
conn.commit()
|
|
conn.close()
|
|
|
|
def get_download_path():
|
|
locations = [
|
|
'/mnt/sdcard/Music',
|
|
'/storage/emulated/0/Music',
|
|
'/sdcard/Music',
|
|
os.path.join(os.environ.get('HOME', ''), 'Music'),
|
|
os.path.join(os.getcwd(), 'music')
|
|
]
|
|
for loc in locations:
|
|
if os.path.exists(loc):
|
|
return loc
|
|
default = os.path.join(os.environ['HOME'], 'Music') if 'HOME' in os.environ else os.path.join(os.getcwd(), 'music')
|
|
os.makedirs(default, exist_ok=True)
|
|
return default
|
|
|
|
def clean_url(url):
|
|
parsed = urlparse(url)
|
|
return parsed.netloc + parsed.path
|
|
|
|
def collect_entries():
|
|
entries = []
|
|
print("\nAdd new music (enter 'q' to quit)")
|
|
while True:
|
|
name = input("\nDisplay name: ").strip()
|
|
if name.lower() == 'q':
|
|
break
|
|
url = input("URL: ").strip()
|
|
fmt = input("Download format (e.g., bestaudio): ").strip()
|
|
|
|
if not all([name, url, fmt]):
|
|
print("Invalid input! All fields required.")
|
|
continue
|
|
|
|
entries.append(f"{name} --- {url} --- {fmt}")
|
|
|
|
if entries:
|
|
with open('other-providers.txt', 'a') as f:
|
|
f.write('\n'.join(entries) + '\n')
|
|
print("\nEntries saved to file!")
|
|
|
|
def process_downloads():
|
|
download_path = get_download_path()
|
|
conn = sqlite3.connect('music.db')
|
|
c = conn.cursor()
|
|
|
|
if not os.path.exists('other-providers.txt'):
|
|
print("No input file found!")
|
|
return
|
|
|
|
with open('other-providers.txt', 'r') as f:
|
|
lines = [line.strip() for line in f if line.strip() and not line.startswith('#')]
|
|
|
|
success_count = 0
|
|
errors = []
|
|
|
|
for idx, line in enumerate(lines, 1):
|
|
try:
|
|
parts = line.split(' --- ')
|
|
if len(parts) != 3:
|
|
raise ValueError("Invalid line format")
|
|
|
|
display_name, url, fmt = parts
|
|
print(f"\nProcessing ({idx}/{len(lines)}): {display_name}")
|
|
|
|
# Configure yt-dlp
|
|
ydl_opts = {
|
|
'format': fmt,
|
|
'outtmpl': '%(title)s.%(ext)s',
|
|
'writethumbnail': True,
|
|
'postprocessors': [
|
|
{'key': 'EmbedThumbnail'},
|
|
{'key': 'FFmpegMetadata'}
|
|
],
|
|
'quiet': True,
|
|
'nooverwrites': True,
|
|
'restrictfilenames': True
|
|
}
|
|
|
|
# Download and get filename
|
|
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
|
info = ydl.extract_info(url)
|
|
filename = ydl.prepare_filename(info)
|
|
final_path = os.path.join(download_path, os.path.basename(filename))
|
|
|
|
if os.path.exists(final_path):
|
|
print("File exists, skipping...")
|
|
continue
|
|
|
|
# Download and move file
|
|
ydl.download([url])
|
|
os.system(f'mv "{filename}" "{final_path}"')
|
|
|
|
# Extract metadata
|
|
tag = tinytag.TinyTag.get(final_path)
|
|
metadata = {
|
|
'artist': tag.artist or 'Unknown',
|
|
'album': tag.album or 'Music',
|
|
'title': tag.title or display_name,
|
|
'duration': tag.duration or 0
|
|
}
|
|
|
|
# Prepare database entry
|
|
cleaned_url = clean_url(url)
|
|
c.execute('''INSERT INTO music VALUES
|
|
(?,?,?,?,?,?,?,?)''',
|
|
(display_name, cleaned_url, 'other', final_path,
|
|
metadata['artist'], metadata['album'],
|
|
metadata['title'], int(metadata['duration'])))
|
|
conn.commit()
|
|
success_count += 1
|
|
|
|
except Exception as e:
|
|
errors.append((line, str(e)))
|
|
print(f"Error: {str(e)}")
|
|
continue
|
|
|
|
conn.close()
|
|
|
|
# Print summary
|
|
print(f"\nProcessing complete!\nSuccess: {success_count}\nErrors: {len(errors)}")
|
|
if errors:
|
|
print("\nError details:")
|
|
for error in errors:
|
|
print(f"- {error[0]}: {error[1]}")
|
|
|
|
if __name__ == "__main__":
|
|
initialize_database()
|
|
collect_entries()
|
|
process_downloads()
|