Пример #1
0
        /// <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);
            }
        }
Пример #2
0
        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");
            }
        }