示例#1
0
        public ChunkFile GetClosestChunk(ChunksCollectorModelByTime 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 minTime   = GetMinChunkTimeSpan(model);
            var minTimeS  = minTime
                            .Add(-DateTimeOffset.Now.Offset)
                            .ToUnixTimeSeconds();

            var testTime = TimeTools.SecsToDateWithOffset((int)minTimeS);

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

            var result = files
                         .Select(x => ChunkFileLoader.Load(x))
                         .Where(x => x.timeSeconds > minTimeS - streamCfg.ChunkTime)
                         .OrderBy(x => x.timeSeconds)
                         .FirstOrDefault();

            if (result == null)
            {
                throw new NoAvailableFilesException();
            }

            return(result);
        }
示例#2
0
        /// <summary>
        /// Get the closest possible time to the target time, depending
        /// on the number of chunks and the newest file.
        /// If it's live, then the newest file - (n + 1) * chunkTime will
        /// be returned. Note +1 because the newest is still being created.
        ///
        /// Otherwise, the received time is returned.
        /// </summary>
        private DateTime GetMinChunkTimeSpan(ChunksCollectorModelByTime model)
        {
            var mostRecent =
                Directory.GetFiles(
                    model.channelRoot,
                    "*.ts",
                    SearchOption.AllDirectories
                    ).OrderByDescending(File.GetCreationTime).FirstOrDefault();

            if (mostRecent == null)
            {
                throw new NoAvailableFilesException($"0/{model.HlsListSize}");
            }

            var targetTime =
                model.RequestedTime
                .AddSeconds(
                    -model.streamSource.ChunkTime * model.HlsListSize);

            var newestChunk    = ChunkFileLoader.Load(mostRecent);
            var newestDateTime =
                TimeTools.SecsToDateWithOffset(newestChunk.timeSeconds);

            var totalRequiredSec =
                (model.HlsListSize + safeHlsLstDelta + 1) *
                (model.streamSource.ChunkTime);

            if (targetTime.AddSeconds(totalRequiredSec) > newestDateTime)
            {
                var delta = newestDateTime - targetTime;
                return(newestDateTime.AddSeconds(-totalRequiredSec)
                       .Add(-delta));
            }
            else
            {
                return(targetTime);
            }
        }