已经问了一个多星期了,实在不想问这个转换问题了,原以为就快解决了,但又遇到了问题。o(︶︿︶)o 唉,纠结。微软的ppt可以读取MP3文件,但是当插入mp3文件的时候不能将mp3文件作为一个对象插入到ppt中,插入的只是一个路径,而wav文件却可以,因为它只允许wav文件这样做,但是,如果将MP3文件用代码直接转换成wav文件,文件将是原来mp3的数倍大小,而且转换速度也不容乐观;我找资料了解到了ppt读取wav文件的特点,只读取它的头部(这是我在一个牛人的博客里面看到的),所以我想将每个mp3文件加一个wav文件头。
各位大虾,我现在已经知道了如何读取mp3文件,知道如何操作mp3文件了,但是现在面临一个问题了,如何给mp3文件添加文件头,我看了一下wav文件的文件头格式,有42个字节,有的可能还有44个字节,格式是这样的
RIFF10018WAVEfmt16111102518data9981,数字代表一些值,字母是wav文件的一些标志,当我将这一行代码插入到每个MP3文件的时候,把mp3文件在此插入到ppt中,仍旧是个地址,没有插入整个MP3对象,请问这是什么原因。谢谢。
由于此问题困扰太久,急需解决,所以多给点分了,呵呵
下面是我的代码:
private FileStream fs;
//MP3文件路径
string filename = "F:\\1.mp3";
//42个字节的wav文件头部
byte[] wavhead = new byte[42] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite);
wavhead = System.Text.Encoding.GetEncoding("GBK").GetBytes("RIFF10018WAVEfmt16111102518data9981");
fs.Seek(0, SeekOrigin.Begin);
fs.Write(wavhead, 0, wavhead.Length);
fs.Read(head, 0, head.Length);
fs.Seek(-128, SeekOrigin.End);
fs.Read(tail, 0, 128);
我再次更新代码,查阅了WAV文件的格式,下面的代码中,有些参数的取值,你需要自己斟酌,我使用了
Windows 7的开机音乐的部分参数值.
Encoding gbkEncoding = Encoding.GetEncoding("GBK");
byte[] mp3Head = new byte[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
byte[] mp3Tail = new byte[128];
using (FileStream mp3Stream = File.OpenRead("E:\\cer\\我和春天有个约会.mp3"))
{
mp3Stream.Read(mp3Head, 0, mp3Head.Length);
mp3Stream.Seek(-128, SeekOrigin.End);
mp3Stream.Read(mp3Tail, 0, 128);
using (FileStream wavStream = File.Open("E:\\cer\\我和春天有个约会.wav", FileMode.Create))
{
int startIndex; // MP3 文件开始读取音频数据的位置。
int dataLen; // 音频数据的长度。
if (gbkEncoding.GetString(mp3Head, 0, 3).ToUpper() == "ID3")
{
startIndex = (mp3Head[6] & 0x7F) * 0x200000 + (mp3Head[7] & 0x7F) * 0x400 + (mp3Head[8] & 0x7F) * 0x80 + (mp3Head[9] & 0x7F);
dataLen = (int)mp3Stream.Length - startIndex;
}
else if (gbkEncoding.GetString(mp3Tail, 0, 3).ToUpper() == "TAG")
{
startIndex = 0;
dataLen = (int)mp3Stream.Length - 128;
}
else
{
// 非法的 MP3 文件格式。
return;
}
// 开始写 WAV 文件。
using (BinaryWriter bw = new BinaryWriter(wavStream))
{
// 下面是写 WAV 文件头。
// 00H 4 char "RIFF"标志
bw.Write(gbkEncoding.GetBytes("RIFF"),0,4);
// 04H 4 long int 文件长度
bw.Write(44 + dataLen);
// 08H 4 char "WAV"标志
bw.Write(gbkEncoding.GetBytes("WAVE"),0,4);
// 0CH 4 char "fmt"标志 ,注意这里 fmt 后要加一个空格,因此需要 4 个字符。
bw.Write(gbkEncoding.GetBytes("fmt "),0,4);
// 10H 4 过渡字节(不定)
bw.Write(new byte[]{0x16,0x00,0x00,0x00},0,4);
// 14H 2 int 格式类别(10H为PCM形式的声音数据)
bw.Write((Int16)1);
// 16H 2 int 单声道为1,双声道为2通道数
bw.Write((Int16)2);
// 18H 4 long 采样率(每秒样本数),表示每个通道的播放速度
bw.Write((Int32)44100);
// 1CH 4 long 波形音频数据传送速率,其值为通道数×每秒数据
// 位数×每样本的数据位数/8。播放软件利用此值可以估计缓冲区的大小
bw.Write((Int32)176400);
// 20H 2 int 数据块的调整数(按字节算的),其值为通道数×每样本的数据位
// 值/8。播放软件需要一次处理多个该值大小的字节数据,以便将其
// 值用于缓冲区的调整。
bw.Write((Int16)4);
// 22H 2 每样本的数据位数,表示每个声道中各个样本的数据位数。
// 如果有多 个声道,对每个声道而言,样本大小都一样。 24H 4 char
// 数据标记符"data" 28H 4 long int 语音数据的长度
bw.Write((Int16)16);
// 24H 4 char 数据标记符"data"
bw.Write(gbkEncoding.GetBytes("data"),0,4);
// 28H 4 long int 语音数据的长度
bw.Write((Int32)dataLen);
// 下面是写音频数据。
mp3Stream.Seek(startIndex, SeekOrigin.Begin);
byte[] buffer = new byte[4096];
while (true)
{
if (dataLen >= 4096)
{
int count = mp3Stream.Read(buffer, 0, 4096);
bw.Write(buffer, 0, count);
dataLen -= count;
}
else
{
int count = mp3Stream.Read(buffer, 0, 4096);
bw.Write(buffer, 0, count);
break;
}
}
}
}
}
真是替你纠结呀....