public void StartChunking( FFMPEGConfig ffmpegConfig, StreamConfig streamConfig) { var procInfo = new ProcessStartInfo(); procInfo.FileName = ffmpegConfig.BinaryPath; streamConfig.Name = streamConfig.Name; var segmentFilename = ffmpegConfig.ChunkStorageDir + "/" + streamConfig.Name + "/" + ffmpegConfig.SegmentFilename; var m3u8File = ffmpegConfig.ChunkStorageDir + "/" + streamConfig.Name + "/" + "index.m3u8"; procInfo.Arguments = string.Join(" ", new[] { "-y -re", "-i " + streamConfig.Link, "-map 0", "-codec:v copy -codec:a copy", "-f hls", "-hls_time " + streamConfig.ChunkTime, "-use_localtime 1 -use_localtime_mkdir 1", "-hls_flags second_level_segment_duration+second_level_segment_index", "-hls_segment_filename " + segmentFilename, m3u8File }); var proc = new Process(); proc.StartInfo = procInfo; proc.Start(); processes.Add(proc); }
public static string GeneratePlaylist( string chanel, DateTime time, FFMPEGConfig ffmpegCfg, IEnumerable <StreamConfig> streamsCfgs, int hlsLstSize = 5) { var streamCfg = streamsCfgs.FirstOrDefault(x => x.Name == chanel); if (streamCfg == null) { throw new Exception("No such chanel"); } var chanelRoot = $"{ffmpegCfg.ChunkStorageDir}/{chanel}/"; var timer1 = new Stopwatch(); var timer2 = new Stopwatch(); timer2.Start(); var targetTime = GetMinChunkTimeSpan( hlsLstSize, streamCfg.ChunkTime, time, chanelRoot); timer2.Stop(); var targetTimeS = targetTime.Add(-DateTimeOffset.Now.Offset) .ToUnixTimeSeconds(); timer1.Start(); var chunks = Directory.GetFiles(chanelRoot, "*.ts", SearchOption.AllDirectories) .Select(x => new ChunkFile(x)) .Where(x => x.timeSeconds >= targetTimeS - streamCfg.ChunkTime && x.millsDuration > 0) .OrderBy(x => x.timeSeconds) .Take(hlsLstSize); var fileChunks = GetContinuousChunks(chunks).ToArray(); if (fileChunks.Length == 0) { throw new Exception("No available files"); } timer1.Stop(); var content = String.Join("\n", new[] { "#EXTM3U", "#EXT-X-VERSION:3", $"#EXT-X-TARGETDURATION:{streamCfg.ChunkTime}", $"#EXT-X-MEDIA-SEQUENCE:{fileChunks[0].index}", $"#Stopwatch:{timer1.Elapsed.TotalMilliseconds}/{timer2.Elapsed.TotalMilliseconds}", $"#RequestTime:{targetTimeS}," }); content += "\n"; foreach (var file in fileChunks) { content += $"#EXTINF:{file.GetMillisecondsStr()}," + "\n"; content += file.fullPath.Replace(chanelRoot, "") + "\n"; } return(content); }