Esempio n. 1
0
        public ChunkFile[] GetNextBatch(ChunksCollectorModelByLast model)
        {
            var streamCfg =
                _streamsConfigs.StreamSources
                .FirstOrDefault(x => x.Name == model.Channel);

            if (streamCfg == null)
            {
                throw new NoSuchChannelException(model.Channel);
            }

            model.channelRoot = Path.Combine(
                _chunkerConfig.ChunkStorageDir,
                streamCfg.Name);
            model.streamSource = streamCfg;

            var chunkTime     = streamCfg.ChunkTime;
            var lastChunk     = ChunkFileLoader.Load(model.LastChunkPath);
            var lastChunkTime =
                TimeTools.SecsToDateWithOffset(lastChunk.timeSeconds);

            var files = GetFilesInsideTimeRange(
                model.channelRoot,
                lastChunkTime.AddSeconds(-chunkTime * 1),
                lastChunkTime.AddSeconds(
                    chunkTime * (model.HlsListSize + safeHlsLstDelta + 1))
                );

            var minTimeS = lastChunk.timeSeconds;
            var chunks   = files
                           .Select(x => ChunkFileLoader.Load(x))
                           .Where(x => x.timeSeconds >= minTimeS - streamCfg.ChunkTime)
                           .OrderBy(x => x.timeSeconds)
                           .Take(model.HlsListSize + safeHlsLstDelta)
                           .ToArray();

            if (chunks.Length != model.HlsListSize + safeHlsLstDelta)
            {
                throw new NoAvailableFilesException(string.Format(
                                                        "{0}/{1} (+{2})",
                                                        (chunks.Length),
                                                        (model.HlsListSize + safeHlsLstDelta),
                                                        safeHlsLstDelta
                                                        ));
            }

            ApplyDisconinuityMarks(chunks, streamCfg.ChunkTime);
            return(chunks.Skip(1).Take(model.HlsListSize).ToArray());
        }
        private async Task <IActionResult> TokenizedStreamInternalAsync(
            string channel,
            string token = null)
        {
            var tokenParseResult = await _tokenParser.ParseAsync(
                new TokenParserModel
            {
                Channel = channel, Token = token, HttpContext = HttpContext
            });

            var session = tokenParseResult.session;

            if (session == null)
            {
                return(tokenParseResult.actionResult);
            }

            M3U8Playlist playlist;

            try
            {
                var collectorModel = new ChunksCollectorModelByLast
                {
                    Channel       = session.Channel,
                    HlsListSize   = session.HlsListSize,
                    LastChunkPath = session.LastFilePath
                };
                playlist = _playlistAssembler.Aseemble(
                    session,
                    _chunkCollector.GetNextBatch(collectorModel));

                //playlist = _m3u8Generator.GenerateNextM3U8(
                //channel,
                //session.HlsListSize,
                //session.LastFileIndex,
                //session.LastFileTimeSpan);
            }
            catch (ChunkCollectorException e)
            { return(Content(e.Message)); }

            Console.WriteLine(
                "[StreamCtrl]:> m3u8: {0} TOKEN: {1}",
                string.Join(
                    ", ",
                    playlist.Files.Select(x => x.FilePath)),
                session.LastFilePath
                );

            session.LastFilePath = playlist.Files.First().FilePath;

            try
            {
                await _cache.SetObjAsync(
                    token,
                    session,
                    GetSessionExpiration());
            }
            catch (Exception)
            { return(View("RedisConnectionException")); }

            var result = playlist.Bake($"token={token}");

            if (session.DisplayContent)
            {
                return(Content(result));
            }
            else
            {
                return(GenerateDownloadableContent(result));
            }
        }