Play videos and audio (windows only)

BlitzMax Forums/BlitzMax Tutorials/Play videos and audio (windows only)

Mirko(Posted 2005) [#1]
Just a small code to show how to play video and audio files on a windows system using BlitzMax and mci.

Its my first try, so code is far from perfect, but it works (at least for me)

ITS WINDOWS ONLY, but perhaps someone might find this usefull for something.

' MCI Video and Audio Player via winmm.dll / Windows ONLY
' Infos on mci commands:
' http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_mcisendstring.asp
' Coded by Mirko 'NAPALM' Tocchella. This code is public domain.
'
 
Strict

Import Pub.Win32

Extern "os"
	Function FreeLibrary ( hnd:Int )
	Function GetActiveWindow ()
End Extern

'test
  Graphics 200,200,0
  Local mci:Tmci = New Tmci
  mci.Create()							' init mci
  mci.OpenMediaFile ("test.mpg")
	mci.BreakOn()						' Will make play work until Lmouse pressed
  mci.Play(True, True)		' Wait for break and play fullscreen
	mci.Close()							' Close file
  mci.Free()								' Free dll
  End

Type Tmci

		Field		LibHandle:Int	
		Field		SendHandle:Int
		
		Method GetLibFunction:Int ( symbol:String, fnc:Byte Ptr)
			(Int Ptr(fnc))[0]= SendHandle 	
		End Method 
	
		Method SendString (command:String)
  		Local lCommand (Command$z, xReturn:Int, xReturnLength:Int, xCallBack:Int) "win32"
			GetLibFunction ("mciSendStringA", Varptr lCommand)
			Local res:Int = lCommand (command, Null, Null, Null)
			Return (res)
		End Method

		Method Create ()
			' Get the library handle
			LibHandle = LoadLibraryA("winmm.dll")
			If Not LibHandle Then Throw "Can't load winmm.dll"
			
			' Get the Adress of the SendString function
			SendHandle = Int ( GetProcAddress( LibHandle, "mciSendStringA" ) )
			If Not SendHandle Then Throw "Can't get adress of mciSendStringA"			
		End Method
		
		Method Free ()
			If LibHandle
				If FreeLibrary ( LibHandle )
					LibHandle = 0
				EndIf
			EndIf
		End Method
		
		
		Method OpenMediaFile (FileName:String)
		  Local whnd:Int = GetActiveWindow()
			Local sCommand:String = "open ~q"+FileName+"~q alias MediaFile parent "+whnd
			Local res:Int = SendString (sCommand);
			Return (res)
		End Method
		
		

		Method Play (fullscreen:Int=True, dowait:Int=False)
			Local sCommand:String = "play MediaFile"
			If (fullscreen) sCommand = sCommand + " fullscreen"
			If (dowait) 			sCommand = sCommand + " wait"
			Local res:Int = SendString (sCommand);
			Return (res)
		End Method		
			
		Method Close ()
			Local sCommand:String = "close MediaFile wait"
			Local res:Int = SendString (sCommand);
			Return (res)
		End Method		
			
		Method Configure ()
			Local sCommand:String = "configure MediaFile wait"
			Local res:Int = SendString (sCommand);
			Return (res)
		End Method		
			
		Method BreakOn (vkey:Int=1)
			Local sCommand:String = "break MediaFile on "+vkey
			Local res:Int = SendString (sCommand);
			Return (res)
		End Method		
			
			

End Type			



xlsior(Posted 2005) [#2]
Very nice!


Perturbatio(Posted 2005) [#3]
nice indeed. :)


Filax(Posted 2005) [#4]
Many thanks !


kenshin(Posted 2005) [#5]
Thanks heaps!'

Is there a way to scale the size of the movie so it fills the entire screen. I find that if I use the movie's resolution then it will fill the screen, but when I use a higher resolution the movie is not scaled to fit the new resolution. Is there a way around this?

Any help would be much appreciated.


kenshin(Posted 2005) [#6]
Worked it out.

You can use the following mci command string to enable stretching of the video.

window MediaFile stretch

Then you use this command string:

put MediaFile destination at x y width height

where x,y,width,height are the dimensions you want to stretch the video to.

Seems as though you can only stretch to multiples of the original dimensions though. For example you can stretch an 800*600 video to 1600*1200. Not sure why this limitation exists as nothing is mentioned about it in the API.

I might look at getting enough of DirectShow going in order to do the stretching properly if I can't get mci past this limitation


Mirko(Posted 2005) [#7]
Now that directx is included in bm i hope someone will write a driect show video and audio playing component ;-)


kenshin(Posted 2005) [#8]
Hmm. That would be nice.

There's no problem stretching when the movie is in window mode, but as soon as you want full screen, no mouse pointer and no resolution switching (ala cut-scene) it becomes a pain in the butt.

I managed to get around the problem by writing a DLL using PureBasic as that has AVI commands built in which don't have any limits on the stretching dimensions. It's not perfect as there is a very brief flash of grey between my in-game screen and the AVI but at the moment it will have to do. I was hoping to go to and from cut-scenes with no flicker, but that seems next to impossible. I've spent the last 2-3 day's trying different methods of overlaying AVI on my game screen and the DLL seems to be the best I can come up with.


DannyD(Posted 2006) [#9]
Anyone done something similar for Mac Os ?


TeaVirus(Posted 2006) [#10]
My MPlayer mod should work on Mac (haven't tried it yet).
http://www.blitzmax.com/Community/posts.php?topic=55043


DannyD(Posted 2006) [#11]
Thanks for the post TeaVirus. If you get a chance could you test it under Mac Os XZ please. I tried but it appears I need MaxGui. I downloaded the BlitzMax trial which has MaxGui bundled but I am unable to compile modules so can't include ProcessSteam module for testing.


TeaVirus(Posted 2006) [#12]
DannyD
I was able to compile the front end app but I can't seem to find a command line version of MPlayer for OSX. Anyway, if I find anything I'll post in the Mac forum so this thread doesn't go any more off topic. =)


TartanTangerine (was Indiepath)(Posted 2006) [#13]
Nice, I have one that lets you use Flash Movies, with command interactions.

But if I release it I'll put these nice fellows out of business, http://www.accode.com/blitz.htm, since it's not just Flash it's pretty much anything.