2016-02-13 3 views
1

I`m пытается сделать Windows 10 приложений, которые используют камеру для записи видео иFrames Извлечение из видео C#

сделать некоторую обработку изображения на этом видео, i`m свежа в обработке изображений, первый

моего приложения запись 10 второе видео с факелом, после 10 секунд видео остановки ...

я использую метод для воспроизведения видео, чтобы увидеть, что я запись ...

i`m застряло на разных вещах. .

1) как я могу преобразовать это видео в рамки?

2) можно ли конвертировать видео во время записи i`m?

3) позволяет сказать, что я конвертирую видео в Frames, как с этим бороться?, Он выглядит как Images (jpeg ..etc)?

Главная

using System; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 

using Windows.UI.Xaml.Navigation; 

namespace App3 
{ 

public sealed partial class MainPage : Page 
{   
    DispatcherTimer D; 
    double basetimer = 0; 
    public MainPage() 
    { 
     this.InitializeComponent();  
     this.NavigationCacheMode = NavigationCacheMode.Required; 
     D = new DispatcherTimer();  
     D.Interval = new TimeSpan(0, 0, 1); 
     D.Tick += timer_Tick; 
     txt.Text = basetimer.ToString(); 
     Play.IsEnabled = false;    
    } 
    public Library Library = new Library(); 
    public object PreviewImage { get; private set; } 
    void timer_Tick(object sender, object e) 
    { 
     basetimer = basetimer - 1; 
     txt.Text = basetimer.ToString(); 
     if (basetimer == 0) 
     { 
      D.Stop();    
      Preview.Source = null; 
      Library.Stop(); 
      Record.IsEnabled = false; 
      Play.IsEnabled = true; 
      Clear.IsEnabled = true; 
      if (Library._tc.Enabled) 
      { 
       Library._tc.Enabled = false; 
      }     
     } 
    } 
    private void Record_Click(object sender, RoutedEventArgs e) 
    {    
     if (Library.Recording) 
     { 
      Preview.Source = null; 
      Library.Stop(); 
      Record.Icon = new SymbolIcon(Symbol.Video);     
     } 
     else 
     { 
      basetimer = 11; 
      D.Start(); 
      //D.Tick += timer_Tick; 
      Display.Source = null; 
      Library.Record(Preview); 
      Record.Icon = new SymbolIcon(Symbol.VideoChat); 
      Record.IsEnabled = false; 
      Play.IsEnabled = false; 
     } 
    } 
    private async void Play_Click(object sender, RoutedEventArgs e) 
    {    
     await Library.Play(Dispatcher, Display); 
     //Extract_Image_From_Video(Library.buffer);    
    } 
    private void Clear_Click(object sender, RoutedEventArgs e) 
    { 
     Display.Source = null;    
     Record.Icon = new SymbolIcon(Symbol.Video); 
     txt.Text = "0"; 
     basetimer= 0; 
     Play.IsEnabled = false; 
     Record.IsEnabled =true; 
     if (Library.capture != null) 
     { 
      D.Stop(); 
      Library.Recording = false; 
      Preview.Source = null;    
      Library.capture.Dispose(); 
      Library.capture = null; 
      basetimer = 11; 
     } 
     } 
    } 
} 

Библиотека классов

using System; 
using System.Diagnostics; 
using System.Linq; 
using System.Threading.Tasks; 
using Windows.Devices.Enumeration; 
using Windows.Media.Capture; 
using Windows.Media.Devices; 
using Windows.Media.MediaProperties; 
using Windows.Storage; 
using Windows.Storage.Streams; 
using Windows.UI.Core; 
using Windows.UI.Xaml.Controls; 
using Windows.UI.Xaml.Media.Imaging; 
using Windows.Graphics.Imaging; 
using Emgu.CV.Structure; 
using Emgu.CV; 
using System.Collections.Generic; 

