2017-08-28 7 views
0

Ich habe einen Windowsservice, der Daumenabdrücke von Videos erzeugen soll. Um dies zu erreichen, versuche ich die MediaElement-Klasse (https://msdn.microsoft.com/en-us/library/system.windows.controls.mediaelement(v=vs.110).aspx) zu verwenden. Um Ereignisse beim Öffnen von Medien auszulösen, muss sich dieses Element in einem Visual Tree befinden. Ist es möglich, einen visuellen Baum zu simulieren oder zu fälschen?C#: Ist es möglich, einen visuellen Baum in einem Service zu erzeugen oder zu fälschen?

Edit: Ich benutze jetzt MediaPlayer anstelle von MediaElements, kann aber nicht auf die Ereignisse verlassen, weil sie nicht geworfen werden.

Aktualisiert Code

 public class Mp4ThumbnailExtractor : IDisposable 
{ 
    private ManualResetEvent waitHandle; 
    private TimeSpan mediaOpenTimeout; 

    public TimeSpan Time { get; set; } 
     = TimeSpan.Parse("00:00:30"); 

    public TimeSpan FallbackTime { get; set; } 
     = TimeSpan.Parse("00:00:10"); 

    public int Height { get; set; } 
     = 400; 

    public int Width { get; set; } 
     = 400; 

    public int Dpi { get; set; } 
     = 96; 

    public Mp4ThumbnailExtractor() 
    { 
     waitHandle = new ManualResetEvent(false); 
     mediaOpenTimeout = TimeSpan.Parse("00:00:15"); 
    } 

    public MemoryStream CreateThumbnail(string videoPath) 
    { 
     MemoryStream memory = new MemoryStream(); 
     Uri sourceUri = new Uri(videoPath); 

     MediaPlayer media = new MediaPlayer(); 
     media.MediaOpened += Media_MediaOpened; 
     media.ScrubbingEnabled = true; 

     try 
     { 
      media.Open(new Uri(videoPath)); 

      //TODO: media.opened event will not get fired 
      Thread.Sleep(mediaOpenTimeout); 
      waitHandle.Set(); 

      //15sec timeout for loading the media 
      if (waitHandle.WaitOne(mediaOpenTimeout)) 
      { 
       SetPosition(media); 

       //TODO: this is bad... 
       Thread.Sleep(2000); 

       DrawingVisual dv = new DrawingVisual(); 
       DrawingContext dc = dv.RenderOpen(); 
       dc.DrawVideo(media, new Rect(0, 0, Width, Height)); 
       dc.Close(); 
       RenderTargetBitmap bmp = new RenderTargetBitmap(Width, Height, Dpi, Dpi, PixelFormats.Pbgra32); 
       bmp.Render(dv); 

       JpegBitmapEncoder encoder = new JpegBitmapEncoder(); 
       encoder.Frames.Add(BitmapFrame.Create(bmp)); 
       encoder.Save(memory); 

       memory.Seek(0, SeekOrigin.Begin); 
      } 
      else 
      { 
       throw new Exception($"Unable to open media '{videoPath}' in '{mediaOpenTimeout}'"); 
      } 
     } 
     finally 
     { 
      media.Close(); 
     } 
     return memory; 
    } 

    private void SetPosition(MediaPlayer player) 
    { 
     if (player.NaturalDuration.HasTimeSpan) 
     { 
      TimeSpan naturalTime = player.NaturalDuration.TimeSpan; 
      if (naturalTime < Time) 
      { 
       if (naturalTime > FallbackTime) 
       { 
        player.Position = FallbackTime; 
       } 
      } 
      else 
      { 
       player.Position = Time; 
      } 
     } 
    } 

    private void Media_MediaOpened(object sender, EventArgs e) 
    { 
     waitHandle.Set(); 
    } 

    public void Dispose() 
    { 
     waitHandle.Dispose(); 
    } 
} 
+1

MediaElement ist ein visuelles Element. Warum nicht stattdessen [MediaPlayer] (https://msdn.microsoft.com/en-us/library/system.windows.media.mediaplayer (v = vs.110) .aspx) verwenden? – icebat

+0

Der MediaPlayer kann Screenshots erstellen, aber das MediaOpened-Ereignis wird nicht ausgelöst und die Positionierung wird 2 bis 3 Mal aktiviert. Ich habe einen hardcoded Thread.Sleep (150000) hinzugefügt; waitHandle.Set(); vor warteHandle.Wait. Dies ist keine zuverlässige Lösung –

Antwort

1

MediaElement ist im Grunde eine visuelle Kontrolle für das Hosting von Medieninhalten:

Stellt ein Steuerelement, das enthält Audio- und/oder Video

Sie benötigen einen UI . Nur nicht vergessen, Open Methode oder MediaOpened anrufen wird nicht ausgelöst.

+0

Ich bin jetzt in der Lage, Bildschirme zu erfassen, aber Ereignisse werden nicht funktionieren. Ich habe jetzt 2 harcoded Verzögerungen, um den Code laufen zu lassen (für die meisten Fälle, aber nicht zuverlässig, Positionseinstellung als auch ein bisschen unzuverlässig) –

Verwandte Themen