Play videos on the console (Windows)

Post your FreeBASIC tips and tricks here. Please don’t post your code without including an explanation.
dodicat
Posts: 6789
Joined: Jan 10, 2006 20:30
Location: Scotland

Play videos on the console (Windows)

Postby dodicat » Sep 12, 2020 12:06

No gfx involved, mcisendstring straight to the console.
If it doesn't show at first, move the console slightly.
Some formats don't show at all, I have set .avi as the first choice.
Should play .mp3 also.
Tested win 10, fbc 32/64/gas64
Added pause/resume e.t.c. for .mp3/ .wav files.

Code: Select all



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

Declare Function SetWindowTheme Lib "UxTheme.dll" Alias "SetWindowTheme"(As Any Ptr,As zstring Ptr,As zstring Ptr) As Long

Dim Shared As String req: req="Media (.avi) files"+NUL+"*.AVI"+NUL+"Others (.mp3,.mpeg, . . .)"+NUL+"*.MP3;*.MPEG"+NUL+"All files (*.*)"+NUL+"*.*"+NUL+NUL
Dim Shared As String message
Dim Shared As Any Ptr p
Dim Shared As hdc hdc
Function map(a As Double,b As Double,_x_ As Double,c As Double,d As Double) As Double
    Return  (((d)-(c))*((_x_)-(a))/((b)-(a))+(c))
End Function

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

Function splice(s As String,a() As Long) As String
    Redim a(1 To 4)
    Dim As Long position=Instr(s," "),count=1
    a(1)= Val(s)
    While position>0
        count+=1
        a(count)= Val(Mid(s,position))
        position=Instr(position+1,s," ")
    Wend
    Return s
End Function

Function Getsize( file As String,Byref _Width As Integer,Byref _Height As Integer,Byref l As Long=0) As Long
    Dim As zstring * 50 mcidata
    Dim As zstring * 20 length
    Redim Elements() As Long
    mciSendString("open  " +Chr(34)+file+Chr(34)+ " type mpegvideo alias file1", NULL, 0, 0)
    Var MCIResult = mciSendString("Where file1 Destination max",@MCIData,50,0)
    If MCIResult = 0 Then
        splice(MCIData,elements())
        _Width = Elements(3)
        _Height = Elements(4)
        mciSendString("status file1 length",@length, 20,0)
        l=Val(length)
    End If
    Return _width*_height
End Function

Function GetHandle As HWND
    Dim As HWND  hwndFound
   Dim pszNewWindowTitle As zstring * 1024
   Dim pszOldWindowTitle As zstring * 1024
   GetConsoleTitle(pszOldWindowTitle, 1024)
   wsprintf(pszNewWindowTitle, "%d/%d", GetTickCount(), GetCurrentProcessId())
   SetConsoleTitle(pszNewWindowTitle)
   Sleep(40)
   hwndFound = FindWindow(NULL, pszNewWindowTitle)
   SetConsoleTitle(pszOldWindowTitle)
   Return hwndFound
End Function

Sub hidecursor()
    Dim As HANDLE consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE)
    Dim As CONSOLE_CURSOR_INFO info
    info.dwSize = 100
    info.bVisible = FALSE
    SetConsoleCursorInfo(consoleHandle, @info)
End Sub

