コード例 #1
0
        private static IEnumerable <SmoothStreamingMediaStreamIndexC> GenerateClientManifestChunks(ManifestTrack track, Box moov)
        {
            // Pull entries that point to different moof boxes, duplicate boxes offsets cause playback issues.
            var entries = track.Fragments.TrackFragmentRandomAccessEntries
                          .GroupBy(entry => entry.MoofOffset)
                          .Select(entry => entry.First())
                          .ToList();
            ulong entriesDuration = 0;

            //create chunks
            for (int i = 0; i < entries.Count; i++)
            {
                var c = new SmoothStreamingMediaStreamIndexC();
                c.n = i;

                if (i != entries.Count - 1)
                {
                    // The duration is the difference between this entry and the next's time
                    c.d              = entries.ElementAt(i + 1).Time - entries.ElementAt(i).Time;
                    entriesDuration += c.d;
                }
                else
                {
                    var mvhd = moov.InnerBoxes.SingleOrDefault(b => b.Type == BoxType.Mvhd) as MovieHeaderFullBox;
                    // Final duration is what we have left, the track duration is in the timescale of the presentation,
                    // so we have to convert to the timescale of the actual media in the track
                    c.d = ConvertTimeToTimescale(track.Duration, mvhd.TimeScale, track.TimeScale) - entriesDuration;
                }
                yield return(c);
            }
        }
コード例 #2
0
        private static IEnumerable<SmoothStreamingMediaStreamIndexC> CreateChunks(SegmentTimeline segmentTimeline)
        {
            int i = 0;

            foreach (var s in segmentTimeline.S)
            {
                for (int repeatIndex = 0; repeatIndex <= s.R; repeatIndex++)
                {
                    var c = new SmoothStreamingMediaStreamIndexC();
                    c.n = i;
                    c.t = s.T;
                    c.d = s.D;
                    //c.d = ConvertTimeToTimescale(track.Duration, mvhd.TimeScale, track.TimeScale) - entriesDuration;

                    yield return c;
                    i++;

                }
            }
        }
コード例 #3
0
 private static IEnumerable<SmoothStreamingMediaStreamIndexC> CreateChunks(SegmentIndexBox sidx)
 {
     int i = 0;
     foreach (var subsegment in sidx.Subsegments)
     {
         var c = new SmoothStreamingMediaStreamIndexC();
         if (i == 0) c.t = sidx.EarliestPresentationTime;
         c.n = i;
         c.d = subsegment.Duration;
         //c.d = ConvertTimeToTimescale(track.Duration, mvhd.TimeScale, track.TimeScale) - entriesDuration;
         yield return c;
     }
 }
コード例 #4
0
        public static void WriteTo(this SmoothStreamingMedia media, XmlWriter writer)
        {
            // The SmoothStreamingMedia element
            writer.WriteStartElement("SmoothStreamingMedia");
            writer.WriteAttributeString("MajorVersion", media.MajorVersion.ToString());
            writer.WriteAttributeString("MinorVersion", media.MinorVersion.ToString());
            writer.WriteAttributeString("Duration", media.Duration.ToString());
            if (media.TimeScale.HasValue)
            {
                writer.WriteAttributeString("TimeScale", media.TimeScale.ToString());
            }
            if (media.IsLive)
            {
                writer.WriteAttributeString("IsLive", "TRUE");
            }
            if (media.LookaheadCount.HasValue)
            {
                writer.WriteAttributeString("LookAheadFragmentCount", media.LookaheadCount.ToString());
            }
            if (media.DVRWindowLength.HasValue)
            {
                writer.WriteAttributeString("DVRWindowLength", media.DVRWindowLength.ToString());
            }

            // The StreamIndex elements
            foreach (var streamIndex in media.StreamIndex)
            {
                // The StreamIndex element
                writer.WriteStartElement("StreamIndex");
                writer.WriteAttributeString("Type", streamIndex.Type);
                if (streamIndex.Subtype != null)
                {
                    writer.WriteAttributeString("Subtype", streamIndex.Subtype);
                }
                writer.WriteAttributeString("Name", streamIndex.Name);
                writer.WriteAttributeString("Chunks", streamIndex.Chunks.ToString());
                writer.WriteAttributeString("QualityLevels", streamIndex.QualityLevels.ToString());
                if (streamIndex.TimeScale != 10000000)
                {
                    writer.WriteAttributeString("TimeScale", streamIndex.TimeScale.ToString());
                }

                switch (streamIndex.Type)
                {
                case "audio":
                    break;

                case "video":
                    writer.WriteAttributeString("MaxWidth", streamIndex.MaxWidth.ToString());
                    writer.WriteAttributeString("MaxHeight", streamIndex.MaxHeight.ToString());
                    writer.WriteAttributeString("DisplayWidth", streamIndex.DisplayWidth.ToString());
                    writer.WriteAttributeString("DisplayHeight", streamIndex.DisplayHeight.ToString());
                    break;

                case "text":
                    writer.WriteAttributeString("Subtype", "SUBT");
                    break;
                }

                // These values may be empty for some StreamIndexes
                if (!string.IsNullOrEmpty(streamIndex.Url))
                {
                    writer.WriteAttributeString("Url", streamIndex.Url);
                }
                if (!string.IsNullOrEmpty(streamIndex.Language))
                {
                    writer.WriteAttributeString("Language", streamIndex.Language);
                }

                foreach (var qualityLevel in streamIndex.QualityLevel)
                {
                    // The QualityLevel element
                    writer.WriteStartElement("QualityLevel");

                    writer.WriteAttributeString("Index", qualityLevel.Index.ToString());
                    writer.WriteAttributeString("Bitrate", qualityLevel.Bitrate.ToString());

                    if (!string.IsNullOrEmpty(qualityLevel.FourCC))
                    {
                        writer.WriteAttributeString("FourCC", qualityLevel.FourCC.ToString());
                    }

                    switch (streamIndex.Type)
                    {
                    case "audio":
                        writer.WriteAttributeString("SamplingRate", qualityLevel.SamplingRate.ToString());
                        writer.WriteAttributeString("Channels", qualityLevel.Channels.ToString());
                        writer.WriteAttributeString("BitsPerSample", qualityLevel.BitsPerSample.ToString());
                        writer.WriteAttributeString("PacketSize", qualityLevel.PacketSize.ToString());
                        writer.WriteAttributeString("AudioTag", qualityLevel.AudioTag.ToString());
                        break;

                    case "video":
                        writer.WriteAttributeString("MaxWidth", qualityLevel.MaxWidth.ToString());
                        writer.WriteAttributeString("MaxHeight", qualityLevel.MaxHeight.ToString());
                        break;

                    case "text":
                        break;
                    }

                    if (!string.IsNullOrEmpty(qualityLevel.CodecPrivateData))
                    {
                        writer.WriteAttributeString("CodecPrivateData", qualityLevel.CodecPrivateData);
                    }

                    // Close the QualityLevel attribute
                    writer.WriteEndElement();
                }

                int i = 0;
                while (i < streamIndex.c.Count)
                {
                    SmoothStreamingMediaStreamIndexC chunk = streamIndex.c[i];
                    int r = 1;
                    while (i + r < streamIndex.c.Count)
                    {
                        var chunkNext = streamIndex.c[i + r];
                        if (chunk.d == chunkNext.d)
                        {
                            r++;
                        }
                        else
                        {
                            break;
                        }
                    }

                    // The c element
                    writer.WriteStartElement("c");

                    if (chunk.t.HasValue)
                    {
                        writer.WriteAttributeString("t", chunk.t.ToString());
                    }
                    writer.WriteAttributeString("d", chunk.d.ToString());
                    if (r > 1)
                    {
                        writer.WriteAttributeString("r", r.ToString());
                    }

                    // Close the c element
                    writer.WriteEndElement();

                    i += r;
                }

                // Close the StreamIndex element
                writer.WriteEndElement();
            }

            if (media.Protection != null)
            {
                // The Protection element
                writer.WriteStartElement("Protection");

                // The ProtectionHeader element
                writer.WriteStartElement("ProtectionHeader");
                writer.WriteAttributeString("SystemID", media.Protection.ProtectionHeader.SystemID);
                writer.WriteValue(media.Protection.ProtectionHeader.Value);
                writer.WriteEndElement();

                writer.WriteEndElement();
            }

            // Close the SmoothStreamingMedia element
            writer.WriteEndElement();
        }
コード例 #5
0
        private static IEnumerable<SmoothStreamingMediaStreamIndexC> GenerateClientManifestChunks(ManifestTrack track, Box moov)
        {
            // Pull entries that point to different moof boxes, duplicate boxes offsets cause playback issues.
            var entries = track.Fragments.TrackFragmentRandomAccessEntries
                .GroupBy(entry => entry.MoofOffset)
                .Select(entry => entry.First())
                .ToList();
            ulong entriesDuration = 0;

            //create chunks
            for (int i = 0; i < entries.Count; i++)
            {
                var c = new SmoothStreamingMediaStreamIndexC();
                c.n = i;

                if (i != entries.Count - 1)
                {
                    // The duration is the difference between this entry and the next's time
                    c.d = entries.ElementAt(i + 1).Time - entries.ElementAt(i).Time;
                    entriesDuration += c.d;
                }
                else
                {
                    var mvhd = moov.InnerBoxes.SingleOrDefault(b => b.Type == BoxType.Mvhd) as MovieHeaderFullBox;
                    // Final duration is what we have left, the track duration is in the timescale of the presentation,
                    // so we have to convert to the timescale of the actual media in the track
                    c.d = ConvertTimeToTimescale(track.Duration, mvhd.TimeScale, track.TimeScale) - entriesDuration;
                }
                yield return c;
            }
        }