c#读取srt字幕文件
在WPF项目中,使用MediaElement实现了一个视频播放器的功能,但是需要实现显示字幕的功能,在网上查看了一些资料之后,算是实现的基本的显示功能。
分析
1.srt字幕文件格式:
srt字幕文件的格式是:
1
00:00:02,580 –> 00:00:05,980
This is from Gagarin.
2
00:00:11,260 –> 00:00:15,760
This is from Gagarin.
3
00:00:18,660 –> 00:00:22,660
初次发帖,欢迎分享.
4
00:00:23,860 –> 00:00:30,860
Trust is like a piece of paper. When it creases, it cannot recover even it is smoothed.
信任就像一张纸,皱了,即使抚平,也恢复不了原样了。
即:
数字
时间 –> 时间
字幕内容(可以多行)
空行
数字
时间 –> 时间
字幕内容(可以多行)
空行
2.读取srt字幕文件格式:
可以发现所有内容都是一个个:
[数字
时间 –> 时间
字幕内容(可以多行)]
的模型,所以:
我们可以生成一个这样的model,将所有的model添加到集合中。
//定义一个StrModel的类,用于接受从srt文件读取的文件格式
public class SrtModel
{
private int beginTime;
private int endTime;
private string srtString;
private int index;
public int BeginTime { get => beginTime; set => beginTime = value; }
public int EndTime { get => endTime; set => endTime = value; }
public string SrtString { get => srtString; set => srtString = value; }
public int Index { get => index; set => index = value; }
}
//解析字幕文件
public class SrtHelper
{
//定义一个ModelList的列表用于接受从文件读取的内容
private static List<SrtModel> mySrtModelList;
//定义一个获取当前时间显示的string的方法
public static string GetTimeString(int timeMile)
{
String currentTimeTxt = "";
if (mySrtModelList != null)
{
foreach (SrtModel sm in mySrtModelList)
{
if (timeMile > sm.BeginTime && timeMile < sm.EndTime)
{
currentTimeTxt = sm.SrtString;
}
}
}
return currentTimeTxt;
}
//读取文件中的内容到mySrtModelList列表
public static List<SrtModel> ParseSrt(string srtPath)
{
mySrtModelList = new List<SrtModel>();
string line;
using (FileStream fs = new FileStream(srtPath, FileMode.Open))
{
using (StreamReader sr = new StreamReader(fs,Encoding.Default))
{
StringBuilder sb = new StringBuilder();
while ((line = sr.ReadLine()) != null)
{
if (!line.Equals(""))
{
sb.Append(line).Append("@");
continue;
}
string[] parseStrs = sb.ToString().Split('@');
if (parseStrs.Length < 3)
{
sb.Remove(0, sb.Length);// 清空,否则影响下一个字幕元素的解析</i>
continue;
}
SrtModel srt = new SrtModel();
string strToTime = parseStrs[1];
int beginHour = int.Parse(strToTime.Substring(0, 2));
int begin_mintue = int.Parse(strToTime.Substring(3, 2));
int begin_scend = int.Parse(strToTime.Substring(6, 2));
int begin_milli = int.Parse(strToTime.Substring(9, 3));
int beginTime = (beginHour * 3600 + begin_mintue * 60 + begin_scend) * 1000 + begin_milli;
int end_hour = int.Parse(strToTime.Substring(17, 2));
int end_mintue = int.Parse(strToTime.Substring(20, 2));
int end_scend = int.Parse(strToTime.Substring(23, 2));
int end_milli = int.Parse(strToTime.Substring(26, 2));
int endTime = (end_hour * 3600 + end_mintue * 60 + end_scend) * 1000 + end_milli;
srt.BeginTime = beginTime;
srt.EndTime = endTime;
string strBody = null;
for (int i = 2; i < parseStrs.Length; i++)
{
strBody += parseStrs[i];
}
srt.SrtString = strBody;
mySrtModelList.Add(srt);
sb.Remove(0, sb.Length);
}
}
}
return mySrtModelList;
}
3.视频中显示字幕:
3.1先根据文件路径,读取字幕文件:
List srtModel=SrtHelper.ParseSrt(str);//str为文件路径
3.1根据视频时间计算相应值,遍历srtModel取出与之对应的字符串
//currentPositionTimeSpan视频当前位置
int timeMiles = (int)currentPositionTimeSpan.TotalHours * 3600 + (int)currentPositionTimeSpan.TotalMinutes * 60 + (int)currentPositionTimeSpan.TotalSeconds * 1000;
//获取字符串
string timeString = SrtHelper.GetTimeString(timeMiles);
//lyrics为当前显示文本容器
lyrics.Text = timeString;
上面代码利用计时器,定时触发。