/// <summary> /// 解析音频文件,获取时间戳,截取音频,语音转文字 /// </summary> /// <param name="sound_path"></param> /// <param name="word_path"></param> /// <param name="language"></param> /// <param name="splitTime"></param> public void GetTimeSpan(string sound_path, string word_path, string language, double splitTime = 1.5) { //通过NAudio读取音频文件流 string sound_path_mp3 = ""; try { if (sound_path.ToLower().EndsWith(".mp3") || sound_path.ToLower().EndsWith(".wav")) { sound_path_mp3 = sound_path; //使用ffmpeg将MP3转换为 单声道 16000Hz 16bit的wav string folder = Path.GetDirectoryName(sound_path); string wav_sound_path = folder + "/" + "_" + Path.GetFileNameWithoutExtension(sound_path) + ".wav"; if (FfmpegHelper.ChangeFileType(sound_path, wav_sound_path)) { sound_path = wav_sound_path; } else { LogHelper.Error("使用ffmpeg,MP3转wav文件失败!"); return; } } string totalTimeStr = FfmpegHelper.getMediaDuration(sound_path); TimeSpan totalTime = TimeSpan.Parse(totalTimeStr); //WAV文件读取 WAVReader reader = new WAVReader(); reader.GetTimeSpan(sound_path, out voicePoint, out voiceMilliSecond, splitTime); int channel = reader.channel; int rate = reader.rate; int bit = reader.bit; //voicePoint是为了截取小音频 //voicePoint是双数的原因是有开始时间就有一个结束时间 //最后一次的时间要加上(结束时,没有停顿时间) if (voicePoint.Count % 2 != 0) { voicePoint.Add(totalTime); } int _name = 1;//命名 //一个时间点对应一段音频对应一段文字 for (int i = 0; i < voicePoint.Count; i += 2) { GetBaiduSpeech(voicePoint[i], voicePoint[i + 1], sound_path, _name, language, splitTime, totalTime, channel, rate, bit); ++_name; } //word原文 originalText = NPOIHelper.ExcuteWordText(word_path); //word原文的集合 results = GetTextContrast(voiceFiles.ToArray(), voiceMilliSecond.ToArray(), baidu_text.ToArray(), originalText, language); } catch (Exception ex) { LogHelper.Error(ex.Message); } finally { isFinish = true; //删除MP3文件 if (Util.isNotNull(sound_path_mp3) && File.Exists(sound_path_mp3)) { File.Delete(sound_path_mp3); string mp3_folder = Path.GetDirectoryName(sound_path_mp3); if (Directory.Exists(mp3_folder) && Directory.GetFiles(mp3_folder).Length == 0) { Directory.Delete(mp3_folder); } } //删除word文件 if (File.Exists(word_path)) { File.Delete(word_path); //删除word文件目录 string word_folder = Path.GetDirectoryName(word_path); if (Directory.Exists(word_folder) && Directory.GetFiles(word_folder).Length == 0) { Directory.Delete(word_folder); } } //删除文件夹,删除原音频文件 if (File.Exists(sound_path)) { File.Delete(sound_path); //删除原音频目录 string sound_folder = Path.GetDirectoryName(sound_path); if (Directory.Exists(sound_folder) && Directory.GetFiles(sound_folder).Length == 0) { Directory.Delete(sound_folder); } } } }
/// <summary> /// 解析音频文件,获取时间戳,截取音频,语音转文字 /// </summary> /// <param name="sound_path"></param> /// <param name="word_path"></param> /// <param name="language"></param> /// <param name="splitTime"></param> public void GetTimeSpanLrc(string sound_path, string word_path, string language, double splitTime = 1.5) { string sound_path_mp3 = ""; //音频格式转换后的文件 List <string> cut_sound_files = new List <string> (); //切分后的音频文件 string folder = Path.GetDirectoryName(sound_path); try { if (sound_path.ToLower().EndsWith(".mp3")) { sound_path_mp3 = sound_path; //通过NAudio将文件转换为WAV格式,返回新的文件路径 sound_path = NAudioHelper.GetWavPath(sound_path); } //音频处理,通过lrc的时间戳来截取音频与内容 //1.先从lrc里面获取时间戳与内容 if (Path.GetExtension(word_path).Contains("lrc")) { Dictionary <TimeSpan, string> lrcs = Util.ReadLrc(word_path); List <TimeSpan> times = lrcs.Keys.ToList(); for (int i = 0; i < times.Count; i++) { TextContrastResult _result = new TextContrastResult(); //2.通过时间戳,截取音频 string cut_sound_file = folder + "\\" + i + "_" + sys.getRandomStr() + Path.GetExtension(sound_path); TimeSpan _start = new TimeSpan(); TimeSpan _end = new TimeSpan(); if (i == times.Count - 1) { _end = TimeSpan.Parse(FfmpegHelper.getMediaDuration(sound_path)); } else { _end = times[i + 1]; } _start = times[i]; _result.timespan = times[i].TotalSeconds; _result.contractText = lrcs[times[i]]; _result.baiduText = lrcs[times[i]]; _result.precent = "100%"; bool is_success = FfmpegHelper.CutAudioFile(sound_path, cut_sound_file, _start, _end - _start); if (is_success) { cut_sound_files.Add(cut_sound_file); } //上传到服务器 if (File.Exists(cut_sound_file)) { string server_path = UploadFile.PostFile(cut_sound_file); _result.file_url = server_path; } results.Add(_result); } } //原文 string _originalText = Util.ReadTxt(word_path); originalText = string.Join("", _originalText.Split('|')); } catch (Exception ex) { LogHelper.Error(ex.Message); } finally { isFinish = true; //删除切分的文件 foreach (string cut_sound_file in cut_sound_files) { if (Util.isNotNull(cut_sound_file) && File.Exists(cut_sound_file)) { File.Delete(cut_sound_file); } } //删除MP3文件 if (Util.isNotNull(sound_path_mp3) && File.Exists(sound_path_mp3)) { File.Delete(sound_path_mp3); string mp3_folder = Path.GetDirectoryName(sound_path_mp3); if (Directory.Exists(mp3_folder) && Directory.GetFiles(mp3_folder).Length == 0) { Directory.Delete(mp3_folder); } } //删除word文件 if (File.Exists(word_path)) { File.Delete(word_path); //删除word文件目录 string word_folder = Path.GetDirectoryName(word_path); if (Directory.Exists(word_folder) && Directory.GetFiles(word_folder).Length == 0) { Directory.Delete(word_folder); } } //删除文件夹,删除原音频文件 if (File.Exists(sound_path)) { File.Delete(sound_path); //删除原音频目录 string sound_folder = Path.GetDirectoryName(sound_path); if (Directory.Exists(sound_folder) && Directory.GetFiles(sound_folder).Length == 0) { Directory.Delete(sound_folder); } } } }
/// <summary> /// 截取音频后,对每个小音频获语音转文字,一个音频对应一段文字 /// </summary> /// <param name="startMilliSecond"></param> /// <param name="endMilliSecond"></param> /// <param name="reader"></param> /// <param name="sound_path"></param> /// <param name="_name"></param> /// <param name="language"></param> /// <param name="splitTime"></param> private void GetBaiduSpeech(TimeSpan startMilliSecond, TimeSpan endMilliSecond, string sound_path, int i, string language, double splitTime, TimeSpan totalTime , int channel, int rate, int bit) { string newFile = ""; string _newFile = ""; bool need_delete = true; //将文件保存到新的文件夹(sound_path是原音频路径,newFolder是新的小音频路径,使用完成后将上传到服务器成功的音频删除) string newFolder = System.AppDomain.CurrentDomain.BaseDirectory + "NewSoundFiles/" + Path.GetFileNameWithoutExtension(sound_path) + "/"; try { #region 为截取音频做准备 //开始时间往前取startMilliSecond一半的偏移,结束时间往后取间隔时间的一半的偏移 if (i == 0) { startMilliSecond = startMilliSecond - TimeSpan.FromMilliseconds(startMilliSecond.TotalMilliseconds / 2); } else { startMilliSecond = startMilliSecond - TimeSpan.FromMilliseconds(splitTime / 2); } if (endMilliSecond < totalTime)//最后一次不用取偏移 { endMilliSecond = endMilliSecond + TimeSpan.FromMilliseconds(splitTime / 2); } TimeSpan span = endMilliSecond - startMilliSecond; #endregion string fileName = Path.GetFileNameWithoutExtension(sound_path) + "_" + i + Path.GetExtension(sound_path);//重命名文件 //重新存储到一个新的文件目录 if (!System.IO.Directory.Exists(newFolder)) { System.IO.Directory.CreateDirectory(newFolder); } //拼接后的文件路径 newFile = newFolder + fileName; if (!FfmpegHelper.CutAudioFile(sound_path, newFile, startMilliSecond, span)) { LogHelper.Error("第" + i + "次音频截取失败"); return; } //上传到文件服务器 string server_path = UploadFile.PostFile(newFile); if (Util.isNotNull(server_path)) { //上传成功 voiceFiles.Add(server_path); } else { need_delete = false; //上传失败,在服务器上的路径 voiceFiles.Add(Util.getServerPath() + "/NewSoundFiles/" + Path.GetFileNameWithoutExtension(sound_path) + "/" + fileName); } //大于60s的需要再处理 if (span.TotalSeconds >= 60)//音频大于60s,只截取50s { span = TimeSpan.FromSeconds(50); //保存新的音频文件 string _fileName = "_" + Path.GetFileNameWithoutExtension(sound_path) + "_" + i + ".wav";//重命名文件 _newFile = newFolder + _fileName; //截取音频 if (!FfmpegHelper.CutAudioFile(sound_path, _newFile, startMilliSecond, span)) { LogHelper.Error("第" + i + "次音频截取失败"); return; } //转成pcm //将音频转换为文字 baidu_text.Add(Rays.Utility.BadiAI.BaiduAI.BaiduTranslateToText(_newFile, language, rate.ToString())); } else { //将音频转换为文字 baidu_text.Add(Rays.Utility.BadiAI.BaiduAI.BaiduTranslateToText(newFile, language, rate.ToString())); } } catch (Exception ex) { LogHelper.Error("GetBaiduSpeech:" + ex.Message); } finally { //删除文件 if (File.Exists(_newFile)) { File.Delete(_newFile); } if (need_delete) { if (File.Exists(newFile)) { File.Delete(newFile); } } //删除目录 if (Directory.Exists(newFolder) && Directory.GetFiles(newFolder).Length == 0) { Directory.Delete(newFolder); } } }