コード例 #1
0
 internal DataReceivedEventArgs(byte[] data, long startTime, long endTime, IManifestStream stream, IManifestTrack track)
 {
     StartTime = startTime;
     EndTime   = endTime;
     Data      = data;
     Stream    = stream;
     Track     = track;
 }
コード例 #2
0
 void UpdateSelectedTrack(TimeSpan position)
 {
     lock (bitrateLog) // make this is thread safe since the collection can be updated on a background thread.
     {
         foreach (var item in bitrateLog.ToList())
         {
             if (item.TimeStamp <= position.Ticks)
             {
                 bitrateLog.Remove(item);
                 selectedTrack = item.Track;
             }
             else
             {
                 break;
             }
         }
     }
 }
コード例 #3
0
        public void RefreshState(TimeSpan position)
        {
            Position = position;
            if (RefreshingState != null)
            {
                RefreshingState(this, new RefreshingStateEventArgs(position));
            }

            IManifestTrack selectedTrack = null;

            lock (bitrateLog) // make this is thread safe since the collection can be updated on a background thread.
            {
                foreach (var item in bitrateLog.ToList())
                {
                    if (item.TimeStamp <= position.Ticks)
                    {
                        bitrateLog.Remove(item);
                        selectedTrack = item.Track;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (selectedTrack != null)
            {
                CurrentBitrate = selectedTrack.Bitrate;
                CurrentWidth   = selectedTrack.MaxWidth;
                CurrentHeight  = selectedTrack.MaxHeight;
                var videoStream = VideoStream;
                LowestBitrate  = videoStream.SelectedTracks.Min(t => t.Bitrate);
                HighestBitrate = videoStream.SelectedTracks.Max(t => t.Bitrate);
                if (StateChanged != null)
                {
                    StateChanged(this, EventArgs.Empty);
                }
            }
        }
コード例 #4
0
 internal DataErrorEventArgs(Exception error, IManifestStream stream, IManifestTrack track)
 {
     Error  = error;
     Stream = stream;
     Track  = track;
 }
コード例 #5
0
        private async Task PollFragmentsAsync(IManifestStream stream, IManifestTrack track, CancellationToken cancellationToken)
        {
            try
            {
                var iter = stream.FirstInCurrentChunkList;

                var       finished  = false;
                ChunkInfo?chunkInfo = await stream.GetChunkInfoAsync(iter);

                cancellationToken.ThrowIfCancellationRequested();
                do
                {
                    try
                    {
                        // add small artificial delay if chunk is more than 1 minute away so we don't hog bandwidth
                        if (chunkInfo.Value.ChunkTime > Position.Add(TimeSpan.FromMinutes(1)).Ticks)
                        {
                            await Task.Delay(ChunkCachePollingIntervalMilliseconds, cancellationToken);
                        }

                        var chunkData = (await stream.GetChunkDataAsync(iter, track)).ToArray();
                        cancellationToken.ThrowIfCancellationRequested();

                        var currentChunkInfo = chunkInfo.Value;

                        if (iter.MoveNext())
                        {
                            chunkInfo = await stream.GetChunkInfoAsync(iter);

                            cancellationToken.ThrowIfCancellationRequested();
                        }
                        else
                        {
                            chunkInfo = null;
                            finished  = true;
                        }

                        OnDataReceived(new DataReceivedEventArgs(chunkData, currentChunkInfo.ChunkTime, chunkInfo.HasValue ? chunkInfo.Value.ChunkTime : ActiveAdaptiveSource.Manifest.Duration, stream, track));

                        if (finished && IsLive) // for live situations, we need to keep checking
                        {
                            do
                            {
                                await Task.Delay(ChunkLivePollingIntervalMilliseconds, cancellationToken); // wait 1 second before checking again

                                finished = !IsLive;                                                        // recheck in case EndOfLive occurred
                            } while (!finished && !iter.MoveNext());
                            if (!finished)
                            {
                                chunkInfo = await stream.GetChunkInfoAsync(iter);

                                cancellationToken.ThrowIfCancellationRequested();
                            }
                        }
                    }
                    catch (OperationCanceledException) { throw; }
                    catch (Exception ex) {
                        OnDataError(new DataErrorEventArgs(ex, stream, track));
                        finished = true;
                    }
                } while (!finished);
            }
            catch (OperationCanceledException) { throw; }
            catch (Exception ex) { OnDataError(new DataErrorEventArgs(ex, stream, track)); }
        }
コード例 #6
0
 public BitrateLogEntry(long timeStamp, IManifestTrack track)
 {
     TimeStamp = timeStamp;
     Track     = track;
 }
コード例 #7
0
 public AudioStreamAttributes(IManifestTrack track)
 {
     this.track = track;
 }
コード例 #8
0
 public VideoTrackAttributes(IManifestTrack track)
 {
     this.track = track;
 }
コード例 #9
0
 public VideoTrackAttributes(IManifestTrack track)
 {
     this.track = track;
 }