SOLVED - MPEG2 Play Code and Win10

Windows specific questions.
xbgtc
Posts: 249
Joined: Oct 14, 2007 5:40
Location: Australia

SOLVED - MPEG2 Play Code and Win10

Post by xbgtc »

EDIT: 07/07/2020
Here is the MCI code to play .MPG or .VOB video files in your game screen and with positioning and resizing code. It's does what the old dshow code (which still works) did but as you can see simpler and better. If for any reason you can't see video but can hear it then you will need an mpeg codec - i myself am using an old KLITE-Codec Pack. Also thanks to DODICAT for his help and code too so i could put this together :)

Code: Select all

#include "Windows.bi"
#include "win/mmsystem.bi"
screencontrol(103,"GDI")    'use GDI driver else video flickers badly in Win10 with directx
screenres 800,600,32
declare sub playvid(param as any ptr)
dim shared as string vtp    'once vtp is not NULL the thread automatically plays the vid till it ends or a new vid takes over  
dim shared as integer terminate,flag
dim shared as any ptr thread
thread=threadcreate(@playvid,0)
sleep 100   'can be omitted as only needed for this test
vtp="yourvid.mpg" 'will trigger vid to play vid with dir specified in thread if needed
sleep
terminate=1
threadwait(thread)

sub playvid(param as any ptr)
    dim windo as hwnd
    screencontrol(2,cast(integer,windo))
    dim as uinteger w,h,hor,ver,vw,vh
    dim as zstring*20 vfp
    screeninfo w,h  'get current resolution width & height
    vw=w/5  'just code to put the video area centred horizontally and just below centre
    vh=h/5
    hor=w/2-vw/2
    ver=h/2
    while (1)   'never understood this but it was in the example so used it and works
        do
            if terminate then
                mciSendString("close vid",NULL,0,0)
                exit sub
            end if
            if flag then
                mciSendString("status vid mode",@vfp,20,0)  'sends max 20 character message to string vfp that's either 'playing' 
                if vfp="stopped" then 'if vid has ended                                                              or 'stopped'
                    mciSendString("close vid",NULL,0,0) 'needed as won't play next vid otherwise
                    line(hor-2,ver-2)-(hor+vw+2,ver+vh+2),&h000000,bf 'get rid of white border + last frame of vid
                    flag=0  'so no checking a vid that isn't running
                end if
            end if
            sleep_ 50   'thread safe sleep
        loop while vtp=""
        'vtp=curdir+"\vid\"+vtp  'add the path to the video file (not needed if all vids in the program dir)
        line(hor-2,ver-2)-(hor+vw+2,ver+vh+2),&hc0c0c0,b  'just a border round the video
        line(hor-1,ver-1)-(hor+vw+1,ver+vh+1),&hc0c0c0,b  '2 lines thick
        mciSendString("open  "+Chr(34)+vtp+Chr(34)+" type mpegvideo alias vid",NULL,0,0)    'vid now holds device\path\filename
        mciSendString("window vid handle "&windo,0,0,0)    'this makes vid appear in your program screen
        mciSendString("put vid destination at "+str(hor)+" "+str(ver)+" "+str(vw)+" "+str(vh),0,0,0)  'everything is strings!
        mciSendString("play vid",NULL,0,0)
        vtp=""  'null vtp so it's back in loop waiting for next vid
        flag=1  'so it can start to find out when the video has finished playing
    wend
end sub


First of all I just wanna say I can not believe that NO-ONE has posted code to simply just play a common mpeg file. There are plenty MP3 and sound but none for video and the useless examples given with FB just don't work.

Anyway... in WinXP I put together some code that actually worked albeit with problems but it did the job. Now, i'm using Win10 ver 10.0.018362 and of course I can't play video in FB now. Actually the video plays but you just get sound and no video. The code that worked in XP (and Win7/8) and worked well is below for you to try (just run it and it will play the video till end and sleep till you hit a key but can ESC anytime). I have heard that they dropped DSHOW in win10 as DirectX does not contain it anymore but not sure if this has anything to do with my problem as the vid plays and you can hear it just no actual video can be seen.

Anyway hope someone out there can help or just provide NEW code to simple just play a damn vid in FB. Oh yer using FB v1.01 but have tried latest versions even 64bit FB but no diff.

Code: Select all

