行き当たりばたりなプログラム:FLVからMP3をブッコ抜く
昨日の仕様に沿ってコーディングしてみた。
C#を使い始めたばかり+試しコーディングなので、あまり考えていません。
ファイルの内容をバイナリとして取得する方法がよくわからないので、いったんArrayListで取得して、チマチマとbyte配列に入れなおすという何とも馬鹿らしい処理を行っています。誰か正しい方法を教えてください。
→2008/08/22追記:fc.Lengthでファイルサイズを取り出しているジャン。これ使って配列の大きさを指定すればいいじゃん。
あと、エラー周りとかも考えんとアカンし、FLVのバイナリデータからmp3のデータを取得するときのindexをインクリメントしているところも、オブジェクト指向ってなにといった体たらくだし。
まあ、とりあえずclassFLV2MP3クラスを使って、以下のようにやれば、FLVファイル:test.flvからぶっこぬいたMP3ファイル:test.mp3ファイルが生成されます。(オイラがアップした”ねんねんころりや”で試してWMPで聴けました)
classFLV2MP3.flv2mp3("test.flv", "test.mp3");
参考(というかここのRubyをC#に落しただけ):BONNOH FRACTION 13さん「RubyでFLVファイルからmp3を抽出する」
using System;
using System.Collections;
using System.IO;
namespace GetNikoDouInfo
{
class classFLV2MP3
{
public static bool flv2mp3(byte[] data, string mp3File)
{
byte[] mp3Data = null;
bool bResult = false;
if (getMP3(data, ref mp3Data))
{
bResult = write(mp3File, mp3Data);
}
return bResult;
}
public static bool flv2mp3(string flvFile, string mp3File)
{
ArrayList dataList = new ArrayList();
if (!File.Exists(flvFile))
{
return false;
}
FileStream fs = new FileStream(flvFile, FileMode.Open, FileAccess.Read);
BinaryReader r = new BinaryReader(fs);
while (fs.Length != fs.Position)
{
dataList.Add(r.ReadByte());
}
r.Close();
fs.Close();
byte[] data = new byte[dataList.Count];
for (int i = 0; i < dataList.Count; i++)
{
data[i] = (byte)dataList[i];
}
return flv2mp3(data, mp3File);
}
// メモリのことを何も考えていない処理
private static bool getMP3(byte[] data, ref byte[] mp3Data)
{
bool bResult = false;
bool bIsError = false;
int index = 0;
int dataType;
int dataSize;
ArrayList mp3DataList = new ArrayList();
// header
index += 9;
for (; data.Length > index && !bIsError; index++)
{
// previous tag size(4)
index += 4;
if (data.Length <= index)
{
break;
}
// DataType(1)
dataType = (int)data[index];
index += 1;
if (data.Length <= index)
{
break;
}
// DataSize(3)
dataSize = (int)data[index] * 0x10000 + (int)data[index + 1] * 0x100 + (int)data[index + 2];
index += 3;
if (data.Length <= index)
{
break;
}
// time stamp(3),time stamp extended(1), stream id(3)
index += 7;
if (data.Length <= index)
{
break;
}
switch (dataType)
{
case 8: // Audio Data
// Audio Info(1)
index += 1;
// mp3data
for (int i = 0; (dataSize - 1 > i) && (data.Length > index); i++, index++)
{
mp3DataList.Add(data[index]);
}
index--;
break;
case 9: // Video Data
index += (dataSize-1);
break;
case 18: // META
index += (dataSize-1);
break;
default:
// ERROR
bIsError = true;
break;
}
}
if (!bIsError)
{
mp3Data = new byte[mp3DataList.Count];
for (int i = 0; mp3DataList.Count > i; i++)
{
mp3Data[i] = (byte)mp3DataList[i];
}
bResult = true;
}
return bResult;
}
private static bool write(string mp3File, byte[] mp3Data)
{
bool bResult = false;
FileStream fs = new FileStream(mp3File, FileMode.Create);
BinaryWriter w = new BinaryWriter(fs);
for (int i = 0; i < mp3Data.Length; i++)
{
w.Write(mp3Data[i]);
}
w.Close();
fs.Close();
bResult = true;
return bResult;
}
}
}
ちなみに環境は、Windows Vista Home Premium + Microsoft Visual C# 2005です。
« 行き当たりばたりでプログラムを作っています | トップページ | 競合しますね »
コメント