[HLS/M3U8/视频切片] [MVC,videoJs] 读取切片文件播放视频

 

一.视频切片

 /// <summary>
        /// 视频切片代码
        /// </summary>
        /// <param name="ffmpegfile"> ffmpeg路径 </param>
        /// <param name="sourceFile"> 待切片源文件路径</param>
        /// <param name="m3U8File"> 待生成m3u8文件路径</param>
        /// <param name="tsFile">待生成ts文件路径</param>
        /// <returns>返回m3u8文件路径</returns>
        public static async Task<string> Conver2M3u8(string ffmpegfile, string sourceFile, string m3U8File, string tsFile)
        {
            Task<string> task = new Task<string>(() =>
            {
                var command =
                    $@" -i {sourceFile} -codec copy -vbsf h264_mp4toannexb -map 0 -f segment -segment_list {m3U8File} -segment_time 10 {tsFile}/out%03d.ts";
                using (System.Diagnostics.Process ffmpeg = new System.Diagnostics.Process())
                {
                    ffmpeg.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
                    ffmpeg.StartInfo.FileName = ffmpegfile;
                    ffmpeg.StartInfo.Arguments = command;
                    ffmpeg.StartInfo.UseShellExecute = false;
                    ffmpeg.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                    ffmpeg.StartInfo.RedirectStandardError = true;
                    try
                    {
                        ffmpeg.Start();
                        ffmpeg.WaitForExit();
                        return m3U8File;
                    }
                    catch (Exception e)
                    {
                        throw e;
                    }

                }
            });
            return await task;

        }

二.修改M3U8文件

 1  /// <summary>
 2         /// 因为ffmpeg 文件生成的m3u8指向的是本地路径 所以修改M3u8文件指向网络路径
 3         /// </summary>
 4         /// <param name="filePath">M3u8文件路径</param>
 5         /// <param name="key">需要加的验证信息</param>
 6         /// <param name="url">网络路径</param>
 7         /// <returns>返回重新生成好的m3u8 字符串</returns>
 8         private string CreateMeta(string filePath,string key,string url)
 9         {
10             if (System.IO.File.Exists(filePath))
11             {
12                 using (var fs = System.IO.File.OpenText(filePath))
13                 {
14                     StringBuilder sb = new StringBuilder(fs.ReadToEnd());
15 
16                     sb.Replace("output", $@"{url}?id=out");
17                     sb.Replace(".ts", $@"&key={key}&type=.ts");
18                     return sb.ToString();
19                 }
20             }
21             return null;
22         }

三. 读取/播放 Action

 1 public async Task<ActionResult> PlayerSource(string id, string key)
 2         {
 3             var filePath = $@"D:\work\DJOASystem\DJOASyetemMvc\test\video\{id}.ts";
 4             Response.AddHeader("Access-Control-Allow-Origin", "*");
 5             Response.AddHeader("Access-Control-Allow-Methods", "GET");
 6             using (var fs = System.IO.File.Open(filePath,FileMode.Open,FileAccess.Read,FileShare.ReadWrite))
 7             {
 8                 byte[] buffer = new byte[fs.Length];
 9                 await fs.ReadAsync(buffer,0,(int)fs.Length);
10                 return new FileContentResult(buffer, "video/MP2T");
11             }
12         }

 

 

 1 public ActionResult PlayerMeta(string id)
 2         {
 3 
 4             var filePath = @"D:\video\playlist.m3u8";
 5             Response.AddHeader("Access-Control-Allow-Origin", "*");
 6             Response.AddHeader("Access-Control-Allow-Methods", "GET");
 7             var fileString = CreateMeta(filePath);
 8             byte[] byteArray = System.Text.Encoding.Default.GetBytes(fileString);
 9             return new FileContentResult(byteArray, "application/vnd.apple.mpegurl");
10         }

 

四.遇到问题

1. 开始使用Response.Flush 写入bytes,发现手机端无法播放,报错 断开连接...后修改为返回FileContentResult 让MVC自己处理各种头

2. 前端的话 用videoJs+videojs-contrib-hls就可以

3. 测试链接 http://videojs.github.io/videojs-contrib-hls/

4. 未来可以考虑m3u8 AES加密 更严密

posted @ 2018-04-03 15:28  Simon_张  阅读(1000)  评论(0)    收藏  举报