大量のWMA Lossless(wma)の音楽ファイルをFFmpegを使ってApple Lossless(m4a)に変換する。

# WMA Losslessの音楽ファイルをFFmpegを使ってApple Lossless(alac)に変換する。

先日久しぶりに実家に帰ったところ、実家のメインPCがiMac 5k（2019）に変わっていた。

旧PC（Windows 7）の内臓HDD内に`WMA Lossless`形式の音楽ファイルが大量に保管されてたので、

「まあ、macOSでWMAからApple Losslessに変換してくれるフリーソフトくらいあるやろ」

と思って調べたがmacOS版は意外と無かったのでFFmpeg使って自分でShell組みました。


([VLC](https://www.videolan.org/vlc/index.ja.html)があるから別にいらんとかは言わないお約束)


## 環境
||旧PC|新PC|
|:---:|:---:|:---|
|OS|Windows 7|macOS 10.15(Catalina)|
|再生環境|Windows Media Player|ミュージック.app|

## 何が問題？

- `WMA Lossless`はMicrosoftが定義したオーディオコーデックで、macOS版の"ミュージック.app"に非対応、再生不可。
- Windows版のiTunesは確かwmaの変換を自動でやってくれたはず。
- そもそも`wma`自体があんまり普及しなかった。

##FFmpegってなに？

クロスプラットフォームのメディアコンバーター
普通に出回ってるフリーソフトは特定のOS（だいたいWindows）しかサポートされてなかったりするのでこれは結構助かる。

ただ、FFmpegはコマンドライン操作が基本になるので、CLIが苦手な人向けにGUIアプリがシェアウェアで提供されてたりする。


## 準備

### ffmpegのインストール

```shell
$ brew install ffmpeg
```

もし、Homebrewが入ってない場合は

AppStoreからXcodeをインストールし
ターミナルから以下のコマンドを叩いてコマンドラインツールを入れる

```shell-session
$ xcode-select --install
```

[Homebrew公式サイト](https://brew.sh/index_ja.html)を参考に以下のコマンドを叩いて実行

```shell-session
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

### AtomicParsleyのインストール

変換後のm4aファイルのメタデータにアルバム毎のアートワークを載せるのでAtomicParsleyを入れておく。

```shell
$ brew install atomicparsley
```

## FFmpegの基本構文

基本はこれ

```shell-session
$ ffmpeg -i "入力ファイル" (変換オプション) "出力ファイル"
```
色んなオプションがついたりして複雑になったりする。

## ShellScript作成

結論から言うと以下のコードになりました。

```convert_wma_to_apple_lossless.sh
#!/bin/sh
IFS_BACKUP=$IFS
IFS=$'\n'
for file in $(\find . -name '*.wma' -maxdepth 6 -type f);
do
  fileext="${file##*.}"
  filename="${file%.*}"
  filedir=$(dirname "${file}")
  echo "filename: $filename"

  if [ $fileext = "wma" ] || [ $fileext = "WMA" ]; then
    echo "Now conberting 🎹 ${file}"
    ffmpeg -i "${filename}.wma" "${filedir%/}/artwork.jpg" -y
    ffmpeg -i "${filename}.wma" -vn -acodec flac "${filename}.flac" -y
    ffmpeg -i "${filename}.flac" -vn -acodec alac "${filename}.m4a" -y
    yes | AtomicParsley "${filename}.m4a" --artwork "${filedir%/}/artwork.jpg" --overWrite
    echo "Image from ${filedir}/artwork.jpg"
    echo "${filedir}"
    rm "${filename}.flac"
    echo "${filename}.wma ===== > ${filename}.m4a"
  fi
done

echo "";
echo "  #######   ####    ##   ##   ####     #####   ##   ##  #######  ##### ";
echo "   ##   #    ##     ###  ##    ##     ##   ##  ##   ##   ##   #   ## ## ";
echo "   ## #      ##     #### ##    ##     #        ##   ##   ## #     ##  ## ";
echo "   ####      ##     ## ####    ##      #####   #######   ####     ##  ## ";
echo "   ## #      ##     ##  ###    ##          ##  ##   ##   ## #     ##  ## ";
echo "   ##        ##     ##   ##    ##     ##   ##  ##   ##   ##   #   ## ## ";
echo "  ####      ####    ##   ##   ####     #####   ##   ##  #######  ##### ";
echo "";

IFS=$IFS_BACKUP

echo $'\a'
```
***


上から順に解説

```convert_wma_to_apple_lossless.sh
#!/bin/sh
IFS_BACKUP=$IFS
IFS=$'\n'
```

- IFS(Internal Field Separator )に改行のみを区切り文字として設定する
- 要は空白文字を区切りと見做さないようにする。

***

```convert_wma_to_apple_lossless.sh
for file in $(\find . -name '*.wma' -maxdepth 6 -type f);
do
  fileext="${file##*.}"
  filename="${file%.*}"
  filedir=$(dirname "${file}")
  echo "filename: $filename"
```

このシェルを実行したディレクトリから6段目の深さのディレクトリに対して、

- .wmaの拡張子を持つファイルを検索
- fileextでディレクトリ名から拡張子を抜き出し
- filenameでディレクトリ名からファイル名を抜き出し
- filedirでディレクトリ抜き出し
- 詳しくは[こちら](https://qiita.com/mriho/items/b30b3a33e8d2e25e94a8)を参照。

***

```convert_wma_to_apple_lossless.sh
if [ $fileext = "wma" ] || [ $fileext = "WMA" ]; then
    echo "Now conberting 🎹 ${file}"
    ffmpeg -i "${filename}.wma" "${filedir%/}/artwork.jpg" -y
    ffmpeg -i "${filename}.wma" -vn -acodec flac "${filename}.flac" -y
    ffmpeg -i "${filename}.flac" -vn -acodec alac "${filename}.m4a" -y
```
- FFmpegで元のwmaファイルからアートワークを`artwork.jpg`として抽出
- 元の`wma`から一旦`flac`に変換
- `flac`からApple Lossless（`alac`）に変換

なぜか`wma`から直接`alac`へ変換すると、ミュージック.appで開いた時に音が出なかった。
VLCでは問題なく再生されるので原因不明だが、一旦flacにして`alac`にするとミュージック.appでも音が出る。
(筆者はこれで嵌った）


***


```convert_wma_to_apple_lossless.sh
    yes | AtomicParsley "${filename}.m4a" --artwork "${filedir%/}/artwork.jpg" --overWrite
    echo "Image from ${filedir}/artwork.jpg"
    echo "${filedir}"
    rm "${filename}.flac"
    echo "${filename}.wma ===== > ${filename}.m4a"
  fi
done
```

- 新しい`m4a(alac)`はアルバムアートワークがないのでAtomicParsleyを使ってアートワーク追加
- `flac`ファイルを削除

***

```convert_wma_to_apple_lossless.sh
echo "";
echo "  #######   ####    ##   ##   ####     #####   ##   ##  #######  ##### ";
echo "   ##   #    ##     ###  ##    ##     ##   ##  ##   ##   ##   #   ## ## ";
echo "   ## #      ##     #### ##    ##     #        ##   ##   ## #     ##  ## ";
echo "   ####      ##     ## ####    ##      #####   #######   ####     ##  ## ";
echo "   ## #      ##     ##  ###    ##          ##  ##   ##   ## #     ##  ## ";
echo "   ##        ##     ##   ##    ##     ##   ##  ##   ##   ##   #   ## ## ";
echo "  ####      ####    ##   ##   ####     #####   ##   ##  #######  ##### ";
echo "";

IFS=$IFS_BACKUP

echo $'\a'
```

- バカでかい**FINISHED**のAA
- `echo $'\a'`でターミナルから音を鳴らして知らせる。

### WMAファイルを消す

このままだと変換前のWMAファイルが残るので、以下を実行

```remove_wma.sh
#!/bin/sh

IFS_BACKUP=$IFS
IFS=$'\n'
for file in $(\find . -name '*.wma' -maxdepth 6 -type f);
do
  fileext="${file##*.}"
  filename="${file%.*}"
  echo "filename: $filename"

  if [ $fileext = "wma" ] || [ $fileext = "WMA" ]; then
    echo "Now conberting 🎹 ${file}"
    rm "${filename}.wma"
    
    echo "${filename}.wma ===== > NONE "
  fi
done

echo "Windows Media Audio データ削除 おしまい!";
echo "";
echo "  #######   ####    ##   ##   ####     #####   ##   ##  #######  ##### ";
echo "   ##   #    ##     ###  ##    ##     ##   ##  ##   ##   ##   #   ## ## ";
echo "   ## #      ##     #### ##    ##     #        ##   ##   ## #     ##  ## ";
echo "   ####      ##     ## ####    ##      #####   #######   ####     ##  ## ";
echo "   ## #      ##     ##  ###    ##          ##  ##   ##   ## #     ##  ## ";
echo "   ##        ##     ##   ##    ##     ##   ##  ##   ##   ##   #   ## ## ";
echo "  ####      ####    ##   ##   ####     #####   ##   ##  #######  ##### ";
echo "";

IFS=$IFS_BACKUP

echo $'\a'
```

## スクリプトのエイリアス登録

`convert_wma_to_apple_lossless.sh`や`remove_wma.sh`をエイリアス登録しておく
筆者はzsh環境なので以下のように設定。

bashの場合は[こちら](https://qiita.com/_ydah/items/18d242b632e5486fe912)を参照。

```~/.zshrc
alias wma-to-alac='zsh -c /Users/ユーザー名/shell_scripts/convert_wma_to_apple_lossles.sh'
alias remove-wma='zsh -c /Users/ユーザー名/shell_scripts/remove_wma.sh'
```

## 実行
一括コンバートしたいファイルがあるディレクトリへ`cd`してスクリプトを実行する。

変換ファイルが大量にあるときは一晩くらい寝かせればOK。


## 結果
一旦`flac`を経由して`alac`にしているので時間はかかるが一応変換はできる
`ミュージック.app`でも再生できる。

※コンバート終了時に音が鳴るので普通にビビります。


## 最後に

今回は初めてShellScriptをQiitaに上げました。
FFmpegは動画の変換や動画から音声抜き出しなんかもできるので便利ですね。