PythonでMP3→WAV変換


まえがき

初投稿になります。普段はC#er1でガチガチのデスクトップアプリの開発をしていますのですが知見を広めるべくpythonに取り組んでみます。フロントエンド?それ喰えるのか?という世界に生きてますのでPythonは結構新鮮。

お題

MMD2にどっぷりな我が娘がファイル形式の変換をいちいち変換サイトにいってファイルをアップロードして・・とやっているのでそんな面倒なことせずとも自分のPCだけで完結するやんという話をしましてコンバータを作ることになりました。
今回はMMDで使うためのMP3→WAV変換になります。

開発環境

  • OS:Windows10Home(1903)
  • Editor:Visual Studio Code
  • Python:3.8.3

調べてみた

「python mp3 wav」でググるとどうやらpydubというライブラリを使えば変換できるらしいので早速導入。

> pip install pydub

えーと、ffmpegが必要?なるほど、ffmpegのラッパー的なライブラリなのか。ffmpegのコマンドを自分でチョイスして書けばいいのだろうけど折角なのでpydubのお世話になることに。

コード

mp32wav.py
import pydub
import os
import sys

if __name__ == "__main__":
    mp3 = sys.argv[1]
    print(f"IN:{mp3}")

    dirname = os.path.dirname(mp3)
    baseName = os.path.splitext(os.path.basename(mp3))[0]
    wav = os.path.join(dirname, f"{baseName}.wav")
    print(f"OUT:{wav}")

    audio = pydub.AudioSegment.from_mp3(mp3)
    audio.export(wav, format='wav')

拡張子を挿げ替えたいだけなのになんかめんどくさいコードになってしまいました。本質的には・・・

  • 元のファイル(mp3)の拡張子を.wavにしたものを出力ファイルとする
  • .mp3を読み込んで.wavとして出力する

だけなんですけどね。
C#erとしてはimport osと書いてるのになぜos.path...と書かねばならないのか疑問。

運用

さて、期待通り動くことは確認できましたがこのmp32wav.pyをデスクトップに置いてもD&Dできるわけではないのでバッチファイルを用意します。

mp32wav.bat
@echo off
py mp32wav.py %1

このバッチファイルのショートカットをデスクトップに作り、変換したい.mp3をD&Dすれば元ファイルと同じフォルダに.wavが生成されます。めでたし。

だがしかし・・・

どうやらこれは既知の問題のようですが、全角スペースを含むファイル名を与えるとそこでぶった切られてしまうようです。半角スペースもクォートしてやれば問題ありませんしD&Dの時には勝手にクォートしたものがコマンドライン引数として渡されるようですが全角スペースの場合はうまくやってくれません。
テストコードをC#で書いてみますが

argsTest.cs
static void Main(string[] args)
{
    Console.WriteLine($"len={args.Length}");
    foreach (var i in Enumerable.Range(0, args.Length))
    {
        Console.WriteLine(args[i]);
    }
    Console.ReadLine();
}

さらにこれをバッチファイルから呼び出すようにして"aaa bbb.txt"(半角スペース)と"aaa bbb.txt"(全角スペース)を喰わせてみると

半角スペース
len=1
C:\Tmp\aaa bbb.txt
全角スペース
len=1
C:\Tmp\aaa

となります。

尤も普通はフォルダ名・ファイル名に全角スペースを使いませんがそういう名前をOSが許容してますし中には半角スペースと全角スペースを全く意識しない人もいるでしょうから何かしらの対処は必要かなと考えています。
娘にはフォルダ名・ファイル名には半角スペースのみ使ってよいと伝え、当面運用で回避です(一応回避案はないこともない・・・)


  1. C#が7.5のVB6が2.0のVB.NETが0.5でしょうか。 

  2. MikuMikuDance