歌詞定義フォーマットの、LRCファイルとKRAファイル(タイムタグフォーマット)の変換用WSHスクリプト(JScript)を作成したので公開。KRA -> LRC変換と、LRC -> KRA変換の2つ。WSHスクリプトなので、Windows専用。
[使い方]
[使い方]
- KRA -> LRC変換スクリプトの場合はKRAファイル(*.kra)をドラッグ&ドロップします。
LRC -> KRA変換スクリプトの場合はLRCファイル(*.lrc)をドラッグ&ドロップします。 - KRAファイルの場合は、同じフォルダ上にLRCファイル(KRAファイル名.lrc)が作成されます。
LRCファイルの場合は、同様にKRAファイルが作成されます。
- 埋め込まれているタグのうち、 タイトル、アーティスト、アルバム、作詞者、曲の長さ、ファイル作成者以外の情報は削除されます。
- UnicodeのBOMが不要な場合は、コメントアウトしてある「// delete BOM」の辺りをコメント解除すると、BOMが削除されます。
- あんまり真面目にテストしてないので、きちんと動かない場合があるかもしれません。
- とりあえず拡張子固定なので、拡張子lrcでKRAフォーマットにしている人や、拡張子txtでフォーマット定義してる人は知ったこっちゃないです。
KRA -> LRC変換WSHスクリプト
/*==== 設定 ==================================================================*/
var inputExt = /\.kra$/i;
var outputExt = ".lrc";
var inputEncoding = "_autodetect_all";
var outputEncoding = "UTF-8";
/*============================================================================*/
/*==== 定数 ==================================================================*/
// 保存データの種類
// StreamTypeEnum
// http://msdn.microsoft.com/ja-jp/library/cc389884.aspx
var adTypeBinary = 1; // バイナリ
var adTypeText = 2; // テキスト
// 読み込み方法
// StreamReadEnum
// http://msdn.microsoft.com/ja-jp/library/cc389881.aspx
var adReadAll = -1; // 全行
var adReadLine = -2; // 一行ごと
// 書き込み方法
// StreamWriteEnum
// http://msdn.microsoft.com/ja-jp/library/cc389886.aspx
var adWriteChar = 0; // 改行なし
var adWriteLine = 1; // 改行あり
// ファイルの保存方法
// SaveOptionsEnum
// http://msdn.microsoft.com/ja-jp/library/cc389870.aspx
var adSaveCreateNotExist = 1; // ない場合は新規作成
var adSaveCreateOverWrite = 2; // ある場合は上書き
/*============================================================================*/
var args = WScript.Arguments;
if (args.length == 0) {
WScript.Echo("引数を指定するか、ファイルをドラッグ&ドロップしてください。");
WScript.Quit();
}
for (var i = 0; i < args.length; i++) {
var path = args(i);
if (path.match(inputExt) != null) {
writeLyrics(path);
}
}
function writeLyrics(path) {
var streamReader = new ActiveXObject("ADODB.Stream");
var streamWriter = new ActiveXObject("ADODB.Stream");
try {
// read
streamReader.Open();
streamReader.Type = adTypeText;
streamReader.Position = 0;
streamReader.Charset = inputEncoding;
streamReader.LoadFromFile( path );
var text = streamReader.ReadText( adReadAll );
if (text.charCodeAt(0) == 0xFEFF || text.charCodeAt(0) == 0xFFFE) {
text = text.substr(1); // delete BOM
}
// replace
text = text.replace(/(^\s+)|(\s+$)/g, "");
text = text.replace(/(\r\n|\n|\r|^)\[(\d\d:\d\d)\:(\d\d)\]/g, "$1[$2.$3]");
text = text.replace(/\[(\d\d:\d\d)\:(\d\d)\]/g, "<$1.$2>");
text = text.replace(/@Title= *(.*?)(\r\n|\n|\r|$)/g, "[ti:$1]$2");
text = text.replace(/@Artist= *(.*?)(\r\n|\n|\r|$)/g, "[ar:$1]$2");
text = text.replace(/@Album= *(.*?)(\r\n|\n|\r|$)/g, "[al:$1]$2");
text = text.replace(/@Lyricist= *(.*?)(\r\n|\n|\r|$)/g, "[au:$1]$2");
text = text.replace(/@Length= *(.*?)(\r\n|\n|\r|$)/g, "[length:$1]$2");
text = text.replace(/@TaggingBy= *(.*?)(\r\n|\n|\r|$)/g, "[by:$1]$2");
var offset = text.match(/\@Offset= *(.*?)(\r\n|\n|\r|$)/);
if (offset && offset.length >= 2) {
text = text.replace(/\@Offset= *(.*?)(\r\n|\n|\r|$)/, "[offset:" + (offset[1] * -1) + "]$2");
}
text = text.replace(/(\@.*=.*?)(\r\n|\n|\r|$)/g, "");
// write
streamWriter.Type = adTypeText;
streamWriter.Charset = outputEncoding;
streamWriter.Open();
streamWriter.WriteText(text, adWriteChar);
/*
// delete BOM
var bomSize = 0;
if (outputEncoding == "UTF-8") {
bomSize = 3;
} else if (outputEncoding.indexOf("UTF-16") == 0) {
bomSize = 2;
}
streamWriter.Position = 0;
streamWriter.Type = adTypeBinary;
streamWriter.Position = bomSize;
var buffer = streamWriter.Read();
streamWriter.Position = 0;
streamWriter.Write(buffer);
streamWriter.SetEOS();
*/
streamWriter.SaveToFile( path.replace(inputExt, outputExt), adSaveCreateOverWrite );
} finally {
if (streamReader != null) streamReader.Close();
if (streamWriter != null) streamWriter.Close();
}
}
LRC -> KRA変換WSHスクリプト
/*==== 設定 ==================================================================*/
var inputExt = /\.lrc$/i;
var outputExt = ".kra";
var inputEncoding = "_autodetect_all";
var outputEncoding = "UTF-8";
/*============================================================================*/
/*==== 定数 ==================================================================*/
// 保存データの種類
// StreamTypeEnum
// http://msdn.microsoft.com/ja-jp/library/cc389884.aspx
var adTypeBinary = 1; // バイナリ
var adTypeText = 2; // テキスト
// 読み込み方法
// StreamReadEnum
// http://msdn.microsoft.com/ja-jp/library/cc389881.aspx
var adReadAll = -1; // 全行
var adReadLine = -2; // 一行ごと
// 書き込み方法
// StreamWriteEnum
// http://msdn.microsoft.com/ja-jp/library/cc389886.aspx
var adWriteChar = 0; // 改行なし
var adWriteLine = 1; // 改行あり
// ファイルの保存方法
// SaveOptionsEnum
// http://msdn.microsoft.com/ja-jp/library/cc389870.aspx
var adSaveCreateNotExist = 1; // ない場合は新規作成
var adSaveCreateOverWrite = 2; // ある場合は上書き
/*============================================================================*/
var args = WScript.Arguments;
if (args.length == 0) {
WScript.Echo("引数を指定するか、ファイルをドラッグ&ドロップしてください。");
WScript.Quit();
}
for (var i = 0; i < args.length; i++) {
var path = args(i);
if (path.match(inputExt) != null) {
writeLyrics(path);
}
}
function writeLyrics(path) {
var streamReader = new ActiveXObject("ADODB.Stream");
var streamWriter = new ActiveXObject("ADODB.Stream");
try {
// read
streamReader.Open();
streamReader.Type = adTypeText;
streamReader.Position = 0;
streamReader.Charset = inputEncoding;
streamReader.LoadFromFile( path );
var text = streamReader.ReadText( adReadAll );
if (text.charCodeAt(0) == 0xFEFF || text.charCodeAt(0) == 0xFFFE) {
text = text.substr(1); // delete BOM
}
// replace
text = text.replace(/(^\s+)|(\s+$)/g, "");
text = text.replace(/\<(\d\d:\d\d)\.(\d\d)\>/g, "[$1:$2]");
text = text.replace(/\[(\d\d:\d\d)\.(\d\d)\]/g, "[$1:$2]");
text = text.replace(/\[ti: *(.*?)\]/g, "@Title=$1");
text = text.replace(/\[ar: *(.*?)\]/g, "@Artist=$1");
text = text.replace(/\[al: *(.*?)\]/g, "@Album=$1");
text = text.replace(/\[au: *(.*?)\]/g, "@Lyricist=$1");
text = text.replace(/\[length: *(.*?)\]/g, "@Length=$1");
text = text.replace(/\[by: *(.*?)\]/g, "@TaggingBy=$1");
var offset = text.match(/\[offset: *(.*?)\]/);
if (offset && offset.length >= 2) {
text = text.replace(/\[offset: *(.*?)\]/, "@Offset=" + (offset[1] * -1));
}
text = text.replace(/\[[^\d].*?\](\r?\n)?/, "");
text = text + "\r\n@TimeRatio=1\r\n";
// write
streamWriter.Type = adTypeText;
streamWriter.Charset = outputEncoding;
streamWriter.Open();
streamWriter.WriteText(text, adWriteChar);
/*
// delete BOM
var bomSize = 0;
if (outputEncoding == "UTF-8") {
bomSize = 3;
} else if (outputEncoding.indexOf("UTF-16") == 0) {
bomSize = 2;
}
streamWriter.Position = 0;
streamWriter.Type = adTypeBinary;
streamWriter.Position = bomSize;
var buffer = streamWriter.Read();
streamWriter.Position = 0;
streamWriter.Write(buffer);
streamWriter.SetEOS();
*/
streamWriter.SaveToFile( path.replace(inputExt, outputExt), adSaveCreateOverWrite );
} finally {
if (streamReader != null) streamReader.Close();
if (streamWriter != null) streamWriter.Close();
}
}
備考
タイムタグ仕様書(一般者向け)で定義されたフォーマットを「KRAフォーマット」と書いてはいますが、「KRAフォーマット」と言う名称はどこにも定義されてないので、便宜上の名前です。「タイムタグ」や「タイムタグ歌詞」という名称は、LRC等を含めた歌詞定義フォーマット全般で使われる名称なので、フォーマット名称としてはあまり適切ではないと思います。そんなわけで、主に利用される拡張子「KRA」に基づき「KRAフォーマット」と呼称しています。
LRCは「LRCフォーマット」として定義されているため、迷うことはないのですが…。
0 件のコメント:
コメントを投稿