Use ffmpeg instead of pydub, support ogg stream copy

This commit is contained in:
shirt 2021-10-26 15:06:17 -04:00
parent 05e2cdda7d
commit eba1ec11c7
No known key found for this signature in database
GPG Key ID: 89EC2E5F699F79E6
3 changed files with 52 additions and 23 deletions

View File

@ -1,6 +1,6 @@
ffmpy
git+https://github.com/kokarare1212/librespot-python
music_tag
pydub
Pillow
tqdm
tabulate
tabulate
tqdm

View File

@ -96,11 +96,34 @@ CHUNK_SIZE = 'CHUNK_SIZE'
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 = {
'ROOT_PATH': '../ZSpotify Music/',
'ROOT_PODCAST_PATH': '../ZSpotify Podcasts/',
'SKIP_EXISTING_FILES': True,
'DOWNLOAD_FORMAT': 'mp3',
'BITRATE': '160k',
'FORCE_PREMIUM': False,
'ANTI_BAN_WAIT_TIME': 1,
'OVERRIDE_AUTO_WAIT': False,

View File

@ -2,16 +2,14 @@ import os
import time
from typing import Any, Tuple, List
from librespot.audio.decoders import AudioQuality
from librespot.metadata import TrackId
from pydub import AudioSegment
from ffmpy import FFmpeg
from tqdm import tqdm
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, \
SKIP_EXISTING_FILES, ANTI_BAN_WAIT_TIME, OVERRIDE_AUTO_WAIT
from utils import sanitize_data, set_audio_tags, set_music_thumbnail, create_download_directory, \
MusicFormat
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 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}'
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:
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(
stream.input_stream.stream().read(ZSpotify.get_config(CHUNK_SIZE))))
if ZSpotify.get_config(DOWNLOAD_FORMAT) == 'mp3':
convert_audio_format(filename)
set_audio_tags(filename, artists, name, album_name,
release_year, disc_number, track_number)
set_music_thumbnail(filename, image_url)
convert_audio_format(filename)
set_audio_tags(filename, artists, name, album_name,
release_year, disc_number, track_number)
set_music_thumbnail(filename, image_url)
if not ZSpotify.get_config(OVERRIDE_AUTO_WAIT):
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:
""" Converts raw audio into playable mp3 """
# print('### CONVERTING TO ' + MUSIC_FORMAT.upper() + ' ###')
raw_audio = AudioSegment.from_file(filename, format=MusicFormat.OGG.value,
frame_rate=44100, channels=2, sample_width=2)
if ZSpotify.DOWNLOAD_QUALITY == AudioQuality.VERY_HIGH:
bitrate = '320k'
""" Converts raw audio into playable file """
temp_filename = f'{os.path.splitext(filename)[0]}.tmp'
os.replace(filename, temp_filename)
download_format = ZSpotify.get_config(DOWNLOAD_FORMAT)
file_codec = CODEC_MAP.get(download_format, "copy")
if file_codec != 'copy':
bitrate = ZSpotify.get_config(BITRATE)
else:
bitrate = '160k'
raw_audio.export(filename, format=ZSpotify.get_config(
DOWNLOAD_FORMAT), bitrate=bitrate)
bitrate = None
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)