Sub play(file As String="")
    If file="" Then file=getfiles(req)
    Dim As Integer x,y,w,h,vflag=1
    Dim As Long l
    Dim As rect r
    Dim As Long diagonal,lastdiagonal
    Dim As String xs,ys,p1,p2
    Getsize(file,x,y,l)
    If Instr(Lcase(file),".mp3") Then vflag=0:Goto lbl
     If Instr(Lcase(file),".wav") Then vflag=0:Goto lbl
    p=gethandle
   
    If x=0 Or y=0 And vflag Then Print "Not valid": Return
    setwindowpos(p,HWND_TOPMOST,0,0,x,y,SWP_SHOWWINDOW)
    lbl:
    SetWindowTheme(p," "," ")
    Dim As zstring * 20 ans,length,position
    Shell "title "+Mid(file,1+Instrrev(file,Any"\/"))+ "       p = pause, r = resume, s = restart, q = quit"
   
    mciSendString("window file1 handle " & p, 0, 0, 0)
    mcisendstring("put file1 destination at "+Str(0)+" "+ Str(10)+" "+ Str(Int(x))+" "+ Str(Int(y))+" ",0,0,0)
    mciSendString("play file1", NULL, 0,0)
   
    Dim As Long Lngth,pst
    Lngth=l
    Dim As Double t=Timer
    Dim As String key
   
    If vflag=0 Then
        Do
            key=Inkey
        Select Case key
        Case "p"
            mciSendString("pause file1", NULL, 0,0)
        Case "r"
            mciSendString("play file1", NULL, 0,0)
        Case "s"
            mciSendString("play file1 from 0", NULL, 0,0)
        Case "q"
            mciSendString("close file1", NULL, 0, 0):End
        End Select
            mciSendString("status file1 position ",@position, 20,0)
            mciSendString("status file1 mode ",@ans,20,0)
            mciSendString("status file1 length",@length, 20,0)
         locate 1,1,0
         print "  ";(100*Vallng(position)\vallng(length));"%"
            message=ans
            if message="paused" then message+="   "
            Locate 3
            Print "Audio ";message
            If ans="stopped" Then  Exit Sub
            Sleep 100
             If key=Chr(27) Then mciSendString("close file1", NULL, 0, 0):End
        Loop
    End If
   
    ShowScrollBar(p, SB_BOTH, FALSE)
    getwindowrect(p,@r)
    diagonal = Sqr((r.right-r.left)*(r.right-r.left) +  (r.bottom-r.top)*(r.bottom-r.top))
    lastdiagonal=diagonal
    hdc=GetDC(p)
    Dim As Long xpos,wd
    wd=r.right-r.left
    hidecursor
    Do
        key=Inkey
        Select Case key
        Case "p"
            mciSendString("pause file1", NULL, 0,0)
        Case "r"
            mciSendString("play file1", NULL, 0,0)
        Case "s"
            mciSendString("play file1 from 0", NULL, 0,0)
        Case "q"
            mciSendString("close file1", NULL, 0, 0):End
        End Select
       
        mciSendString("status file1 position ",@position, 20,0)
        pst=Vallng(position)
        xpos=map(0,1,pst/Lngth,0,wd)
        SetPixel(hdc,xpos,5,bgr(255,255,255))
        getwindowrect(p,@r)
        diagonal = Sqr((r.right-r.left)*(r.right-r.left) +  (r.bottom-r.top)*(r.bottom-r.top))
        If (lastdiagonal<>diagonal)  Then
            movewindow(p,r.left,r.top,r.right-r.left,r.bottom-r.top,true)
            ShowScrollBar(p, SB_BOTH, FALSE)
            xs= Str((r.right-r.left))
            wd=(r.right-r.left)
            ys= Str((r.bottom-r.top))
            p1= "0"
            p2= "10"
            Dim As String  moveposition= "put file1 destination at "+p1+" "+p2+" "+xs+" "+ys
            mcisendstring(moveposition,null,0,0)
            hidecursor
        End If
        lastdiagonal=diagonal
       
        mciSendString("status file1 mode ",@ans,20,0)
        message=ans
        If ans="stopped" Then Locate 1,1: Print message  : Exit Sub
        Sleep 100
        If key=Chr(27) Then mciSendString("close file1", NULL, 0, 0):End
    Loop
End Sub


Dim As String filepath=""     'optional path otherwise openfile window
play(filepath)

Sleep

Sub finish Destructor
    mciSendString("close file1", NULL, 0, 0)   
    ReleaseDC(p,hdc)
End Sub



 
Last edited by dodicat on Sep 12, 2020 16:24, edited 1 time in total.
grindstone
Posts: 784
Joined: May 05, 2015 5:35
Location: Germany

Re: Play videos on the console (Windows)

Postby grindstone » Sep 12, 2020 14:04

Here (WinXP 32) only .mp3 works. No controls (pause, resume...) while playing.
dodicat
Posts: 6789
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Play videos on the console (Windows)

Postby dodicat » Sep 12, 2020 14:41

Hi grindstone.
I have Win 10 here and I wrote the code in Win 10.
Maybe XP doesn't have the wherewithall to run the code.
(Added pause e.t.c. for audio mp3/wav)
grindstone
Posts: 784
Joined: May 05, 2015 5:35
Location: Germany

Re: Play videos on the console (Windows)

Postby grindstone » Sep 13, 2020 12:25

Correction: I used a corrupted .avi file for testing. Playing .avi files now works.

I'm not really sure, but maybe the program changed the "view" options of the searching function (F3) on my machine from "details" to "thumbnail".
dodicat
Posts: 6789
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Play videos on the console (Windows)

Postby dodicat » Sep 13, 2020 13:25

Thanks for testing Grindstone.
My Win 10 is brand new, I have no video codecs installed, If I see an icon with a snapshot of the video clip on a film strip frame mcisendstring usually plays it, and clicking that file plays it (Films & TV)
The blue icon with a triangle doesn't play.
.mp3 and .wav have an icon like a record and play (Groove Music).
I haven't altered the view, but it has defaulted to large icons for media files.
I cannot see how any of the fields set in getfiles, or mcisendstring has done this, I think It was the same before I ever called mcisendstring.
grindstone
Posts: 784
Joined: May 05, 2015 5:35
Location: Germany

