ipadにflacを移行できなかったためpythonでm4aにする。
またflac-m4a変換だけはなくタグの情報等も編集する。
当方、初投稿、故にMarkdown記法適当です。見にくかったらすみません。
事前準備
ffmpegをPCにインストールする
上のサイトからダウソして、解凍。詳しいインストール方法は各自お調べください。
次にPythonのライブラリのpydubとmutagenをインストールする
pip install pydub
pip install mutagen
サンプルコード
encode.py
#-*- coding:utf-8 -*-
import time, os, re
from pydub import AudioSegment
AudioSegment.converter = "C:\\ffmpeg\\bin\\ffmpeg.exe"
from mutagen.flac import FLAC, Picture
from mutagen.mp4 import MP4Tags, MP4, MP4Cover
from os import path
#flacのタグ名とm4aのタグ名に整合性を取る
def tag_flac_m4a(tag):
match tag:
case 'title':
return "\xa9nam"
case 'artist':
return "\xa9ART"
case 'albumartist':
return 'aART'
case 'tracknumber':
return 'trkn'
case 'date':
return '\xa9day'
case 'genre':
return '\xa9gen'
case 'album':
return '\xa9alb'
class tag:
def __init__(self, name, path_in, path_out=None):
#インスタンス変数に値を入力
self.name = name #ファイル名を定義
self.path_in = path_in #元ファイルのディレクトリのパスを定義
self.path_out = path_out #出力ファイルのディレクトリのパスを定義
#flacをm4a変換
def convert_m4a(self, path_out=None):
path_out=self.path_out if path_out is None else None #出力フォルダが定義されていなかったらインスタンス変数から取り出す
import_path = self.path_in + self.name + '.flac'
Audiodata = AudioSegment.from_file(import_path, 'flac') #flacファイルの読み込み
#m4aへエクスポート(タグはすべて消去される)
export_path = path_out + self.name + '.m4a' #ファイルのパスを定義
Audiodata.export(export_path, format='ipod', codec='aac', bitrate='320k') #エンコード
print(f'{self.name}のエクスポートが完了しました。')
#タグを抽出
def get(self):
audio_info = FLAC(self.path_in + self.name + '.flac')
tagname_list = ['title','artist','albumartist','date','tracknumber','genre','album']
tag_dict = dict()
#タグの情報を辞書に格納{tag:info}
for tagname in tagname_list:
try:
tag_temp = {tagname:audio_info.tags[tagname]}
except KeyError:
continue
tag_dict = {**tag_dict, **tag_temp}
self.tag_dict = tag_dict
print('タグの抽出を完了しました。')
return tag_dict
def embed(self, path_out=None):
path_out=self.path_out if path_out is None else None
self.get()
#m4aのタグを初期化
tags = MP4Tags()
for k,v in self.tag_dict.items():
tagname = tag_flac_m4a(k)
#トラック番号の場合 入力方法が異なる
if tagname == 'trkn':
v = re.findall(r'[0-9]+', v[0])
if len(v)==2:
tags[tagname] = [(int(v[0]), int(v[1]))]
else:
tags[tagname] = [(int(v[0]), int(v[0]))]
continue
tags[tagname] = v[0]
tags.save(path_out + self.name + '.m4a')
print('タグの埋め込みを完了しました。')
#海外の方から拝借
class cover(tag):
#画像をflacファイルから抽出
# ' https://stackoverflow.com/questions/67394817/from-flac-file-get-cover-image-and-display-it-on-a-tkinter-window '
def get(self):
audio_file = self.path_in + self.name + '.flac'
flacObj = FLAC(audio_file)
coverArt = flacObj.pictures
for img in coverArt:
if img.type == 3:
with open(f'cover_file\\{self.name}.jpg', "wb") as f:
f.write(img.data)
print(f"{self.name}_cover.jpg の保存を完了しました。")
#画像をm4aファイルに埋め込む
#' https://python.hotexamples.com/jp/site/file?hash=0xf3bcb50e83333b6591172b93a6b1089b4f05105494cf35ac8c56441d132c78dd&fullName=musicgen.py&project=nejsan/sound_bubble '
def embed(self, cover_file=None):
"""Embeds cover art into an audio file.
Arguments:
audio_file (str): The path to the audio file to embed the artwork in.
cover_file (str): The path to the artwork file to embed.
"""
if cover_file is None:
cover_file = f'cover_file\\{self.name}.jpg'
audio_file = self.path_out + self.name + '.m4a'
if path.isfile(audio_file) and path.isfile(cover_file):
artwork = open(cover_file, "rb").read()
# Determine which filetype we're handling
if audio_file.endswith("m4a"):
audio = MP4(audio_file)
covr = []
if cover_file.endswith("png"):
covr.append(MP4Cover(artwork, MP4Cover.FORMAT_PNG))
else:
covr.append(MP4Cover(artwork, MP4Cover.FORMAT_JPEG))
audio.tags["covr"] = covr
audio.save()
print(f'{self.name}のエクスポートを完全に完了しました。')
else:
with open('encoding.log', 'a', encoding='utf-8') as f:
f.writelines('/cover:File is Not Found')
#glob.globのほうがいいかも
#変換したい音楽ファイルのディレクトリ
_in = "Music\\"
_out = "C:\\Documents\\music_m4a\\"
#ファイルの名前をリストに落とす
file_list = os.listdir(path=_in)
#flac拡張子のファイル名を抽出
flac_list = [s for s in file_list if '.flac' in s]
#拡張子を削除した名前リスト
name_list = [re.sub('.flac', '', name) for name in flac_list]
with open('encoding.log', 'w', encoding='utf-8') as f:
for name in name_list:
f.writelines(name + '\n')
if __name__=='__main__':
for name in name_list:
info = tag(name, path_in=_in, path_out=_out)
with open('encoding.log', 'a', encoding='utf-8') as f:
f.writelines('\n'+info.name)
info.convert_m4a()
info.get()
info.embed()
cover.get(info)
cover.embed(info)
name_list = ['Perfect', 'Shape Of You']
#カバーを埋め込むだけ
if __name__ == '__main__':
for name in name_list:
info = tag(name, path_in=_in, path_out=_out)
cover.embed(info, cover_file='divide.jpg')
質問や指摘や、効率のいいコードがあれば是非コメントをください。
参考