public class Library 
{ 

private const string videoFilename = "video.mp4"; 
private string filename; 
public MediaCapture capture; 
public InMemoryRandomAccessStream buffer; 
public static bool Recording; 
public TorchControl _tc; 
public int basetimer ; 
public async Task<bool> init() 
{ 
    if (buffer != null) 
    { 
     buffer.Dispose(); 
    } 
    buffer = new InMemoryRandomAccessStream(); 
    if (capture != null) 
    { 
     capture.Dispose(); 
    } 
    try 
    { 

     if (capture == null) 
     { 
      var allVideoDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);    
      DeviceInformation cameraDevice = 
      allVideoDevices.FirstOrDefault(x => x.EnclosureLocation != null && 
      x.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back); 
      capture = new MediaCapture(); 
      var mediaInitSettings = new MediaCaptureInitializationSettings { VideoDeviceId = cameraDevice.Id }; 
      // Initialize 
      try 
      { 
       await capture.InitializeAsync(mediaInitSettings); 
       var videoDev = capture.VideoDeviceController; 
       _tc = videoDev.TorchControl; 
       Recording = false; 
       _tc.Enabled = false;          
      } 
      catch (UnauthorizedAccessException) 
      { 
       Debug.WriteLine("UnauthorizedAccessExeption>>"); 
      } 
      catch (Exception ex) 
      { 
       Debug.WriteLine("Exception when initializing MediaCapture with {0}: {1}", cameraDevice.Id, ex.ToString()); 
      } 
     } 
      capture.Failed += (MediaCapture sender, MediaCaptureFailedEventArgs errorEventArgs) => 
     { 
      Recording = false; 
      _tc.Enabled = false; 
      throw new Exception(string.Format("Code: {0}. {1}", errorEventArgs.Code, errorEventArgs.Message)); 
     }; 
    } 
    catch (Exception ex) 
    { 
     if (ex.InnerException != null && ex.InnerException.GetType() == typeof(UnauthorizedAccessException)) 
     { 
      throw ex.InnerException; 
     } 
     throw; 
    } 
    return true; 
} 
public async void Record(CaptureElement preview) 
{  
    await init(); 
    preview.Source = capture; 
    await capture.StartPreviewAsync(); 
    await capture.StartRecordToStreamAsync(MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto), buffer); 
    if (Recording) throw new InvalidOperationException("cannot excute two records at the same time"); 
    Recording = true; 
    _tc.Enabled = true; 

} 
public async void Stop() 
{ 
    await capture.StopRecordAsync(); 
    Recording = false; 
    _tc.Enabled = false;  
}  

public async Task Play(CoreDispatcher dispatcher, MediaElement playback) 
{ 
    IRandomAccessStream video = buffer.CloneStream(); 

    if (video == null) throw new ArgumentNullException("buffer"); 
    StorageFolder storageFolder = Windows.ApplicationModel.Package.Current.InstalledLocation; 
    if (!string.IsNullOrEmpty(filename)) 
    { 
     StorageFile original = await storageFolder.GetFileAsync(filename); 
     await original.DeleteAsync(); 
    } 
    await dispatcher.RunAsync(CoreDispatcherPriority.Normal, async() => 
    { 
     StorageFile storageFile = await storageFolder.CreateFileAsync(videoFilename, CreationCollisionOption.GenerateUniqueName); 
     filename = storageFile.Name; 
     using (IRandomAccessStream fileStream = await storageFile.OpenAsync(FileAccessMode.ReadWrite)) 
     { 
      await RandomAccessStream.CopyAndCloseAsync(video.GetInputStreamAt(0), fileStream.GetOutputStreamAt(0)); 
      await video.FlushAsync(); 
      video.Dispose(); 
     } 
     IRandomAccessStream stream = await storageFile.OpenAsync(FileAccessMode.Read); 

     playback.SetSource(stream, storageFile.FileType); 
     playback.Play(); 





    }); 


} 

ответ

3

Я понял это только вчера.

Здесь приведен полный и легкий для понимания пример с выбором видеофайла и сохранением моментального снимка в 1-й секунде видео.

Вы можете взять детали, припадки свой проект и изменить некоторые из них (то есть получать разрешение видео с камеры)

1) и 3)

