はじめに
本記事は、Sonyのウォークマンにアルバムを転送するとアルバムの最後の1曲しか転送されない件について、対処を行った時の記録です。
背景
旧PCにて、x-アプリからMusic Centerに移行をしました。その後、新PCにデータ移行するためにバックアップファイルを作成し、旧PCから新PCに移行をしました。ウォークマンの中身を整理するために、いったん全てのファイルを削除してMusic Centerからウォークマンに転送すると、なにやら一部の曲しか転送されていないことに気が付きました。
事象としては「アルバムの最後の1曲しか転送されない」というもので、FAQにも掲載されている内容です。FAQは以下。
https://musiccenter.sony.net/ja/faqs/faq028.php
FAQにあった策を試してみましたが、上手くいかず。そもそも随分前に新PCに移行したため、バックアップファイルは既になくFAQの方法ではおそらく無理っぽい。
FAQをよく読むと、バックアップして取り込む際にアルバム内のファイル名が同一となるのが原因らしく、それをウォークマンに転送すると同一アルバムの曲が上書きされていくというもの。
どこからどう見ても、バグですね、これ。
Sonyのバグで音楽データ資産を失うのは癪なので、自分で対処方法を考えたという次第です。
対処方法の概要
全ての音楽ファイルは特定フォルダ以下に格納されており、以下のようになっていました。
"C:\Music\0001\1001\500\000.mp3"
"C:\Music\0010\66\500\000.mp3"
音楽ファイルのプロパティには、アーティストやアルバム名、タイトルなどの情報がありこの情報を使ってリネームしてやれば良いのでは?という考え。
今後のことも考え以下のように再構築し、再構築したものをMusic Centerに取り込み直す。
"C:\Music\[アーティスト]\[アルバム]\[トラックNo.]_[タイトル].[拡張子]"
例えば以下のような感じ。
"C:\Music\星野源\POP VIRUS\02_恋.mp3"
手作業ではやってられないので、Windows PowerShellで自動化します。
PowerShellのソースコード
実行したソースコードは以下の通りです。
実施したいことは説明済で、説明はソースコードにコメントとして入れているので、説明は省略します。
$sh = New-Object -ComObject Shell.Application
# 読込/書込先のフォルダを指定
$infolder = "C:\Music\MusicCenter"
$outfolder = "C:\Music\Convert"
# 読込先のフォルダ以降の階層で音楽ファイルを検索
$items = Get-ChildItem -Recurse -Path $infolder -Include *.mp* -Name
# 音楽ファイルの情報出力用
Write-Host "アーティスト アルバム トラック番号 タイトル"
Write-Host "----------------------------------------------"
# 音楽ファイル毎に処理
foreach($f in $items)
{
#プロパティ取得用に音楽ファイルのあるディレクトリとファイル名を分割
$infile = $infolder + "\" + $f
$file_n = [System.IO.Path]::GetFileName($infile)
$file_d = [System.IO.Path]::GetDirectoryName($infile)
#プロパティのリストを取得
$folder = $sh.Namespace($file_d)
$fi = $folder.ParseName($file_n)
#プロパティを取得
$artist = $folder.GetDetailsOf($fi,13)
$album = $folder.GetDetailsOf($fi,14)
$num = $folder.GetDetailsOf($fi,26).PadLeft(2,"0")
$title = $folder.GetDetailsOf($fi, 21)
$time = $folder.GetDetailsOf($fi, 27)
$size = $folder.GetDetailsOf($fi,1)
#デバッグ用に情報を出力
Write-Host $artist ":" $album ":" $num ":" $title
#使用できない文字を置換
$artist = $artist -replace "\/","-"
$artist = $artist -replace "\[","["
$artist = $artist -replace "\]","]"
$artist = $artist -replace "\?","?"
$artist = $artist -replace "\:",":"
$artist = $artist -replace '"',''
$artist = $artist -replace "\*","*"
$artist = $artist -replace "\<","<"
$artist = $artist -replace "\>",">"
$artist = $artist -replace "\\"," "
$album = $album -replace "\/","-"
$album = $album -replace "\[","["
$album = $album -replace "\]","]"
$album = $album -replace "\?","?"
$album = $album -replace "\:",":"
$album = $album -replace '"',''
$album = $album -replace "\*","*"
$album = $album -replace "\<","<"
$album = $album -replace "\>",">"
$album = $album -replace "\\"," "
$title = $title -replace "\/","-"
$title = $title -replace "\[","["
$title = $title -replace "\]","]"
$title = $title -replace "\?","?"
$title = $title -replace "\:",":"
$title = $title -replace '"','”'
$title = $title -replace "\*","*"
$title = $title -replace "\<","<"
$title = $title -replace "\>",">"
$title = $title -replace "\\"," "
#ファイルコピー用のディレクトリ/ファイル名の指定
$extension = [System.IO.Path]::GetExtension($infile);
$artist_d = $outfolder + "\" + $artist
$album_d = $outfolder + "\" + $artist + "\" + $album
$outfile = $outfolder + "\" + $artist + "\" + $album + "\" + $num + "_" + $title + $extension
#音楽ファイルに対応するアーティストのフォルダがない場合は作成
if ( !(Test-Path $artist_d -PathType Container))
{
New-Item $artist_d -ItemType Directory
}
#音楽ファイルに対応するアルバムのフォルダがない場合は作成
if ( !(Test-Path $album_d -PathType Container))
{
New-Item $album_d -ItemType Directory
}
#指定ファイル名で音楽ファイルをコピー
if (!(Test-Path $outfile -PathType Leaf))
{
Copy-Item $infile -Destination $outfile
}
}
"終了するには何かキーを押してください
補足
音楽ファイルのプロパティから情報を取り出す際に、環境によっては上記の引数では所望の情報を取り出せない可能性があるかも(知らんけど)。以下のスクリプトをPowerShellで実行するとプロパティの一覧を出力できるので、各自で欲しい情報の引数を探して対応すればよい。
$path = "C:\Music\星野源\POP VIRUS\02_恋.mp3"
$shell = New-Object -COMObject Shell.Application
$folder = Split-Path $path
$file = Split-Path $path -Leaf
$shellfolder = $shell.Namespace($folder)
$shellfile = $shellfolder.ParseName($file)
0..310 | Foreach-Object { '{0}:{1}' -f $_, $shellfolder.GetDetailsOf($null, $_) }
"続行するには何かキーを押し. . ."
$host.UI.RawUI.ReadKey()
参考にしたサイトは色々とありますが、メモしていなかったので省略させて頂きます。
以上