mirror of
https://github.com/arcctgx/ARver
synced 2025-06-04 14:33:46 +02:00
By default arver tries to match ARv2 checksum first, and if a match is found it never tries to match ARv1 checksum. This approach matches the reference implementation and works well for most CDs. However, there are some (often older) CDs in the database where ARv1 track checksums have higher confidence values than corresponding ARv2 checksums. Using ARv1 checksums may be preferred for these CDs. Add -1/--use-arv1 command-line option. When enabled, arver will not try to match ARv2 checksums and will only use ARv1. If ARv1 checksums don't exist in the database, verification will fail.
132 lines
4.4 KiB
Python
132 lines
4.4 KiB
Python
"""Verify rip correctness using AccurateRip database."""
|
|
|
|
import argparse
|
|
import sys
|
|
import textwrap
|
|
|
|
from arver.disc.info import DiscInfo, get_disc_info
|
|
from arver.rip.rip import Rip
|
|
from arver.version import version_string
|
|
|
|
|
|
def _parse_args():
|
|
parser = argparse.ArgumentParser(formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
description=textwrap.dedent("""\
|
|
Verify a set of audio tracks against checksums from AccurateRip database.
|
|
|
|
Disc TOC necessary for AccurateRip lookup is obtained either from reading a
|
|
physical CD in drive (the default behavior, recommended if the disc contains
|
|
data tracks), from MusicBrainz disc ID query, or is estimated from the lengths
|
|
of provided audio tracks.
|
|
|
|
Calculation of AccurateRip checksums requires correct track sequence, so the
|
|
files must be specified in the correct order. Pregap track (HTOA) must not be
|
|
included.
|
|
|
|
Disc ID calculation requires information about the length of track one pregap,
|
|
and of the data track, if they exist. This information cannot be derived from
|
|
a set of ripped files, so options for specifying lengths of these tracks are
|
|
available. They have no effect when the disc TOC is obtained from a physical
|
|
CD or from MusicBrainz disc ID query."""))
|
|
|
|
parser.add_argument('rip_files',
|
|
nargs='+',
|
|
metavar='file',
|
|
help='audio file for calculating checksums')
|
|
|
|
toc_source = parser.add_mutually_exclusive_group()
|
|
|
|
toc_source.add_argument('-d',
|
|
'--drive',
|
|
metavar='device_path',
|
|
help='read disc TOC from a CD in specified drive (e.g. /dev/sr0)')
|
|
|
|
toc_source.add_argument('-i',
|
|
'--disc-id',
|
|
metavar='disc_id',
|
|
help='get disc TOC from MusicBrainz by disc ID query')
|
|
|
|
toc_source.add_argument('-t',
|
|
'--track-lengths',
|
|
action='store_true',
|
|
help='derive disc TOC from the lengths of audio tracks')
|
|
|
|
parser.add_argument('-p',
|
|
'--permissive',
|
|
action='store_true',
|
|
help='ignore mismatched track lengths')
|
|
|
|
parser.add_argument('-x',
|
|
'--exclude',
|
|
action='append',
|
|
metavar='pattern',
|
|
help='file name pattern to exclude')
|
|
|
|
parser.add_argument('-1',
|
|
'--use-arv1',
|
|
action='store_true',
|
|
help='use only ARv1 checksums for verification')
|
|
|
|
parser.add_argument('-P',
|
|
'--pregap-length',
|
|
metavar='frames',
|
|
type=int,
|
|
default=0,
|
|
help='length of track one pregap in CDDA frames')
|
|
|
|
parser.add_argument('-D',
|
|
'--data-length',
|
|
metavar='frames',
|
|
type=int,
|
|
default=0,
|
|
help='length of Enhanced CD data track in CDDA frames')
|
|
|
|
parser.add_argument('-v', '--version', action='version', version=version_string())
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def main():
|
|
args = _parse_args()
|
|
|
|
rip = Rip(args.rip_files, args.exclude)
|
|
if len(rip) == 0:
|
|
print('No audio files were loaded. Did you specify correct files?')
|
|
sys.exit(1)
|
|
|
|
if args.track_lengths:
|
|
disc = DiscInfo.from_track_lengths(rip.track_frames(), args.pregap_length, args.data_length)
|
|
else:
|
|
disc = get_disc_info(args.drive, args.disc_id)
|
|
|
|
if disc is None:
|
|
print('Failed to get disc info, exiting.')
|
|
sys.exit(2)
|
|
|
|
print(disc)
|
|
print()
|
|
|
|
disc.fetch_accuraterip_data()
|
|
if disc.accuraterip_data is None:
|
|
print('Cannot verify, showing rip info instead.')
|
|
print()
|
|
print(rip.as_table())
|
|
sys.exit(3)
|
|
|
|
print(disc.accuraterip_data.summary())
|
|
print()
|
|
|
|
try:
|
|
verdict = rip.verify(disc, args.permissive, args.use_arv1)
|
|
except ValueError:
|
|
print("Audio files don't match CD TOC, exiting.")
|
|
sys.exit(4)
|
|
|
|
print()
|
|
print(verdict.as_table())
|
|
print()
|
|
print(verdict.summary())
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|