背景:IOS中实现视频和语音的同步播放(视频静音情况下),安卓实现不了audio与video的同时播放,所以出此下策,如果能实现求告知!
因为安卓微信用的x5 video标签与原来的video不同,在聊天框输入debugx5.qq.com 点击清除tbs后,安卓浏览器可同步播放,不利于客户操作。
技术实现步骤:
1.后台通过微信多媒体接口下载多个音频文件
2。把下载的语音合成一个语音
3.把合成的语音添加到视频中
代码:
1.下载
List<string> pathList = new List<string>(); //下载的录音文件地址集合
for (int i = 0; i < mediaList.Length; i++)
{
string stUrl = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=" + Token + "&media_id=" + mediaList[i];//mediaList是微信录音upload的id集合
string savepath = Path.Combine(basePath, "part", openid + i.ToString() + ".amr"); //basePath 是服务器路径 openid + i 的方式区分第几段录音
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(stUrl);
req.Method = "GET";
using (WebResponse wr = req.GetResponse())
{
HttpWebResponse myResponse = (HttpWebResponse)req.GetResponse();
strpath = myResponse.ResponseUri.ToString();
WebClient mywebclient = new WebClient();
try
{
//下载多个录音文件
mywebclient.DownloadFile(strpath, savepath); //下载到savepath
pathList.Add(savepath); 记录集合,为了之后的合成一段录音
}
catch (Exception ex)
{
Log.Error("bug1", ex.ToString().Substring(0, 2000));
}
}
}
2.拼接
微信接口下的都是amr文件,用ffmpeg转成mp3(应该可以不转直接放入视频中,我是因为一开始打算让video+audio同步播放所以才转成mp3的,后来为了实现功能这部分就没改)
类:
public class CombineFile
{
private List<string> files = new List<string>();
// 需要合并的文件
public List<string> Files
{
get
{
return files;
}
}
public CombineFile()
{
}
public CombineFile(List<string> filePath)
{
this.files = filePath;
}
public void Combine(string fullName)
{
if (!(this.files.Count > 0))
{
throw new Exception("文件列表为空");
}
foreach (string item in this.files)
{
if (!File.Exists(item))
{
throw new Exception(string.Format("文件{0}不存在", item));
}
}
byte[] buffer = new byte[1024 * 100];
using (FileStream outStream = new FileStream(fullName, FileMode.Create))
{
int readedLen = 0;
FileStream srcStream = null;
for (int i = 0; i < files.Count; i++)
{
srcStream = new FileStream(files[i], FileMode.Open);
while ((readedLen = srcStream.Read(buffer, 0, buffer.Length)) > 0)
{
outStream.Write(buffer, 0, readedLen);
}
srcStream.Close();
}
}
}
}
使用方法:
//list是上面pathList 把string[]转成list<string>放进去
CombineFile cf = new CombineFile(list);
//
cf.Combine("合成的文件路径");
3.转换
filename是原地址,targetFilName是生成的目标地址 少了个e。。
G:\toolsZ\ffmpeg64\bin是我服务器的ffmpeg文件地址,改成你的
下载地址:https://ffmpeg.zeranoe.com/builds/ 如果是windows的选中间windows 64 或32位的
public void ConvertToAmr(string fileName, string targetFilName)
{
string c1 = @"G:\toolsZ\ffmpeg64\bin" + @"\ffmpeg.exe -i " + fileName + " -codec:a libmp3lame -qscale:a 320k " + targetFilName;
c1 = c1.Replace("//", "\\").Replace("/", "\\");
string c2 = @"G:\toolsZ\ffmpeg64\bin" + @"\ffmpeg.exe -i F:\pro_other\file\DubIn\base\defaultN.mp4 -i " + targetFilName + " " + targetFilName.Replace("mp3", "mp4").Replace("//", "\\").Replace("/", "\\");
Cmd(c1 + " && " + c2);
//Thread.Sleep(2000);
//Cmd1(c2);
}
c1的意思是 把原来合成的amr文件转成mp3,码率参考https://www.cnblogs.com/coolbear/p/8758527.html
c2的意思是把生成的mp3加入到mp4中 defaultN.mp4是我要合成的视频模版,改成你们用的固定的或者对应的。
cmd中“&&” 代表前面一句完成后执行下一句
private void Cmd(string c1)
{
try
{
Process[] myproc = Process.GetProcesses();
foreach (Process item in myproc)
{
if (item.ProcessName == "cmd")
{
item.Kill();
}
}
System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardInput = true;
process.Start();
process.StandardInput.WriteLine(c1 + "&& exit");
process.StandardInput.AutoFlush = true;
//process.StandardInput.WriteLine("exit");
StreamReader reader = process.StandardOutput;//截取输出流
Log.Info("end", "end1");
//process.StandardInput.Flush();
//process.StandardInput.Close();
process.WaitForExit(10000);
process.Close();
Log.Info("end", "end2");
//process.Kill();
//Log.Info("end", "end3");
}
catch(Exception ex)
{
Log.Info("cmdBUG","cmdBUG");
Log.Info("cmdBUG",ex.ToString());
}
}