Merge pull request #145 from shirt-dev/ffmpeg

Use ffmpeg instead of pydub, support ogg stream copy
This commit is contained in:
Footsiefat 2021-10-27 08:12:09 +13:00 committed by GitHub
commit 494fd350d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 23 deletions

View File

@ -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

View File

@ -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,

View File

@ -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)