pythonでMP3タイトルを一括変更する

森沢洋介著「瞬間英作文」。素晴らしいですね。英語で会話するときに言いたいことがあるけれど、文章にできずに簡単にしか言えませんでしたが。この本をきっかけに打開できてきたような気がします。付録CDをiPhoneに入れて、ミュージックアプリで通勤途中に聞いています。日本語を聞いて、英語の文章を作って、英語の音声と比べてみる。というのを繰り返して、長い文書も段々と自然と作れるようになってきました。この学習も次の段階で、話すための瞬間英作文シャッフルトレーニングを買ってやろうとしています。

前置きは長くなりましたが、今回は瞬間英作文シャッフルトレーニングのCDをMP3にしてiPhoneへ転送したところで、意外な苦労をしたので書きます。

問題1 アルバムのタイトルがまとまらない

何故かアルバム名がたくさんできてしまいました。アルバム名を揃えたり短くしたりいろいろやってみましたがうまくいきませんでした。結果的に、いったんmp3ファイルを1つだけ転送してから、残りのファイルを転送するとうまくいきました。下記のブログにずばり答えが書いてあったので助かりました。
iPadのMusicアプリ上でアルバムがまとまらない

またMacでMP3のアルバム名やタイトルなどをGUIで設定したい場合はID3 Editorが利用できます。アルバム名やジャンルなど共通の項目は複数のファイルをまとめて編集することができます。

問題2 曲名が長すぎてはみ出してしまう

これは曲名をすべて半角に変更して対応しました。ID3 Editorで曲名は一つずつ編集するしか無いのでコマンドラインですることを考えました。ID3 Editorでもコマンドラインのツールが有るようですが、やり方があまり詳しく乗っていないので、今回はpythonでライブラリを読み込んでやることにしました。まず作成したコードは

mutagenというライブラリを使用しています。ライブラリのインストールは

pip install mutagen

全角半角の変換はjaconvライブラリを使用しています。これもライブラリのインストールが必要です。

pip install jaconv

.replace(‘Part’,”)でPartという文字を消していますが、これは、CD2のタイトルがPart1と2に分かれていて、これがあるとiPhoneのミュージックアプリで見たときはみ出してしまうので削除しました。編集した結果下記のように見やすくなりました。

ASIO C++ UDPクライアントをモジュール化

前回まで三菱MCプロトコルのライブラリをつくるため通信テストをしてきましたが、プロクラムの中にASIOの記述をずらずらと書いていたのでクラスにまとめてモジュール化しようと考えています。

クラスにするだけでも、結構苦労しました。特にsocketをローカル変数宣言して、コンストラクタで設定するところです。構造体のデータを転送してみましたが、エラーが発生してうまく行かなかったので、まずはnetcatで立ち上げたローカルサーバへの送信プログラムを作ってみました。プログラムはgistへアップしましたので参照してください。
UDPClient

早速説明していきます。UDPClientクラスの変数はendpointとsocketを宣言します。コンストラクタではio_contextとIPアドレスとポート番号を受けて、socketとendpointを初期化しています。

class UDPClient
{
private:
	asio::ip::udp::endpoint endpoint;
	asio::ip::udp::socket socket;

public:
	UDPClient(
		asio::io_context& io_contex, 
		const std::string host, 
		const short port)
		: socket(io_contex)
	{
		asio::ip::udp::endpoint endpoint_(asio::ip::address::from_string(host), port);
		endpoint = endpoint_;
	}

UDP送信は構造体で送信することを考えて、テンプレートで作成しました。(まだ実際に構造体での転送は試していません。)

template <typename T>
void Send(T msg,int size)
{
	socket.send_to(asio::buffer(&msg, size, endpoint);
}

mainの中は次のとおりです。io_contexとIPアドレスとポート番号を指定してクラスを宣言し、キーボードで入力した文字をUDPサーバへ送信するだけのプログラムです。

asio::io_context io_context;
const std::string host = "127.0.0.1"; 
const short port = (short)60000;

UDPClient udp(io_context,host,port);
udp.Open();    
for(;;)
{
    std::string inmsg;
    getline(std::cin, inmsg);        
    if(inmsg=="q") break;
    inmsg+="\r\n\r\n";
    udp.Send(inmsg,inmsg.size());
}
udp.Close();

私のMacbook環境ではnetcatが使えるのでnetcatが使えるので、netcatをUDPサーバ、ポート番号60000で立ち上げて、文字が表示することを確認しました。

$ netcat -l -u -p 60000

メインのプログラムでinmsg+=”\r\n\r\n”;としているのは、netcatでうまく開業されなかったからです。他に1文字か2文字だと一段多く改行したり、十何文字か多く打つと文字が変になったりするのですが、とりあえずモジュール化して通信できるました。

次は受信についてやり、構造体のデータを送ります。