TimeSpan timeOfFrame = new TimeSpan(0, 0, 1); 

     //pick mp4 file 
     var picker = new Windows.Storage.Pickers.FileOpenPicker(); 
     picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary; 
     picker.FileTypeFilter.Add(".mp4"); 
     StorageFile pickedFile = await picker.PickSingleFileAsync(); 
     if (pickedFile == null) 
     { 
      return; 
     } 
     /// 


     //Get video resolution 
     List<string> encodingPropertiesToRetrieve = new List<string>(); 
     encodingPropertiesToRetrieve.Add("System.Video.FrameHeight"); 
     encodingPropertiesToRetrieve.Add("System.Video.FrameWidth"); 
     IDictionary<string, object> encodingProperties = await pickedFile.Properties.RetrievePropertiesAsync(encodingPropertiesToRetrieve); 
     uint frameHeight = (uint)encodingProperties["System.Video.FrameHeight"]; 
     uint frameWidth = (uint)encodingProperties["System.Video.FrameWidth"]; 
     /// 


     //Use Windows.Media.Editing to get ImageStream 
     var clip = await MediaClip.CreateFromFileAsync(pickedFile); 
     var composition = new MediaComposition(); 
     composition.Clips.Add(clip); 

     var imageStream = await composition.GetThumbnailAsync(timeOfFrame, (int)frameWidth, (int)frameHeight, VideoFramePrecision.NearestFrame); 
     /// 


     //generate bitmap 
     var writableBitmap = new WriteableBitmap((int)frameWidth, (int)frameHeight); 
     writableBitmap.SetSource(imageStream); 


     //generate some random name for file in PicturesLibrary 
     var saveAsTarget = await KnownFolders.PicturesLibrary.CreateFileAsync("IMG" + Guid.NewGuid().ToString().Substring(0, 4) + ".jpg"); 


     //get stream from bitmap 
     Stream stream = writableBitmap.PixelBuffer.AsStream(); 
     byte[] pixels = new byte[(uint)stream.Length]; 
     await stream.ReadAsync(pixels, 0, pixels.Length); 

     using (var writeStream = await saveAsTarget.OpenAsync(FileAccessMode.ReadWrite)) 
     { 
      var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, writeStream); 
      encoder.SetPixelData(
       BitmapPixelFormat.Bgra8, 
       BitmapAlphaMode.Premultiplied, 
       (uint)writableBitmap.PixelWidth, 
       (uint)writableBitmap.PixelHeight, 
       96, 
       96, 
       pixels); 
      await encoder.FlushAsync(); 

      using (var outputStream = writeStream.GetOutputStreamAt(0)) 
      { 
       await outputStream.FlushAsync(); 
      } 
     } 

Если вы хотите отобразить кадры в XAML изображения, вы должны использовать ImageStream

BitmapImage bitmapImage = new BitmapImage(); 
bitmapImage.SetSource(imageStream); 

XAMLImage.Source = bitmapImage; 

Если вы хотите, чтобы извлечь больше кадров, есть также composition.GetThumbnailsAsync

2) Используйте mediaCapture, когда таймер тикает

+0

Я думаю, что это будет работать. Мое видео не будет выбрано из пути, im запись в потоковое видео, 'InMemoryRandomAccessStream buffer', есть ли способ конвертировать' InMemoryRandomAccessStream buffer' в 'storegfile', тогда я могу, возможно, использовать ваши путь ? Спасибо за помощь. – Ahmed

+0

У вас есть объект MediaCapture, когда в методе записи, и, очевидно, файл хранилища в методе воспроизведения. Что не работает? – Alamakanambra

+0

Если вы хотите использовать это в стандартном рабочем приложении .net, выполните следующие действия: https://github.com/jbe2277/waf/wiki/Using-Windows-Runtime-in-a-.NET-desktop-application – Hans

1

Использование FFmpeg http://ffmpeg.org/

using (var vFReader = new VideoFileReader()) 
{ 
    vFReader.Open("video.mp4"); 
    for (int i = 0; i < vFReader.FrameCount; i++) 
    { 
     Bitmap bmpBaseOriginal = vFReader.ReadVideoFrame(); 
    } 
    vFReader.Close(); 
} 
+0

Какую оболочку вы использовали для ffmpeg в C#? –

+0

@MajidHojati Это похоже на Accord.net, который теперь поглотил Афар. Следует отметить, что он выпущен под GPL. – Gui

0

Я закончил с использованием MediaToolkit решить подобную проблему после того, как тонна неприятностей с согласия ,

мне нужно, чтобы сохранить изображение на каждую секунду видео:

using (var engine = new Engine()) 
{ 
    var mp4 = new MediaFile { Filename = mp4FilePath }; 

    engine.GetMetadata(mp4); 

    var i = 0; 
    while (i < mp4.Metadata.Duration.Seconds) 
    { 
     var options = new ConversionOptions { Seek = TimeSpan.FromSeconds(i) }; 
     var outputFile = new MediaFile { Filename = string.Format("{0}\\image-{1}.jpeg", outputPath, i) }; 
     engine.GetThumbnail(mp4, outputFile, options); 
     i++; 
    } 
} 

Надеется, что это помогает кто-нибудь.

Смежные вопросы