#include once "win/dshow.bi"
screencontrol(103,"GDI")    'use GDI driver else video flickers badly in Win10 with directx
screenres 800,600,32
declare sub playvid(param as any ptr)
dim shared as string vid
dim shared as integer terminate,flag,t=48
dim shared HWND as hwnd
screencontrol(2,cast(integer,hwnd))
dim shared as any ptr thread,p
thread=threadcreate(@playvid,0)
sleep 100
'p=imagecreate(160,120)
vid="C:\Users\Name\Videos\somevideo.mpg" 'insert your video file here (.mpg or .vob)
sleep
terminate=1
threadwait(thread)
'imagedestroy(p)
sub playvid(param as any ptr)
    dim as any ptr evCode,param1,param2
    dim as uinteger sh,sw,hor,ver,wid,hei,flag2,pevc,pp1,pp2,vidon
    sw=800
    sh=600
    evCode=@pevc
    param1=@pp1
    param2=@pp2
    if sh<601 then
        hor=sw/2-80
        wid=160
        hei=120
    else
        hor=sw/2-160
        wid=320
        hei=240
    end if
    ver=sh/2+92
    vid="dummy" 'needed else exits with error if ESC before vid plays
    dim as IGraphBuilder Ptr pGraph
    dim as IMediaEvent   Ptr pEvent
    dim as IMediaControl Ptr pControl
    dim as IVideoWindow  Ptr vidwindow
    while (1)
        do
            if terminate then
                IMediaControl_Stop(pControl)
                IBasicVideo_Release(pEvent)
                IBasicVideo_Release(pControl)
                IBasicVideo_Release(pGraph)
                IBasicVideo_Release(vidwindow)
                CoUninitialize()
                exit sub
            end if
            if flag2=1 then
                sleep_ 50
                IMediaEvent_GetEvent(pEvent,evCode,param1,param2,0)
                if pevc=1 then 'if vid has ended
                    line(hor-2,ver-2)-(hor+wid+2,ver+hei+2),&h000000,bf 'line(350,474)-(674,718),&h000000,bf
                    vidon=0
                    flag2=2 'so only calls IMediaEvent after a vid is played
                end if
                if flag then 'for when you blank it out with text
                    IVideoWindow_put_visible(vidwindow,oafalse)
                    IVideoWindow_put_visible(vidwindow,oatrue)
                end if
            end if
            sleep_ 50
        loop while vid=""
        vidon=1
        if flag2 then
            line(hor-2,ver-2)-(hor+wid+2,ver+hei+2),&hc0c0c0,b
            line(hor-1,ver-1)-(hor+wid+1,ver+hei+1),&hc0c0c0,b
            IMediaControl_Stop(pControl)
            IBasicVideo_Release(pEvent)
            IBasicVideo_Release(pControl)
            IBasicVideo_Release(pGraph)
            IBasicVideo_Release(vidwindow)
            CoUninitialize()
        end if
        if flag2 then
            dim as IGraphBuilder Ptr pGraph
            dim as IMediaEvent   Ptr pEvent
            dim as IMediaControl Ptr pControl
            dim as IVideoWindow  Ptr vidwindow
        end if
        dim pasta as any ptr
        dim msg as integer
        pasta=@msg
        Var hr=CoInitialize(0)
        hr=CoCreateInstance(@CLSID_FilterGraph,NULL,CLSCTX_INPROC_SERVER,@IID_IGraphBuilder,@pGraph)
        hr=IGraphBuilder_QueryInterface(pGraph,@IID_IMediaEvent,@pEvent)
        hr=IGraphBuilder_QueryInterface(pGraph,@IID_IMediaControl,@pControl)
        hr=IGraphBuilder_QueryInterface(pGraph,@IID_IVideoWindow,@vidwindow)
        IGraphBuilder_RenderFile(pGraph,vid,NULL)
        'IVideoWindow_put_FullScreenMode(vidwindow,oatrue) 'puts in fullscreen mode 
        IVideoWindow_put_Owner(vidwindow,cast(integer,hwnd))
        'take this next line out then it draws in your screen but in window (full screen only)
        IVideoWindow_put_WindowStyle(vidwindow,WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN)
        IVideoWindow_SetWindowPosition(vidwindow,cast(uinteger,hor),cast(uinteger,ver),cast(uinteger,wid),cast(uinteger,hei))
        IMediaControl_Run(pControl)
        vid=""
        'IMediaEvent_WaitForCompletion(pEvent,-1,pasta)
        flag2=1
    wend
end sub
Last edited by xbgtc on Jul 11, 2020 3:06, edited 3 times in total.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: MPEG2 Play Code and Win10

Post by Josep Roca »

I have one that works, but haven't posted it here because I use my own framework.
See: https://github.com/JoseRoca/WinFBX/blob ... ayClip.bas
xbgtc
Posts: 249
Joined: Oct 14, 2007 5:40
Location: Australia

Re: MPEG2 Play Code and Win10

Post by xbgtc »

thanks but I can't get it to run because I get this:

C:\FreeBASICHacker\FBIDETEMP.bas(30) error 23: File not found, "Afx/CWindow.inc" in '#INCLUDE ONCE "Afx/CWindow.inc"'

