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)); } }
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 }
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()); } } }
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); } }
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); }
/// <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); } } }
/// <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); } }
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); }
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(); } } }
private static async Task <WebRequestorResponse> DownloadFragment(Uri uri, long offset, long size) { return(await WebRequestor.GetResponseAsync(uri, offset, offset + size - 1)); }
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)); }