mirror of
https://github.com/THIS-IS-NOT-A-BACKUP/zspotify.git
synced 2024-11-29 19:24:34 +01:00
Use ffmpeg instead of pydub, support ogg stream copy
This commit is contained in:
parent
05e2cdda7d
commit
eba1ec11c7
@ -1,6 +1,6 @@
|
|||||||
|
ffmpy
|
||||||
git+https://github.com/kokarare1212/librespot-python
|
git+https://github.com/kokarare1212/librespot-python
|
||||||
music_tag
|
music_tag
|
||||||
pydub
|
|
||||||
Pillow
|
Pillow
|
||||||
tqdm
|
tabulate
|
||||||
tabulate
|
tqdm
|
@ -96,11 +96,34 @@ CHUNK_SIZE = 'CHUNK_SIZE'
|
|||||||
|
|
||||||
SPLIT_ALBUM_DISCS = 'SPLIT_ALBUM_DISCS'
|
SPLIT_ALBUM_DISCS = 'SPLIT_ALBUM_DISCS'
|
||||||
|
|
||||||
|
BITRATE = 'BITRATE'
|
||||||
|
|
||||||
|
CODEC_MAP = {
|
||||||
|
'aac': 'aac',
|
||||||
|
'fdk_aac': 'libfdk_aac',
|
||||||
|
'm4a': 'aac',
|
||||||
|
'mp3': 'libmp3lame',
|
||||||
|
'ogg': 'copy',
|
||||||
|
'opus': 'libopus',
|
||||||
|
'vorbis': 'copy',
|
||||||
|
}
|
||||||
|
|
||||||
|
EXT_MAP = {
|
||||||
|
'aac': 'm4a',
|
||||||
|
'fdk_aac': 'm4a',
|
||||||
|
'm4a': 'm4a',
|
||||||
|
'mp3': 'mp3',
|
||||||
|
'ogg': 'ogg',
|
||||||
|
'opus': 'ogg',
|
||||||
|
'vorbis': 'ogg',
|
||||||
|
}
|
||||||
|
|
||||||
CONFIG_DEFAULT_SETTINGS = {
|
CONFIG_DEFAULT_SETTINGS = {
|
||||||
'ROOT_PATH': '../ZSpotify Music/',
|
'ROOT_PATH': '../ZSpotify Music/',
|
||||||
'ROOT_PODCAST_PATH': '../ZSpotify Podcasts/',
|
'ROOT_PODCAST_PATH': '../ZSpotify Podcasts/',
|
||||||
'SKIP_EXISTING_FILES': True,
|
'SKIP_EXISTING_FILES': True,
|
||||||
'DOWNLOAD_FORMAT': 'mp3',
|
'DOWNLOAD_FORMAT': 'mp3',
|
||||||
|
'BITRATE': '160k',
|
||||||
'FORCE_PREMIUM': False,
|
'FORCE_PREMIUM': False,
|
||||||
'ANTI_BAN_WAIT_TIME': 1,
|
'ANTI_BAN_WAIT_TIME': 1,
|
||||||
'OVERRIDE_AUTO_WAIT': False,
|
'OVERRIDE_AUTO_WAIT': False,
|
||||||
|
@ -2,16 +2,14 @@ import os
|
|||||||
import time
|
import time
|
||||||
from typing import Any, Tuple, List
|
from typing import Any, Tuple, List
|
||||||
|
|
||||||
from librespot.audio.decoders import AudioQuality
|
|
||||||
from librespot.metadata import TrackId
|
from librespot.metadata import TrackId
|
||||||
from pydub import AudioSegment
|
from ffmpy import FFmpeg
|
||||||
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
|
SKIP_EXISTING_FILES, ANTI_BAN_WAIT_TIME, OVERRIDE_AUTO_WAIT, BITRATE, CODEC_MAP, EXT_MAP
|
||||||
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
|
||||||
MusicFormat
|
|
||||||
from zspotify import ZSpotify
|
from zspotify import ZSpotify
|
||||||
|
|
||||||
|
|
||||||
@ -72,7 +70,7 @@ def download_track(track_id: str, extra_paths='', prefix=False, prefix_value='',
|
|||||||
) else f'{prefix_value} - {song_name}'
|
) else f'{prefix_value} - {song_name}'
|
||||||
|
|
||||||
filename = os.path.join(
|
filename = os.path.join(
|
||||||
download_directory, f'{song_name}.{ZSpotify.get_config(DOWNLOAD_FORMAT)}')
|
download_directory, f'{song_name}.{EXT_MAP.get(ZSpotify.get_config(DOWNLOAD_FORMAT))}')
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print('### SKIPPING SONG - FAILED TO QUERY METADATA ###')
|
print('### SKIPPING SONG - FAILED TO QUERY METADATA ###')
|
||||||
@ -107,11 +105,10 @@ def download_track(track_id: str, extra_paths='', prefix=False, prefix_value='',
|
|||||||
p_bar.update(file.write(
|
p_bar.update(file.write(
|
||||||
stream.input_stream.stream().read(ZSpotify.get_config(CHUNK_SIZE))))
|
stream.input_stream.stream().read(ZSpotify.get_config(CHUNK_SIZE))))
|
||||||
|
|
||||||
if ZSpotify.get_config(DOWNLOAD_FORMAT) == 'mp3':
|
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):
|
||||||
time.sleep(ZSpotify.get_config(ANTI_BAN_WAIT_TIME))
|
time.sleep(ZSpotify.get_config(ANTI_BAN_WAIT_TIME))
|
||||||
@ -124,13 +121,22 @@ def download_track(track_id: str, extra_paths='', prefix=False, prefix_value='',
|
|||||||
|
|
||||||
|
|
||||||
def convert_audio_format(filename) -> None:
|
def convert_audio_format(filename) -> None:
|
||||||
""" Converts raw audio into playable mp3 """
|
""" Converts raw audio into playable file """
|
||||||
# print('### CONVERTING TO ' + MUSIC_FORMAT.upper() + ' ###')
|
temp_filename = f'{os.path.splitext(filename)[0]}.tmp'
|
||||||
raw_audio = AudioSegment.from_file(filename, format=MusicFormat.OGG.value,
|
os.replace(filename, temp_filename)
|
||||||
frame_rate=44100, channels=2, sample_width=2)
|
|
||||||
if ZSpotify.DOWNLOAD_QUALITY == AudioQuality.VERY_HIGH:
|
download_format = ZSpotify.get_config(DOWNLOAD_FORMAT)
|
||||||
bitrate = '320k'
|
file_codec = CODEC_MAP.get(download_format, "copy")
|
||||||
|
if file_codec != 'copy':
|
||||||
|
bitrate = ZSpotify.get_config(BITRATE)
|
||||||
else:
|
else:
|
||||||
bitrate = '160k'
|
bitrate = None
|
||||||
raw_audio.export(filename, format=ZSpotify.get_config(
|
|
||||||
DOWNLOAD_FORMAT), bitrate=bitrate)
|
ff_m = FFmpeg(
|
||||||
|
global_options=['-y', '-hide_banner', '-loglevel error'],
|
||||||
|
inputs={temp_filename: None},
|
||||||
|
outputs={filename: ['-c:a', file_codec] + ['-b:a', bitrate] if bitrate else []}
|
||||||
|
)
|
||||||
|
ff_m.run()
|
||||||
|
if os.path.exists(temp_filename):
|
||||||
|
os.remove(temp_filename)
|
||||||
|
Loading…
Reference in New Issue
Block a user