have you just got the bare bones of this code that just plays a vid?
Arachnophilia
Posts: 25
Joined: Sep 04, 2015 13:33

Re: MPEG2 Play Code and Win10

Post by Arachnophilia »

Hi xbgtc

As Jose wrote elsewhere, the easiest way to use the framework is to use the libraries with WinFBE.
Jose's framework WinFBX is installed automatically.
You can find WinFBE at https://github.com/PaulSquires/WinFBE/releases
But you can also copy the Framework into your installation directory of the FreeBasic Compiler.

For example E:\Programming\WinFBE_Suite\FreeBASIC-1.08.0-gcc-9.2\inc\Afx\
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: MPEG2 Play Code and Win10

Post by Josep Roca »

> have you just got the bare bones of this code that just plays a vid?

The main code is in the sub PlayMovieInWindow and in the processing of the WM_GRAPHNOTIFY message. In Windows we need a GUI to be able to process the WM_GRAPHNOTIFY (*) message in the callback procedure of the window. CWindow.inc is class to ease the building of a GUI.

(*) Instead of WM_GRAPHNOTIFY you can choose another name and value of your liking, The important part if to tell Windows which message it has to send to the callback procedure with hr = pIMediaEventEx->lpvtbl->SetNotifyWindow(pIMediaEventEx, cast(OAHWND, hwnd), WM_GRAPHNOTIFY, 0). If you don't, then getting notifications can become a mess.
xbgtc
Posts: 249
Joined: Oct 14, 2007 5:40
Location: Australia

Re: MPEG2 Play Code and Win10

Post by xbgtc »

Hi and thanks for this info. Although I don't understand this 'framework' and why it's needed will install/copy it and hopefully get it going, cheers!
Arachnophilia wrote:Hi xbgtc

As Jose wrote elsewhere, the easiest way to use the framework is to use the libraries with WinFBE.
Jose's framework WinFBX is installed automatically.
You can find WinFBE at https://github.com/PaulSquires/WinFBE/releases
But you can also copy the Framework into your installation directory of the FreeBasic Compiler.

For example E:\Programming\WinFBE_Suite\FreeBASIC-1.08.0-gcc-9.2\inc\Afx\
xbgtc
Posts: 249
Joined: Oct 14, 2007 5:40
Location: Australia

Re: MPEG2 Play Code and Win10

Post by xbgtc »

Oh ok will have to play with it and I don't get the messaging part (why it's needed) but will follow what you have stated and hopefully get what I need from the code you have provided - thanks again. :)
Josep Roca wrote:> have you just got the bare bones of this code that just plays a vid?

The main code is in the sub PlayMovieInWindow and in the processing of the WM_GRAPHNOTIFY message. In Windows we need a GUI to be able to process the WM_GRAPHNOTIFY (*) message in the callback procedure of the window. CWindow.inc is class to ease the building of a GUI.

(*) Instead of WM_GRAPHNOTIFY you can choose another name and value of your liking, The important part if to tell Windows which message it has to send to the callback procedure with hr = pIMediaEventEx->lpvtbl->SetNotifyWindow(pIMediaEventEx, cast(OAHWND, hwnd), WM_GRAPHNOTIFY, 0). If you don't, then getting notifications can become a mess.
xbgtc
Posts: 249
Joined: Oct 14, 2007 5:40
Location: Australia

Re: MPEG2 Play Code and Win10

Post by xbgtc »

OK think i'm getting to the bottom of this.

After running into all sorts of trouble found that the code I copy/pasted from that link was no good as in WINFBE Suite (that I installed) I happen to find that exact code so used that and then it actually ran with no errors. The example .wmv file played ok but when I tried an .mpg there was audio but no video. So then I went to try my original code with an .mpg converted to .wmv and that actually worked but had to use GDI as vid was jittery.

Anyway long story short it appears that my code was fine but this WIN10 system just can't do MPG files although the default movieplayers in Win10 plays them no probs but I do see that WMP says it needs a codec so that may just be the problem! - We will See!
xbgtc
Posts: 249
Joined: Oct 14, 2007 5:40
Location: Australia

Re: MPEG2 Play Code and Win10

Post by xbgtc »

After running WMP it initially has that settings screen (where you disable most) it went into the GUI and it plays MPG, VOB no probs. I guess when Win10 upgraded itself it must of installed new codecs as I remember when I went through this before it said it needed codecs so...

Anyone know why I would be having this problem with trying to play vid in code?
xbgtc
Posts: 249
Joined: Oct 14, 2007 5:40
Location: Australia

Re: SOLVED - MPEG2 Play Code and Win10

Post by xbgtc »

