Автоматическая конвертация и добавление аннотации к аудиофайлам в Windows

Автоматическая конвертация и добавление аннотации к аудиофайлам в Windows

Меломаны и просто лю­бите­ли хорошей музыки порой стал­кива­ются с необ­ходимостью автоматической конвертации и анно­тиро­вания аудиофайлаов своей музыкальной коллекции. В этой статье рассмотрим спо­соб авто­мати­чес­кой кон­верта­ции и добавления аннотации к ауди­офай­лам с помощью инструмента FFmpeg и сценариев CMD.

Автоматическая конвертация аудиофайлов в Windows

Существует множество различных программ для кон­верта­ции ауди­офай­лов и редак­тирова­ния тегов, но почти все из них — обо­лоч­ки утилит командной строки вок­руг одно­го‑двух про­ектов с откры­тым исходным кодом, в которых как раз и реали­зова­на вся необ­ходимая фун­кци­ональ­ность. Как пра­вило, в осно­ве лежат несколько ути­лит коман­дной стро­ки.

Итак. У нас есть музыкальные альбомы, в виде наборов ауди­офай­лов. Необходимо добавить к данным аудиофай­лам изоб­ражение обложки аль­бома и опи­сание из тек­сто­вого фай­ла, а так­же есть желание кон­верти­ровать эти фай­лы в фор­мат MP3 с определенными парамет­рами ауди­одан­ных. Для решения этой задачи попробуем исполь­зовать утилиту FFmpeg и язык сце­нари­ев CMD.EXE.

FFmpeg для автоматической конвертации файлов

В начале я сомневался в идее применения FFmpeg, но мои сом­нения были раз­веяны этой стать­ей. Идея в том, что теги ука­зыва­ются утилите FFmpeg в виде парамет­ров:

Кроме того, в статье есть при­мер исполь­зования фай­ла txt в качес­тве источни­ка тегов. К моему сожале­нию, для реализации этого надо для каждого аудифайла соз­давать отдель­ные тек­сто­вые фай­лы с тегами, тог­да как намного удоб­нее все све­дения о содер­жимом музыкального альбома дер­жать в одном тек­сто­вом фай­ле.

Ука­зывать пол­ный путь к исполня­емо­му фай­лу FFmpeg в коман­дной стро­ке край­не неудоб­но. Как правило во время уста­нов­ки прог­раммы пред­лага­ется вклю­чить путь в сис­темную перемен­ную окру­жения PATH, но лично я не люблю ее засорять. Вмес­то это­го рекомендую помес­тить в пап­ку, уже при­сутс­тву­ющую в данной перемен­ной, коман­дный файл ffmpeg.cmd такого содер­жания:

Сим­вол @ подав­ляет эхо‑печать коман­дной стро­ки, а вмес­то сочета­ния %* при выпол­нении будут под­став­лены все парамет­ры, передан­ные сце­нарию ffmpeg.cmd. Таким обра­зом, исполь­зовать FFmpeg из коман­дной стро­ки для кон­верта­ции фай­ла SRC\sample.wav в TGT\sample.mp3 мож­но  следующим образом:

Можно также использовать FFmpeg для того чтобы добавить к  MP3-файлу изоб­ражени­ем обложки.Изоб­ражение обложки — для MP3-фай­ла виде­опо­ток и, для слкеивания его с ауди­одан­ными, воспользуемся коман­дой вида:

С помощью параметра -map источни­ки дан­ных из вход­ных фай­лов отоб­ража­ются в потоки выход­ного фай­ла:

  • Пер­вый опция опре­деля­ет пер­вый поток, ее параметр говорит о том, что надо исполь­зовать пер­вый ука­зан­ный с помощью опции -i источник, в при­веден­ном при­мере это ауди­одан­ные из фай­ла SRC\audio.mp3.
  • Вто­рая опция опре­деля­ет вто­рой поток, ее параметр 1 говорит, что надо исполь­зовать вто­рой ука­зан­ный с помощью опции -i источник — изоб­ражение из фай­ла SRC\cover.jpg.
Сли­яние фай­лов с ауди­одан­ными и изоб­ражени­ем в аудио- и виде­опо­токи фай­ла‑кон­тей­нера MP3
Сли­яние фай­лов с ауди­одан­ными и изоб­ражени­ем в аудио- и виде­опо­токи фай­ла‑кон­тей­нера MP3

