2020年2月17日月曜日

soxコマンドでFlacファイルを分割する

僕はすべてのトラックを完全ランダム再生している。
それで困るのは非常に1曲が長いCDの場合だ。
例えば、極端な例だが、「セイシェル」は1CD1トラック。1曲(?)が57分ある。

普通は冒頭部分を少し聴いてスキップすることになる。
ただそれだと後半部などは一生聴くことがない。

そこで長いトラックを再生しようとした時、その曲のある部分だけ選択して再生するよう提案してくれるスクリプトをHaskellで書いてみた。

以下が実行結果。

$ runghc m2.hs
分 秒
57 42
3462.0
12.0
288.5
[(0.0,288.5),(288.5,577.0),(577.0,865.5),(865.5,1154.0),(1154.0,1442.5),(1442.5,1731.0),(1731.0,2019.5),(2019.5,2308.0),(2308.0,2596.5),(2596.5,2885.0),(2885.0,3173.5),(3173.5,3462.0)]
(0.0,288.5)
(0,0),(4,49)

「セイシェル」のケース。
トラックの演奏時間が、3462秒。
12分割すると
1単位が288秒。

その場合の各サブトラックがタプルのリストで表示されている。
そこからランダムに選びスクリプトが提案したのが
(0,0),(4,49)
つまり冒頭から4分49秒まで。

また別の機会では、

(38,29),(43,17)
つまり38分29秒から43分17秒まで。

これなら1回5分程度の演奏で済み、やがては、まんべんなく全曲を聴くことができるはずだ。(長い目でみれば)

スクリプトは高度なアルゴリズムなどは使っておらず、適当に分割してリストの要素をランダムに選択しているだけです。

なおあるトラックの演奏時間は「Soxi」コマンドにDオプションをつければ取得できます。

$ soxi -D ~/music/Seychelles/Seychelles/sdem.flac 
3462.866667
$ soxi -d ~/music/Seychelles/Seychelles/sdem.flac 
00:57:42.87



実際に使ってみると演奏を中断してスクリプトを実行する、というのはとても面倒だった。

で予め適当な長さに分割しておくことにした。
本当はプレイリストなどから、自動で分割してまわるようにするといいのかもしれないが、
残念ながらそこまでの知識はないので、一つ一つ手作業で分割する。

まず適当なディレクトリー(tmp)をつくって目的のファイルをコピーしておく。

このディレクトリーには各種スクリプトがすでに存在するものとする。

a.hs
m.hs
の2つ。

$ ls tmp
a.hs  m.hs  sdem.flac



実行例
$ runghc a.hs sdem.flac | runghc m.hs
("sdem.flac",3462.866667)
12.0
288.57222225
[0.0,288.57222225,577.1444445,865.71666675,1154.288889,1442.8611112499998,1731.4333335,2020.00555575,2308.577778,2597.1500002499997,2885.7222224999996,3174.29444475]
"sdem.flac"
288.57222225
sdem.flac -> trimed0sdem.flac
sdem.flac -> trimed289sdem.flac
sdem.flac -> trimed577sdem.flac
sdem.flac -> trimed866sdem.flac
sdem.flac -> trimed1154sdem.flac
sdem.flac -> trimed1443sdem.flac
sdem.flac -> trimed1731sdem.flac
sdem.flac -> trimed2020sdem.flac
sdem.flac -> trimed2309sdem.flac
sdem.flac -> trimed2597sdem.flac
sdem.flac -> trimed2886sdem.flac

