def transcode(flac_file, output_dir, output_format):
'''
Transcodes a FLAC file into another format.
'''
# gather metadata from the flac file
flac_info = mutagen.flac.FLAC(flac_file)
sample_rate = flac_info.info.sample_rate
bits_per_sample = flac_info.info.bits_per_sample
resample = sample_rate > 48000 or bits_per_sample > 16
# if resampling isn't needed then needed_sample_rate will not be used.
needed_sample_rate = resample_rate(os.path.dirname(flac_file))
if resample and needed_sample_rate is None:
raise UnknownSampleRateException(
'FLAC file "{0}" has a sample rate {1}, which is not 88.2,',
'176.4, or 96kHz, but needs resampling. This is unsupported.'.format(flac_file, sample_rate)
)
if flac_info.info.channels > 2:
raise TranscodeDownmixException('FLAC file "%s" has more than 2 channels, unsupported' % flac_file)
# determine the new filename
transcode_basename = os.path.splitext(os.path.basename(flac_file))[0]
transcode_basename = re.sub(r'[\?<>\\*\|"]', '_', transcode_basename)
transcode_file = os.path.join(output_dir, transcode_basename)
transcode_file += ENCODERS[output_format]['ext']
if not os.path.exists(os.path.dirname(transcode_file)):
try:
os.makedirs(os.path.dirname(transcode_file))
except OSError as e:
if e.errno == errno.EEXIST:
# Harmless race condition -- another transcode process
# beat us here.
pass
else:
raise e
commands = transcode_commands(output_format, resample, needed_sample_rate, flac_file, transcode_file)
results = run_pipeline(commands)
# Check for problems. Because it's a pipeline, the earliest one is
# usually the source. The exception is -SIGPIPE, which is caused
# by "backpressure" due to a later command failing: ignore those
# unless no other problem is found.
last_sigpipe = None
for (cmd, (code, stderr)) in zip(commands, results):
if code:
if code == -signal.SIGPIPE:
last_sigpipe = (cmd, (code, stderr))
else:
raise TranscodeException('Transcode of file "%s" failed: %s' % (flac_file, stderr))
if last_sigpipe:
# XXX: this should probably never happen....
raise TranscodeException('Transcode of file "%s" failed: SIGPIPE' % flac_file)
return transcode_file
评论列表
文章目录