Seite 1 von 1

Problem mit der "AVIServ093.dll"

Verfasst: 14.11.2006 17:47
von coder
Ich wollte mal ein Programm schreiben was den Bildschirminhalt "abfotografiert" und in ein Video packt.

Code: Alles auswählen

; gPreferences[460-5-1-1-794-154-0-331-144]


Structure AVI_INFO
  aviWidth.l
  aviHeight.l
  aviFirstFrame.l
  aviNumFrames.l
  aviFPS.b
  hWnd.l
EndStructure

Structure Aufloesung
  Width.l
  Height.l
EndStructure

Global AVI.AVI_INFO
Global AnzAuf.l
Global AddFrameToAVI, OpenAVIforWrite, CloseAVIStreams
Global Pfad$
Global T
T = 0
ImagePfad$ = "Data\Kamera.ico"

AnzAuf = 4
Dim Auf.Aufloesung(AnzAuf)

  Auf(0)\Width = 640
  Auf(0)\Height = 480

  Auf(1)\Width = 800
  Auf(1)\Height = 600

  Auf(2)\Width = 1024
  Auf(2)\Height = 768

  Auf(3)\Width = 1152
  Auf(3)\Height = 864

  Auf(4)\Width = 1280
  Auf(4)\Height = 720

#Library_AVIServ093 = 0


