Вопрос или проблема
У меня есть полный альбом в формате FLAC и файл CUE для него. Как я могу разделить это на треки в формате FLAC?
Я пользователь KDE, поэтому я предпочёл бы способ с использованием KDE/Qt. Я бы также хотел увидеть ответы с командной строки и другие графические интерфейсы, но они не являются моим предпочтительным методом.
Shnsplit может читать файл CUE напрямую, что также означает, что он может получить доступ к другим данным из файла CUE (не только к контрольным точкам) и генерировать более красивые имена файлов, чем split-*.flac
:
shnsplit -f file.cue -t %n-%t -o flac file.flac
Конечно, это усложняет использование cuetag.sh, если оригинальный файл FLAC находится в той же директории.
Flacon — это интуитивный графический интерфейс с открытым исходным кодом, который делает именно это: разделяет FLAC с CUE.
Flacon извлекает отдельные треки из одного большого аудиофайла, содержащего весь альбом, и сохраняет их как отдельные аудиофайлы. Для этого он использует информацию из соответствующего файла CUE.
Он поддерживает, среди прочего:
Поддерживаемые форматы ввода: WAV, FLAC, APE, WavPack, True Audio (TTA).
Поддерживаемые форматы вывода: FLAC, WAV, WavPack, AAC, OGG или MP3.
Автоматическое определение кодировки для файлов CUE.
Чтобы использовать его, вам нужно просто открыть файл *.cue
с Flacon. Затем он автоматически обнаружит большой файл *.flac
(если нет, вы можете указать это вручную), затем вы должны выбрать формат вывода FLAC (и опционально настроить кодировщик) и начать процесс конвертации.
Я знаю только способ через командную строку. Вам понадобятся cuetools и shntool.
cuebreakpoints file.cue | shnsplit -o flac file.flac
cuetag.sh file.cue "split-*".flac
если используются файлы высокого качества, shnsplit с удовольствием выдает ошибку с
shnsplit: error: формат m:ss.ff может быть использован только с файлами
с качеством CD
к счастью, бинарный файл flac поддерживает –skip=mm:ss.ss и –until=mm:ss.ss, так что скрипт может использовать cuebreakpoints следующим образом:
[..]
time[0]="00:00.00"
c=1
for ts in $(cuebreakpoints "${cue_file}"); do
time[${c}]=${ts}
c=$((c+1))
done
time[${c}]='-0'
for ((i=0;i<$((${#time[@]}-1));i++)); do
trackno=$(($i+1))
TRACKNUMBER="$(printf %02d ${trackno})"
title="$(cueprint --track-number ${trackno} -t '%t' "${cue_file}")"
flac --silent --exhaustive-model-search --skip=${time[$i]} --until=${time[$(($i+1))]} --tag=ARTIST="${ARTIST}" --tag=ALBUM="${ALBUM}" --tag=DATE="${DATE}" --tag=TITLE="${title}" --tag=TRACKNUMBER="${TRACKNUMBER}" "${aud_file}" --output-name="${TRACKNUMBER}-${title}.flac"
done
Если у вас установлен к параметрам типа файла k3b
, k3b
автоматически разделит файл, если вы откроете файл CUE и позволит вам повторно рипнуть.
Вот PHP-скрипт:
<?php
$s_cue = $argv[1];
$a_cue = file($s_cue);
$n_row = -1;
foreach ($a_cue as $s_row) {
$s_trim = trim($s_row);
$a_row = str_getcsv($s_trim, ' ');
if (preg_match('/^FILE\s/', $s_row) == 1) {
$s_file = $a_row[1];
}
if (preg_match('/^\s+TRACK\s/', $s_row) == 1) {
$n_row++;
$a_table[$n_row]['track'] = $a_row[1];
}
if (preg_match('/^\s+TITLE\s/', $s_row) == 1) {
$a_table[$n_row]['title'] = $a_row[1];
}
if (preg_match('/^\s+PERFORMER\s/', $s_row) == 1) {
$a_table[$n_row]['artist'] = $a_row[1];
}
if (preg_match('/^\s+INDEX\s/', $s_row) == 1) {
$s_dur = $a_row[2];
$a_frame = sscanf($s_dur, '%d:%d:%d', $n_min, $n_sec, $n_fra);
$n_index = $n_min * 60 + $n_sec + $n_fra / 75;
$a_table[$n_row]['ss'] = $n_index;
if ($n_row > 0) {
$a_table[$n_row - 1]['to'] = $n_index;
}
}
}
$a_table[$n_row]['to'] = 10 * 60 * 60;
foreach ($a_table as $m_row) {
$a_cmd = [
'ffmpeg',
'-i', $s_file,
'-ss', $m_row['ss'],
'-to', $m_row['to'],
'-metadata', 'artist=" . $m_row["artist"],
'-metadata', 'title=" . $m_row["title"],
'-metadata', 'track=' . $m_row['track'],
$m_row['track'] . ' ' . $m_row['title'] . '.m4a'
];
$a_esc = array_map('escapeshellarg', $a_cmd);
$s_esc = implode(' ', $a_esc);
system($s_esc);
}
Существует проект, который работает с несколькими входными файлами: split2flac
Из описания проекта:
split2flac разделяет один большой аудиообраз APE/FLAC/TTA/WV/WAV (или
коллекцию таких файлов, рекурсивно) с CUE-листом на
треки FLAC/M4A/MP3/OGG_VORBIS/WAV с тегированием, переименованием,
конвертацией кодировки CUE-листа, изображениями обложек альбомов. Он также использует
конфигурационный файл, так что нет необходимости передавать много аргументов каждый раз,
только входной файл. Должен работать в любой POSIX-совместимой оболочке.
unflac автоматически разделяет на flac
и также правильно выполняет тегирование!
Вам нужно установить go
, а затем запустить его, указав cue
в качестве входного: ~/go/bin/unflac filename.cue
.
Я узнал об этом после того, как файлы, которые я разделил с другими инструментами, не воспроизводились.
Я обнаружил, что mac
(что является командой, которую shntool
использовал для декодирования APE-файлов) гораздо менее терпим к незначительным ошибкам в исходном файле, чем ffmpeg
.
Обычно ffmpeg
по-прежнему полностью конвертирует файл, в то время как mac
, скорее всего, выдаст ошибку во время обработки.
Поэтому я в конечном итоге написал скрипт для разделения APE-файла, разбирая файл CUE и конвертируя APE в файлов FLAC, отделенных по заголовкам, с использованием ffmpeg:
#!/usr/bin/env python2.7
import subprocess as subp
import sys
import os
from os.path import splitext, basename
import random
import glob
records = []
filename = ""
album=''
alb_artist=""
codec="flac"
ffmpeg_exec="ffmpeg"
encodingList = ('utf-8','euc-kr', 'shift-jis', 'cp936', 'big5')
filecontent = open(sys.argv[1]).read()
for enc in encodingList:
try:
lines = filecontent.decode(enc).split('\n')
encoding = enc
break
except UnicodeDecodeError as e:
if enc == encodingList[-1]:
raise e
else:
pass
for l in lines:
a = l.split()
if not a:
continue
if a[0] == "FILE":
filename=" ".join(a[1:-1]).strip('\'"')
elif a[0]=='TRACK':
records.append({})
records[-1]['index'] = a[1]
elif a[0]=='TITLE':
if len(records)>0:
records[-1]['title'] = ' '.join(a[1:]).strip('\'"')
else:
album = ' '.join(a[1:]).strip('\'"')
elif a[0]=='INDEX' and a[1]=='01':
timea = a[2].split(':')
if len(timea) == 3 and int(timea[0]) >= 60:
timea.insert(0, str(int(timea[0])/60))
timea[1] = str(int(timea[1])%60)
times="{0}.{1}".format(':'.join(timea[:-1]), timea[-1])
records[-1]['start'] = times
elif a[0]=='PERFORMER':
if len(records)>1:
records[-1]['artist'] = ' '.join(a[1:]).strip('\'"')
else:
alb_artist=" ".join(a[1:]).strip('\'"')
for i, j in enumerate(records):
try:
j['stop'] = records[i+1]['start']
except IndexError:
pass
if not os.path.isfile(filename):
tmpname = splitext(basename(sys.argv[1]))[0]+splitext(filename)[1]
if os.path.exists(tmpname):
filename = tmpname
del tmpname
else:
for ext in ('.ape', '.flac', '.wav', '.mp3'):
tmpname = splitext(filename)[0] + ext
if os.path.exists(tmpname):
filename = tmpname
break
if not os.path.isfile(filename):
raise IOError("Не удается найти файл: {0}".format(filename))
fstat = os.stat(filename)
atime = fstat.st_atime
mtime = fstat.st_mtime
records[-1]['stop'] = '99:59:59'
if filename.lower().endswith('.flac'):
tmpfile = filename
else:
tmpfile = splitext(filename)[0] + str(random.randint(10000,90000)) + '.flac'
try:
if filename != tmpfile:
ret = subp.call([ffmpeg_exec, '-hide_banner', '-y', '-i', filename,
'-c:a', codec,'-compression_level','12','-f','flac',tmpfile])
if ret != 0:
raise SystemExit('Конвертация не удалась.')
for i in records:
output = i['index'] +' - '+ i['title']+'.flac'
commandline = [ffmpeg_exec, '-hide_banner',
'-y', '-i', tmpfile,
'-c', 'copy',
'-ss', i['start'], '-to', i['stop'],
'-metadata', u'title={0}'.format(i['title']),
'-metadata', u'artist={0}'.format(i.get('artist', '')),
'-metadata', u'performer={0}'.format(i.get('artist', '')),
'-metadata', u'album={0}'.format(album),
'-metadata', 'track={0}/{1}'.format(i['index'], len(records)),
'-metadata', u'album_artist={0}'.format(alb_artist),
'-metadata', u'composer={0}'.format(alb_artist),
'-metadata', 'encoder=Meow',
'-write_id3v1', '1',
output]
ret = subp.call(commandline)
if ret == 0:
os.utime(output, (atime, mtime))
finally:
if os.path.isfile(tmpfile):
os.remove(tmpfile)
shntool
на Ubuntu 14.04
shntool
отсутствует зависимость исполняемого файла mac
(Monkey’s Audio Console), и единственный пакет, который я смог найти, находился в PPA flacon
:
sudo add-apt-repository -y ppa:flacon
sudo apt-get update
sudo apt-get install -y flacon shntool
shntool split -f *.cue -o flac -t '%n - %p - %t' *.ape
flacon
— это графический интерфейс для shntool
, но он поставляется со всеми необходимыми ему кодеками… иначе я получал ошибку:
shnsplit: warning: не удалось прочитать данные из входного файла, используя формат: [ape]
shnsplit: + возможно, у вас нет разрешения на чтение файла: [example.ape]
shnsplit: + аргументы могут быть неверными для декодера: [mac]
shnsplit: + проверьте, что декодер установлен и в вашем PATH
shnsplit: + этот файл может быть неподдерживаемым, усеченным или поврежденным
shnsplit: error: не удается продолжить из-за вышеуказанных ошибок
Foobar2000 доступен в виде snap, так что мы можем добавить его в список решений. Это работает как для разделения существующего flac, так и для разделения другого безпотерянутого файла и сохранения в flac.
Ответ или решение
Чтобы разделить файл FLAC на отдельные треки с использованием файла CUE, существует множество методов, включая как графические интерфейсы, так и командные строки. В данном ответе подробно рассмотрим несколько подходов, подходящих для пользователей KDE, а также другие доступные решения.
Использование графических интерфейсов
-
Flacon:
Flacon — это простой в использовании графический интерфейс, специальное приложение для извлечения отдельных треков из больших аудиофайлов, таких как FLAC, используя информацию из CUE-файла.- Установка: Для установки Flacon в Ubuntu:
sudo add-apt-repository ppa:flacon sudo apt-get update sudo apt-get install flacon
- Использование: Откройте файл CUE с помощью Flacon. Программа автоматически обнаружит связанный файл FLAC. Выберите формат вывода (например, FLAC) и нажмите на кнопку для начала процесса.
- Установка: Для установки Flacon в Ubuntu:
-
K3b:
Если вы используете K3b, вы можете автоматически разделить файл. Просто откройте CUE-файл в K3b, и программа предложит вам возможность перерипать аудиотрек с разделением на треки.
Использование командной строки
-
shnsplit и cuetools:
Эти инструменты позволяют разбивать файлы CUE напрямую:shnsplit -f file.cue -t %n-%t -o flac file.flac
Первый параметр указывает на CUE-файл, а
-t %n-%t
используется для задания формата именования выходных файлов (номер трека и его название).Если высшее качество файлов, возможно, придется обрабатывать их с помощью
flac
с опциями--skip
и--until
:cuebreakpoints file.cue | shnsplit -o flac file.flac cuetag.sh file.cue "split-*".flac
-
Использование ffmpeg через скрипт:
Можно также написать Bash или Python-скрипт, использующийffmpeg
для более гибкого разделения:#!/bin/bash cue_file="yourfile.cue" flac_file="yourfile.flac" time[0]="00:00.00" c=1 for ts in $(cuebreakpoints "${cue_file}"); do time[${c}]=${ts} c=$((c+1)) done time[${c}]='-0' for ((i=0;i<$((${#time[@]}-1));i++)); do trackno=$(($i+1)) title="$(cueprint --track-number ${trackno} -t '%t' "${cue_file}")" flac --silent --skip=${time[$i]} --until=${time[$(($i+1))]} --tag=ARTIST="${ARTIST}" --tag=ALBUM="${ALBUM}" --tag=DATE="${DATE}" --tag=TITLE="${title}" --tag=TRACKNUMBER=${trackno} "${flac_file}" --output-name="${trackno}-${title}.flac" done
-
split2flac:
Еще одно отличное решение для разделения файлов:git clone https://github.com/ftrvxmtrx/split2flac.git cd split2flac ./split2flac.sh yourfile.cue
Использование unflac
Так же существует проект unflac
, который позволяет автоматически разделять файлы FLAC, также осуществляя оформление тегов.
Установка:
go get -u github.com/ftrvxmtrx/unflac
Используйте команду:
~/go/bin/unflac filename.cue
Заключение
Выбор метода зависит от ваших предпочтений — используете ли вы графические интерфейсы или предпочитаете командную строку. Как графическое, так и командное решение могут быть эффективными для разделения аудиофайлов с CUE. Flacon и K3b обеспечивают наилучший опыт для пользователей с графическим интерфейсом, в то время как shnsplit, ffmpeg и unflac предоставляют мощные инструменты для технических пользователей.
Если у вас возникнут дополнительные вопросы или вам потребуется помощь, не стесняйтесь обращаться для консультаций!