Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi DSPack Video Vorspulen (https://www.delphipraxis.net/43410-dspack-video-vorspulen.html)

helen 3. Apr 2005 17:01


DSPack Video Vorspulen
 
Hallo,

ich versuche mit dem DSpack einen VideoPlayer zu basteln.
Aus Effizienzgründen will ich das Video auf ButtonClick um 1 Minute vorspulen.

Wie geht das?

Gruß
Helen

PS: Es ist kein DVD Player

Christian Seehase 3. Apr 2005 17:50

Re: DSPack Video Vorspulen
 
Moin Helen,

das müsste sich eigentlich mit dem IMediaSeeking-Interface machen lassen.
Deklariert ist es in der DirectX9-Unit von DSPACK.

So in dieser Art müsste es gehen (nicht unbedingt Copy&Paste fähig ;-)):

Delphi-Quellcode:
var
  ms        : IMediaSeeking;
  i64Current : int64;
  i64Stop   : int64;

begin // fgMain : TFilterGraph
  if fgMain.Active then begin // definierten Zustand schaffen
    fgMain.Stop;
    fgMain.Active := false;
  end;
  fgMain.Active := true;
  fgMain.RenderFile(...);
  fgMain.Pause;
  fgMain.QueryInterface(IMediaSeeking,ms);
  ms.SetTimeFormat(TIME_FORMAT_FRAME); // evtl. anpassen
  ms.GetPositions(i64Current,i64Stop);
  ms.SetPositions(i64Stop,AM_SEEKING_AbsolutePositioning,i64Stop,AM_SEEKING_AbsolutePositioning);
end;

omata 3. Apr 2005 19:24

Re: DSPack Video Vorspulen
 
Moin,

etwas konkreter sieht das dann so aus...

Delphi-Quellcode:
procedure TMain.SetPosition(FilterGraph:TFilterGraph; secPos: Cardinal);
var FMediaSeeking:IMediaSeeking;
    StopPosition, CurrentPosition: int64;
    MlsStopPos: Cardinal;
begin
  FilterGraph.QueryInterface(IMediaSeeking, FMediaSeeking);
  FMediaSeeking.GetStopPosition(StopPosition);
  MlsStopPos   := RefTimeToMiliSec(StopPosition);
  CurrentPosition := (StopPosition * secPos) div (MlsStopPos div 1000) ;
  StopPosition:=0;
  FMediaSeeking.SetPositions(CurrentPosition, AM_SEEKING_AbsolutePositioning,
                             StopPosition,   AM_SEEKING_NoPositioning);
end;
Und der Aufruf...

Delphi-Quellcode:
  SetPosition(FilterGraph, 60);
MfG
Thorsten

helen 5. Apr 2005 19:31

Re: DSPack Video Vorspulen
 
Es funktioniert!!! Danke!

Zimond 14. Jul 2007 16:51

Re: DSPack Video Vorspulen
 
Mahlzeit, ich versuche eine Software zu Stande zu bringen die einzelne Frames eines Videos abspeichert.

Ich habe es hinbekommen, die Frames einzeln zu seeken und mittels VMRGetBitmap auch als Bitmap abzuspeichern, ich habe allerdings noch ein kleines Problem bevor ich mit der Auswertung der Bilder anfangen kann, zu dem ich beim googlen leider nichts finden konnte.

Wird mit der hier beschriebenen Methode ein Frame geseekt wartet das Programm nicht ab das dieser Frame auch im VideoWindow angezeigt wird (weil, wie ich mich von einer Microsoft Developer Seite schlau gemacht hab, jenes Seeken in einem anderem Thread läuft als das Programm.) Die Methode VideoWindow.VMRGetBitmap(Stream) kopiert immer das was im VideoWindow zu sehen ist und die Folge : Von Testweise Hundert Frames die ich hab hintereinander speichern lassen sind in der Regel 10 Stück das selbe Bild da das Videowindow sich noch nicht geupdated hatte.

Ich konnte kein Event finden das genau dann reagiert wenn der neue Frame fertig angezeigt wird. Mir ist es zwar gelungen durch eine Warteschleife die eine etwaige Anzahl an Millisekunden wartet 100 fortlaufende Bilder zu speichern, aber die Methode ist natürlich mehr als unbefriedigend : Schnelle Rechner werden dabei ausgebremst und lahme werden immer noch Frames doppelt speichern.


Das muss doch irgendwie abfragbar sein wann der neue Frame fertig geseekt wurde.

Gruß, ben.

Zimond 14. Jul 2007 19:15

Re: DSPack Video Vorspulen
 
Ich hab doch noch eine Lösung hierzu gefunden :

Zitat:

I find a solution with the manual seeking while paused that works pretty well... if you pause the graph every time you make a seek to the next frame, it will generate a EC_PAUSED event. Then you can check this event to prevent seeking the next frame.

Something like this:
CODE
while ContinueSeeking do
begin
if SeekCanGoOn then
begin
GoToNextFrame;
SeekCanGoOn := False;
end;
FilterGraph.Pause;
Application.ProcessMessages;
end;

And on the "OnDSEvent" event:
CODE
if event = EC_PAUSED then SeekCanGoOn := True;

This way I can render every frame, with perfect accuracy, on every kind of video file (I'm seeking by time, calculating the frames with FPS), and with better performance then the IVideoFrameStep::Step method!
Funktioniert prächtig


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:01 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz