hi,
Günter Beyes hat geschrieben:
Oder laufen gleichzeitig vier Mediaplayer, die aus einem bestimmten Grund miteinander synchronisiert werden müssen?
ok ich muss wohl weiter ausholen:
TLB2CH.EXE WMPLAYER.OCX.7 >> WMP.CH
damit erhält man die Events des Mediaplayer v9/v10 in der Datei WMP.CH
sieht man sicht die jetzt an so fallen "Gruppen" auf. Für jeden einzelne
"Gruppe" läuft ein Thread der die Events überwacht. Wird jetzt innerhalb
einer Gruppe (WMPOpenState) ein passender Event (wmposMediaOpen)
ausgelöst so muss ich innerhalb einer anderen Gruppe (WMPPlayState)
auf den dazu gehörigen Event (wmppsPlaying) warten bevor ich die
Methoden ansprechen darf ... sonst knallt es.
der alte "procedurale" Code sah so aus:
Code: Alles auswählen
::oWMP:Settings:AutoStart := .T. // start to play after load
//
// now we load media via :URL
// depending what Codec is need
// it will invoke WMP Event :
// wmppsTransitioning
//
::oWMP:URL := cFile // play via :URL
//
// "resize" parent to same size
//
::oWMP:setparent():setPosAndSize( aPosi ,{aSize[1],aSize[2]} )
//
// reset fail counter
::failcount := 0
SP_Duration(0)
DO WHILE .T.
// is Media open ?
IF ::oWMP:openState = wmposMediaOpen
//
// wmppsTransitioning here can fail e.g missing codec
//
// is playing ?
IF ::oWMP:PlayState = wmppsPlaying
::nIMGhigh := ::oWMP:currentMedia:imageSourceHeight
::nIMGwide := ::oWMP:currentMedia:imageSourceWidth
SP_Duration(::oWMP:currentMedia:Duration)
// ok now we can exit loop
EXIT
ENDIF
ENDIF
SLEEP(10)
::failcount++
IF ::failcount > 10*5
// 1st stop it
::oWMP:Controls:stop()
RETURN .F.
ENDIF
ENDDO
man sieht das SLEEP und das try & Error ... aber in 99% geht es damit
nun läuft es also in einzelnen "Gruppen" jeweils als Thread
Code: Alles auswählen
PROCEDURE EVTHREAD(oParent,aoChild, ...)
LOCAL cPosi
LOCAL nZahl := 1
LOCAL nNum := 0
STATIC lIsplayin := .F.
STATIC nLstPlState := 0
IF SP_IsRUN() // pause Tread before :destroy
SP_Threadwrk(.T.) // signal i´m running
IF( aoChild[CH_WMP]:openState = wmposUndefined , EVSCT(aEVTh,01,"T"), EVSCT(aEVTh,01," "))
...
IF( aoChild[CH_WMP]:openState = wmposMediaOpen , EVSCT(aEVTh,14,"T"), EVSCT(aEVTh,14," "))
...
/*
hier kommen dann noch die "Prüfungen" des activeX und deren Status
wmposBeginCodecAcquisition
wmposEndCodecAcquisition
wmposBeginLicenseAcquisition
wmposEndLicenseAcquisition
wmposBeginIndividualization
wmposEndIndividualization
wmposMediaWaiting
*/
...
IF( aoChild[CH_WMP]:openState = wmposOpeningUnknownURL , EVSCT(aEVTh,22,"T"), EVSCT(aEVTh,22," "))
...
SP_Threadwrk(.F.) // signal i´m finsh, now :playstate can
ENDIF // lIsRUN
RETURN
Ein DO CASE geht übrigens nicht weil mehrer Zustände gleichzeitig "T"
werden können.
Das selbe dann für :Playstate
Code: Alles auswählen
IF .NOT. SP_Threadwrk() // if Thread1 is still working do NOT
...
IF aoChild[CH_WMP]:PlayState = wmppsPlaying
EVSCT(aEVTh,26,"T") // setzte
IF EVIST(aEVTh,14,"T") // Abfrage Media ist noch ge”ffnet ?
IF cInfofile == SP_Playlast()
ELSE
MSGBOX("drin") // bei 99%
...
/*
hier kann er bei Problemen im Sinne "hängen" bleiben, aber er
läuft ja einfach weiter vom activeX aus gesehen ...
*/
IF aoChild[CH_WMP]:PlayState = wmppsTransitioning // this event is after open Media
EVSCT(aEVTh,32,"T") // but before wmppsPlaying
aoChild[CH_STATBAR]:oMSG:setCaption( "Transitioning ..." )
ELSE
EVSCT(aEVTh,32," ")
ENDIF
...
ENDIF
...
soweit sogut bei 99% ... aber bei 1% geht nun was schief beim :PlayState
Thread. Nun ist mein (timeing) Problem, das ja immer erst den Code
durchlaufen bevor :SetInterval(nTime) den Thread neu startet und das
Array dann den letzten Stand behält bis zum nächsten durchlauf.
Beide Thread greifen auf das selbe Array aEVTH zu und erhalten ihren
Status vom activeX Thread der die Events feuert. Der 4st Thread ist
die "play" Funktionen (start/stop/pause/step sowie Fastforward)
sowie die "open" Funktionen (nächste Stück/vorheriges).
Thread 4 wird also vom User kontrolliert und löst damit Reaktionen im
activeX Thread 3 aus in Form von Events. Diese werden nun von dem
beiden ersten Threads "abgehört" und das Array von beiden mit "T"/" "
gefüllt.
erst wenn ich ein bestimmtes Muster im Array habe darf die Reaktion
erfolgen.
bei 99% ist Thread1 wohl rechtzeitig fertig um für Thread2 die richtige
Grundlage zu sein. Bei 1% startet sozusagen Thread2 früher sodas er
einen weiter Durchlauf machen muss um das aktuelle Ergebnis von
Thread1 zu erhalten statt dem "letzten" was sich evtl. geändert hat
Im Prinzip müsste ich Thread2 aus Thread1 starten, aber das bekomme
ich nun auch nicht in Griff den es können ja mehrer Event auf "T" stehen
bei den ich dann jeweils (?) einen neuen(?) Thread starten müsste ...
gerne hätte ich ja auch die Idee mit den UserDef Event weiterverfolgt,
aber ein Eventhandler in den Threads reagiert "sehr träge" (wegen der
vielen IF Abfragen ? ).
bei der SYNC Methode hatte ich nun gehofft das sich die Threads schön
in einer Warteschlange "anstellen" und abgearbeitet werden, aber das
scheint ja wohl nicht so (auf meinen Intel PC´s)
ich hoffe nicht zu weit ausgeholt zu haben und die Forum User mit meinem
Problem zu nerven, aber ich hätte gerne auch die 1% gelöst auch wenn es
das original in einer solchen Situation auch nicht viel besser löst und dann
"nach Hause telefonieren" will.
gruss by OHR
Jimmy