10 февр. 2021 г.

Audacity+Chapters

Утверждалось, что Audacity не умеет делать звуковые файлы с главами (chapters). Оказалось, это возможно, хотя и с бубнами. Более того, этот подход можно использовать для своих целей.

Делаю авторское переизложение англоязычной заметки. А также, привожу свое решение на том же подходе.

Счастье состоит из 3-х фаз:

  1. Установки на Audacity plug-in (однократно)
  2. Выгрузки с помощью plug-in текстового файла с разметкой глав
  3. Скрещивания исходного звукового файла с файлом разметки в командной строке ffmpeg

Я не стал реализовывать этот алгоритм полностью, но, из уважения к первоисточнику, в конце текста командная строка с ffmpeg честно описана. Зато идея с plug-in получила авторское развитие. ffmpeg я поленился устанавливать, а по умолчанию он на Мак не устанавливается.

Хронологически, сначала я поставил описанный в статье plug-in и с его помощью выгрузил метаданные – полет нормальный. Потом переделал plug-in для вывода метаданных в формате, который может импортировать mChapters — я его использую для разметки глав звукового файла. Исходный формат выгрузки из Audacity можно переделать вручную под mChapters, но удобнее свой plug-in.

Здесь описание не только исходного варианта, но и моего для импорта в mChapters — он приведен ниже.

Установка plug-in

Plug-in представляет собой текстовый файл с расширением «.ny». Содержимое приведено в конце этого текста. Его достаточно сохранить в простом текстовом редакторе, например BBEdit, а потом подсунуть Audacity.

Описание процедуры установки plug-in:

  1. Открыть Audacity
  2. Выбрать в меню "Tools" -> "Nyquist Plug-in Installer..."
  3. В окне выбора файла указать на тот, который сделали «.ny»
  4. В меню "Tools" -> "Add / Remove Plug-ins..." найти его в списке plug-in и сделать «enable»

В результате в меню Tools появится пункт «Labels to Chapters» (мой называется «Labels for mChapters»).

Использование plug-in

Если теперь средствами Audacity разметить звуковой файл метками (Labels), то при запуске этого plug-in появится окно с полями метаданных и возможностью сохранить файл с ними. Дальше предполагается, что итоговый файл с метаданными назвали «metadata.txt».

Стоит обратить внимание на то, что этот plug-in русские буквы в названии глав (в файле метаданных) заменяет знаком подчеркивания.

Командная строка для ffmpeg

Остается его скрестить со звуковым файлом. На Маке это делается в командной строке приложения Terminal:

ffmpeg -i audio.mp3 -i metadata.txt -map_metadata 1 -codec copy -id3v2_version 3 -write_id3v1 1 audio-with-chapters.mp3

Только надо не забыть правильно указать имена файлов и пути к ним:

  • исходного звукового «audio.mp3»,
  • итогового «audio-with-chapters.mp3»
  • с метаданными «metadata.txt»

Plug-in для ffmpeg

;nyquist plug-in
;version 4
;type tool
;codetype lisp
;name "Labels to Chapters"
;author "Steve Daulton"
;release 2.3.2
;copyright "Released under terms of the GNU General Public License version 2"

;control timebase "Time base" int "" 1000 100 2000
;control title "Title" string "" ""
;control encodedby "Encoded by" string "" ""
;control artist "Artist" string "" ""
;control date "Date" string "" "2020"
;control filename "Save file as" file "" "*default*/metadata.txt" "Text file|*.txt;*.TXT|All files|*.*;*" "save,overwrite"


(setf metadata
  (format nil ";FFMETADATA1~%~
              title=~a~%~
              encoded_by=~a~%~
              artist=~a~%~
              date=~a~%~
              encoder=Lavf58.27.103~%"
              title
              encodedby
              artist
              date))

;;  Get label data from first label track
(setf labels (second (first (aud-get-info "Labels"))))


(dolist (label labels)
  (setf chapter
    (format nil "[CHAPTER]~%~
                TIMEBASE=1/~a~%~
                START=~a~%~
                END=~a~%~
                title=~a~%"
                timebase
                (round (* timebase (first label)))
                (round (* timebase (second label)))
                (third label)))
  (string-append metadata chapter))


(setf fp (open filename :direction :output))
(format fp metadata)
(close fp)
(format nil "File written to~%~a" filename)

Plug-in для mChapters

;nyquist plug-in
;version 4
;type tool
;codetype lisp
;name "Labels for mChapters"
;author "Michael Kushnir from Steve Daulton"
;release 2.3.2
;copyright "Released under terms of the GNU General Public License version 2"

;control filename "Save file as" file "" "*default*/metadata.txt" "Text file|*.txt;*.TXT|All files|*.*;*" "save,overwrite"

(defun timeing (sss)
  (setf mss (truncate sss))
  (setf ms (truncate (* (- sss mss) 1000)))
  (setf ss (rem mss 60))
  (setf hmm (truncate (/ mss 60)))
  (setf mm (rem hmm 60))
  (setf hh (truncate (/ hmm 60)))
  (format nil "~a:~a:~a.~a" hh mm ss ms)
)

(setf metadata
  (format nil "~
     <@TimeScale:44100>~%~
     <@Start>~%"
  )
)

;;  Get label data from first label track
(setf labels (second (first (aud-get-info "Labels"))))


(dolist (label labels)
  (setf chapter
    (format nil "[~a] ~a~%"
                 (timeing (first label))
                 (third label)
    )
  )
  (string-append metadata chapter)
)

;;  Finish label track
(string-append metadata (format nil"<@End>~%"))


(setf fp (open filename :direction :output))
(format fp metadata)
(close fp)
(format nil "File written to~%~a" filename)

Plug-in в разметке QuickTime

;nyquist plug-in
;version 4
;type tool
;codetype lisp
;name "Labels for QuickTime"
;author "Michael Kushnir from Steve Daulton"
;release 2.3.2
;copyright "Released under terms of the GNU General Public License version 2"

;control filename "Save file as" file "" "*default*/metadata.txt" "Text file|*.txt;*.TXT|All files|*.*;*" "save,overwrite"

(defun timeing (sss)
  (setf mss (truncate sss))
  (setf ms (truncate (* (- sss mss) 100000)))
  (setf ss (rem mss 60))
  (setf hmm (truncate (/ mss 60)))
  (setf mm (rem hmm 60))
  (setf hh (truncate (/ hmm 60)))
  (format nil "~a:~a:~a.~a" hh mm ss ms)
)

(setf metadata
  (format nil "{QTtext}{timeScale:44100}~%")
)

;;  Get label data from first label track
(setf labels (second (first (aud-get-info "Labels"))))

(dolist (label labels)
  (setf chapter
    (format nil "[~a]~%~a~%"
                 (timeing (first label))
                 (third label)
    )
  )
  (string-append metadata chapter)
)


(setf fp (open filename :direction :output))
(format fp metadata)
(close fp)
(format nil "File written to~%~a" filename)

Комментариев нет: