コード例 #1
0
        private async Task <Box> GetBox(BoxType boxType)
        {
            // get the box size
            var size = await this.GetBoxSize(this.fileOffset);

            // gets the box
            var stream = await WebRequestor.GetStreamRangeAsync(this.fileUri, this.fileOffset, this.fileOffset + (long)size);

            Box box = null;

            using (var boxReader = new BoxBinaryReader(stream))
            {
                box              = boxReader.ReadNextBox();
                this.fileOffset += (long)size;
            }

            if (box.Type == boxType)
            {
                return(box);
            }
            else
            {
                return(await this.GetBox(boxType));
            }
        }
コード例 #2
0
        private async Task <WebRequestorResponse> GetChunkAsync(Uri source, CancellationToken c)
        {
            if (ChunkLookup != null && ChunkLookup.Any())
            {
                var key = source.AbsolutePath;

                if (ChunkLookup.ContainsKey(key))
                {
                    ChunkLocation chunkLocation = ChunkLookup[key];
                    if (ChunkRequested != null)
                    {
                        ChunkRequested(this, new ChunkRequestedEventArgs(source, chunkLocation.Uri, string.Format("{0}-{1}", chunkLocation.From, chunkLocation.To)));
                    }
                    return(await DownloadResolvedChunkAsync(source, chunkLocation, c));
                }
            }
            if (ChunkRequested != null)
            {
                ChunkRequested(this, new ChunkRequestedEventArgs(source, source, null));
            }
#if SILVERLIGHT // SILVERLIGHT requires that we download the chunk
            return(await WebRequestor.GetResponseAsync(source));
#else
            return(null);
#endif
        }
コード例 #3
0
 private static async Task <IList <Box> > GetBoxesAsync(Uri uri, WebRequestor.Range range)
 {
     using (var stream = await WebRequestor.GetStreamRangeAsync(uri, range))
     {
         using (var reader = new BoxBinaryReader(stream))
         {
             return(reader.GetAllBoxes());
         }
     }
 }
コード例 #4
0
        private async Task <ulong> GetBoxSize(long position)
        {
            var stream = await WebRequestor.GetStreamRangeAsync(this.fileUri, position, position + 16);

            using (var reader = new BoxBinaryReader(stream))
            {
                var size = this.ReadBoxSize(reader);
                return(size);
            }
        }
コード例 #5
0
        private async Task <Box> GetNextBox()
        {
            var size = await this.GetBoxSize(this.fileOffset);

            var boxStream = await WebRequestor.GetStreamRangeAsync(this.fileUri, this.fileOffset, this.fileOffset + (long)size);

            Box box = null;

            using (var boxReader = new BoxBinaryReader(boxStream))
            {
                box              = boxReader.ReadNextBox();
                this.fileOffset += (long)size;
            }

            return(box);
        }
コード例 #6
0
        /// <summary>
        /// Reads the header boxes for the video, which includes
        /// ftyp, pdin, bloc, moov, and the optional mdat.
        /// </summary>
        /// <param name="callback"></param>
        private async Task ReadMovieHeaderBoxes()
        {
            var moov = await this.GetBox(BoxType.Moov);

            this.Boxes.Add(moov);

            // See if we have an mdat next and grab it if we do
            var stream = await WebRequestor.GetStreamRangeAsync(this.fileUri, this.fileOffset, this.fileOffset + 8);

            using (var reader = new BoxBinaryReader(stream))
            {
                if (reader.PeekNextBoxType() == BoxType.Mdat)
                {
                    var mdat = await this.GetNextBox();

                    this.Boxes.Add(mdat);
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// This method of building the mfra will make web requests in order to download the data
        /// from the online source.
        /// </summary>
        /// <param name="callback">The action that should be notified when the process is complete.</param>
        private async Task ReadMovieFragmentRandomAccess()
        {
#if !RANGESUFFIXSUPPORTED // not all backend services support range suffixes. For example, Azure Blobs. Here is a way around this but it requires an extra request to get the length and therefore does not perform as well.
            var fileSize = await WebRequestor.GetFileSizeAsync(this.fileUri);
#endif

            // grab the mfra offset
#if RANGESUFFIXSUPPORTED
            var offsetStream = await WebRequestor.GetStreamRangeAsync(this.fileUri, -4);
#else
            var offsetStream = await WebRequestor.GetStreamRangeNoSuffixAsync(this.fileUri, -4, fileSize);
#endif
            uint mfraOffset = 0;

            using (var reader = new BoxBinaryReader(offsetStream))
            {
                mfraOffset = reader.ReadUInt32();
            }

            // grab the mfra data
#if RANGESUFFIXSUPPORTED
            var mfraStream = await WebRequestor.GetStreamRangeAsync(this.fileUri, -mfraOffset);
#else
            var mfraStream = await WebRequestor.GetStreamRangeNoSuffixAsync(this.fileUri, -mfraOffset, fileSize);
#endif
            // Write the bytes to our TOC file
            using (var reader = new BoxBinaryReader(mfraStream))
            {
                reader.GotoPosition(0);

                Box box = null;

                do
                {
                    box = reader.ReadNextBox();
                    if (box != null)
                    {
                        this.Boxes.Add(box);
                    }
                } while (box != null);
            }
        }
コード例 #8
0
        private async Task <WebRequestorResponse> DownloadManifestAsync(Uri source, CancellationToken c)
        {
            // download and convert the manifest
            var response = await WebRequestor.GetResponseAsync(source);

            c.ThrowIfCancellationRequested();
            // convert the DASH stream to Smooth Streaming format
            XDocument sourceXml = XDocument.Load(response.Stream);
            Stream    destStream;

            switch (sourceXml.Root.Name.LocalName)
            {
            case "SmoothStreamingMedia":
                destStream = response.Stream;
                break;

            case "MPD":
                response.Stream.Dispose();     // we don't need it anymore
                var conversionResult = await DashManifestConverter.ConvertToSmoothManifest(sourceXml, source);

                destStream  = conversionResult.Manifest.ToStream();
                ChunkLookup = conversionResult.ChunkLookup;
                break;

            default:
                throw new NotImplementedException();
            }

            if (ManifestRequested != null)
            {
                var destXml = new StreamReader(destStream).ReadToEnd();
                ManifestRequested(this, new ManifestRequestedEventArgs(source, sourceXml.ToString(), destXml));
            }

            destStream.Seek(0, SeekOrigin.Begin);
            response.Stream = destStream;
            return(response);
        }
コード例 #9
0
 private static async Task<IList<Box>> GetBoxesAsync(Uri uri, WebRequestor.Range range)
 {
     using (var stream = await WebRequestor.GetStreamRangeAsync(uri, range))
     {
         using (var reader = new BoxBinaryReader(stream))
         {
             return reader.GetAllBoxes();
         }
     }
 }
コード例 #10
0
 private static async Task <WebRequestorResponse> DownloadFragment(Uri uri, long offset, long size)
 {
     return(await WebRequestor.GetResponseAsync(uri, offset, offset + size - 1));
 }
コード例 #11
0
 private static async Task <WebRequestorResponse> DownloadResolvedChunkAsync(Uri source, ChunkLocation chunkLocation, CancellationToken c)
 {
     // download the chunk and keep the stream open
     return(await WebRequestor.GetResponseAsync(chunkLocation.Uri, (long)chunkLocation.From, (long)chunkLocation.To));
 }