Esempio n. 1
0
        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);
        }