Added realtime downloading for songs

This commit is contained in:
logykk 2021-10-27 22:49:21 +13:00
parent 8bab8a03c5
commit fe6f266b41
3 changed files with 33 additions and 8 deletions

View File

@ -2,5 +2,7 @@ ffmpy
git+https://github.com/kokarare1212/librespot-python git+https://github.com/kokarare1212/librespot-python
music_tag music_tag
Pillow Pillow
protobuf
pydub
tabulate tabulate
tqdm tqdm

View File

@ -96,6 +96,8 @@ CHUNK_SIZE = 'CHUNK_SIZE'
SPLIT_ALBUM_DISCS = 'SPLIT_ALBUM_DISCS' SPLIT_ALBUM_DISCS = 'SPLIT_ALBUM_DISCS'
DOWNLOAD_REAL_TIME = 'DOWNLOAD_REAL_TIME'
BITRATE = 'BITRATE' BITRATE = 'BITRATE'
CODEC_MAP = { CODEC_MAP = {
@ -127,5 +129,6 @@ CONFIG_DEFAULT_SETTINGS = {
'ANTI_BAN_WAIT_TIME': 1, 'ANTI_BAN_WAIT_TIME': 1,
'OVERRIDE_AUTO_WAIT': False, 'OVERRIDE_AUTO_WAIT': False,
'CHUNK_SIZE': 50000, 'CHUNK_SIZE': 50000,
'SPLIT_ALBUM_DISCS': False 'SPLIT_ALBUM_DISCS': False,
'DOWNLOAD_REAL_TIME': True
} }

View File

@ -5,11 +5,12 @@ from typing import Any, Tuple, List
from librespot.audio.decoders import AudioQuality from librespot.audio.decoders import AudioQuality
from librespot.metadata import TrackId from librespot.metadata import TrackId
from ffmpy import FFmpeg from ffmpy import FFmpeg
from pydub import AudioSegment
from tqdm import tqdm from tqdm import tqdm
from const import TRACKS, ALBUM, NAME, ITEMS, DISC_NUMBER, TRACK_NUMBER, IS_PLAYABLE, ARTISTS, IMAGES, URL, \ from const import TRACKS, ALBUM, NAME, ITEMS, DISC_NUMBER, TRACK_NUMBER, IS_PLAYABLE, ARTISTS, IMAGES, URL, \
RELEASE_DATE, ID, TRACKS_URL, SAVED_TRACKS_URL, SPLIT_ALBUM_DISCS, ROOT_PATH, DOWNLOAD_FORMAT, CHUNK_SIZE, \ RELEASE_DATE, ID, TRACKS_URL, SAVED_TRACKS_URL, SPLIT_ALBUM_DISCS, ROOT_PATH, DOWNLOAD_FORMAT, CHUNK_SIZE, \
SKIP_EXISTING_FILES, ANTI_BAN_WAIT_TIME, OVERRIDE_AUTO_WAIT, BITRATE, CODEC_MAP, EXT_MAP SKIP_EXISTING_FILES, ANTI_BAN_WAIT_TIME, OVERRIDE_AUTO_WAIT, BITRATE, CODEC_MAP, EXT_MAP, DOWNLOAD_REAL_TIME
from utils import sanitize_data, set_audio_tags, set_music_thumbnail, create_download_directory from utils import sanitize_data, set_audio_tags, set_music_thumbnail, create_download_directory
from zspotify import ZSpotify from zspotify import ZSpotify
@ -80,11 +81,11 @@ def download_track(track_id: str, extra_paths='', prefix=False, prefix_value='',
try: try:
if not is_playable: if not is_playable:
print('\n### SKIPPING:', song_name, print('\n### SKIPPING:', song_name,
'(SONG IS UNAVAILABLE) ###') '(SONG IS UNAVAILABLE) ###')
else: else:
if os.path.isfile(filename) and os.path.getsize(filename) and ZSpotify.get_config(SKIP_EXISTING_FILES): if os.path.isfile(filename) and os.path.getsize(filename) and ZSpotify.get_config(SKIP_EXISTING_FILES):
print('\n### SKIPPING:', song_name, print('\n### SKIPPING:', song_name,
'(SONG ALREADY EXISTS) ###') '(SONG ALREADY EXISTS) ###')
else: else:
if track_id != scraped_song_id: if track_id != scraped_song_id:
track_id = scraped_song_id track_id = scraped_song_id
@ -102,13 +103,20 @@ def download_track(track_id: str, extra_paths='', prefix=False, prefix_value='',
unit_divisor=1024, unit_divisor=1024,
disable=disable_progressbar disable=disable_progressbar
) as p_bar: ) as p_bar:
for _ in range(int(total_size / ZSpotify.get_config(CHUNK_SIZE)) + 1): for chunk in range(int(total_size / ZSpotify.get_config(CHUNK_SIZE)) + 1):
p_bar.update(file.write( data = stream.input_stream.stream().read(ZSpotify.get_config(CHUNK_SIZE))
stream.input_stream.stream().read(ZSpotify.get_config(CHUNK_SIZE)))) if data == b'':
break
p_bar.update(file.write(data))
if ZSpotify.get_config(DOWNLOAD_REAL_TIME):
if chunk == 0:
pause = get_segment_duration(p_bar)
if pause:
time.sleep(pause)
convert_audio_format(filename) convert_audio_format(filename)
set_audio_tags(filename, artists, name, album_name, set_audio_tags(filename, artists, name, album_name,
release_year, disc_number, track_number) release_year, disc_number, track_number)
set_music_thumbnail(filename, image_url) set_music_thumbnail(filename, image_url)
if not ZSpotify.get_config(OVERRIDE_AUTO_WAIT): if not ZSpotify.get_config(OVERRIDE_AUTO_WAIT):
@ -121,6 +129,18 @@ def download_track(track_id: str, extra_paths='', prefix=False, prefix_value='',
os.remove(filename) os.remove(filename)
def get_segment_duration(segment):
""" Returns playback duration of given audio segment """
sound = AudioSegment(
data = segment,
sample_width = 2,
frame_rate = 44100,
channels = 2
)
duration = len(sound) / 5000
return duration
def convert_audio_format(filename) -> None: def convert_audio_format(filename) -> None:
""" Converts raw audio into playable file """ """ Converts raw audio into playable file """
temp_filename = f'{os.path.splitext(filename)[0]}.tmp' temp_filename = f'{os.path.splitext(filename)[0]}.tmp'