M3u8Timer.cs 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using EMISOnline.WinService.Common;
  6. using System.IO;
  7. using System.Diagnostics;
  8. namespace EMISOnline.WinService
  9. {
  10. public class M3u8Timer
  11. {
  12. public M3u8Timer()
  13. {
  14. }
  15. public void doingM3u8()
  16. {
  17. Log.Info(this.GetType().ToString(), "Start m3u8...");
  18. //获取所有可以转换的文件
  19. string convertPath = "", Comments = "";
  20. List<FileInfo> lists = FileHelper.GetAllFiles(Config.FtpPath,Config.FtpFileType);
  21. foreach (FileInfo file in lists)
  22. {
  23. Comments = FileHelper.GetFilePropertiesComments(file.FullName);
  24. if (string.IsNullOrEmpty(Comments)) Comments = "";
  25. //已经标识为上传完成的文件,且没有转换过的文件才进行转换。
  26. if (Comments.IndexOf("UploadOver") < 0 || Comments.IndexOf("ConvertM3u8") >= 0) continue;
  27. //每次时序 只转换一个文件,转换完成释放时序。
  28. convertPath = file.FullName;
  29. break;
  30. }
  31. //没有需要转换的文件
  32. if (convertPath.Length == 0) return;
  33. //开始进行 m3u8转换
  34. string m3u8Path = "";
  35. string[] comArys = Comments.Split('|');
  36. //为m3u8创建文件夹
  37. if (comArys.Length == 1)
  38. {
  39. m3u8Path = Config.M3U8Path + "\\" + DateTime.Now.ToString("yyyyMMdd") + "\\" + DateTime.Now.Ticks.ToString();
  40. if (!Directory.Exists(m3u8Path))//若文件夹不存在则新建文件夹
  41. {
  42. Directory.CreateDirectory(m3u8Path); //新建文件夹
  43. }
  44. //把该文件对应的m3u8文件路径保存起来
  45. Comments += "|" + m3u8Path;
  46. FileHelper.SaveFilePropertiesComments(convertPath, Comments);
  47. }
  48. else m3u8Path = comArys[1];
  49. Log.Info(this.GetType().ToString(), "Find File:" + convertPath + "。try to Convert。M3u8Path:" + m3u8Path);
  50. //通知教学平台有这样的一个文件正在进行m3u8转换
  51. M3u8Timer.SaveFtpFile(convertPath, m3u8Path + "\\x.m3u8", "", "", "", 2);
  52. //开始进行转换
  53. runJpg(convertPath, m3u8Path + "\\x.jpg");
  54. runM3u8(convertPath, m3u8Path + "\\x.m3u8");
  55. //保存状态,下次将不在进行转换检查
  56. Comments += "|ConvertM3u8";
  57. FileHelper.SaveFilePropertiesComments(convertPath, Comments);
  58. //通知教学平台有这样的一个文件m3u8转换完成
  59. string m3u8Url = Config.M3u8Server + m3u8Path.Replace(Config.M3U8Path, "").Replace("\\","/")+"/x.m3u8";
  60. M3u8Timer.SaveFtpFile(convertPath, "", "", m3u8Url , "", 3);
  61. }
  62. public bool runM3u8(string sourcePath, string mPath)
  63. {
  64. string cmd = string.Format(" -i \"{0}\" -c:v libx264 -c:a aac -strict -2 -hls_list_size 0 -f hls \"{1}\"", sourcePath, mPath);
  65. Log.Info(this.GetType().ToString(), "RunCmd: " + cmd);
  66. cmd = RunCmd(cmd);
  67. if (cmd == "-1")
  68. {
  69. return false;
  70. }
  71. return true;
  72. }
  73. public bool runJpg(string sourcePath, string mPicPath)
  74. {
  75. string cmd = string.Format(" -i \"{0}\" -f image2 -ss 1 -vframes 1 \"{1}\"", sourcePath, mPicPath);
  76. Log.Info(this.GetType().ToString(), "RunCmd: " + cmd);
  77. cmd = RunCmd(cmd);
  78. if (cmd == "-1")
  79. {
  80. return false;
  81. }
  82. return true;
  83. }
  84. public string RunCmd(string cmdStr)
  85. {
  86. try
  87. {
  88. using (Process p = new Process())
  89. {
  90. p.StartInfo.FileName = Config.FfmpegExe+"\\bin\\ffmpeg.exe";//要调用外部程序的绝对路径
  91. p.StartInfo.Arguments = cmdStr;//参数(这里就是FFMPEG的参数了)
  92. p.StartInfo.UseShellExecute = false;//不使用操作系统外壳程序启动线程(一定为FALSE,详细的请看MSDN)
  93. p.StartInfo.RedirectStandardError = true;//把外部程序错误输出写到StandardError流中(这个一定要注意,FFMPEG的所有输出信息,都为错误输出流,用StandardOutput是捕获不到任何消息的...这是我耗费了2个多月得出来的经验...mencoder就是用standardOutput来捕获的)
  94. p.StartInfo.CreateNoWindow = false;//不创建进程窗口
  95. p.ErrorDataReceived += new DataReceivedEventHandler(Output);//外部程序(这里是FFMPEG)输出流时候产生的事件,这里是把流的处理过程转移到下面的方法中,详细请查阅MSDN
  96. p.OutputDataReceived += new DataReceivedEventHandler(Output);
  97. p.Start();//启动线程
  98. p.BeginErrorReadLine();//开始异步读取
  99. //p.BeginOutputReadLine();
  100. p.WaitForExit();//阻塞等待进程结束
  101. p.Close();//关闭进程
  102. p.Dispose();//释放资源
  103. return "0";
  104. }
  105. }
  106. catch (Exception ex)
  107. {
  108. Log.Info(this.GetType().ToString(),"RunCmd error: " + ex.Message + ex.StackTrace);
  109. }
  110. return "-1";
  111. }
  112. private void Output(object sendProcess, DataReceivedEventArgs output)
  113. {
  114. if (!String.IsNullOrEmpty(output.Data))
  115. {
  116. Log.Info(this.GetType().ToString(), "RunCmd: " + output.Data);
  117. }
  118. }
  119. public static string SaveFtpFile(string FTPPath, string M3u8Path, string FTPUrl, string M3u8Url, string Name, int Status)
  120. {
  121. string param = "FTPPath=" + FTPPath;
  122. param += "&M3u8Path=" + M3u8Path;
  123. param += "&FTPUrl=" + FTPUrl;
  124. param += "&M3u8Url=" + M3u8Url;
  125. param += "&Name=" + Name;
  126. param += "&Status=" + Status.ToString();
  127. return HttpHelper.PostWebRequest(Config.DataServer + "/FtpFile/SaveFtpFile", param, Encoding.UTF8);
  128. }
  129. }
  130. }