/// <summary> /// Reads all the blocks of the specified media type from the source url. /// </summary> /// <param name="mediaSource">The subtitles URL.</param> /// <param name="sourceType">Type of the source.</param> /// <param name="parent">The parent.</param> /// <returns>A buffer containing all the blocks.</returns> internal static MediaBlockBuffer LoadBlocks(string mediaSource, MediaType sourceType, ILoggingHandler parent) { if (string.IsNullOrWhiteSpace(mediaSource)) { throw new ArgumentNullException(nameof(mediaSource)); } using (var tempContainer = new MediaContainer(mediaSource, null, parent)) { tempContainer.Initialize(); // Skip reading and decoding unused blocks tempContainer.MediaOptions.IsAudioDisabled = sourceType != MediaType.Audio; tempContainer.MediaOptions.IsVideoDisabled = sourceType != MediaType.Video; tempContainer.MediaOptions.IsSubtitleDisabled = sourceType != MediaType.Subtitle; // Open the container tempContainer.Open(); if (tempContainer.Components.Main == null || tempContainer.Components.MainMediaType != sourceType) { throw new MediaContainerException($"Could not find a stream of type '{sourceType}' to load blocks from"); } // read all the packets and decode them var outputFrames = new List <MediaFrame>(1024 * 8); while (true) { tempContainer.Read(); var frames = tempContainer.Decode(); foreach (var frame in frames) { if (frame.MediaType != sourceType) { continue; } outputFrames.Add(frame); } if (frames.Count <= 0 && tempContainer.IsAtEndOfStream) { break; } } // Build the result var result = new MediaBlockBuffer(outputFrames.Count, sourceType); foreach (var frame in outputFrames) { result.Add(frame, tempContainer); } tempContainer.Close(); return(result); } }
static void Start(string[] args) { InputFile = TestInputs.HlsStream; StartTime = 0; DecodeDurationLimit = 20; IsBenchmarking = false; SaveWaveFile = true; SaveSnapshots = true; Container = new MediaContainer(InputFile); Container.Initialize(); TestNormalDecoding(); //TestMultipleSeeks(); Container.Dispose(); Terminal.WriteLine("All Tests Done!"); Terminal.ReadKey(true, true); }
public void Open(IMediaInputStream stream, Uri streamUri, HardwareDeviceInfo ha) { if (stream != null || streamUri != null) { Close(); try { // TODO: Sometimes when the stream can't be read, the sample player stays as if it were trying to open // until the interrupt timeout occurs but and the Real-Time Clock continues. Strange behavior. Investigate more. // Signal the initial state var source = stream != null ? stream.StreamUri : streamUri; State.ResetAll(); State.UpdateSource(source); // Create a default stream container configuration object var containerConfig = new ContainerConfiguration(); // Convert the URI object to something the Media Container understands (Uri to String) var mediaSource = source.IsWellFormedOriginalString() ? source.OriginalString : Uri.EscapeUriString(source.OriginalString); // When opening via URL (and not via custom input stream), fix up the protocols and stuff if (stream == null) { try { // the async protocol prefix allows for increased performance for local files. // or anything that is file-system related if (source.IsFile || source.IsUnc) { // Set the default protocol Prefix // The async protocol prefix by default does not ssem to provide // any performance improvements. Just leaving it for future reference below. // containerConfig.ProtocolPrefix = "async" mediaSource = source.LocalPath; } } catch { /* Ignore exception and continue */ } // Support device URLs // GDI GRAB: Example URI: device://gdigrab?desktop if (string.IsNullOrWhiteSpace(source.Scheme) == false && (source.Scheme == "format" || source.Scheme == "device") && string.IsNullOrWhiteSpace(source.Host) == false && string.IsNullOrWhiteSpace(containerConfig.ForcedInputFormat) && string.IsNullOrWhiteSpace(source.Query) == false) { // Update the Input format and container input URL // It is also possible to set some input options as follows: // Example: streamOptions.PrivateOptions["framerate"] = "20" containerConfig.ForcedInputFormat = source.Host; mediaSource = Uri.UnescapeDataString(source.Query).TrimStart('?'); //this.LogInfo(Aspects.EngineCommand, // $"Media URI will be updated. Input Format: {source.Host}, Input Argument: {mediaSource}"); } } // Instantiate the public container using either a URL (default) or a custom input stream. Container = stream == null ? new MediaContainer(mediaSource, containerConfig, this) : new MediaContainer(stream, containerConfig, this); // Initialize the container Container.Initialize(); Container.MediaOptions.VideoHardwareDevice = ha; // Side-load subtitles if requested // Get the main container open Container.Open(); State.InitializeBufferingStatistics(); Workers = new MediaWorkerSet(this); Workers.Start(); } catch { try { Workers?.Dispose(); } catch { /* Ignore any exceptions and continue */ } try { Container?.Dispose(); } catch { /* Ignore any exceptions and continue */ } Container = null; throw; } } else { Close(); } }
/// <summary> /// Opens the specified media Asynchronously /// </summary> /// <param name="uri">The URI.</param> /// <returns></returns> private async Task OpenAsync(Uri uri) { try { await Task.Run(() => { var mediaUrl = uri.IsFile ? uri.LocalPath : uri.ToString(); Container = new MediaContainer(mediaUrl); RaiseMediaOpeningEvent(); Container.Log(MediaLogMessageType.Debug, $"{nameof(OpenAsync)}: Entered"); Container.Initialize(); }); foreach (var t in Container.Components.MediaTypes) { Blocks[t] = new MediaBlockBuffer(MaxBlocks[t], t); Frames[t] = new MediaFrameQueue(); LastRenderTime[t] = TimeSpan.MinValue; Renderers[t] = CreateRenderer(t); } IsTaskCancellationPending = false; BlockRenderingCycle.Set(); FrameDecodingCycle.Set(); PacketReadingCycle.Set(); PacketReadingTask = new Thread(RunPacketReadingWorker) { IsBackground = true }; FrameDecodingTask = new Thread(RunFrameDecodingWorker) { IsBackground = true }; BlockRenderingTask = new Thread(RunBlockRenderingWorker) { IsBackground = true }; PacketReadingTask.Start(); FrameDecodingTask.Start(); BlockRenderingTask.Start(); RaiseMediaOpenedEvent(); if (LoadedBehavior == MediaState.Play) { Play(); } } catch (Exception ex) { RaiseMediaFailedEvent(ex); } finally { UpdateMediaProperties(); Container.Log(MediaLogMessageType.Debug, $"{nameof(OpenAsync)}: Completed"); } }