Можно ли добавить теги ID3 в файлы m4a с помощью мутагена?

Я столкнулся с проблемой при написании скрипта для пометки моей музыкальной библиотеки мутагеном. Следующий код отлично работает с файлами mp3, но повреждает файлы m4a.

def set_video_tags(video, filepath):
    try:
        tags = ID3(filepath, v2_version=3)
    except ID3NoHeaderError:
        tags = ID3()

    tags.add(TXXX(3, desc='desc:custom_tag',text= video.custom_text))
    tags.save(filepath, v2_version=3)

После обработки файлов m4a теги могут быть прочитаны с помощью мутагена, но не обнаруживаются никакими другими плеерами, и звук не воспроизводится.

Я пытался удалить теги MP4 из файлов перед вызовом этой функции, но это не помогло.

Что я делаю не так?


person dobrovv    schedule 03.07.2017    source источник
comment
MP3 != MP4, почему вы пытаетесь использовать ID3 в своих файлах M4A? Было ли слишком сложно ввести в Google: mutagen m4a tags и перейти по самой первой ссылке, которое всплывает и объясняет, что использовать для редактирования тегов в файлах MP4?   -  person zwer    schedule 04.07.2017
comment
Какая версия питона и ОС?   -  person Anthony Kong    schedule 04.07.2017
comment
@Энтони Конг python3.6 на Windows10   -  person dobrovv    schedule 04.07.2017
comment
@zwer Я просмотрел его, но, если я правильно понимаю, mp4 также должен поддерживать теги ID3. Я спрашиваю конкретно о тегах ID3   -  person dobrovv    schedule 04.07.2017
comment
@zwer: я не вижу ничего, что объясняло бы, что использовать для редактирования тегов в файлах MP4 по предоставленной вами ссылке? Пожалуйста, просветите нас.   -  person martineau    schedule 04.07.2017
comment
@martineau - каждая вещь (с точки зрения кода), которую я написал в своем ответе, полученном на этой странице документации. Считайте себя просветленным ;)   -  person zwer    schedule 04.07.2017


Ответы (1)


Как я уже говорил в своем комментарии, MP4 и MP3 — это разные контейнеры, и они используют совершенно разные структуры для хранения метаданных. Хотя технически вы можете кодировать поля ID3 в метаданных MP4, их использование будет сильно зависеть от вашего тегировщика/проигрывателя, потому что есть много способов сделать это, и каждый думает, что у него есть лучший способ, следовательно, продвигать свои собственные структуры.

Что такое ID3 для контейнеров MP3, XMP для контейнеров MP4/M4A (и для многих других контейнеры, такие как JPEG, PDF и даже MP3, если хотите) - за исключением того, что XMP является фактическим стандартом, в то время как ID3 был второстепенным (буквально это была просто добавленная конечная структура в конце файлов MP3), с которой все согласились, и ее функции были в основном продиктованы популярными плеерами того времени, такими как WinAmp, foobar2000 и им подобными. Напротив, XMP представляет собой структуру, подобную потоку атомов (поэтому вы услышите, что теги mp4 называются «атомами», даже если они не относятся к одному и тому же), который вместе со своими метаданными также несет информацию о том, что эти метаданные представлены таким образом, что даже игроки, впервые столкнувшиеся с ними, теоретически могут отличить релевантные метаданные от нерелевантных.

Конечно, на практике это также превратилось в войну между игроками и тегировщиками, поэтому многие из них используют свои собственные «расширения» для тегов — в настоящее время iTunes имеет огромное влияние на то, какие поля следует использовать и как, а другие игроки — игрового мяча - так mutagen. Вместо единой структуры XMP iTunes распространяет теги как не видео/аудио кадры (фактические «атомы») в самой структуре MP4, и некоторые «теги» должны иметь странные имена (двоичные имена и т. д.), чтобы они не т вмешиваться в сам формат. Хотя в этом подходе есть некоторое преимущество (изменение метаданных при потоковой передаче, очень полезное для прямых трансляций), он делает тегирование излишне сложным и, опять же, нестандартным.

В любом случае, ваша проблема возникает из-за того, что вы пытаетесь записать структуру ID3 в контейнер MP4 - при записи тегов ID3 ​​mutagen не анализирует весь файл, чтобы определить, поддерживает ли базовый файл ID3 и где/как его записать, вместо этого предполагает, что он был загружен обычным файлом MP3 и записывает его не в том месте, в неправильном формате, в лучшем случае просто добавляя мусор в конец вашего файла (более ранние версии ID3 без потоковой передачи) или, в худшем случае, повреждая ваш Контейнер М4А как следствие. То же самое происходит, когда вы читаете файл обратно - он может прочитать структуру ID3, которую он написал ранее, в предсказуемом месте, ему все равно, какие остальные данные.

Итак, как я уже говорил и как показано в документации, используйте mutagen.mp4.MP4 (или, скорее, базовый mutagen.mp4.MP4Tags) при работе с контейнерами MP4/M4A, поскольку они созданы для работы с контейнерами MP4. Например, чтобы изменить тег desc, как вы пытаетесь:

from mutagen.mp4 import MP4

def get_description(filename):
    return MP4(filename).tags.get("desc", [None])[-1]

def set_description(filename, description):
    tags = MP4(filename).tags
    tags["desc"] = description
    tags.save(filename)

ПРИМЕЧАНИЕ. Я использую только последнюю запись desc в функции get_description(), так как поддерживается несколько записей на «тег», поэтому существующие теги возвращаются в виде списков. Вы, очевидно, не будете использовать вышеперечисленное в производственных условиях.

Вы можете протестировать его с помощью:

print("Current description: {}".format(get_description("test.m4a")))
# Current description: None

set_description("test.m4a", "Test description")  # let's add some description
print("Current description: {}".format(get_description("test.m4a")))
# Current description: Test description

# You can also modify the description once set:
set_description("test.m4a", get_description("test.m4a") + " update")
print("Current description: {}".format(get_description("test.m4a")))
# Current description: Test description update

# etc.

Полный набор «поддерживаемых» (или, скорее, iTunes, хммм, рекомендуемых) ключей вы можете проверить на mutagen.mp4.MP4Tag документы. Конечно, вы можете изобрести свои собственные ключи, используя структуру произвольной формы (например, ----:foo:bar), но не ожидайте, что кто-то другой распознает их.

person zwer    schedule 04.07.2017