のStandardに付属のMedia Player Classic Home Cinemaが優秀でした。
SoX、Winamp、FFmpegのインストール
SoXはVPCJ2: SoX(Sound eXchange)とwinampのインストールのWindows10と同じ14.4.2をインストールしました。
Winampはv2.95をインストールしました。
Winampは再生に使うだけなので話声抽出には必要ありません。
m4aファイルも処理させようと思うのでm4aを変換するためにffmpegもダウンロードします。
mp3ファイルを入力に使うにはSoXがmp3ファイルを扱えるような設定が必要ですが、できないときはffmpegでwavに変換する必要があります。(SoX(Sound eXchange)でMP3を扱う参照。)
ffmpegは最新版だと「プロシージャ エントリ ポイント _wfopen_s がダイナミック リンク ライブラリ msvcrt.dll から見つかりませんでした。」というエラーが出てきてインストールできないので古いバージョンをインストールします。
ffmpegだけでGYAO動画をダウンロードする方法 - ギャッターのフリーソフト広場
ここにffmpeg-20140609-git-6d40849-win32-static.7zはうまくいったという報告があったので、Zeranoe FFmpeg - BuildsからたどってZeranoe FFmpeg - Buildsから同じバージョンをダウンロードしました。
7zファイルを解凍してでてきたファイルの中にあるff-prompt.batを起動するとffmpeg用に環境変数を設定してコマンドプロンプトが立ち上がります。
設定しているの環境変数はPATHだけのようです。
ffmpegでm4aファイルをwavに変換する
SoXはm4aファイルを扱えないのでm4aファイルはまずffmpegでwavファイルに変換しておきます。
ffmpeg -i input.m4a output.wav
これでwavファイルに変換できました。
ffmpegのお仕事はここまでで終わりです。
m4aファイルから録音開始日時を取得するのは断念
ファイルの更新日時は録音終了日時に該当するので録音開始日時を取得する方法を考えます。
for %i in ( input.m4a ) do echo %~ti
> for %i in ( 1.m4a ) do echo %~ti > echo 2016/07/01 10:37 2016/07/01 10:37 |
開始日時は録音時間を更新日時から引けばよいのですが、m4aの録音時間を得る方法がわかりません。
wavファイルならsox -i -dで録音時間がわかるのでこの情報と併用します。
と、思ってバッチファイルを作り始めたらffpmeg.exeと同じフォルダにffprobe.exeを発見しました。
ffmpeg 動画や音声の時間を取得する - Qiita
ffprobe 1.m4a -hide_banner -show_entries format
>ffprobe 1.m4a -hide_banner -show_entries format Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '1.m4a' : Metadata: major_brand : M4A minor_version : 0 compatible_brands: M4A mp42isom creation_time : 2016-07-01 01:37:29 date : 2016-07-01T10:28:18+0900 encoder : com.apple.VoiceMemos (iPhone OS 9.3.2) Duration: 00:09:06.39, start : 0.000000, bitrate: 64 kb/s Stream #0:0(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 62 k b/s (default) Metadata: creation_time : 2016-07-01 01:37:29 handler_name : Core Media Audio [ FORMAT ] filename=1.m4a nb_streams=1 nb_programs=0 format_name=mov,mp4,m4a,3gp,3g2,mj2 format_long_name=QuickTime / MOV start_time=0.000000 duration=546.388322 size=4380133 bit_rate=64132 probe_score=100 TAG:major_brand=M4A TAG:minor_version=0 TAG:compatible_brands=M4A mp42isom TAG:creation_time=2016-07-01 01:37:29 TAG: date =2016-07-01T10:28:18+0900 TAG:encoder=com.apple.VoiceMemos (iPhone OS 9.3.2) [/ FORMAT ] |
ちなみにffprobeで調べるとm4aファイルをwavに変換してもメタデータのdateは元のm4aファイルの情報を引き継いでいました。
なので作るとしたらwavファイルをffprobeで調べてdateを取得してそれの加工ですね。
入力音声ファイルを60秒ずつに分割してそれに対応する話声抽出ファイルを作成するバッチファイル
まず環境設定用のバッチファイルsettings.batを作成します。
結局32bitでも64bitのWindowsでも動くように設定しました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
rem 記録しない音声ファイルの長さ(秒以下)。 set SEC=3 rem vadエフェクト後に分割する間隔(秒) set F_LEN=10 rem 分割1ファイル当たりの録音区間の秒数の設定(秒)。 set DUR=60 rem 分割処理後に削除する音声ファイルの長さ(秒) set SEC2=1 rem ディレクトリ名の設定。スクリプトファイルのあるディレクトリの下層に作られる。 rem データディレクトリ名。 set DATA_DIR=data rem 分割後のデータをいれるディレクトリ名。 set DIVIDED_DIR=divided rem 無音区間削除後のファイルの移動先ディレクトリ名。 set EXTRACTED_DIR=extracted rem ffmpeg.exeのパスの設定。 rem Windows10 64bitの場合。 path %PATH% ;C:\Program Files2\ffmpeg-20160707-b450b82-win64-static\bin rem WindowsXPの場合。 path %PATH% ;C:\Program Files2\ffmpeg-20140609-git-6d40849-win32-static\bin rem sox.exeへのパスの設定。 rem Windows10 64bitの場合。 path %PATH% ;C:\Program Files (x86)\sox-14-4-2 rem WindowsXPの場合。 path %PATH% ;C:\Program Files\sox-14-4-2 rem sox.exeにパスが通っているかの確認。 set T=0 for /F "delims= " %%t in ( 'sox --version' ) do set T= %%t if %T% ==0 ( cls echo sox.exeが見つかりません。 echo . pause exit ) rem SoXの既定の音声デバイスの設定。 set AUDIODRIVER=waveaudio rem このスクリプトがあるディレクトリ。 set SD= %CD% rem データディレクトリDATA_DIRのフルパス。 set DATA_DIR_P= %SD% \ %DATA_DIR% if not exist "%DATA_DIR_P%" ( mkdir "%DATA_DIR_P%" ) rem 改名後のデータをいれるディレクトリRENAMED_DIRのフルパス。 set DIVIDED_DIR_P= %SD% \ %DIVIDED_DIR% if not exist "%DIVIDED_DIR_P%" ( mkdir "%DIVIDED_DIR_P%" ) rem 処理後のファイルの移動先ディレクトリEXTRACTED_DIRのフルパス。 set EXTRACTED_DIR_P= %SD% \ %EXTRACTED_DIR% if not exist "%EXTRACTED_DIR_P%" ( mkdir "%EXTRACTED_DIR_P%" ) rem 再抽出の作業フォルダのフルパス set TMP_DIR_P= %SD% \temp if not exist "%TMP_DIR_P%" ( mkdir "%TMP_DIR_P%" ) |
このバッチファイルがあるフォルダにあるdataフォルダにある音声ファイルに対して処理します。
話声抽出にはSoXの VAD(Voice Activity Detection)エフェクトを使います(SoXで音声感知録音:その4 VAD(Voice Activity Detection)の利用参照)。
60秒(変数DURで設定)ごとに分割した音声ファイルに対して前後からVADエフェクトをかけます。
話声抽出後のファイルの長さが3秒(変数SEC)以下のときはファイルを削除します。
話声抽出後のファイルの長さが10秒(変数F_LEN)より長い時はそのファイルを半割してそれぞれにさらにVADエフェクトをかけて話声抽出をし、その後半割したファイルを結合します。
結合したファイルがの長さが3秒(変数SEC)以下のときはファイルを削除します。
分割されたファイルはdividedフォルダ、話声抽出はextractedフォルダに保存されます。
これらのフォルダはsettings.batを起動すると作成されます。
次は実際に処理を行うextract.batファイルです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
@ echo off call settings.bat setlocal enabledelayedexpansion echo ファイル名に空白があると支障があるのでまずファイル名から空白を除去します。 for %%f in ( "%DATA_DIR_P%\*.*" ) do ( set F=%%~nf move "%%f" "%%~dpf!F: =!%%~xf" ) echo %DATA_DIR_P% にある音声ファイルを %DUR% 秒ごとのwavファイルに分割して %DIVIDED_DIR_P% に保存します。 for %%f in ( "%DATA_DIR_P%\*.*" ) do ( rem 処理ファイルフルパスの取得。 set F_P= %%f if "%%~xf" == ".m4a" ( echo %%~nxfをwavファイルに変換しています。 set F_P= "!TMP_DIR_P!\%%~nf.wav" ffmpeg -hide_banner -i "%%f" "!F_P!" ) echo % %~nf.wavを% DUR %秒ごとのwavファイルに分割して% DIVIDED_DIR_P%に保存しています。 sox "!F_P!" -p | sox -p "%DIVIDED_DIR_P%\%%~nf_%%5n.wav" trim 0 %DUR% : newfile : restart ) rem 削除した全ファイル数 set DCNT=0 rem 再抽出したファイル数 set REEXT=0 rem 再抽出後に削除したファイル数 set DCNT2=0 for %%f in ( "%DIVIDED_DIR_P%\*.wav" ) do ( rem 抽出後のファイル名 set F_NAME= "%EXTRACTED_DIR_P%\%%~nxf" echo 話声抽出後の% %~nxfの長さが% SEC%秒以下なら削除します。 echo 既削除数 !DCNT! (再抽出後既削除数 !DCNT2! / !REEXT! ^) sox "%%f" !F_NAME! vad reverse vad reverse rem sox --iで測定できないときのためにTをリセットする。 set T=0 for /F "tokens=1 delims=." %%t in ( 'sox --i -D !F_NAME!' ) do set T= %%t if !T! LEQ %SEC% ( del /Q !F_NAME! set /A DCNT= !DCNT! +1 echo !F_NAME! の長さが %SEC% 秒以下なので削除しました。 ) rem %F_LEN%秒より長いファイルは半割して再抽出 if !T! GTR %F_LEN% ( set /A REEXT= !REEXT! +1 echo !F_NAME! は %F_LEN% 秒より長いので再抽出します set /A T2= !T! /2 sox !F_NAME! "%TMP_DIR_P%\001.wav" trim 0 !T2! vad reverse vad reverse sox !F_NAME! "%TMP_DIR_P%\002.wav" trim !T2! vad reverse vad reverse del /Q !F_NAME! sox "%TMP_DIR_P%\001.wav" "%TMP_DIR_P%\002.wav" !F_NAME! del /Q "%TMP_DIR_P%\001.wav" del /Q "%TMP_DIR_P%\002.wav" for /F "tokens=1 delims=." %%t in ( 'sox --i -D !F_NAME!' ) do set T= %%t if !T! LEQ 1 ( del /Q !F_NAME! set /A DCNT= !DCNT! +1 set /A DCNT2= !DCNT2! +1 echo 話声再抽出後の !F_NAME! の長さが1秒以下なので削除しました。 ) ) ) rem 作業ディレクトリの削除 rd /s /q "%TMP_DIR_P%" endlocal rem winamp.exeへのパスの設定。 rem Windows7 64bitの場合。 path %PATH% ;C:\Program Files (x86)\Winamp rem WindowsXPの場合。 path %PATH% ;C:\Program Files\Winamp echo %EXTRACTED_DIR_P% のファイルリスト作成中。 rem 第一引数をダブルクォートで括るとウィンドウタイトルとして解釈されてしまう。ダミーを入れておく。 start "" winamp /NEW "%EXTRACTED_DIR_P%" echo %DIVIDED_DIR_P% のファイルリスト作成中。 winamp /NEW /PLAYPAUSE "%DIVIDED_DIR_P%" |
ファイル名に空白があるとffmpegでうまく処理できなかったので事前にファイル名を除く処理を追加しました。
SoXをmp3対応にできていないときにmp3ファイルを処理したいときは13行目の.m4aを.mp3に変更すればffmpegがmp3ファイルをwavファイルに変更してくれると思います(未確認)。
64行目以降は処理したファイルを再生するためのものです。
71行目は話声抽出後のファイルの再生、73行目で話声抽出していない分割ファイルの再生をします。
話声抽出ファイルの再生は/PLAYPUASEスイッチで止まるはずはずなのですが、うまく動いていません。
出力ファイルをmp3に変換する
wavファイルのままだとやっぱりファイルサイズが大きくなりすぎるので出力ファイルをmp3に変換することにしました。
SoXファイルがmp3ファイルを扱えるよう設定されていることが必要です。
また前回出力ファイルを消去するかどうか問い合わせするようにしました。
extract.bat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
@ echo off call 削除.bat call settings.bat setlocal enabledelayedexpansion echo ファイル名に空白があると支障があるのでまずファイル名から空白を除去します。 for %%f in ( "%DATA_DIR_P%\*.*" ) do ( set F=%%~nf move "%%f" "%%~dpf!F: =!%%~xf" ) echo %DATA_DIR_P% にある音声ファイルを %DUR% 秒ごとのwavファイルに分割して %DIVIDED_DIR_P% に保存します。 for %%f in ( "%DATA_DIR_P%\*.*" ) do ( rem 処理ファイルフルパスの取得。 set F_P= %%f if "%%~xf" == ".m4a" ( echo %%~nxfをwavファイルに変換しています。 set F_P= "!TMP_DIR_P!\%%~nf.wav" ffmpeg -hide_banner -i "%%f" "!F_P!" ) echo % %~nf.wavを% DUR %秒ごとのwavファイルに分割して% DIVIDED_DIR_P%に保存しています。 sox "!F_P!" -p | sox -p "%DIVIDED_DIR_P%\%%~nf_%%5n.wav" trim 0 %DUR% : newfile : restart ) rem 削除した全ファイル数 set DCNT=0 rem 再抽出したファイル数 set REEXT=0 rem 再抽出後に削除したファイル数 set DCNT2=0 for %%f in ( "%DIVIDED_DIR_P%\*.wav" ) do ( rem 抽出後のファイル名 set F_NAME= "%EXTRACTED_DIR_P%\%%~nxf" echo 話声抽出後の% %~nxfの長さが% SEC%秒以下なら削除します。 echo 既削除数 !DCNT! (再抽出後既削除数 !DCNT2! / !REEXT! ^) sox "%%f" !F_NAME! vad reverse vad reverse echo 抽出元ファイル%%~nxfをmp3に変換します。 sox "%%f" %OUTOPT% "%%~dpnf.mp3" del /Q "%%f" rem sox --iで測定できないときのためにTをリセットする。 set T=0 for /F "tokens=1 delims=." %%t in ( 'sox --i -D !F_NAME!' ) do set T= %%t if !T! LEQ %SEC% ( del /Q !F_NAME! set /A DCNT= !DCNT! +1 echo !F_NAME! の長さが %SEC% 秒以下なので削除しました。 ) rem %F_LEN%秒より長いファイルは半割して再抽出 if !T! GTR %F_LEN% ( set /A REEXT= !REEXT! +1 echo !F_NAME! は %F_LEN% 秒より長いので再抽出します set /A T2= !T! /2 sox !F_NAME! "%TMP_DIR_P%\001.wav" trim 0 !T2! vad reverse vad reverse sox !F_NAME! "%TMP_DIR_P%\002.wav" trim !T2! vad reverse vad reverse del /Q !F_NAME! sox "%TMP_DIR_P%\001.wav" "%TMP_DIR_P%\002.wav" !F_NAME! del /Q "%TMP_DIR_P%\001.wav" del /Q "%TMP_DIR_P%\002.wav" for /F "tokens=1 delims=." %%t in ( 'sox --i -D !F_NAME!' ) do set T= %%t if !T! LEQ 1 ( del /Q !F_NAME! set /A DCNT= !DCNT! +1 set /A DCNT2= !DCNT2! +1 echo 話声再抽出後の !F_NAME! の長さが1秒以下なので削除しました。 ) ) if exist !F_NAME! ( echo 抽出後のファイル !F_NAME! をmp3に変換します。 sox "!F_NAME!" %OUTOPT% "%EXTRACTED_DIR_P%\%%~nf.mp3" del /Q "!F_NAME!" ) ) rem 作業ディレクトリの削除 rd /s /q "%TMP_DIR_P%" endlocal rem winamp.exeへのパスの設定。 rem Windows7 64bitの場合。 path %PATH% ;C:\Program Files (x86)\Winamp rem WindowsXPの場合。 path %PATH% ;C:\Program Files\Winamp echo %EXTRACTED_DIR_P% のファイルリスト作成中。 rem 第一引数をダブルクォートで括るとウィンドウタイトルとして解釈されてしまう。ダミーを入れておく。 start "" winamp /NEW "%EXTRACTED_DIR_P%" echo %DIVIDED_DIR_P% のファイルリスト作成中。 winamp /NEW /PLAYPAUSE "%DIVIDED_DIR_P%" |
1 2 3 4 5 6 7 8 9 10 11 |
echo 前回処理したファイルをすべて削除します。 echo . echo はい(y^)/いいえ(n^)を選択後Enterキーを押してください。 echo . set /p KEY= "削除しますか?(y/n)" if "%KEY%" == "y" ( rd /s /q extracted rd /s /q divided rd /s /q temp ) cls |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
rem 記録しない音声ファイルの長さ(秒以下)。 set SEC=3 rem vadエフェクト後に分割する間隔(秒) set F_LEN=10 rem 分割1ファイル当たりの録音区間の秒数の設定(秒)。 set DUR=60 rem 分割処理後に削除する音声ファイルの長さ(秒) set SEC2=1 rem ディレクトリ名の設定。スクリプトファイルのあるディレクトリの下層に作られる。 rem データディレクトリ名。 set DATA_DIR=data rem 分割後のデータをいれるディレクトリ名。 set DIVIDED_DIR=divided rem 無音区間削除後のファイルの移動先ディレクトリ名。 set EXTRACTED_DIR=extracted rem 出力音声ファイルの圧縮オプション set OUTOPT=-C -9.2 rem ffmpeg.exeのパスの設定。 rem Windows10 64bitの場合。 path %PATH% ;C:\Program Files2\ffmpeg-20160707-b450b82-win64-static\bin rem WindowsXPの場合。 path %PATH% ;C:\Program Files2\ffmpeg-20140609-git-6d40849-win32-static\bin rem sox.exeへのパスの設定。 rem Windows10 64bitの場合。 path %PATH% ;C:\Program Files (x86)\sox-14-4-2 rem WindowsXPの場合。 path %PATH% ;C:\Program Files\sox-14-4-2 rem sox.exeにパスが通っているかの確認。 set T=0 for /F "delims= " %%t in ( 'sox --version' ) do set T= %%t if %T% ==0 ( cls echo sox.exeが見つかりません。 echo . pause exit ) rem SoXの既定の音声デバイスの設定。 set AUDIODRIVER=waveaudio rem このスクリプトがあるディレクトリ。 set SD= %CD% rem データディレクトリDATA_DIRのフルパス。 set DATA_DIR_P= %SD% \ %DATA_DIR% if not exist "%DATA_DIR_P%" ( mkdir "%DATA_DIR_P%" ) rem 改名後のデータをいれるディレクトリRENAMED_DIRのフルパス。 set DIVIDED_DIR_P= %SD% \ %DIVIDED_DIR% if not exist "%DIVIDED_DIR_P%" ( mkdir "%DIVIDED_DIR_P%" ) rem 処理後のファイルの移動先ディレクトリEXTRACTED_DIRのフルパス。 set EXTRACTED_DIR_P= %SD% \ %EXTRACTED_DIR% if not exist "%EXTRACTED_DIR_P%" ( mkdir "%EXTRACTED_DIR_P%" ) rem 再抽出の作業フォルダのフルパス set TMP_DIR_P= %SD% \temp if not exist "%TMP_DIR_P%" ( mkdir "%TMP_DIR_P%" ) |
参考にしたサイト
無償のFFmpegでWavファイルの変換(Wavに変換)
FFmpegはm4aファイルも扱えます。
ffmpegだけでGYAO動画をダウンロードする方法 - ギャッターのフリーソフト広場
最新版はWindowsXPでは起動できませんでした。
Zeranoe FFmpeg - Builds
WindowsXPにはffmpeg-20140609-git-6d40849-win32-static.7zが使えました。
ffmpeg 動画や音声の時間を取得する - Qiita
ffmpeg付属のffprove.exeで情報の表示はできましたがバッチファイルでの処理はなかなか難しそうです。
0 件のコメント:
コメントを投稿