예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FFmpegMedia"/> class.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="errorCallback">The error callback.</param>
        /// <exception cref="System.ArgumentException">
        /// errorCallback cannot be null
        /// or
        /// filePath cannot be null or empty
        /// </exception>
        /// <exception cref="System.Exception"></exception>
        public FFmpegMedia(string filePath, MediaErrorOccurredCallback errorCallback)
        {
            // Argument validation
            if (errorCallback == null)
            {
                throw new ArgumentException("errorCallback cannot be null");
            }

            if (string.IsNullOrWhiteSpace(filePath))
            {
                throw new ArgumentException("filePath cannot be null or empty");
            }

            // Error callback
            this.ErrorOccurredCallback = errorCallback;

            // Register the property state change handler
            this.RealtimeClock.PropertyChanged += (s, e) => { NotifyPlayStateChanged(); };

            // Make sure we registwered the library
            Helper.RegisterFFmpeg();

            // Create the audio provider and audio renderer
            this.PcmAudioProvider = new AudioBufferProvider(this);
            this.AudioRenderer    = new AudioRenderer();

            // load input, codec and output contexts
            this.InitializeMedia(filePath);

            // Setup the frames Cache
            this.VideoFramesCache = new FFmpegMediaFrameCache(this.VideoFrameRate, MediaFrameType.Video);
            this.AudioFramesCache = new FFmpegMediaFrameCache(this.AudioSampleRate / 1000M, MediaFrameType.Audio);

            // Setup the Leading and Lagging frames cache
            if (HasVideo && (HasAudio == false || InputAudioStream->index > InputVideoStream->index))
            {
                this.LeadingFramesCache = VideoFramesCache;
                this.LaggingFramesCache = AudioFramesCache;
                this.StartDts           = InputVideoStream->start_time;

                LeadingStreamType = MediaFrameType.Video;
                LaggingStreamType = HasAudio ? MediaFrameType.Audio : MediaFrameType.Unknown;
            }
            else
            {
                this.LeadingFramesCache = AudioFramesCache;
                this.LaggingFramesCache = VideoFramesCache;
                this.StartDts           = InputAudioStream->start_time;

                LeadingStreamType = MediaFrameType.Audio;
                LaggingStreamType = HasVideo ? MediaFrameType.Video : MediaFrameType.Unknown;
            }

            if (Helper.IsNoPtsValue(StartDts))
            {
                StartDts = 0;
            }

            // Setup Video Renderer and Video Frames Cache
            if (HasVideo)
            {
                this.VideoRenderer = new WriteableBitmap(this.VideoFrameWidth, this.VideoFrameHeight, 96, 96, System.Windows.Media.PixelFormats.Bgr24, null);
            }
            else
            {
                this.VideoRenderer = new WriteableBitmap(1, 1, 96, 96, System.Windows.Media.PixelFormats.Bgr24, null);
            }


            // Setup Audio Renderer and Audio Frames Cache
            if (HasAudio)
            {
                this.StartAudioRenderer();
            }

            // Start the continuous Decoder thread that fills up our queue.
            MediaFrameExtractorThread = new Thread(ExtractMediaFramesContinuously)
            {
                IsBackground = true,
                Priority     = ThreadPriority.AboveNormal
            };

            // Begin the media extractor
            MediaFrameExtractorThread.Start();
            MediaFramesExtractedDone.Reset();
            if (MediaFramesExtractedDone.Wait(Constants.WaitForPlaybackReadyStateTimeout) == false)
            {
                throw new Exception(string.Format("Could not load sream frames in a timely manner. Timed out in {0}", Constants.WaitForPlaybackReadyStateTimeout));
            }

            // Initialize the Speed Ratio to 1.0 (Default)
            this.SpeedRatio = Constants.DefaultSpeedRatio;

            // Start the render timer on the UI thread.
            this.VideoRenderTimer.Tick     += RenderVideoImage;
            this.VideoRenderTimer.Interval  = TimeSpan.FromMilliseconds(Constants.VideoRenderTimerIntervalMillis);
            this.VideoRenderTimer.IsEnabled = true;
            this.VideoRenderTimer.Start();
        }
