19 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
3 changed files with 106 additions and 35 deletions
+13 -12
View File
@@ -1,22 +1,22 @@
# 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 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 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
Simply run:
Simply run...
```
flac2pod
flac2pod <source_dir> <destination_dir>
```
...and you will be prompted for your source and destination directories.
...to convert your library, or run...
```
flac2pod --help
```
...to see additional options.
In order for flac2pod to function, your source_dir must be structured as follows:
In order for flac2pod to function, your library must be structured as follows:
library parent 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
@@ -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 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
+92 -22
View File
@@ -2,8 +2,13 @@
# 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 subprocess import check_output, Popen
from sys import exit as s_exit
from time import sleep
# utility functions
@@ -34,30 +39,95 @@ def create_destination():
.mkdir(0o700, parents=True, exist_ok=True)
def scan_destination_convert_mp3():
def scan_destination_convert():
_i, _i_total, _total_files = 0, 0, len(source_directories[1])
for _file in source_directories[1]:
if not Path(f"{_file.replace(path.expanduser(source), path.expanduser(destination))}.mp3").is_file():
_file_s = _file.replace(' ', '\\ ').replace("'", "\\'") + '.flac'
_file_d = _file.replace(path.expanduser(source),
path.expanduser(destination)).replace(' ', '\\ ').replace("'", "\\'") + '.mp3'
print(f"\n\u001b[38;5;0;48;5;15mConverting {_file_s} to {_file_d}...\u001b[0m\n")
system(f"ffmpeg -i {_file_s} -c:v copy -ab 320k -map_metadata 0 -id3v2_version 3 {_file_d}")
rg2sc(_file_d)
_i_total += 1
_progress = round((_i_total / _total_files) * 100, 2)
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 rg2sc(_file):
system(f"rg2sc -f {_file}")
# argument parsing
if __name__ == "__main__":
parser = ArgumentParser(description='Convert your existing FLAC library to be played on an iPod Classic.')
parser.add_argument('source_dir', nargs='+',
help='directory tree containing music files - folder must contain library sorted into artists '
'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()
# program start sequence
if args.source_dir[0].endswith('/'):
source = args.source_dir[0][:-1]
else:
source = args.source_dir[0]
if args.destination_dir[0].endswith('/'):
destination = args.destination_dir[0][:-1]
else:
destination = args.destination_dir[0]
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()
scan_destination_convert_mp3()
source_directories = scan_source()
create_destination()
scan_destination_convert()
+1 -1
View File
@@ -39,7 +39,7 @@ pkgdesc='Converts your FLAC library to be iPod-ready'
url='https://github.com/rwinkhart/flac2pod'
arch=('any')
license=('GPL2')
depends=(python ffmpeg lame rg2sc)
depends=(python ffmpeg lame rg2sc screen python-mutagen)
source=(\""$source"\")
sha512sums=('"$sha512"')