Procedure MakeDesktopScreenshot(ImageNr,x,y,Width,Height)  
   hImage = CreateImage(ImageNr,Width,Height)  
   hDC    = StartDrawing(ImageOutput(ImageNr))  
   DeskDC = GetDC_(GetDesktopWindow_())  
      BitBlt_(hDC,0,0,Width,Height,DeskDC,x,y,#SRCCOPY)  
   StopDrawing()  
   ReleaseDC_(GetDesktopWindow_(),DeskDC)  
   ProcedureReturn hImage  
EndProcedure 

Procedure proc2(x)
  If Not IsWindow(1)
    Win = OpenWindow(1, -100, -100, 0, 0, "Null", #PB_Window_BorderLess)
  EndIf
  Win = WindowID(1)
  AVI\hWnd.l
  Debug Pfad$
  Debug AVI\aviFPS
  If CallFunctionFast(OpenAVIforWrite, Pfad$, @AVI) = #True
    Debug "AVI geöffnet"
    hBMP = MakeDesktopScreenshot(1, 0, 0, AVI\aviWidth, AVI\aviHeight)
    If hBMP
      Debug "Screenshot"
      If AVI\aviWidth + AVI\aviHeight <> ImageWidth(1) + ImageHeight(1)
        ResizeImage(1, AVI\aviWidth, AVI\aviHeight)
        Debug "Image Resized"
      EndIf
      CallFunctionFast(AddFrameToAVI, hBMP, -1)
      Debug "OK"
    EndIf
    CallFunctionFast(CloseAVIStreams)
  EndIf
EndProcedure

Procedure proc()
  Debug T
  If T
    CreateThread(@proc2(), 1)
  Else
    Proc2(0)
  EndIf
EndProcedure

If OpenLibrary(#Library_AVIServ093, "D:\FileDownloads\Software\AVIServ\AVIServ093.dll")
  AVI_Info = GetFunction(#Library_AVIServ093, "AVI_Info")
  AVI_Init = GetFunction(#Library_AVIServ093, "AVI_Init")
  AVI_Quit = GetFunction(#Library_AVIServ093, "AVI_Quit")
  AddFrameToAVI = GetFunction(#Library_AVIServ093, "AddFrameToAVI")
  CloseAVIStreams = GetFunction(#Library_AVIServ093, "CloseAVIStreams")
  GetFrameFromAVI = GetFunction(#Library_AVIServ093, "GetFrameFromAVI")
  OpenAVIforRead = GetFunction(#Library_AVIServ093, "OpenAVIforRead")
  OpenAVIforWrite = GetFunction(#Library_AVIServ093, "OpenAVIforWrite")

  If AVI_Info And AVI_Init And AVI_Quit And AddFrameToAVI And CloseAVIStreams And GetFrameFromAVI And OpenAVIforRead And OpenAVIforWrite
    ;alle Functionen OK
  Else
    MessageRequester("Fehler", "Eine oder mehrere Funktionen der AVIServ093.dll konnten nicht geladen werden.")
    End
  EndIf
Else
  MessageRequester("Fehler", "Die Bibliothek AVIServ093.dll konnte nicht geladen werden.")
  End
EndIf

If LoadImage(0, ImagePfad$) = 0
  MessageRequester("Fehler", "Eine Bilddatei konnte nicht geladen werden.")
  End
EndIf

OpenWindow(0, 0, 0, 200, 140, "Desktop2avi", #PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(0))
  TextGadget(0, 5, 5, 60, 20, "Auflösung:")
  ComboBoxGadget(1, 65, 5, 130, 200)
  For x = 0 To AnzAuf
    AddGadgetItem(1, x, Str(Auf(x)\Width)+"*"+Str(Auf(x)\Height))
  Next
  SetGadgetState(1, 0)
  
  TextGadget(2, 5, 35, 55, 25, "Frames pro Sek.:")
  StringGadget(3, 65, 35, 130, 25, "15", #PB_String_Numeric)
  
  TextGadget(4, 5, 70, 30, 20, "Pfad:")
  StringGadget(5, 65, 70, 98, 25, "C:\Bildschirmaufnahme.avi")
  ButtonGadget(6, 170, 70, 25, 25, "...")
  
  ButtonGadget(7, 5, 105, 90, 30, "Beenden")
  ButtonGadget(8, 105, 105, 90, 30, "Start")
EndIf

Quit = 0

If Not CallFunctionFast(AVI_Init)
  MessageRequester("Fehler", "Library konnte nicht initraliersiert werden.")
  End
EndIf

Repeat
  Event = WaitWindowEvent()
  If Event = #PB_Event_Gadget
    Select EventGadget()
      Case 6
        Pfad$ = SaveFileRequester("Speichern", GetGadgetText(5), "avi-Datein|*.avi", 0)
        If Pfad$
          If LCase(Right(Pfad$, 4)) <> ".avi"
            Pfad$ = Pfad$+".avi"
          EndIf
          SetGadgetText(5, Pfad$)
        EndIf
      Case 7
        Quit = 1
      Case 8
        Frames = Val(GetGadgetText(3))
        Width = Auf(GetGadgetState(1))\Width
        Height = Auf(GetGadgetState(1))\Height
        Pfad$ = GetGadgetText(5)
        
        
        If Frames And Width And Height And Pfad$ And Timer = 0
          XX = GetMinTimerResolution()
          MaxFrames = 60/XX
        
          If Frames > MaxFrames Or Frames < 1
            MessageRequester("Fehler", "Die Anzahl der Frames pro Sekunde müssen zwischen "+Str(MaxFrames)+" und 1 liegen.")
            Goto E
          EndIf
          
          AVI\aviWidth = Widht
          AVI\aviHeight = Height
          AVI\aviFPS = Frames
          
          HideWindow(0, 1)
          
          MessageRequester("Aufzeichnung beenden", "Klicken Sie auf die kleine Kamera neben ihrer Uhr um die Aufzeichnung zu beenden. Wenn Sie einen Signalton von ihrem Systemlautsprecher (Speaker) hören wurde die Aufzeichnung begonnen."+Chr(10)+Chr(10)+"Klicken Sie auf OK um die Aufzeichnung zu beginnen.")
          
          FPMS.f = Frames/60
          FPMS.f = FPMS.f*1000
          
          Timer = StartTimer(0, FPMS.f, @proc())
          If Timer
            Beep(800, 20)
          EndIf
          
          AddSysTrayIcon(0, WindowID(0), ImageID(0))
          SysTrayIconToolTip(0, "Aufzeichnung beenden")
        EndIf
        E:
        
    EndSelect
  ElseIf Event = #PB_Event_SysTray
    If EventGadget() = 0
      EndTimer(0)
      Timer = 0
      RemoveSysTrayIcon(0)
      MessageRequester("Aufnahme beendet", "Sie haben die Aufnahme beendet."+Chr(10)+Chr(10)+"Der Pfad zu der Datei: "+Pfad$)
      Pfad$ = ""
      Quit = 1
    EndIf
  ElseIf event = #PB_Event_CloseWindow
    Quit = 1
  EndIf
Until Quit = 1

CallFunctionFast(AVI_Quit)
End
Nun zeichnet das nur nichts auf /:->
Ist zum verrückt werden!

Verfasst: 15.11.2006 10:20
von nicolaus
Mal ne frage wo nimmst du denn die AVIServ093.dll her? Ist das ne Standart Windows DLL?

Verfasst: 15.11.2006 13:22
von scholly
nicolaus hat geschrieben:Mal ne frage wo nimmst du denn die AVIServ093.dll her?
Guck mal hier: http://www.purebasic.fr/english/viewtop ... ht=aviserv

Verfasst: 16.11.2006 00:29
von nicolaus
thx für den link.

und was dein prob angeht gehts auch einfacher schau dir folgenden code an:

Code: Alles auswählen

Procedure.l CaptureScreen()
  ExamineDesktops()
  width = DesktopWidth(0)
  height = DesktopHeight(0)
  srcDC = CreateDC_("DISPLAY", "", "", dm.DEVMODE)
  trgDC = CreateCompatibleDC_(srcDC)
  BMPHandle = CreateCompatibleBitmap_(srcDC, width, height)
  SelectObject_( trgDC, BMPHandle)
  BitBlt_( trgDC, 0, 0, width, height, srcDC, 0, 0, #SRCCOPY)
  DeleteDC_( trgDC)
  ReleaseDC_(BMPHandle, srcDC)
  CreateImage(0, width, height, 32)
  StartDrawing(ImageOutput(0))
  DrawImage(BMPHandle, 0, 0)
  StopDrawing()
  DeleteObject_(BMPHandle)
EndProcedure

OpenWindow(0,0,0,320,240,"",$CF0001)
SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_LAYERED)

Delay(100)
CaptureScreen()
ResizeImage(0,640,480)
OpenWindow(1,0,0,640,480,"",$CF0001)
CreateGadgetList(WindowID(1))
ImageGadget(0,0,0,0,0,ImageID(0))
Repeat:Until WaitWindowEvent()=#WM_CLOSE

Verfasst: 19.11.2006 17:38
von coder
Sorry das ich mich lange nicht gemeldet habe, da habe doch tatsächlich so par Bauerbeiter das Telefonkabel durchgehackt :roll: und dann bin ich übers Wochenede in den Urlaub gefahren (Opa hatte geburtstag).
Aber nun zurück!!

@nicolaus:

Bei mir ist deine Procedure viel langsamer als meine!
Probier mal das hier aus:

Code: Alles auswählen

Procedure.l CaptureScreen() 
  ExamineDesktops() 
  width = DesktopWidth(0) 
  height = DesktopHeight(0) 
  srcDC = CreateDC_("DISPLAY", "", "", dm.DEVMODE) 
  trgDC = CreateCompatibleDC_(srcDC) 
  BMPHandle = CreateCompatibleBitmap_(srcDC, width, height) 
  SelectObject_( trgDC, BMPHandle) 
  BitBlt_( trgDC, 0, 0, width, height, srcDC, 0, 0, #SRCCOPY) 
  DeleteDC_( trgDC) 
  ReleaseDC_(BMPHandle, srcDC) 
  CreateImage(0, width, height, 32) 
  StartDrawing(ImageOutput(0)) 
  DrawImage(BMPHandle, 0, 0) 
  StopDrawing() 
  DeleteObject_(BMPHandle) 
EndProcedure 

Procedure MakeDesktopScreenshot(ImageNr,x,y,Width,Height)  
   hImage = CreateImage(ImageNr,Width,Height)  
   hDC    = StartDrawing(ImageOutput(ImageNr))  
   DeskDC = GetDC_(GetDesktopWindow_())  
      BitBlt_(hDC,0,0,Width,Height,DeskDC,x,y,#SRCCOPY)  
   StopDrawing()  
   ReleaseDC_(GetDesktopWindow_(),DeskDC)  
   ProcedureReturn hImage  
EndProcedure 

start = ElapsedMilliseconds()
ExamineDesktops()
Makedesktopscreenshot(0, 0, 0, DesktopWidth(0), DesktopHeight(0))
ende = ElapsedMilliseconds()
MessageRequester("Time1", "Zeit in Millisekunden: "+Str(ende-start))

ResizeImage(0, 640, 480)

OpenWindow(0, 0, 0, 640, 480, "Capture", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ImageGadget(0, 0, 0, 640, 480, ImageID(0))

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

OpenWindow(0, 0, 0, 640, 480, "Capture", #PB_Window_ScreenCentered | #PB_Window_SystemMenu)
CreateGadgetList(WindowID(0))
ImageGadget(0, 0, 0, 640, 480, ImageID(0))

OpenWindow(0,0,0,320,240,"",$CF0001) 
SetWindowLong_(WindowID(0),#GWL_EXSTYLE,GetWindowLong_(WindowID(0),#GWL_EXSTYLE)|#WS_EX_LAYERED) 

Delay(100) 

start = ElapsedMilliseconds()
CaptureScreen() 
ende = ElapsedMilliseconds()
MessageRequester("Time2", "Zeit in Millisekunden: "+Str(ende-start))

ResizeImage(0,640,480) 
OpenWindow(1,0,0,640,480,"",$CF0001) 
CreateGadgetList(WindowID(1)) 
ImageGadget(0,0,0,0,0,ImageID(0)) 
Repeat:Until WaitWindowEvent()=#WM_CLOSE
@All

Ich habe es nun geschaft das er wenigstens das erste Bild aufzeichnet:

Code: Alles auswählen

; gPreferences[460-5-1-1-794-154-0-331-144]


Structure AVI_INFO
  aviWidth.l
  aviHeight.l
  aviFirstFrame.l
  aviNumFrames.l
  aviFPS.b
  hWnd.l
EndStructure

Structure Aufloesung
  Width.l
  Height.l
EndStructure

Global AVI.AVI_INFO
Global AnzAuf.l
Global AVI_Info, AVI_Init, AVI_Quit, AddFrameToAVI, CloseAVIStreams, GetFrameFromAVI, OpenAVIforRead, OpenAVIforWrite
Global Pfad$
Global T
T = 0
ImagePfad$ = "Data\Kamera.ico"

UseJPEGImageDecoder()

AnzAuf = 4
Dim Auf.Aufloesung(AnzAuf)

  Auf(0)\Width = 640
  Auf(0)\Height = 480

  Auf(1)\Width = 800
  Auf(1)\Height = 600

  Auf(2)\Width = 1024
  Auf(2)\Height = 768

  Auf(3)\Width = 1152
  Auf(3)\Height = 864

  Auf(4)\Width = 1280
  Auf(4)\Height = 720

#Library_AVIServ093 = 0


Procedure MakeDesktopScreenshot(ImageNr,x,y,Width,Height)  
   hImage = CreateImage(ImageNr,Width,Height)  
   hDC    = StartDrawing(ImageOutput(ImageNr))  
   DeskDC = GetDC_(GetDesktopWindow_())  
      BitBlt_(hDC,0,0,Width,Height,DeskDC,x,y,#SRCCOPY)  
   StopDrawing()  
   ReleaseDC_(GetDesktopWindow_(),DeskDC)  
   ProcedureReturn hImage  
EndProcedure 

Procedure proc2(x)

  ;If IsWindow(1) <> 0
    ;OpenWindow(1, -100, -100, 0, 0, "Null", #PB_Window_BorderLess)
  ;EndIf
  If Not Init
    Init = CallFunctionFast(AVI_Init)
    ;d = 100
  ;Else
    ;d = 0
  EndIf
  If Init
    Win = WindowID(0)
    AVI\hWnd.l = Win
    Debug Pfad$
    Debug AVI\aviFPS
    Debug OpenAVIforWrite
    If CallFunctionFast(OpenAVIforWrite, Pfad$, @AVI)
      If d : Delay(d) : d = 0 : EndIf
      Debug "AVI geöffnet"
      hBMP = MakeDesktopScreenshot(1, 0, 0, AVI\aviWidth, AVI\aviHeight)
      If hBMP
        Debug "Screenshot"
        If AVI\aviWidth + AVI\aviHeight <> ImageWidth(1) + ImageHeight(1)
          ResizeImage(1, AVI\aviWidth, AVI\aviHeight)
          Debug "Image Resized"
        EndIf
        If CallFunctionFast(AddFrameToAVI, hBMP, -1) = #True
          Debug "OK"
        EndIf
      EndIf
      ;CallFunctionFast(CloseAVIStreams)
    EndIf
    ;CallFunctionFast(AVI_Quit)
    ;End
  EndIf
EndProcedure

Procedure proc()
  Debug T
  If T
    CreateThread(@proc2(), 1)
  Else
    Proc2(0)
  EndIf
EndProcedure

If OpenLibrary(#Library_AVIServ093, "AVIServ093.dll")
  AVI_Info = GetFunction(#Library_AVIServ093, "AVI_Info")
  AVI_Init = GetFunction(#Library_AVIServ093, "AVI_Init")
  AVI_Quit = GetFunction(#Library_AVIServ093, "AVI_Quit")
  AddFrameToAVI = GetFunction(#Library_AVIServ093, "AddFrameToAVI")
  CloseAVIStreams = GetFunction(#Library_AVIServ093, "CloseAVIStreams")
  GetFrameFromAVI = GetFunction(#Library_AVIServ093, "GetFrameFromAVI")
  OpenAVIforRead = GetFunction(#Library_AVIServ093, "OpenAVIforRead")
  OpenAVIforWrite = GetFunction(#Library_AVIServ093, "OpenAVIforWrite")

  If AVI_Info And AVI_Init And AVI_Quit And AddFrameToAVI And CloseAVIStreams And GetFrameFromAVI And OpenAVIforRead And OpenAVIforWrite
    ;alle Functionen OK
  Else
    MessageRequester("Fehler", "Eine oder mehrere Funktionen der AVIServ093.dll konnten nicht geladen werden.")
    End
  EndIf
Else
  MessageRequester("Fehler", "Die Bibliothek AVIServ093.dll konnte nicht geladen werden.")
  End
EndIf

If LoadImage(0, ImagePfad$) = 0
  MessageRequester("Fehler", "Eine Bilddatei konnte nicht geladen werden.")
  End
EndIf

OpenWindow(0, 0, 0, 200, 140, "Desktop2avi", #PB_Window_ScreenCentered)
If CreateGadgetList(WindowID(0))
  TextGadget(0, 5, 5, 60, 20, "Auflösung:")
  ComboBoxGadget(1, 65, 5, 130, 200)
  For x = 0 To AnzAuf
    AddGadgetItem(1, x, Str(Auf(x)\Width)+"*"+Str(Auf(x)\Height))
  Next
  SetGadgetState(1, 0)
  
  TextGadget(2, 5, 35, 55, 25, "Frames pro Sek.:")
  StringGadget(3, 65, 35, 130, 25, "15", #PB_String_Numeric)
  
  TextGadget(4, 5, 70, 30, 20, "Pfad:")
  StringGadget(5, 65, 70, 98, 25, "C:\Bild.avi")
  ButtonGadget(6, 170, 70, 25, 25, "...")
  
  ButtonGadget(7, 5, 105, 90, 30, "Beenden")
  ButtonGadget(8, 105, 105, 90, 30, "Start")
EndIf

Quit = 0

;If Not CallFunctionFast(AVI_Init)
;  MessageRequester("Fehler", "Library konnte nicht initraliersiert werden.")
;  End
;EndIf

Repeat
  Event = WindowEvent()
  If Event = #PB_Event_Gadget
    Select EventGadget()
      Case 6
        Pfad$ = SaveFileRequester("Speichern", GetGadgetText(5), "avi-Datein|*.avi", 0)
        If Pfad$
          If LCase(Right(Pfad$, 4)) <> ".avi"
            Pfad$ = Pfad$+".avi"
          EndIf
          SetGadgetText(5, Pfad$)
        EndIf
      Case 7
        Quit = 1
      Case 8
        Frames = Val(GetGadgetText(3))
        Width = Auf(GetGadgetState(1))\Width
        Height = Auf(GetGadgetState(1))\Height
        Pfad$ = GetGadgetText(5)
        
        
        If Frames And Width And Height And Pfad$ And Timer = 0
          ;XX = GetMinTimerResolution()
          ;MaxFrames = 60/XX
        
          ;If Frames > MaxFrames Or Frames < 1
            ;MessageRequester("Fehler", "Die Anzahl der Frames pro Sekunde müssen zwischen "+Str(MaxFrames)+" und 1 liegen.")
            ;Goto E
          ;EndIf
          
          AVI\aviWidth = Width
          AVI\aviHeight = Height
          AVI\aviFPS = Frames
          
          HideWindow(0, 1)
          
          MessageRequester("Aufzeichnung beenden", "Klicken Sie auf die kleine Kamera neben ihrer Uhr um die Aufzeichnung zu beenden. Wenn Sie einen Signalton von ihrem Systemlautsprecher (Speaker) hören wurde die Aufzeichnung begonnen."+Chr(10)+Chr(10)+"Klicken Sie auf OK um die Aufzeichnung zu beginnen.")
          
          FPMS.f = Frames/60
          FPMS.f = FPMS.f*1000
          
          ;Timer = StartTimer(0, FPMS.f, @proc())
          Timer = 1
          ;If Timer
            Beep_(800, 20)
          ;EndIf
          
          AddSysTrayIcon(0, WindowID(0), ImageID(0))
          SysTrayIconToolTip(0, "Aufzeichnung beenden")
        EndIf
        E:
        
    EndSelect
  ElseIf Event = #PB_Event_SysTray
    If EventGadget() = 0
      ;EndTimer(0)
      Timer = 0
      RemoveSysTrayIcon(0)
      MessageRequester("Aufnahme beendet", "Sie haben die Aufnahme beendet."+Chr(10)+Chr(10)+"Der Pfad zu der Datei: "+Pfad$)
      Pfad$ = ""
      Quit = 1
    EndIf
  ElseIf event = #PB_Event_CloseWindow
    Quit = 1
  EndIf
  If Timer
    proc()
    Debug "ende"
  EndIf
  Delay(10)
Until Quit = 1


CallFunctionFast(CloseAVIStreams)
CallFunctionFast(AVI_Quit)
End

Verfasst: 20.11.2006 10:42
von dige
Leider ist Dein Code sehr unübersichtlich und aus meiner Sicht
nicht nachvollziehbar was Du da genau machst.

Versuche doch erstmal nur ein Bild zu erstellen, schreibe da zum
Bsp. Datum / Uhrzeit rein und füge diese als Frame in den AVI
Stream. Wenn das funktioniert kannste den ganzen anderen Krams
drum rum basteln.

Prinzipiell ist der Ablauf so:
1. OpenAVIforWrite
2. AddFrameToAVI
. AddFrameToAVI
. AddFrameToAVI
3. CloseAVIStreams

Das Close ist sehr wichtig, da erst zum Schluss der AVI Header ge-
schrieben wird!

Verfasst: 22.11.2006 17:35
von coder
Danke jetz geht es endlich. Hatte wirklich nur die falsche Reigenfolge drin.

Nochmals danke an Alle!!