예제 #2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FFmpegMedia" /> class.
        /// </summary>
        /// <param name="filePath">The file path.</param>
        /// <param name="errorCallback">The error callback.</param>
        /// <param name="referer">The referer. Leave null or emtpy to skip setting it.</param>
        /// <param name="userAgent">The user agent. Leave null or empty in order to skip setting a User Agent</param>
        /// <exception cref="ArgumentException">errorCallback cannot be null
        /// or
        /// filePath cannot be null or empty</exception>
        /// <exception cref="Exception"></exception>
        /// <exception cref="System.ArgumentException">errorCallback cannot be null
        /// or
        /// filePath cannot be null or empty</exception>
        /// <exception cref="System.Exception"></exception>
        public FFmpegMedia(string filePath, MediaErrorOccurredCallback errorCallback, string referer, string userAgent)
        {
            // Argument validation
            if (errorCallback == null)
                throw new ArgumentException("errorCallback cannot be null");

            if (string.IsNullOrWhiteSpace(filePath))
                throw new ArgumentException("filePath cannot be null or empty");

            // Error callback
            this.ErrorOccurredCallback = errorCallback;

            // Register the property state change handler
            this.RealtimeClock.PropertyChanged += (s, e) => { NotifyPlayStateChanged(); };

            // Make sure we registwered the library            
            Helper.RegisterFFmpeg();

            // Create the audio provider and audio renderer
            this.PcmAudioProvider = new AudioBufferProvider(this);
            this.AudioRenderer = new AudioRenderer();

            // load input, codec and output contexts
            this.InitializeMedia(filePath, null, referer, userAgent);

            // Setup the frames Cache
            this.VideoFramesCache = new FFmpegMediaFrameCache(this.VideoFrameRate * (int)FramesCacheLength.TotalSeconds, MediaFrameType.Video);
            this.AudioFramesCache = new FFmpegMediaFrameCache(this.AudioSampleRate / (int)FramesCacheLength.TotalMilliseconds, MediaFrameType.Audio);

            // Setup the Leading and Lagging frames cache
            if (HasVideo && (HasAudio == false || InputAudioStream->index > InputVideoStream->index))
            {
                this.PrimaryFramesCache = VideoFramesCache;
                this.SecondaryFramesCache = AudioFramesCache;
                this.StartDts = InputVideoStream->start_time;

                LeadingStreamType = MediaFrameType.Video;
                LaggingStreamType = HasAudio ? MediaFrameType.Audio : MediaFrameType.Unknown;
            }
            else
            {
                this.PrimaryFramesCache = AudioFramesCache;
                this.SecondaryFramesCache = VideoFramesCache;
                this.StartDts = InputAudioStream->start_time;

                LeadingStreamType = MediaFrameType.Audio;
                LaggingStreamType = HasVideo ? MediaFrameType.Video : MediaFrameType.Unknown;
            }

            if (Helper.IsNoPtsValue(StartDts))
                StartDts = 0;

            // Setup Video Renderer and Video Frames Cache
            if (HasVideo)
                this.VideoRenderer = new WriteableBitmap(this.VideoFrameWidth, this.VideoFrameHeight, 96, 96, System.Windows.Media.PixelFormats.Bgr24, null);
            else
                this.VideoRenderer = new WriteableBitmap(1, 1, 96, 96, System.Windows.Media.PixelFormats.Bgr24, null);


            // Setup Audio Renderer and Audio Frames Cache
            if (HasAudio)
            {
                this.StartAudioRenderer();
            }

            // Start the continuous Decoder thread that fills up our queue.
            MediaFrameExtractorThread = new Thread(ExtractMediaFramesContinuously)
            {
                IsBackground = true,
                Priority = ThreadPriority.AboveNormal
            };

            // Begin the media extractor
            MediaFrameExtractorThread.Start();
            MediaFramesExtractedDone.Reset();
            if (MediaFramesExtractedDone.Wait(Constants.WaitForPlaybackReadyStateTimeout) == false)
            {
                throw new Exception(string.Format("Could not load sream frames in a timely manner. Timed out in {0}", Constants.WaitForPlaybackReadyStateTimeout));
            }

            // Initialize the Speed Ratio to 1.0 (Default)
            this.SpeedRatio = Constants.DefaultSpeedRatio;

            // Start the render timer on the UI thread.
            this.VideoRenderTimer.Tick += RenderVideoImage;
            this.VideoRenderTimer.Interval = TimeSpan.FromMilliseconds(Constants.VideoRenderTimerIntervalMillis);
            this.VideoRenderTimer.IsEnabled = true;
            this.VideoRenderTimer.Start();
        }