По умол­чанию FFmpeg авто­мати­чес­ки кодиру­ет потоки в соот­ветс­твии со сво­ими пре­дус­танов­ками так, что­бы они отве­чали фор­мату выход­ного фай­ла (опре­деля­ется по рас­ширению). Нап­ример, аудио она кон­верти­рует кодеком LAME с час­тотой дис­кре­тиза­ции 44 100 Гц и ско­ростью потока 128 Кбит/с, а изоб­ражение пре­обра­зует в фор­мат PNG.

Если манипу­ляции с обложкой еще мож­но прос­тить, то опи­сан­ные дей­ствия со зву­ком мелома­ны могут вос­при­нять как лич­ное оскор­бле­ние. К счастью, мож­но зап­ретить прог­рамме выпол­нять какие бы то ни было пре­обра­зова­ния, ука­зав в коман­дной стро­ке опцию -c copy. Или зап­ретить пре­обра­зовы­вать толь­ко аудио, кон­кре­тизи­ровав опцию так: -c:a copy.

Оп­ция -id3v2_version 3 тре­бует исполь­зовать вер­сию 2.3 тегов ID3. Без нее записан­ное в выход­ной файл изоб­ражение не будет отыс­кивать­ся и демонс­три­ровать­ся про­игры­вате­лями. Наобо­рот, опция -metadata:s:v title=»Album cover», наз­нача­ющая потоку ([b]s[/b]tream) с виде­одан­ными ([b]v[/b]ideo) атри­бут title со зна­чени­ем «Album cover», слу­жит толь­ко декора­тив­ной цели.

Те­ги ID3 дол­жны наз­начать­ся кон­тей­неру MP3 в целом, а не отдель­ному содер­жащему­ся в нем потоку. Поэто­му для них опция -metadata исполь­зует­ся без допол­нитель­ных спе­цифи­като­ров.

В моей ауди­окол­лекции наряду с музыкаль­ными про­изве­дени­ями обна­ружи­лись ауди­опод­касты, записан­ные с высоким качес­твом. Вос­при­ятие этих матери­алов на слух не стра­дает, если понизить час­тоту дис­кре­тиза­ции (sample rate) до 22 кГц и свес­ти сте­реоз­вук в монодо­рож­ку. Кон­кре­тизи­ровать парамет­ры пре­обра­зова­ния ауди­опо­тока прог­рамме FFmpeg мож­но с помощью таких опций:

Оп­ция -c пред­писыва­ет выпол­нять обра­бот­ку ауди­опо­тока кодеком Lame MP3, опция -ar зада­ет час­тоту дис­кре­тиза­ции ауди­опо­тока 22 050 Гц, а опция -ac тре­бует свес­ти звук в одну дорож­ку. Пос­ле такого пре­обра­зова­ния раз­мер MP3-фай­лов зна­читель­но умень­шил­ся. Допус­тимые зна­чения час­тоты дис­кре­тиза­ции в поряд­ке убы­вания качес­тва (Гц): 48 000, 44 100, 32 000, 24 000, 22 050, 16 000, 11 025, 8000.

Уп­равлять качес­твом зву­ково­го потока мож­но и с помощью опции, поз­воля­ющей задать мак­сималь­ную ско­рость переда­чи дан­ных (bitrate). Нап­ример, для огра­ниче­ния ско­рос­ти до 96 Кбит/с надо ука­зать: -b:a 96k.

Возможности CMD-сценариев

Язык CMD-сце­нари­ев базиру­ется на край­не огра­ничен­ном язы­ке пакет­ных batch-фай­лов, который изна­чаль­но исполь­зовал­ся толь­ко для выпол­нения одной и той же линей­ной пос­ледова­тель­нос­ти команд опе­раци­онной сис­темы. Но со вре­менем инс­трук­ция FOR была рас­ширена для того, что­бы с ее помощью мож­но было обра­баты­вать тек­сто­вые фай­лы, выпол­нять син­такси­чес­кий раз­бор строк и прис­ваивать перемен­ным сце­нария зна­чения на осно­ве обна­ружен­ных фраг­ментов.

Под­робную справ­ку о воз­можнос­тях инс­трук­ции FOR выг­рузит в тек­сто­вый файл help-for.txt такая пос­ледова­тель­ность команд:

Ко­ман­да CHCP уста­нав­лива­ет кодиров­ку сим­волов, которая исполь­зует­ся в сеан­се коман­дной стро­ки. По умол­чанию дей­ству­ет кодиров­ка CP866 (DOS), с которой не уме­ет работать штат­ный тек­сто­вый редак­тор «Блок­нот». Что­бы читать получен­ный тек­сто­вый файл в блок­ноте, надо перед фор­мирова­нием фай­ла уста­новить кодиров­ку CP1251 (Windows). В резуль­тате изу­чать докумен­тацию мож­но с помощью коман­ды

Раз­берем прин­цип работы язы­ка сце­нари­ев с тек­сто­выми фай­лами на сле­дующем при­мере. Пред­положим, у нас есть CSV-файл employees.csv со сле­дующим содер­жимым в кодиров­ке CP1251:

При­меним к нему коман­ду test-for.cmd employees.csv, где файл test-for.cmd содер­жит сле­дующий сце­нарий:

Ключ /F инс­трук­ции FOR зас­тавля­ет ее обра­баты­вать содер­жащи­еся в тек­сто­вом фай­ле стро­ки с име­нем, передан­ным в качес­тве пер­вого парамет­ра коман­дной стро­ки, в соот­ветс­твии с опи­сани­ем струк­туры тек­сто­вого фай­ла, которое зак­лючено в кавыч­ки. Эле­мент eol это­го опи­сания зада­ет сим­вол (он может быть толь­ко один), которым начина­ется однос­троч­ный ком­мента­рий (в при­веден­ном при­мере это сим­вол решет­ки #). Такой выбор поз­воля­ет исклю­чить из обра­бот­ки пер­вые три стро­ки фай­ла employees.csv. Пус­тые стро­ки в обра­бот­ке тоже не учас­тву­ют, поэто­му и его чет­вертая стро­ка будет про­пуще­на.

В эле­мен­те tokens через запятую перечис­ляют­ся поряд­ковые номера инте­ресу­ющих раз­работ­чика информа­цион­ных полей, зна­чения которых раз­деля­ются в обра­баты­ваемой стро­ке сим­волами‑раз­делите­лями, ука­зан­ными в эле­мен­те delims. В при­веден­ном при­мере это вто­рое, третье и пятое поле, что соот­ветс­тву­ет фамилии, име­ни и дол­жнос­ти. В качес­тве раз­делите­ля будет исполь­зован сим­вол точ­ка с запятой, но при необ­ходимос­ти в эле­мен­те delims мож­но ука­зать один за дру­гим сра­зу нес­коль­ко сим­волов‑раз­делите­лей.

Нес­коль­ко иду­щих под­ряд раз­делите­лей счи­тают­ся одним, а сто­ящий в самом начале стро­ки раз­делитель игно­риру­ется. Пос­леднее свой­ство инс­трук­ции FOR поз­волит орга­низо­вать хра­нение и обра­бот­ку двух спис­ков в одном тек­сто­вом фай­ле.

Пос­ле опи­сания струк­туры в инс­трук­ции FOR ука­зыва­ется имя перемен­ной, которой прис­воит­ся зна­чение пер­вого поля обра­ботан­ной стро­ки. В при­веден­ном при­мере фамилия будет записа­на в перемен­ную %%I. Зна­чения осталь­ных полей будут прис­воены перемен­ным, сле­дующим пос­ле ука­зан­ной в алфа­вит­ном поряд­ке. В рас­смат­рива­емом при­мере фамилия и дол­жность попадут в перемен­ные %%J и %%K соот­ветс­твен­но.

На каж­дой ите­рации цик­ла FOR перемен­ные ини­циали­зиру­ются зна­чени­ями соот­ветс­тву­ющих полей, пос­ле чего они могут исполь­зовать­ся в коман­де, которая записы­вает­ся в инс­трук­ции FOR пос­ле сло­ва DO. В при­веден­ном при­мере это коман­да ECHO, печата­ющая стро­ку вида «Имя Фамилия — Должность». В резуль­тате обра­бот­ки фай­ла employees.csv на экран будут выведе­ны стро­ки:

Ко­ман­ды CHCP в сце­нарии test-for.cmd нуж­ны толь­ко для того, что­бы кор­рек­тно отоб­ражал­ся текст в Windows-кодиров­ке, а конс­трук­ции … > NUL: исполь­зованы для подав­ления вывода их информа­цион­ных сооб­щений «Текущая кодовая страница такая-то».

Мо­дер­низации под­вер­гся и механизм вызова под­прог­рамм. Если в BAT-сце­нари­ях инс­трук­ция CALL поз­воляла толь­ко передать управле­ние находя­щему­ся в дру­гом фай­ле BAT-сце­нарию с пос­леду­ющим воз­вра­том, то в CMD-сце­нари­ях появи­лась воз­можность вре­мен­ной переда­чи управле­ния внут­ри выпол­няюще­гося сце­нария. К сожале­нию, пос­ле перехо­да по мет­ке отсутс­тву­ет воз­можность дос­рочно­го воз­вра­та в точ­ку вызова, то есть под­прог­раммой счи­тает­ся код от мет­ки до кон­ца фай­ла.

Ра­боту под­прог­раммы рас­смот­рим на исправ­ленном сце­нарии, который не толь­ко выводит информа­цию о сот­рудни­ках, но и под­счи­тыва­ет фонд заработ­ной пла­ты.

Пос­коль­ку теперь на каж­дой ите­рации цик­ла тре­бует­ся выпол­нять не одну коман­ду, а нес­коль­ко, то удоб­но в опе­рато­ре FOR заменить коман­ду печати ECHO коман­дой вызова под­прог­раммы CALL. Пос­ле сло­ва CALL ука­зыва­ется мет­ка стро­ки, с которой начина­ется под­прог­рамма (в при­веден­ном при­мере это :CALCULATE), а даль­ше сле­дуют аргу­мен­ты, зна­чения которых в под­прог­рамме будут прис­воены парамет­рам %1, %2, %3 и так далее по количес­тву аргу­мен­тов. В при­веден­ном при­мере их четыре: Фамилия, Имя, Должность и Оклад.

В под­прог­рамме :CALCULATE выпол­няют­ся все необ­ходимые для обра­бот­ки полей информа­цион­ной стро­ки дей­ствия. Во‑пер­вых, коман­да ECHO печата­ет информа­цию о сот­рудни­ке, допол­ненную величи­ной его окла­да. Во‑вто­рых, инс­трук­ция SET (тоже модер­низиро­ван­ная и допол­ненная приз­наком выпол­нения ариф­метичес­ких опе­раций /A) уве­личи­вает зна­чение перемен­ной TOTAL, ини­циали­зиро­ван­ной нулевым зна­чени­ем, на величи­ну окла­да сот­рудни­ка.
warning

Как бы тебе ни хотелось укра­сить лис­тинг сце­нария, ни в коем слу­чае не встав­ляй про­белы в инс­трук­ции SET меж­ду име­нем перемен­ной, зна­ком равенс­тва и прис­ваиваемым зна­чени­ем. В этой инс­трук­ции каж­дый про­бел име­ет зна­чение!

Ког­да цикл FOR завер­шит обра­бот­ку информа­цион­ных строк фай­ла со штат­ным рас­писани­ем, сле­дующей коман­дой ECHO будет рас­печатан общий фонд зар­пла­ты, пос­ле чего коман­да SET уда­лит перемен­ную TOTAL. Одна из важ­ней­ших ролей в этом зак­лючитель­ном бло­ке отве­дена коман­де безус­ловно­го перехо­да GOTO, которая слу­жит барь­ером меж­ду основной прог­раммой и под­прог­раммой. Она переда­ет управле­ние на вир­туаль­ный конец сце­нария, которо­му соот­ветс­тву­ет пре­доп­ределен­ная мет­ка :EOF, в резуль­тате чего сце­нарий завер­шает свою работу.

Разработка прототипа командного сценария

Те­перь, ког­да воз­можнос­ти FFmpeg и язы­ка коман­дных сце­нари­ев про­ясни­лись, мож­но прис­тупать к решению нашей задачи — раз­работ­ке сце­нария для кон­верта­ции и наз­начения ID3-тегов ауди­офай­лам из кол­лекции. Для начала решим, как будет хра­нить­ся информа­ция о тегах.

Ауди­офай­лы обыч­но сущес­тву­ют не сами по себе, а сгруп­пирова­ны в аль­бомы, которые изда­тели записы­вают на один информа­цион­ный носитель: ком­пакт‑диск, винило­вую плас­тинку и про­чее. Поэто­му в одном информа­цион­ном тек­сто­вом фай­ле будем хра­нить теги для одно­го такого аль­бома. Если про­ана­лизи­ровать мно­жес­тво ID3-тегов, то мож­но выделить в нем две катего­рии: теги, которые отно­сят­ся ко все­му аль­бому в целом (нап­ример, наз­вание аль­бома и исполни­тель аль­бома), и теги, которые отно­сят­ся к отдель­ному тре­ку (номер тре­ка на носите­ле, наз­вание тре­ка, исполни­тель тре­ка).

Что­бы не дуб­лировать для каж­дого ауди­офай­ла «аль­бом­ные» теги, запишем их один раз в заголов­ке информа­цион­ного фай­ла. Теги для отдель­ных тре­ков удоб­но хра­нить в стро­ках тек­сто­вого фай­ла с раз­делите­лями. В качес­тве раз­делите­ля будем исполь­зовать сим­вол, встре­тить который в зна­чени­ях тегов малове­роят­но. Я выб­рал сим­вол тиль­да ~. А для аль­бом­ных тегов, которые естес­твен­но пред­став­лять в виде пар «ТЕГ=ЗНА­ЧЕНИЕ», было решено исполь­зовать в качес­тве раз­делите­ля знак равенс­тва =.

Вы­рисо­выва­ется сле­дующая струк­тура информа­цион­ного фай­ла:

Ори­енти­руясь на раз­работан­ную струк­туру, наб­роса­ем про­тотип коман­дно­го сце­нария, который будет ее исполь­зовать для обра­бот­ки ауди­офай­лов.

Пос­коль­ку для тегов пред­почти­тель­но исполь­зовать кодиров­ку Unicode, то все тек­сто­вые фай­лы, как со сце­нари­ем, так и со зна­чени­ями тегов, дол­жны быть сох­ранены в фор­мате UTF-8. В соот­ветс­твии с этим для сеан­са коман­дной стро­ки уста­нав­лива­ется кодовая стра­ница 65001. Пред­полага­ется, что исходные ауди­офай­лы будут хра­нить­ся в под­катало­ге SRC, а пре­обра­зован­ные фай­лы — записы­вать­ся в под­каталог TGT текуще­го катало­га. Информа­ция о тегах будет хра­нить­ся вмес­те с исходны­ми фай­лами в тек­сто­вом фай­ле SRC\id3tags.txt опи­сан­ной выше струк­туры.

При сох­ранении тек­сто­вых фай­лов в фор­мате UTF-8 обра­щай вни­мание, что­бы они не пред­варялись мар­кером пос­ледова­тель­нос­ти бай­тов BOM. Коман­дный про­цес­сор не уме­ет его пра­виль­но обра­баты­вать, в резуль­тате чего он не рас­позна­ет пер­вую коман­ду @ECHO OFF и при работе сце­нария на экран выводит­ся мно­го «мусора». В край­нем слу­чае мож­но сде­лать пер­вую стро­ку сце­нария пус­той, но и тог­да его вывод будет начинать­ся с сооб­щения:

Пос­коль­ку в информа­цион­ном фай­ле при­сутс­тву­ют два бло­ка раз­ной струк­туры, он будет обра­баты­вать­ся в два про­хода дву­мя цик­лами FOR. Пер­вый цикл прис­воит зна­чения аль­бом­ных тегов перемен­ным окру­жения сце­нария с тем, что­бы их мож­но было в даль­нейшем исполь­зовать для каж­дого ауди­офай­ла. Вто­рой цикл на каж­дой ите­рации будет запус­кать FFmpeg для обра­бот­ки ауди­офай­ла.

И здесь нуж­но най­ти метод, который поз­волит раз­личать информа­цион­ные стро­ки пер­вого и вто­рого типов. Это мож­но сде­лать раз­ными спо­соба­ми. Я решил исполь­зовать сим­вол — раз­делитель полей одно­го бло­ка в качес­тве приз­нака ком­мента­рия для дру­гого бло­ка и в начало каж­дой информа­цион­ной стро­ки добавить сим­вол‑раз­делитель, пос­ле чего струк­тура информа­цион­ного фай­ла при­няла такой вид:

Пос­ле это­го пер­вый цикл вос­при­нима­ет стро­ки вто­рого бло­ка как ком­мента­рии, а вто­рой цикл так же отно­сит­ся к стро­кам пер­вого бло­ка.

Средс­тва работы с под­прог­рамма­ми в язы­ке CMD-сце­нари­ев доволь­но огра­ничен­ны. Из‑за отсутс­твия инс­трук­ции дос­рочно­го воз­вра­та из под­прог­раммы приш­лось модели­ровать в одной под­прог­рамме работу нес­коль­ких вир­туаль­ных под­прог­рамм. Для это­го через аргу­мент инс­трук­ции CALL переда­ется имя вир­туаль­ной под­прог­раммы («header» или «body»), которое ана­лизи­рует­ся в начале нас­тоящей под­прог­раммы (:PROCESSING). Пос­ле это­го выпол­няет­ся переход к бло­ку инс­трук­ций выз­ванной вир­туаль­ной под­прог­раммы (на мет­ку :HEADER или :BODY). Что­бы исклю­чить став­шее ненуж­ным имя под­прог­раммы из спис­ка получен­ных парамет­ров, вир­туаль­ные под­прог­раммы начина­ются с инс­трук­ции SHIFT.

Ес­ли сей­час выпол­нить при­веден­ный про­тотип сце­нария, то на экра­не отоб­разят­ся сле­дующие стро­ки:

Зна­чит, раз­бор тек­сто­вого фай­ла со зна­чени­ями тегов работа­ет так, как задума­но, и мож­но перехо­дить к реали­зации обра­бот­ки ауди­офай­лов с помощью FFmpeg.

Сценарий пакетной обработки аудиофайлов

Для выпол­нения реаль­ных опе­раций над фай­лами надо в про­тоти­пе сце­нария заменить отла­доч­ный вывод ECHO DEBUG… на блок инс­трук­ций, которые эти опе­рации будут выпол­нять. Я офор­мил этот блок сле­дующим обра­зом:

Ко­рот­кое имя фай­ла по его поряд­ковому номеру фор­миру­ется и записы­вает­ся в перемен­ную MP3FN пер­вой инс­трук­цией SET. В моих кол­лекци­ях ауди­офай­лы хра­нят­ся под сво­ими поряд­ковыми номера­ми в аль­бомах: 01.mp3, 02.mp3, 03.mp3, …, 10.mp3, 11.mp3… В сце­нарии для уни­вер­саль­нос­ти я пред­положил, что номер в име­ни фай­ла может не содер­жать ведуще­го нуля: 1.mp3, 2.mp3 и так далее. Что­бы авто­мати­чес­ки обра­баты­вались фай­лы вплоть до трех­разряд­ных номеров, даль­ше сле­дуют инс­трук­ции IF, добав­ляющие ведущие нули к име­ни фай­ла, если таковой отсутс­тву­ет в пап­ке SRC. Если отсутс­тву­ет файл и с трех­разряд­ным номером, то будет выдано сооб­щение об ошиб­ке.

В слу­чае успе­ха в перемен­ные SRCFN и TGTFN записы­вают­ся пол­ные име­на вход­ного и выход­ного ауди­офай­лов, зна­чения которых исполь­зуют­ся в коман­дной стро­ке FFmpeg. Коман­дная стро­ка получи­лась доволь­но длин­ной, и, что­бы раз­бить ее на час­ти, приш­лось вос­поль­зовать­ся сим­волом экра­ниро­вания перево­да стро­ки, роль которо­го в коман­дной стро­ке Windows игра­ет не обратная нак­лонная чер­та \, как мож­но было бы подумать, а крыш­ка ^.

Па­рамет­ры коман­дной стро­ки FFmpeg дол­жны быть понят­ны из пре­дыду­щих при­меров. Раз­ве что может воз­никнуть резон­ный воп­рос, отку­да возь­мут­ся зна­чения перемен­ных: имя фай­ла с изоб­ражени­ем обложки %COVER%, час­тота дис­кре­тиза­ции %FQ%, ско­рость потока %BR% и количес­тво ауди­одо­рожек %AC%. Дей­стви­тель­но, их надо опре­делить в начале сце­нария, допол­нив блок ини­циали­зации перемен­ных окру­жения стро­ками

По­лучив­ший­ся сце­нарий я при­менил для обра­бот­ки ауди­оза­писей лек­ций цик­ла «Вос­ток (Лек­торий ВШЭ)», сте­реофай­лы которых с час­тотой дис­кре­тиза­ции 44 100 Гц при ско­рос­ти потока 128 Кбит занима­ли на дис­ке 877 Мбайт. Объ­ем пре­обра­зован­ных фай­лов умень­шил­ся до 219 Мбайт (то есть при­мер­но в четыре раза), а тембр речи лек­торов субъ­ективно даже улуч­шился.

Ре­зуль­тат автоматического анно­тиро­вания MP3-фай­лов с ауди­оза­пися­ми лек­ций
Ре­зуль­тат автоматического анно­тиро­вания MP3-фай­лов с ауди­оза­пися­ми лек­ций

Доработка сценария

По боль­шому сче­ту пос­тавлен­ную в этой статье задачу уже мож­но счи­тать решен­ной. Одна­ко, как извес­тно, начав прог­рамми­ровать (пусть даже на язы­ке сце­нари­ев), потом очень труд­но оста­новить­ся. В опи­сании тегов ID3 мож­но обна­ружить, что допус­кает­ся нумера­ция тре­ка в фор­мате «i/n», где i — поряд­ковый номер тре­ка, а n — общее количес­тво тре­ков в аль­боме. Почему бы не вос­поль­зовать­ся ариф­метичес­кими спо­соб­ностя­ми инс­трук­ции SET и не под­счи­тать это количес­тво, что­бы фор­мировать тег номера в рас­ширен­ном фор­мате?

Ко­неч­но, это пот­ребу­ет еще одной перемен­ной для под­сче­та тре­ков и допол­нитель­ного про­хода по информа­цион­ному фай­лу с помощью инс­трук­ции FOR с вызовом под­прог­раммы, выпол­няющей инкре­мен­тирова­ние зна­чения перемен­ной для каж­дой обна­ружен­ной записи об ауди­офай­ле.

До­бавим в блок ини­циали­зации перемен­ных стро­ку

А пос­ле пер­вой инс­трук­ции FOR, выпол­няющей ини­циали­зацию аль­бом­ных перемен­ных, добавим стро­ку для под­сче­та тре­ков:

Те­перь мож­но рас­ширить блок печати информа­ции об обра­баты­ваемом аль­боме стро­кой

Ос­талось в коман­дной стро­ке FFmpeg заменить наз­начения ID3-тега с номером тре­ка на -metadata track=»%1/%TOTAL%». С это­го момен­та сце­нарий нач­нет анно­тиро­вать MP3-фай­лы номером тре­ка в рас­ширен­ном фор­мате.

Здесь мож­но заг­рузить ис­ходные дан­ные и код, исполь­зован­ные в статье.

Заключение

В резуль­тате про­делан­ной работы мы получи­ли удоб­ный инс­тру­мент для пакет­ной обра­бот­ки ауди­офай­лов. Если при­нять во вни­мание, что FFmpeg уме­ет еще и обра­баты­вать виде­офай­лы и фай­лы с изоб­ражени­ями, а сце­нарий авто­мати­зации без осо­бых проб­лем адап­тиру­ется для решения дру­гих подоб­ных задач, то инс­тру­мент этот мож­но наз­вать уни­вер­саль­ным. При этом гра­фичес­кая обо­лоч­ка не скры­вает от нас воз­можнос­тей базовой ути­литы, а для прог­рамми­рова­ния дос­таточ­но штат­ного тек­сто­вого редак­тора опе­раци­онной сис­темы.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий