25 Commits
Author SHA1 Message Date
RandyTheSilly b5a2b9adb3 Compatibility with new commits to rg2sc 2022-03-30 04:28:14 -04:00
RandyTheSilly 3c7ec3e921 Added python-mutagen as a dependency 2022-03-29 01:18:28 -04:00
RandyTheSilly 10973e3ac8 Added tag for transfering FLAC RG data to rg2sc for MP4s 2022-03-28 23:59:44 -04:00
RandyTheSilly c8ef53bc17 Add screen to dependencies 2022-03-28 22:35:28 -04:00
RandyTheSilly 144c3f53e0 Update README.md 2022-03-28 22:33:28 -04:00
RandyTheSilly 998c73c20f Overhauled argument system 2022-03-28 22:19:01 -04:00
RandyTheSilly df1dce38eb Rounded percentage counter 2022-03-28 21:28:47 -04:00
RandyTheSilly ed12cc5d23 AAC support 2022-03-28 21:26:56 -04:00
RandyTheSilly f72d3ac9b7 Basic compatibility with new commits to rg2sc 2022-03-28 21:00:42 -04:00
RandyTheSilly 95a8dacd29 Fix percentage counter not being multiplied properly 2022-03-27 19:05:16 -04:00
RandyTheSilly d64f4c56fa Still strip album art in ffmpeg before rg2sc pass 2022-03-27 17:23:09 -04:00
RandyTheSilly 137e30c80b Move APIC stripping to rg2sc 2022-03-27 16:31:20 -04:00
RandyTheSilly be5c96e182 Fixed inaccurate percentage counter 2022-03-26 21:24:44 -04:00
RandyTheSilly 7db318b561 Added percentage counter 2022-03-26 21:06:44 -04:00
RandyTheSilly dee1c3158f Multithreading support and TXXX stripping moved to rg2sc 2022-03-26 20:54:42 -04:00
RandyTheSilly d973a3f659 Simplified argument parser 2022-03-26 16:42:40 -04:00
RandyTheSilly d00e516e6c Strip TXXX tags from output files 2022-03-26 16:35:21 -04:00
RandyTheSilly ea485480c4 Added flag for stripping album art (for monochrome iPods) 2022-03-26 10:28:33 -04:00
RandyTheSilly b56dd7e5f5 Whitelisted more special characters 2022-03-26 07:04:39 -04:00
RandyTheSilly c321e4d856 Update README.md 2022-03-17 15:36:51 -04:00
RandyTheSilly 17df92256f Update README.md 2022-03-17 15:35:54 -04:00
RandyTheSilly 76e7beb27d Removed -f option, as it is irrelevant when converting from FLAC 2022-03-17 15:34:07 -04:00
RandyTheSilly b41698ab65 Filename handling fixes & rg2sc is now run after each file is converted 2022-03-17 15:23:45 -04:00
RandyTheSilly 94fa7570ec Fixed transcoding of songs with special characters 2022-03-16 20:38:59 -04:00
RandyTheSilly 9f9d69b1a3 Removed alac support, as it does not work with Sound Check 2022-03-16 19:23:27 -04:00
3 changed files with 105 additions and 55 deletions
+13 -12
View File
@@ -1,22 +1,22 @@
# flac2pod # flac2pod
Seamlessly converts your existing FLAC library to be played on an iPod Classic. Converts your existing FLAC library to be played on an iPod Classic.
This script makes use of ffmpeg to convert your existing FLAC music library to either MP3-320 or ALAC for easy iPod Classic use. It also takes advantage of "rg2sc" (https://github.com/rwinkhart/rg2sc) to convert any existing ReplayGain tags to Apple Sound Check tags that are compatible with Apple products. This script makes use of ffmpeg to convert your existing FLAC music library to AAC-256 or MP3-320 for easy iPod Classic use. It also takes advantage of "rg2sc" (https://github.com/rwinkhart/rg2sc) to convert any existing ReplayGain tags to Apple SoundCheck tags that are compatible with Apple products.
# Usage # Usage
Simply run...
``` ```
flac2pod -f --mp3 # will convert library to MP3-320 and forcefully update Sound Check tags (even if they already exist) flac2pod <source_dir> <destination_dir>
flac2pod --alac # will convert library to ALAC in a .m4a container - only updates missing Sound Check tags
flac2pod # will convert library to MP3-320 - only updates missing Sound Check tags
``` ```
...to convert your library, or run...
```
flac2pod --help
```
...to see additional options.
In order for flac2pod to function, your library must be structured as follows: In order for flac2pod to function, your source_dir must be structured as follows:
Library dir -> Artist dir -> Album dir -> FLAC files
When prompted for the source directory, you want to input your library parent directory. source_dir -> artist dir -> album dir -> FLAC files
# Installation # Installation
@@ -24,4 +24,5 @@ flac2pod is available in the AUR as "flac2pod". If installing on a non-Arch-base
- copy the flac2pod executable from https://github.com/rwinkhart/flac2pod/blob/master/bin/flac2pod to your /usr/bin/ - copy the flac2pod executable from https://github.com/rwinkhart/flac2pod/blob/master/bin/flac2pod to your /usr/bin/
- copy the rg2sc executable from https://github.com/rwinkhart/rg2sc/blob/master/bin/rg2sc to your /usr/bin - copy the rg2sc executable from https://github.com/rwinkhart/rg2sc/blob/master/bin/rg2sc to your /usr/bin
- install python-mutagen, ffmpeg, and lame - install python-mutagen, ffmpeg, lame, and screen
- start converting
+91 -42
View File
@@ -2,9 +2,13 @@
# external modules # external modules
from os import path, system, walk from argparse import ArgumentParser
from mutagen.flac import FLAC
from os import cpu_count, path, walk
from pathlib import Path from pathlib import Path
from sys import argv from subprocess import check_output, Popen
from sys import exit as s_exit
from time import sleep
# utility functions # utility functions
@@ -35,50 +39,95 @@ def create_destination():
.mkdir(0o700, parents=True, exist_ok=True) .mkdir(0o700, parents=True, exist_ok=True)
def scan_destination_convert_alac(): def scan_destination_convert():
_i, _i_total, _total_files = 0, 0, len(source_directories[1])
for _file in source_directories[1]: for _file in source_directories[1]:
if not Path(f"{_file.replace(path.expanduser(source), path.expanduser(destination))}.m4a").is_file(): _i_total += 1
system(f"ffmpeg -i '{_file}.flac' -c:v copy -c:a alac -map_metadata 0 -id3v2_version 3 " _progress = round((_i_total / _total_files) * 100, 2)
f"'{_file.replace(path.expanduser(source), path.expanduser(destination))}.m4a'") if not Path(f"{_file.replace(path.expanduser(source), path.expanduser(destination))}.mp3").is_file() and not \
Path(f"{_file.replace(path.expanduser(source), path.expanduser(destination))}.m4a").is_file():
_file_s = _file.replace(' ', '\\ ').replace("'", "\\'").replace(')', '\\)').replace('(', '\\(')\
.replace('&', '\\&').replace('`', '\\`').replace('$', '\\$') + '.flac'
if args.mp3:
_file_d = _file.replace(path.expanduser(source), path.expanduser(destination)).replace(' ', '\\ ') \
.replace("'", "\\'").replace(')', '\\)').replace('(', '\\(').replace('&', '\\&') \
.replace('`', '\\`').replace('$', '\\$') + '.mp3'
else:
_file_d = _file.replace(path.expanduser(source), path.expanduser(destination)).replace(' ', '\\ ') \
.replace("'", "\\'").replace(')', '\\)').replace('(', '\\(').replace('&', '\\&') \
.replace('`', '\\`').replace('$', '\\$') + '.m4a'
_active_processes = int(check_output('ps -C ffmpeg | wc -l', shell=True)) - 1
if _active_processes >= cpu_count():
while _active_processes >= cpu_count():
print(f"\nThere are already {cpu_count()} processes running...\n")
sleep(1)
_active_processes = int(check_output('ps -C ffmpeg | wc -l', shell=True)) - 1
_i += 1
print(f"\n{_progress}% | \u001b[38;5;0;48;5;15mConverting {_file_s} to {_file_d}...\u001b[0m\n")
if args.mp3:
if args.strip:
_cmd = f"screen -DmS flac2pod{_i} ffmpeg -i {_file_s} -map 0:a -ab 320k -map_metadata 0" \
f" -id3v2_version 3 {_file_d} </dev/null; rg2sc -f -s {_file_d}"
else:
_cmd = f"screen -DmS flac2pod{_i} ffmpeg -i {_file_s} -c:v copy -ab 320k -map_metadata 0" \
f" -id3v2_version 3 {_file_d} </dev/null; rg2sc -f {_file_d}"
else:
_audio = FLAC(f"{_file}.flac")
if _audio.get('replaygain_track_gain'):
_rggain = float(_audio.get('replaygain_track_gain')[0][:-3])
elif _audio.get('REPLAYGAIN_TRACK_GAIN'):
_rggain = float(_audio.get('REPLAYGAIN_TRACK_GAIN')[0][:-3])
else:
_rggain = None
if _audio.get('replaygain_track_peak'):
_rgpeak = float(_audio.get('replaygain_track_peak')[0])
elif _audio.get('REPLAYGAIN_TRACK_PEAK'):
_rgpeak = float(_audio.get('REPLAYGAIN_TRACK_PEAK')[0])
else:
_rgpeak = None
if args.strip:
_cmd = f"screen -DmS flac2pod{_i} ffmpeg -i {_file_s} -c:a aac -ab 256k -map_metadata 0 -metadata" \
f" comment='FLAC2PODRG#{_rggain}#{_rgpeak}#' -aac_pns 0 -movflags +faststart -vn" \
f" {_file_d} </dev/null; rg2sc -f -s {_file_d}"
else:
_cmd = f"screen -DmS flac2pod{_i} ffmpeg -i {_file_s} -c:a aac -ab 256k -c:v copy -map_metadata" \
f" 0 -metadata comment='FLAC2PODRG#{_rggain}#{_rgpeak}#' -aac_pns 0 -movflags +faststart" \
f" {_file_d} </dev/null; rg2sc -f {_file_d}"
Popen(_cmd, shell=True)
_active_processes = int(check_output('ps -C ffmpeg | wc -l', shell=True)) - 1
while _active_processes != 0:
print('\nPlease wait for the remaining conversions to complete...\n')
sleep(1)
_active_processes = int(check_output('ps -C ffmpeg | wc -l', shell=True)) - 1
sleep(1)
print('\niPod conversion complete!\n')
s_exit()
def scan_destination_convert_mp3(): # argument parsing
for _file in source_directories[1]: if __name__ == "__main__":
print(_file) parser = ArgumentParser(description='Convert your existing FLAC library to be played on an iPod Classic.')
if not Path(f"{_file.replace(path.expanduser(source), path.expanduser(destination))}.mp3").is_file(): parser.add_argument('source_dir', nargs='+',
system(f"ffmpeg -i '{_file}.flac' -c:v copy -ab 320k -map_metadata 0 -id3v2_version 3 " help='directory tree containing music files - folder must contain library sorted into artists '
f"'{_file.replace(path.expanduser(source), path.expanduser(destination))}.mp3'") 'and albums')
parser.add_argument('destination_dir', nargs='+',
help='destination parent directory for output - will be created if it does not already exist')
parser.add_argument('-s', '--strip', action='store_true',
help='strip all TXXX, APIC, and covr tags from the output files')
parser.add_argument('--mp3', action='store_true',
help='convert to MP3, as opposed to the default of AAC .M4A')
args = parser.parse_args()
def rg2sc(): if args.source_dir[0].endswith('/'):
if argument.__contains__('-f'): source = args.source_dir[0][:-1]
system(f"{rg2sc} -f {destination}")
else: else:
system(f"{rg2sc} {destination}") source = args.source_dir[0]
if args.destination_dir[0].endswith('/'):
destination = args.destination_dir[0][:-1]
else:
destination = args.destination_dir[0]
source_directories = scan_source()
# program start sequence create_destination()
scan_destination_convert()
# retrieve typed argument
argument_list = argv
i, argument = 0, ''
for _ in argument_list:
while i < len(argument_list) - 1:
i += 1
argument += argument_list[i] + ' '
argument = argument[:-1]
source = input('Source parent directory: ')
if source.endswith('/'):
source = source[:-1]
destination = input('Destination parent directory: ')
if destination.endswith('/'):
destination = destination[:-1]
source_directories = scan_source()
create_destination()
if argument.__contains__('--alac'):
scan_destination_convert_alac()
else:
scan_destination_convert_mp3()
rg2sc()
+1 -1
View File
@@ -39,7 +39,7 @@ pkgdesc='Converts your FLAC library to be iPod-ready'
url='https://github.com/rwinkhart/flac2pod' url='https://github.com/rwinkhart/flac2pod'
arch=('any') arch=('any')
license=('GPL2') license=('GPL2')
depends=(python ffmpeg lame rg2sc) depends=(python ffmpeg lame rg2sc screen python-mutagen)
source=(\""$source"\") source=(\""$source"\")
sha512sums=('"$sha512"') sha512sums=('"$sha512"')