//public bool IsCropEnabled //{ // get { return this.Cropper.IsCropEnabled; } // set { this.Cropper.IsCropEnabled = value; } //} //public Rect CropRectangle //{ // get { return this.Cropper.CropRectangle; } //} private async void InitializeVideo(StorageFile file) { Media.Source = MediaSource.CreateFromStorageFile(file); Media.MediaPlayer.AutoPlay = true; Media.MediaPlayer.IsMuted = true; Media.MediaPlayer.IsLoopingEnabled = true; Media.MediaPlayer.PlaybackSession.PositionChanged += MediaPlayer_PositionChanged; var clip = await MediaClip.CreateFromFileAsync(file); var composition = new MediaComposition(); composition.Clips.Add(clip); var props = clip.GetVideoEncodingProperties(); double ratioX = (double)40 / props.Width; double ratioY = (double)40 / props.Height; double ratio = Math.Max(ratioY, ratioY); var width = (int)(props.Width * ratio); var height = (int)(props.Height * ratio); var count = Math.Ceiling(280d / width); var times = new List <TimeSpan>(); for (int i = 0; i < count; i++) { times.Add(TimeSpan.FromMilliseconds(clip.OriginalDuration.TotalMilliseconds / count * i)); // TimeSpan.FromMilliseconds for older Frameworks (instead of Divide) } TrimThumbnails.Children.Clear(); #if MOBILE var lumiaScaleFactor = 4; // prevents Catastrophic failure on Lumia 640 & probably others var thumbnails = await composition.GetThumbnailsAsync(times, width *lumiaScaleFactor, height *lumiaScaleFactor, VideoFramePrecision.NearestKeyFrame); #else var thumbnails = await composition.GetThumbnailsAsync(times, width, height, VideoFramePrecision.NearestKeyFrame); #endif foreach (var thumb in thumbnails) { var bitmap = new BitmapImage(); await bitmap.SetSourceAsync(thumb); var image = new Image(); image.Width = width; image.Height = height; image.Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill; image.Source = bitmap; TrimThumbnails.Children.Add(image); } TrimRange.SetOriginalDuration(clip.OriginalDuration); }
private async void InitializeVideo(StorageFile file) { Media.Source = MediaSource.CreateFromStorageFile(file); Media.MediaPlayer.AutoPlay = true; Media.MediaPlayer.IsMuted = true; Media.MediaPlayer.IsLoopingEnabled = true; Media.MediaPlayer.PlaybackSession.PositionChanged += MediaPlayer_PositionChanged; var clip = await MediaClip.CreateFromFileAsync(file); var composition = new MediaComposition(); composition.Clips.Add(clip); var props = clip.GetVideoEncodingProperties(); double ratioX = (double)40 / props.Width; double ratioY = (double)40 / props.Height; double ratio = Math.Max(ratioY, ratioY); var width = (int)(props.Width * ratio); var height = (int)(props.Height * ratio); var count = Math.Ceiling(296d / width); var times = new List <TimeSpan>(); for (int i = 0; i < count; i++) { times.Add(clip.OriginalDuration / count * i); } TrimThumbnails.Children.Clear(); var thumbnails = await composition.GetThumbnailsAsync(times, width, height, VideoFramePrecision.NearestKeyFrame); foreach (var thumb in thumbnails) { var bitmap = new BitmapImage(); await bitmap.SetSourceAsync(thumb); var image = new Image(); image.Width = width; image.Height = height; image.Stretch = Windows.UI.Xaml.Media.Stretch.UniformToFill; image.Source = bitmap; TrimThumbnails.Children.Add(image); } TrimRange.SetOriginalDuration(clip.OriginalDuration); }
private async void ThumbnailButton_Click(object sender, RoutedEventArgs e) { if (!(composition is null)) { var thumbnailTimes = new List <TimeSpan>(); for (int i = 0; i < 10; i++) { thumbnailTimes.Add(TimeSpan.FromSeconds(i + .5)); } var thumbnails = await composition.GetThumbnailsAsync(thumbnailTimes, 320, 240, VideoFramePrecision.NearestFrame); foreach (var thumb in thumbnails) { var image = new Image(); var bitmapImage = new BitmapImage(); bitmapImage.SetSource(thumb); image.Source = bitmapImage; ThumbnailStackPanel.Children.Add(image); } } }
private async void Button_ClickAsync(object sender, RoutedEventArgs e) { StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/beru.wmv")); var clip = await MediaClip.CreateFromFileAsync(file); var composition = new MediaComposition(); composition.Clips.Add(clip); var framePeriod = 1 / 25d;//25 is fps of video var frameTimes = Enumerable.Range(0, 250).Select(x => TimeSpan.FromSeconds(framePeriod * x)).ToList(); //generate multiple image streams using GetThumbnailsAsync var imageStreamsMultiple = (await composition.GetThumbnailsAsync(frameTimes, 0, 0, VideoFramePrecision.NearestFrame)); int i = 0; foreach (var frameTime in frameTimes)//check all frameTimes. Looking for differences { // get single image stream for frameTime var imageStreamsSingle = await composition.GetThumbnailAsync(frameTime, 0, 0, VideoFramePrecision.NearestFrame); var bytesFromMultiple = await GetBytesFromImageStreamAsync(imageStreamsMultiple[i++]); var bytesFromSingle = await GetBytesFromImageStreamAsync(imageStreamsSingle); //compare bytes from both methods var absDiff = bytesFromMultiple.Zip(bytesFromSingle, (m, s) => Math.Abs(m - s)).Sum(); if (absDiff != 0) { //it should not jump here !!! Debug.WriteLine($"There is difference {absDiff}"); } Debug.WriteLine(i); } }
public IAsyncActionWithProgress <double> TranscodeGifAsync(StorageFile source, StorageFile destination, uint width, uint height) { return(AsyncInfo.Run(async delegate(CancellationToken token, IProgress <double> progress) { var composition = new MediaComposition(); System.Diagnostics.Debug.WriteLine(source.Path); var clip = await MediaClip.CreateFromFileAsync(source); if (token.IsCancellationRequested) { return; } progress.Report(10); composition.Clips.Add(clip); using (var outputStream = await destination.OpenAsync(FileAccessMode.ReadWrite)) { if (token.IsCancellationRequested) { return; } progress.Report(20); var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.GifEncoderId, outputStream); if (token.IsCancellationRequested) { return; } progress.Report(30); var increment = TimeSpan.FromSeconds(1.0 / 10.0); var timesFromStart = new List <TimeSpan>(); for (var timeCode = TimeSpan.FromSeconds(0); timeCode < composition.Duration; timeCode += increment) { timesFromStart.Add(timeCode); } var thumbnails = await composition.GetThumbnailsAsync( timesFromStart, System.Convert.ToInt32(width), System.Convert.ToInt32(height), VideoFramePrecision.NearestFrame); progress.Report(40); if (token.IsCancellationRequested) { return; } var index = 0; var progressPerStep = (90.0 - 40.0) / thumbnails.Count / 3.0; var currentProgress = 40.0; foreach (var thumbnail in thumbnails) { var decoder = await BitmapDecoder.CreateAsync(thumbnail); if (token.IsCancellationRequested) { return; } progress.Report(currentProgress += progressPerStep); var pixels = await decoder.GetPixelDataAsync(); if (token.IsCancellationRequested) { return; } progress.Report(currentProgress += progressPerStep); encoder.SetPixelData( decoder.BitmapPixelFormat, BitmapAlphaMode.Ignore, decoder.PixelWidth, decoder.PixelHeight, decoder.DpiX, decoder.DpiY, pixels.DetachPixelData()); if (index < thumbnails.Count - 1) { await encoder.GoToNextFrameAsync(); if (token.IsCancellationRequested) { return; } progress.Report(currentProgress += progressPerStep); } index++; } await encoder.FlushAsync(); if (token.IsCancellationRequested) { return; } progress.Report(100); } })); }
/// <summary> /// Transcode a GIF file /// </summary> /// <param name="source">the source video file</param> /// <param name="destination">the destination .gif file</param> /// <param name="width">the destination image width</param> /// <param name="height">the destination image height</param> /// <param name="fps">the frames per second to encode at</param> /// <returns>an async operation with boolean result and double (0-100) progress.</returns> public IAsyncOperationWithProgress <bool, double> TranscodeGifAsync(StorageFile source, StorageFile destination, uint width, uint height, double fps) { if (source == null) { throw new ArgumentNullException("source", "source cannot be null."); } if (destination == null) { throw new ArgumentNullException("destination", "destination cannot be null."); } if (width == 0) { throw new ArgumentOutOfRangeException("width", "width cannot be 0."); } if (height == 0) { throw new ArgumentOutOfRangeException("height", "height cannot be 0."); } if (fps <= 0) { throw new ArgumentOutOfRangeException("fps", "fps must be greater than 0."); } return(AsyncInfo.Run(async delegate(CancellationToken token, IProgress <double> progress) { var composition = new MediaComposition(); System.Diagnostics.Debug.WriteLine(source.Path); var clip = await MediaClip.CreateFromFileAsync(source); if (token.IsCancellationRequested) { return false; } progress.Report(10); composition.Clips.Add(clip); using (var outputStream = await destination.OpenAsync(FileAccessMode.ReadWrite)) { if (token.IsCancellationRequested) { return false; } progress.Report(20); var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.GifEncoderId, outputStream); if (token.IsCancellationRequested) { return false; } progress.Report(30); var increment = TimeSpan.FromSeconds(1.0 / fps); var timesFromStart = new List <TimeSpan>(); for (var timeCode = TimeSpan.FromSeconds(0); timeCode < composition.Duration; timeCode += increment) { timesFromStart.Add(timeCode); } var thumbnails = await composition.GetThumbnailsAsync( timesFromStart, System.Convert.ToInt32(width), System.Convert.ToInt32(height), VideoFramePrecision.NearestFrame); progress.Report(40); if (token.IsCancellationRequested) { return false; } var index = 0; var progressPerStep = (90.0 - 40.0) / thumbnails.Count / 3.0; var currentProgress = 40.0; foreach (var thumbnail in thumbnails) { var decoder = await BitmapDecoder.CreateAsync(thumbnail); if (token.IsCancellationRequested) { return false; } progress.Report(currentProgress += progressPerStep); var pixels = await decoder.GetPixelDataAsync(); if (token.IsCancellationRequested) { return false; } progress.Report(currentProgress += progressPerStep); encoder.SetPixelData( decoder.BitmapPixelFormat, BitmapAlphaMode.Ignore, decoder.PixelWidth, decoder.PixelHeight, decoder.DpiX, decoder.DpiY, pixels.DetachPixelData()); var delayTime = System.Convert.ToUInt16(increment.TotalSeconds * 1000); var properties = new BitmapPropertySet { { "/grctlext/Delay", new BitmapTypedValue(delayTime / 10, PropertyType.UInt16) } }; await encoder.BitmapProperties.SetPropertiesAsync(properties); if (index < thumbnails.Count - 1) { await encoder.GoToNextFrameAsync(); if (token.IsCancellationRequested) { return false; } progress.Report(currentProgress += progressPerStep); } index++; } await encoder.FlushAsync(); if (token.IsCancellationRequested) { return false; } progress.Report(100); return true; } })); }