$ ls -hl
合計 559M
-rw-rw-r-- 1 i i  147  2月 21 09:43 a.hs
-rw-rw-r-- 1 i i  882  2月 22 05:13 m.hs
-rwxrwxr-x 1 i i 276M  2月 22 05:11 sdem.flac
-rw-rw-r-- 1 i i  27M  2月 22 05:14 trimed0sdem.flac
-rw-rw-r-- 1 i i  23M  2月 22 05:14 trimed1154sdem.flac
-rw-rw-r-- 1 i i  23M  2月 22 05:14 trimed1443sdem.flac
-rw-rw-r-- 1 i i  22M  2月 22 05:14 trimed1731sdem.flac
-rw-rw-r-- 1 i i  23M  2月 22 05:14 trimed2020sdem.flac
-rw-rw-r-- 1 i i  24M  2月 22 05:14 trimed2309sdem.flac
-rw-rw-r-- 1 i i  24M  2月 22 05:14 trimed2597sdem.flac
-rw-rw-r-- 1 i i  25M  2月 22 05:14 trimed2886sdem.flac
-rw-rw-r-- 1 i i  26M  2月 22 05:14 trimed289sdem.flac
-rw-rw-r-- 1 i i  22M  2月 22 05:14 trimed3174sdem.flac
-rw-rw-r-- 1 i i  26M  2月 22 05:14 trimed577sdem.flac
-rw-rw-r-- 1 i i  25M  2月 22 05:14 trimed866sdem.flac

$ soxi -d *flac
00:57:42.87
00:04:58.57
00:04:58.57
00:04:58.57
00:04:58.57
00:04:58.57
00:04:58.57
00:04:58.57
00:04:58.57
00:04:58.57
00:04:48.57
00:04:58.57
00:04:58.57


確かにFlacファイルが12分割されている。

なお1から11までのサブトラックと最後のサブトラックの処理をわけているのは、
元のトラックの長さを超えて時間指定すると、Soxがエラーになるためです。
気にしなければ必要ありません。

前後に無音部分を挿入したり、フェードイン、フェードアウトしたり色々できるとは思いますが、
そのへんは演奏ソフトに任せたほうが得策かも・・・

Soxコマンドには分割のためのオプションも存在しますが、曲の途中でぶつ切りしてしまいます。

Haskellのスクリプトでは10秒分クロスするようにしています。



Gui版

https://github.com/index333/trim

すべてのHaskellスクリプトはホームディレクトリーに置くことにした。

trim というスクリプトを用意している。

$ cat trim
runghc ~/fc.hs > fn
runghc ~/t.hs | runghc ~/t2.hs
runghc ~/del.hs

gtk2hs のファイル・チューザー・ダイアログはデフォルトで開くディレクトリーなどを指定できない。

ひと工夫必要だった。

まずファイル・チューザー・ダイアログの設定ファイル

~/.config/gtk-2.0/gtkfilechooser.ini

を編集する。

$ cat ~/.config/gtk-2.0/gtkfilechooser.ini
[Filechooser Settings]
LocationMode=path-bar
ShowHidden=false
ShowSizeColumn=true
GeometryX=0
GeometryY=0
GeometryWidth=720
GeometryHeight=540
SortColumn=name
SortOrder=ascending
StartupMode=recent

StartupModeがrecentとなっているのをcwd(current-working-directory) に書き換える。

StartupMode=cwd

次にファイルマネージャーで分割したいFlacファイルのあるディレクトリーを探し
そのディレクトリーで端末を開く。


Mateのファイルマネージャー「Caja」の場合

「端末の中に開く」をクリック。

このように端末が開くので、このディレクトリーからスクリプトを起動する。

なおスクリプト「trim」は、実行権限を与えておく。

$ chmod 777 trim

またTrisquelではあらかじめ$HOME/binに実行パスが通っているので
 
bin ディレクトリーを作ってコピーしておけばよい。

$ mkdir bin
$ cp trim bin

$ ll bin
合計 4.0K
-rwxrwxr-x 1 i i 67  3月 12 12:36 trim

実行例



ファイル・チューザー・ダイアログが開くので目的のFlacファイルを選択すればSoxコマンドにより適当に分割してくれる。

同ディレクトリー内の他のファイルも分割したければ、再度スクリプトを起動すればよい。

注:Soxコマンドはイメージタグ等の編集はできないので、分割で作られた新たなFlacファイルには
EasyTag等で手動でタグ付けが必要です。

0 件のコメント:

コメントを投稿