Frage zur Movie()-Library (2 mp4-Files im Wechsel abspielen)

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
diceman
Beiträge: 340
Registriert: 06.07.2017 12:24
Kontaktdaten:

Frage zur Movie()-Library (2 mp4-Files im Wechsel abspielen)

Beitrag von diceman »

Hallo ihr Lieben,
Ich spiele gerade mit der Movie-Library von PureBasic herum; das funktioniert soweit ganz gut und intuitiv, allerdings ist mir aufgefallen, daß wenn man zwei Filme im Wechsel abspielen wird, dieses nur solange gut geht, wenn man jeden nur einmal abspielt. Wenn man aber anschließend nochmal den ersten Film abruft, ist Ton zu hören, aber kein Bild. Das kann ich zwar umgehen, wenn ich für jeden Film ein eigenes Fenster erstelle, und jeweils den Fokus gebe, wenn dort ein Film abgespielt wird, möchte aber trotzdem gerne wissen, ob ich irgendwas initialisieren/aufrufen/whatever muß, damit das auch mit nur einem Fenster funktioniert ...
Danke! :)

Code: Alles auswählen

EnableExplicit

Declare play(movieID)

InitSprite()
InitMovie()
InitKeyboard()

Global xRes, yRes
Global screen


;Zwei Clips in den Speicher laden
Global movie1 = LoadMovie(#PB_Any,"movie1.mp4")
Global movie2 = LoadMovie(#PB_Any,"movie2.mp4")


play(movie1)		;Ersten Film abspielen
CloseWindow(screen)	;Fenster schließen
play(movie2)		;Zweiten Film abspielen
CloseWindow(screen)
play(movie1)		;Den ersten Film wiederholen (Bild bleibt schwarz)
CloseWindow(screen)
End



Procedure play(movieID)
	xRes = MovieWidth(movieID)
	yRes = MovieHeight(movieID)
	;Fenster gemäß Filmgröße initialisieren
	screen = OpenWindow(#PB_Any,0,0,xRes,yRes,"Base",#PB_Window_ScreenCentered)
	OpenWindowedScreen(WindowID(screen),0,0,xRes,yRes)
	
	;Film abspielen ...
	PlayMovie(movieID,WindowID(screen))
	Repeat
		If WaitWindowEvent(16) = #PB_Event_CloseWindow
			End
		EndIf
		ExamineKeyboard()
	Until KeyboardPushed(#PB_Key_Return) ;... bis RETURN-Taste gedrückt wird
	StopMovie(movieID)
EndProcedure
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
RSBasic
Admin
Beiträge: 7891
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Frage zur Movie()-Library (2 mp4-Files im Wechsel abspie

Beitrag von RSBasic »

Anscheinend kannst du ein Video nur einmal auf einem bestimmten Fenster abspielen. Oder bin ich blind? :?

Mit folgendem Code mit OpenWindow mit statischer ID habe ich genau das gleiche Problem:

Code: Alles auswählen

EnableExplicit

InitMovie()

Global movie1 = LoadMovie(#PB_Any,"C:\Ray\1.avi")
Global movie2 = LoadMovie(#PB_Any,"C:\Ray\2.avi")
Global CurrentMovie

Procedure play(movieID)
  Protected xRes
  Protected yRes
  
  xRes = MovieWidth(movieID)
  yRes = MovieHeight(movieID)
  
  If OpenWindow(1, 0, 0, xRes, yRes, "Movie", #PB_Window_SystemMenu, WindowID(0))
    AddKeyboardShortcut(1, #PB_Shortcut_Return, 1)
    
    PlayMovie(movieID, WindowID(1))
  EndIf
  
EndProcedure

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CurrentMovie = movie1
  play(CurrentMovie)
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            If CurrentMovie = movie2
              CurrentMovie = movie1
            Else
              CurrentMovie = movie2
            EndIf
            play(CurrentMovie)
        EndSelect
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf
Mit folgendem Code mit OpenWindow mit #PB_Any würde es zwar gehen, aber man sieht, dass das Video immer von dem anderen Fenster geklaut wird:

Code: Alles auswählen

EnableExplicit

InitMovie()

Global movie1 = LoadMovie(#PB_Any,"C:\Ray\1.avi")
Global movie2 = LoadMovie(#PB_Any,"C:\Ray\2.avi")
Global CurrentMovie
Global LastWindow


Procedure play(movieID)
  Protected xRes
  Protected yRes
  Protected SecWindow
  
  xRes = MovieWidth(movieID)
  yRes = MovieHeight(movieID)
  
  SecWindow = OpenWindow(#PB_Any, Random(500), Random(500), xRes, yRes, "Movie", #PB_Window_SystemMenu, WindowID(0))
  If SecWindow
    AddKeyboardShortcut(SecWindow, #PB_Shortcut_Return, 1)
    PlayMovie(movieID, WindowID(SecWindow))
  EndIf
  LastWindow = SecWindow
EndProcedure

If OpenWindow(0, 0, 0, 500, 400, "Window", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  CurrentMovie = movie1
  play(CurrentMovie)
  
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_Menu
        Select EventMenu()
          Case 1
            ;CloseWindow(LastWindow)
            If CurrentMovie = movie2
              CurrentMovie = movie1
            Else
              CurrentMovie = movie2
            EndIf
            play(CurrentMovie)
        EndSelect
      Case #PB_Event_CloseWindow
        End
    EndSelect
  ForEver
EndIf
Bild
Benutzeravatar
diceman
Beiträge: 340
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Frage zur Movie()-Library (2 mp4-Files im Wechsel abspie

Beitrag von diceman »

Habe selber etwas weiter rumexperimentiert, und gelernt, daß wenn man, nachdem ein Video einmal abgespielt wurde, dieses mit LoadMovie() neu lädt, es dann funktioniert.
Also dann kannst ein Video beliebig oft im selben Fenster abspielen.
Ist auch grad nicht sehr wichtig für mich, fands nur merkwürdig und habe mich gewundert, ob ich was falsch mache ...
Zuletzt geändert von diceman am 28.05.2019 17:10, insgesamt 1-mal geändert.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
RSBasic
Admin
Beiträge: 7891
Registriert: 05.10.2006 18:55
Wohnort: Gernsbach
Kontaktdaten:

Re: Frage zur Movie()-Library (2 mp4-Files im Wechsel abspie

Beitrag von RSBasic »

Ja, an das Neuladen habe ich auch schon gedacht, aber ist ein Workaround. Normalerweise sollte das auch ohne Neuladen funktionieren.
Bild
Benutzeravatar
tft
Beiträge: 561
Registriert: 08.09.2004 20:18
Computerausstattung: GTX Titan , i9 9900K , 32 GB Ram , 500 GB SSD , 3 ASUS FullHD Monitore and more
Wohnort: Dachsen
Kontaktdaten:

Re: Frage zur Movie()-Library (2 mp4-Files im Wechsel abspie

Beitrag von tft »

Hallo,

ich habe vor Jahren einen Player , speziell für Anime Serien gebastelt. Leider ist die Lib nicht gerade aktuell. Es ist zwar möglich, mit KLite etliche Formate hinzuzustellen. Aber außer reines Abspielen habe ich nur mit PB Mitteln nicht hinbekommen. Das Seeking funktioniert nicht immer und die Fenster Auflösung im Verhältnis zur Video Auflösung ist Gücks-Sache. Der Player kann Sprungmarken setzen um die In/Outros zu überspringen. Wenn jemand in diesem Zusammenhang eine bessere Lib kennt. Ich würde den Player gerne Aktualisieren.

Gruss TFT
TFT

W10 , i9 9900K ,32 GB Ram , GTX Titan , 3 Monitore FHD
ARDUINO Freak :-)
Benutzeravatar
diceman
Beiträge: 340
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Frage zur Movie()-Library (2 mp4-Files im Wechsel abspie

Beitrag von diceman »

Mir ist aufgefallen, daß MovieLength() und MovieStatus() - zumindest bei .mp4-Files - inkompatible Daten liefert. MovieLength() gibt mir beispielsweise einen 4-5stelligen Wert, wenn ich dann aber mit Debug in einer Schleife den MovieStatus() kontinuierlich abfrage, welcher ja den aktuellen Frame-Index liefern sollte, bekomme ich bereits in den ersten Sekunden inflationäre Zahlen im hundertaustender- bzw. Millionen-Bereich (schreibe aus dem Kopf, bin grad nicht im "Testgelände unterwegs" :wink: ) angezeigt. Die Werte von MovieStatus() sind zumindest soweit kompatibel, daß man damit MovieSeek() füttern kann. Ansonsten scheint die Movie-Library derzeit etwas verbuggt zu sein - zumindest "vong mp4 her".

Ich habe zum Spaß (und weil ich eine Challenge brauchte) eine Scan-Funktion geschrieben, welche bei mp4-Files die für MovieSeek()-kompatiblen Werte ermittelt. Hab's dann aber nicht tiefergehend getestet, da derzeit die Movie-Library für meine Zwecke irrelevant ist. /:->
Zuletzt geändert von diceman am 04.06.2019 23:59, insgesamt 1-mal geändert.
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Benutzeravatar
dige
Beiträge: 1090
Registriert: 08.09.2004 08:53

Re: Frage zur Movie()-Library (2 mp4-Files im Wechsel abspie

Beitrag von dige »

@diceman: ich würde das gern mal testen :D
"Papa, mein Wecker funktioniert nicht! Der weckert immer zu früh."
Benutzeravatar
diceman
Beiträge: 340
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Frage zur Movie()-Library (2 mp4-Files im Wechsel abspie

Beitrag von diceman »

Du meinst meine Scan-Funktion?
Kann die heute abend mal hier reinstellen und ein paar Worte zum Prinzip schreiben; ist eher ein "brute force"-Verfahren, der Code läuft aber angemessen flott, ordentlich und verlässlich. :)
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Benutzeravatar
diceman
Beiträge: 340
Registriert: 06.07.2017 12:24
Kontaktdaten:

Re: Frage zur Movie()-Library (2 mp4-Files im Wechsel abspie

Beitrag von diceman »

Hier ist der kommentierte Code; du mußt lediglich ein .mp4-File zur Verfügung stellen ...
Im Grunde mache ich nichts anderes, als einen maximal effizienten "Zahlenraten"-Algorithmus über die MovieLibrary laufen zu lassen. :)
Alledings mit dem Handycap, daß wir die exakte range nicht kennen, in der sich die gesuchte Zahl findet. Die müssen wir erst eingrenzen.

Code: Alles auswählen

EnableExplicit

Declare seekEnd()
Declare playFromMiddle()

Global screen
Global movieID
Global realLength        ;Wir suchen die "reelle" Zahl, welche tatsächlich mit MovieSeek() verwertbar ist
                         ;MovieLength() gibt eine viel zu kleine Zahl wieder, bzw. ist der Rest der Movie-Library
                         ;verbuggt und arbeitet mit viel zu großen Zahlen (zumindest bei .mp4-Files).

InitSprite()
InitMovie()
InitKeyboard()
movieID = LoadMovie(#PB_Any,"myMovie.mp4")
screen = OpenWindow(#PB_Any,0,0,MovieWidth(movieID),MovieHeight(movieID),"clipScan.exe",#PB_Window_ScreenCentered | #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(screen),0,0,MovieWidth(movieID),MovieHeight(movieID))



realLength = seekEnd()	;Wir suchen den Index des letzten Frames

;Diskrepanz offenlegen:
Debug "MovieLength(): "+MovieLength(movieID)
Debug "Actual length: "+realLength

playFromMiddle()
End





Procedure seekEnd()
	Define seek = 1				;Der Index des ersten Frames, bei dem wir anfangen zu suchen
	Define factor = 2			 ;Initialer Faktor (zum exponentiell ins "Blaue" schießen, bis MovieStatus() = #False)
	Define lastSeek				;zuletzt gefundenen Frame-Index merken
	Define lowest				  ;höchster aktuell gefundener Frame-Index, welcher sich noch "im Film" befindet" = lowest(!)
	Define highest				 ;niedrigster aktuell gefundener Frame-Index, welcher sich "nach dem Film" befindet = highest(!)
	Define event
	
	;Brute-Force-Search nach ungefährer Länge des Videos:
	Repeat
		PlayMovie(movieID,WindowID(screen))	  ;Film abspielen ...
		MovieSeek(movieID,seek)			  	   ;... zum aktuellen Frame-Index skippen
		
		If MovieStatus(movieID) > 0		 	   ;Wenn wir uns noch "im Film" befinden ...
			lowest = seek					         ;... 'lowest' auf den aktuellen Frame-Index setzen
			seek*factor						        ;aktuelle Suchposition mit dem aktuellen Faktor multiplizieren
			factor +1						          ;den Faktor um 1 vergrößern
		EndIf
		event = WaitWindowEvent(16)
	Until MovieStatus(movieID) = 0			   ;Solange wiederholen, bis man über das Ziel hinausgeschossen ist
	highest = seek							       ;'highest' auf den aktuellen Frame-Index setzen
	
	;Suche verfeinern um den exakten letzten Frame zu finden:
	Repeat
		lastSeek = seek							      ;den zuletzt gefundenen Frame-Index zwischenspeichern
		seek = (lowest+highest)/2				     ;Mittelwert vom letzten Abschnitt bilden, und ...
		PlayMovie(movieID,WindowID(screen))
		MovieSeek(movieID,seek)					    ;... zur entsprechenden Stelle "spulen", und ...
		ResumeMovie(movieID)
		If MovieStatus(movieID) = 0				   ;... checken, ob sich der Frame-Index immer noch "nach dem Film" befindet ...
			highest = seek						       ;... in diesem Fall, 'highest' aktualisieren (herabsetzen)
		Else									           ;Wenn man sich aber wieder "im Film" befindet, stattdessen ...
			lowest = seek						        ;... 'lowest' heraufsetzen
		EndIf
		event = WaitWindowEvent(16)
	Until seek = lastSeek						;Solange wiederholen, bis seek und lastSeek denselben Wert zurückgeben.
												      ;Dies ist zugleich der letzte Frame im Film
	
	StopMovie(movieID)
	ProcedureReturn seek						;die reelle Länge an den Requester zurückgeben
EndProcedure





Procedure playFromMiddle()					   ;Als Testlauf spielen wir unser Video ab der Hälfte:
	Define event
	
	PlayMovie(movieID,WindowID(screen))		;Film abspielen, und direkt ...
	MovieSeek(movieID,realLength/2)			 ;... zur Mitte des Videos "skippen"
	
	Repeat
		event = WaitWindowEvent(16)
		ExamineKeyboard()
	Until event = #PB_Event_CloseWindow Or KeyboardPushed(#PB_Key_Escape)
EndProcedure
Now these points of data make a beautiful line,
And we're out of Beta, we're releasing on time.
Antworten