Re: Play videos on the console (Windows)

Postby grindstone » Sep 13, 2020 15:54

I apologise, it was not caused by your program, Windows automatically changes the view if searching for media files ("It's not a bug, it's a feature"). Thank you for that hint.
xbgtc
Posts: 211
Joined: Oct 14, 2007 5:40
Location: Australia

Re: Play videos on the console (Windows)

Postby xbgtc » Oct 07, 2020 4:16

Wow amazing! (didn't think you could do this).

just a few hiccups: in both WINFBE + FBIDE there are no controls in title bar and when vid ends you have to close the window which then hangs the program (not responding message in title bar) then a small FBIde/WINFBE window opens and you select 'close program now' which then wants to send microsoft a message :)
dodicat
Posts: 6789
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Play videos on the console (Windows)

Postby dodicat » Oct 07, 2020 9:51

Thanks for testing xbgtc.
The title bar should have
" p = pause, r = resume, s = restart, q = quit"
Try disabling the blue frame ~~line 102, comment out SetWindowTheme(p," "," ")
When the video is finished q or the esc key or clicking off the window should end the program, I have set the sub finish Destructor to clean up properly in the event of any of these ends.
Everything works OK here, I have no other decoders installed on this system.
The console is resizable, if the default screen is very large, which is the case with many of the downloadable samples, then you can pull it in a bit.
(Win 10 here, the console has more functionality than say xp)
srvaldez
Posts: 2635
Joined: Sep 25, 2005 21:54

Re: Play videos on the console (Windows)

Postby srvaldez » Oct 07, 2020 10:07

@dodicat
I get audio but no video
dodicat
Posts: 6789
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Play videos on the console (Windows)

Postby dodicat » Oct 07, 2020 10:37

Hi srvaldez.
Move the console a bit, this should activate the video.
Some formats don't work very well.
I have been reading up about the console, seemingly it is completely owned by the operating system (Winapi wise).
I cannot tell it explicitly what to do, I can only get a handle to it, and hope it works favourably enough.
Sometimes a little nudge helps it along.
aurelVZAB
Posts: 384
Joined: Jul 02, 2008 14:55
Location: Croatia
Contact:

Re: Play videos on the console (Windows)

Postby aurelVZAB » Oct 07, 2020 13:55

Usual way is to use static control with bitmap style
xbgtc
Posts: 211
Joined: Oct 14, 2007 5:40
Location: Australia

Re: Play videos on the console (Windows)

Postby xbgtc » Oct 08, 2020 22:17

dodicat wrote:Try disabling the blue frame ~~line 102, comment out SetWindowTheme(p," "," ")

Made no difference at all.

I tried an AVI file and that has weirder behavior eg. while playing if you click on the title bar the video stops then shows 'not responding' then if you close the window same deal as i have with MPG but now it has left an FBITempxxx.exe running and you have to stop that in task manager if you want to run the program again and this is with FBIde, running the program in WINFBE just throws a window saying 'Not valid' when you try AVI files. Also Win10 here too :)

Anyway don't worry too much about it as i don't really need console vid :)

EDIT: ahh in WINFBE the 'not valid' was due to the option -s console 64 setting so setting it to 32 and vid plays with the appropriate controls in the title bar but one problem: sound but no vid :) (moving window does nothing).

changed it to -s gui and i have sound + vid but no controls in title bar (same as FBIde) and same closing problem. In FBIDE -s gui or -s console makes no diff.
dodicat
Posts: 6789
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Play videos on the console (Windows)

Postby dodicat » Oct 08, 2020 23:49

Hi xbgtc.
I run this with no compiler options, but I have tested with -s console and various optimisations 32/64/gas64 all OK.
Perhaps you could do this :

Function GetHandle As HWND
return GetConsoleWindow()
End Function

instead of the longer method.

Win 10.

I can only think that your samples are causing the problems, some hit and some miss, even using a winapi window or a gfx window.
xbgtc
Posts: 211
Joined: Oct 14, 2007 5:40
Location: Australia

Re: Play videos on the console (Windows)

Postby xbgtc » Oct 09, 2020 4:10

No difference with that shorter function. Could just be my system setup or configuration maybe even my version. Win10 has these weird problems like all of a sudden my jpg graphics program (Lview Pro) causes a delay once a pic is loaded (can't open a directory - you have to wait) and also my screen brightness setting in nvidia settings does not work as it should because Win10 overides it so i have to disable the color system in task scheduler. Used to be fine but when damn windows upgrades itself always these kinda problems arise, oh and another is the network too! damn Win10.

Return to “Tips and Tricks”

Who is online

Users browsing this forum: No registered users and 8 guests