2017-07-03 90 views
1

我寫了一個腳本,用誘變劑標記我的音樂庫時遇到了問題。 以下代碼在處理mp3文件時工作正常,但破壞了m4a文件。是否可以使用誘變劑將ID3標籤添加到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標籤,但它沒有幫助。

我在做什麼錯?

+0

MP3!= MP4,你爲什麼試圖在你的M4A文件上使用ID3?是不是很難輸入Google:'mutagen m4a tags'並轉到[第一個鏈接](http://mutagen.readthedocs.io/en/latest/api/mp4.html),彈出並解釋了什麼用於編輯MP4文件上的標籤? – zwer

+0

哪個版本的python和OS? –

+0

@anony Kong python3.6 on windows10 – dobrovv

回答

3

正如我在評論中所說的,MP4和MP3是不同的容器,它們使用完全不同的結構來存儲元數據。從技術上講,你可以在MP4元數據中編碼ID3字段,這樣的用法很大程度上取決於你的標籤/播放器,因爲有很多方法可以做到這一點,每個人都認爲他們有最好的方式,因此推動他們自己的結構。

什麼是MP3容器的ID3,XMP是用於MP4/M4A容器(以及許多其他容器,如JPEG,PDF甚至MP3,如果你想的話) - 除了XMP是一個實際的標準,而ID3是一個事後考慮(它實際上只是MP3文件末尾附加的尾部結構),每個人都隨之而來,其功能主要由像WinAmp,foobar2000等大衆流行播放器支配。相比之下,XMP本質上是一個類似於原子結構的結構(這就是爲什麼你會聽到mp4標籤被稱爲「原子」,即使他們不是指同一個東西),它與元數據一起還攜帶了什麼信息元數據表現出來,即使是第一次遇到它的玩家在理論上也可以從不相關的元數據中識別出相關的元數據。

當然,實際上這也變成了玩家/標籤戰爭,所以他們中的很多人都使用自己的自定義「擴展」進行標記 - 目前iTunes在應用字段和方式方面擁有巨大的影響力,其他球員類球 - 這是mutagen。 iTunes並不是一個單一的XMP結構,而是將這些標籤作爲非視頻/音頻幀(MP4中的實際'原子')傳播,並且一些'標籤'必須被怪異地命名(二進制名稱等)不會干擾格式本身。雖然這種方法有一些優勢(改變流媒體的元數據,對於現場活動非常有用),但這使得標記不必要地變得複雜,並且也是非標準的。

無論如何,您的問題發生是因爲您試圖將一個ID3結構寫入MP4容器 - 寫入ID3標記時mutagen不會分析整個文件以辨別底層文件是否支持ID3以及在何處/如何寫入它會假設它已經被一個普通的MP3文件提供,並在錯誤的位置寫下了錯誤的格式,最好只是在文件末尾添加一些垃圾(早期的非流式ID3版本),或者在最糟糕的是,因此會損壞M4A容器。當你讀迴文件時也是如此 - 它可以讀取之前在可預測的地方寫入的ID3結構,它不關心其餘數據是什麼。

因此,正如我剛纔所說的那樣,並且正如文檔中所示,在處理MP4/M4A容器時使用mutagen.mp4.MP4(或者更確切地說是底層mutagen.mp4.MP4Tags),因爲這些容器是爲創建與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) 

注:我只用在get_description()功能按「標籤」的多個條目的最後desc條目被支撐着現有的標記作爲回報名單。你顯然不會在生產環境中使用上述內容。

你可以測試一下:

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. 

對於全套您可以檢查mutagen.mp4.MP4Tag文檔「支持」(或相當的iTunes,嗯,鼓勵)鍵。當然,您可以使用自由形式的結構(即----:foo:bar)創建自己的密鑰,但不要指望其他玩家識別它們。

相關問題