After lots of stuffing around trying to find out if it was a codec problem or what codec I needed I remembered that in Win XP I could never get that media player to play mpeg/vob and always had to install third party codecs namely K-Lite Codec Pack. So I ran this old program and just installed a mpeg2 codec and yep that fixed mpeg2/vob playback (although I have to use the GDI driver else video flickers something shocking).

I just don't get it - Win10 + DirectX 12 and you can't play mpeg via code even though the default players play them fine - mind boggling!
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: SOLVED - MPEG2 Play Code and Win10

Post by dodicat »

Josep Roca's code works fine.
I put his .bas file into the

. . . WinFBE_Suite\WinFBE_Suite\FreeBASIC-1.07.1-gcc-5.2\inc

folder

His .bas file
https://github.com/JoseRoca/WinFBX/blob ... ayClip.bas

You will need to get the IDE (and his framework) from
viewtopic.php?f=8&t=25215

(Maybe the \FreeBASIC-1.07.1-gcc-5.2\ has been updated (renamed)), but to get the file to run with your own ide that is where you should put it to test.
After that you can isolate the necessary bare bones include files at your leisure.

In the old days with slow processors I used dxr2 and dxr3 pci cards which play videos by hardware, you could watch a film on a 255 mhz computer.

Now I have Win 10 with directx 12.
Josep Roca
Posts: 564
Joined: Sep 27, 2016 18:20
Location: Valencia, Spain

Re: SOLVED - MPEG2 Play Code and Win10

Post by Josep Roca »

> I put his .bas file into the WinFBE_Suite\WinFBE_Suite\FreeBASIC-1.07.1-gcc-5.2\inc folder

If you have WinFBE installed, the full example, complete with a manifest and other resources is provided in the WinFBE\Sample_Projects\DShow_PlayClip subfolder.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: SOLVED - MPEG2 Play Code and Win10

Post by dodicat »

You could try this also, tested on mp3 and .mpg, but should play other formats within reason.(An adaptation of code by angros47)

Code: Select all

 

#define WIN_INCLUDEALL
#include "Windows.bi"
#include "win/mmsystem.bi"
#Include once "/win/commctrl.bi"
#define nul chr(0)

var req="Media (.mpg) files"+NUL+"*.MPG"+NUL+"Others (.mp3,.mpeg, . . .)"+NUL+"*.MP3;*.MPEG"+NUL+"All files (*.*)"+NUL+"*.*"+NUL+NUL

sub play(file as string)
mciSendString("open  " +chr(34)+file+chr(34)+ " type mpegvideo alias file1", NULL, 0, 0)
mciSendString("play file1", NULL, 0, 0)
end sub

sub playend
    mciSendString("close file1", NULL, 0, 0)
end sub

Sub done Destructor
    mciSendString("close file1", NULL, 0, 0)
End Sub

Function getfiles(filetypes As String) As String
    Dim As zstring * 2048 SELFILE
    Dim As String MYFILTER
    myfilter=filetypes
    Dim As OpenFileName SomeFile
    With SomeFile
        .lStructSize = Sizeof(OpenFileName)
        .hInstance = null
        .lpstrFilter = Strptr(MYFILTER)
        .lpstrFile = @SELFILE
        .nMaxFile = 2048
        .nMaxFileTitle = 0
        .lpstrTitle =@"Movies and songs"
        .Flags = OFN_PATHMUSTEXIST Or OFN_FILEMUSTEXIST
    End With
    GetOpenFileName(@SomeFile)
    Return *SomeFile.lpstrFile
End Function

dim as string v= getfiles(req)
print "Your file:"
print 
print v
print

play(v)
lbl:
locate 6
print "Press <esc> to end"
var fin=input(1)
if fin=chr(27) then playend else goto lbl
sleep
 
xbgtc
Posts: 249
Joined: Oct 14, 2007 5:40
Location: Australia

Re: SOLVED - MPEG2 Play Code and Win10

Post by xbgtc »

dodicat as I posted earlier I did install WINFBE and use his/that code but same result as my code - audio but no video.

After my last post saying it is working now with the codec installed I somehow stuffed it up (by playing around) and now back to square one - audio but no video, but the video will show if I play another mpg on top of the one already playing - WEIRD!

dodicat I just tried your code and I selected an mpg and it played!... but.. after it played and I went to close the box it errored with a popup and I forced it closed then I ran the program again, selected an mpg to play and now I have audio but no VIDEO!?

this is getting weird!
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: SOLVED - MPEG2 Play Code and Win10

Post by dodicat »

Here are the full set of command strings for MCI
https://docs.microsoft.com/en-us/window ... nd-strings

Possibly a flag needed after play in play file1.

In the meantime just press escape from the console, it ends cleanly.
Post Reply