CLASS fwTVCL for IP-TV

CLASS fwTVCL for IP-TV

Postby Jimmy » Mon Aug 01, 2022 5:45 pm

hi,

Media Player can not only use "Local" Files, it also can "Stream" from Internet

using VLC ActiveX i have create CLASS fwTVLC and use it in this Sample to play IP-TV

i have wrote this HMG App
Image
btw. FiveWin Version does not use DWM Effect

please read more about it
https://hmgforum.com/viewtopic.php?p=68321

---

Version have 3 Part

FWIPTV.PRG Main App
FWVLC.PRG CLASS fwTVLC
READM3U.PRG read *.M3U Files into DBF

Problem : i can only provide a (working) *.MAK for BCC7 32 Bit

i would like to use 64 Bit too, using MSVC, before i release Source Code
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: CLASS fwTVCL for IP-TV

Postby Jimmy » Mon Aug 01, 2022 9:52 pm

hi,

i was able now to compile/link 3 x Module under FiveWin 64 Bit using MSVC

Code: Select all  Expand view  RUN
#define _WIN64
#ifdef _WIN64
   #include "FWVLC.PRG"
   #include "READM3U.PRG"
#endif

but this is just a Workaround and not the Solution

does somebody use a Project File with MSVC and FiveWin and can show me "how" :?:
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: CLASS fwTVCL for IP-TV

Postby Antonio Linares » Mon Aug 01, 2022 11:43 pm

Dear Jimmy,

go64.bat
Code: Select all  Expand view  RUN
call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
c:\harbour\bin\hbmk2 test64.hbp -comp=msvc64

test64.hbp
Code: Select all  Expand view  RUN
-gui

-Ic:\fwh\include

FWIPTV.PRG
FWVLC.PRG
READM3U.PRG

-Lc:\fwh\lib

-lFiveH64
-lFiveHC64

-lgdiplus
-lole32
-lOleDlg
-lversion

xhb.hbc
hbct.hbc
hbwin.hbc
hbmzip.hbc
hbziparc.hbc
hbfoxpro.hbc

-ldflag=/NODEFAULTLIB:msvcrt

test.rc
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42121
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: CLASS fwTVCL for IP-TV

Postby Jimmy » Tue Aug 02, 2022 12:17 am

hi Antonio,

sorry to ask again
[vcvarsall.bat] Environment initialized for: 'x64'
Error BASE/1126 Argument error: STRTRAN (Quit)
Error BASE/1126 Argument error: STRTRAN
Called from STRTRAN(0)
Called from __HBMK(0)
Called from HBMK_LOCAL_ENTRY(0)
Called from __HBMK_FAKE_ENTRY(0)


Code: Select all  Expand view  RUN
set HBDIR=C:\HARBOUR64
set FWDIR=C:\FWH64
set fwh=c:\fwh64
call "%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" amd64
C:\HARBOUR64\bin\hbmk2 test64.hbp -comp=msvc64


Code: Select all  Expand view  RUN
   -gui

    -Ic:\fwh64\include

    FWIPTV.PRG
    FWVLC.PRG
    READM3U.PRG

    -Lc:\fwh64\lib

    -lFiveH64
    -lFiveHC64

    -lgdiplus
    -lole32
    -lOleDlg
    -lversion

    xhb.hbc
    hbct.hbc
    hbwin.hbc
    hbmzip.hbc
    hbziparc.hbc
    hbfoxpro.hbc

    -ldflag=/NODEFAULTLIB:msvcrt

    FWIPTV.RC

have no Idea what Error mean
same Code will compile/link/run when using BUILDh64.BAT
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: CLASS fwTVCL for IP-TV

Postby Antonio Linares » Tue Aug 02, 2022 5:17 am

Dear Jimmy,

What Windows version are you using and what Visual Studio Community version ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42121
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: CLASS fwTVCL for IP-TV

Postby Jimmy » Tue Aug 02, 2022 6:24 am

hi Antonio,

it is 2022\Community on 64 Bit OS

BUILDh64.BAT work to build other App and File
Code: Select all  Expand view  RUN
"%ProgramFiles%\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat"

does exist

i can compile/link with MSVC 64 Bit when use
Code: Select all  Expand view  RUN
BUILDh64 FWIPTV /DUSE_INC


Code: Select all  Expand view  RUN
PROCEDURE MAIN
...
#IFDEF USE_INC
   #include "FWVLC.PRG"
   #include "READM3U.PRG"
#endif
 

this will include other Files and it will compile/link and run

---

i will release Source, after cleanup, soon
Workaround /DUSE_INC can be used under 32 and 64 Bit

but i like to know how it work with go64.bat / test64.HBP
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: CLASS fwTVCL for IP-TV

Postby Jimmy » Tue Aug 02, 2022 8:01 pm

as Source is still under Construction it have some "onDummy()" DEBUG Code

fwTVCL.PRG
Code: Select all  Expand view  RUN
*+--------------------------------------------------------------------
*+
*+ Source Module => c:\fwh\0\IPTV\FWVLC.PRG
*+
*+    Copyright(C) 1983-2022 by Auge & Ohr
*+
*+    Functions: Class FWTVlc
*+
*+    Reformatted by Click! 2.05.40 on Aug-2-2022 at  9:10 pm
*+
*+--------------------------------------------------------------------

#include "fivewin.ch"
#include "common.ch"

#define HB_VERSION_BITWIDTH            17

#define VLC_INPUT_STATE_IDLE           0
#define VLC_INPUT_STATE_OPENING        1
#define VLC_INPUT_STATE_BUFFERING      2
#define VLC_INPUT_STATE_PLAYING        3
#define VLC_INPUT_STATE_PAUSED         4
#define VLC_INPUT_STATE_STOPPING       5
#define VLC_INPUT_STATE_ENDED          6
#define VLC_INPUT_STATE_ERROR          7

#define MK_LBUTTON                     0x0001
#define MK_RBUTTON                     0x0002
#define MK_SHIFT                       0x0004
#define MK_CONTROL                     0x0008

*+--------------------------------------------------------------------
*+
*+    Class FWTVlc
*+
*+--------------------------------------------------------------------
*+
CLASS FWTVlc FROM TActiveX

   DATA oControl, oPlayList, oInput, oVideo, oAudio, oMedia
   DATA nStepVolume, nVolumen, nFilterRec, nRECNO, nIndex
   DATA cFileName
   DATA lRun
   DATA lLoop
   DATA lEndless
   DATA bRClicked, bMenu, bPlayNext
   DATA oFont, oParent
   DATA cTimer, lStream

   METHOD New( oParent, nRow, nCol, nWidth, nHeight, nIndex ) CONSTRUCTOR
   METHOD Destroy()
   METHOD SetFile( cFileName )
   METHOD Play()
   METHOD Stop()
   METHOD Position( nPosition )
   METHOD GetLength()
   METHOD GetLengthStr()
   METHOD GetTime()
   METHOD GetTimeStr()
   METHOD GetVersion()
   METHOD SetTime( n )
   METHOD Mute( lIn )
   METHOD IsPlaying()
   METHOD State()
   METHOD Marquee( cText, cPos, nTimeout, nSize )
   METHOD VLCevent( cEvent, aParams )
   METHOD VLCstate()
   METHOD CheckFullScreen()
   METHOD IsFullScreen()
   METHOD Time2MiliSec( cTime )
   METHOD MiliSec2Time( nMiliSec )
   METHOD Play_Next()

   ENDCLASS

METHOD New( oParent, nRow, nCol, nWidth, nHeight, nIndex, oFont ) CLASS FWTVlc
LOCAL oError, bOldError

   DEFAULT nIndex TO 1

   ::cTimer := "VLC_TIMER"
   ::cTimer += STRZERO( nIndex, 3 )

   ::oParent := oParent

   ::lEndless = .T.
   ::lLoop := .F.
   ::cFileName := ""
   ::lStream := .F.

   IF EMPTY( oFont )
      DEFINE FONT oFont NAME "TAHOMA" SIZE 0, - 12
#IFDEF __HMG__
      END FONT
#ENDIF
   ENDIF
   // just to be compatible but not used
   ::oFont := oFont

   bOldError := ERRORBLOCK( { | e | BREAK( e ) } )
   BEGIN SEQUENCE
      ::oControl := ::SUPER:New( oParent, "VideoLAN.VLCPlugin.2", nRow, nCol, nWidth, nHeight )
   RECOVER USING oError
      ERRORBLOCK( bOldError )
      MsgStop( 'This Program Required Installed ' + hb_ntos( hb_Version( HB_VERSION_BITWIDTH ) ) + '-bit AXVLC.DLL!', 'Error VLC ActiveX ' + LTRIM( HB_VALTOSTR( oError:osCode ) ) )
      QUIT
   END SEQUENCE
   ERRORBLOCK( bOldError )

   IF hb_isObject( ::oControl )
      ::nRECNO := 0
      ::nIndex := nIndex
      ::nStepVolume := 10
      ::nvolumen := 100

      ::oControl:Toolbar := .T.
      ::oControl:volume := ::nvolumen
      ::oControl:FullscreenEnabled := .T.

      ::oPlaylist := ::oControl:playlist
      ::oInput := ::oControl:input
      ::oVideo := ::oControl:video
      ::oAudio := ::oControl:audio
      ::oMedia := ::oControl:MediaDescription

      ::oAudio:mute := .T.

      // Events
      ::oControl:bOnEvent = { | cEvent, aParams | ::VLCevent( cEvent, aParams ) }

      ::bMenu := { || NIL }                                           // init with Codeblock
      ::bPlayNext := { || NIL }                                       // init with Codeblock

      // ActiveX have no Property bRClicked so ADD it
      ::bRClicked = { | nRow, nCol | EVAL( ::bMenu, nRow, nCol, ::oParent, ::nIndex ) }

*      OnDummy( TIME(), "End VLC Setup" )

      // for each Instanze internal TIMER
      DEFINE TIMER ::cTimer of oParent INTERVAL 100 ACTION ::VLCstate()                                                                     // check Play-State
      ACTIVATE TIMER ::cTimer
   ELSE
      MsgStop( 'Control not create ?!"+CRLF+"This Program Required Installed ' + hb_ntos( hb_Version( HB_VERSION_BITWIDTH ) ) + '-bit AXVLC.DLL!', 'Error VLC ActiveX ' + LTRIM( HB_VALTOSTR( oError:osCode ) ) )
      QUIT
   ENDIF
RETURN Self

METHOD Destroy() CLASS FWTVlc

   RELEASE TIMER ::cTimer

   ::oPlaylist := NIL
   ::oInput := NIL
   ::oVideo := NIL
   ::oAudio := NIL
   ::oMedia := NIL
   ::oControl := NIL

RETURN NIL                                                            // ::SUPER:Destroy()

METHOD SetFile( cFileName ) CLASS FWTVlc
LOCAL oError, bOldError := ERRORBLOCK( { | e | BREAK( e ) } )
LOCAL lRet   := NIL

   IF ::IsPlaying()
      ::Stop()
   ENDIF

   ::cFileName := TRIM( cFileName )
   IF !EMPTY( ::cFileName )
      ::oPlaylist:items:clear()

      IF "http" $ LOWER( ::cFileName )
         // add Stream
         lRet := ::oPlaylist:add( ::cFileName )
      ELSE
         // add local Media
         lRet := ::oPlaylist:add( "File:///" + ::cFileName )
      ENDIF

      IF ::State() == VLC_INPUT_STATE_ERROR
         msginfo( "VLC_INPUT_STATE_ERROR", "Error" )
         RETURN lRet
      ENDIF

      ::oInput:position := 0
      ::oVideo:aspectRatio := "16:9"
      ::oControl:Toolbar := .T.
      ::oControl:FullscreenEnabled := .T.

      ::nRECNO := RECNO()
      ::Marquee( "Record : " + LTRIM( STR( ::nRECNO ) ), "top-right", 1000 * 5 )

*      onDummy( TIME(), "SetFile()", ::nIndex, lRet, ::nRECNO, ::cFileName )

      // lRet := .t.
   ELSE
      MsgInfo( "can not use Empty Filename" )
   ENDIF

RETURN lRet

METHOD Play() CLASS FWTVlc
LOCAL lRet := NIL

   IF ::IsPlaying()
      ::Stop()
   ENDIF

   lRet := ::oPlaylist:playitem( 0 )

   SysRefresh()
   ::lRun := .T.

*   onDummy( TIME(), "PlayURL()", ::nIndex, lRet, RECNO(), TRIM( TVURL->TVURL ) )
RETURN lRet

METHOD Stop() CLASS FWTVlc
LOCAL lRet := NIL

   lRet := ::oPlaylist:stop()
RETURN lRet

METHOD Position( nPosition ) CLASS FWTVlc
   IF HB_ISNIL( nPosition )
      RETURN ::oControl:input:position
   ELSE
      IF nPosition >= 0 .AND. nPosition <= 1
         ::oControl:input:position := nPosition
      ENDIF
   ENDIF
RETURN NIL

METHOD GetLength() CLASS FWTVlc
RETURN ::oInput:length()

METHOD GetLengthStr() CLASS FWTVlc
RETURN ::MiliSec2Time( ::oInput:length() )

METHOD GetTime() CLASS FWTVlc
RETURN ::oInput:time()

METHOD GetTimeStr() CLASS FWTVlc
RETURN ::MiliSec2Time( ::oInput:time() )

METHOD GetVersion() CLASS FWTVlc
RETURN ::oControl:getVersionInfo()

METHOD SetTime( n ) CLASS FWTVlc
LOCAL nRet := ::oInput:time * 1000
   IF HB_ISNUMERIC( n )
      nRet := ::oInput:time := n * 1000
   ENDIF
RETURN nRet

METHOD Mute( lIn ) CLASS FWTVlc
   IF PCOUNT() > 0
      ::oAudio:mute := lIn
   ENDIF
RETURN ::oAudio:mute

METHOD IsPlaying() CLASS FWTVlc
RETURN ::oPlaylist:IsPlaying

METHOD IsFullScreen() CLASS FWTVlc
RETURN ::oVideo:fullscreen

METHOD State() CLASS FWTVlc
RETURN ::oInput:state

METHOD Marquee( cText, cPos, nTimeout, nSize ) CLASS FWTVlc
LOCAL nAt := 1, acPos := { "center", "left", "right", "top", "top-left", "top-right", "bottom", "bottom-left", "bottom-right" }

   IF HB_ISSTRING( cText )
      ::oVideo:marquee:text := cText
      IF HB_ISSTRING( cPos )
         nAt := ASCAN( acPos, { | i | i == cPos } )
      ENDIF
      IF HB_ISNUMERIC( nTimeout )
         ::oVideo:marquee:timeout := nTimeout
      ENDIF
      IF HB_ISNUMERIC( nSize )
         ::oVideo:marquee:size := nSize
      ENDIF
      ::oVideo:marquee:position := acPos[ nAt ]
      ::oVideo:marquee:enable()
   ENDIF
RETURN NIL

METHOD Time2MiliSec( cTime ) CLASS FWTVlc
LOCAL nMiliSec := 0
LOCAL nH, nM, nS, nT

   IF !EMPTY( cTime )
      nH = VAL( SUBSTR( cTime, 1, 2 ) )
      nM = VAL( SUBSTR( cTime, 4, 2 ) )
      nS = VAL( SUBSTR( cTime, 7, 2 ) )
      nT = ( nH * 3600 ) + ( nM * 60 ) + nS
      nMiliSec := nT * 1000
   ENDIF
RETURN nMiliSec

METHOD MiliSec2Time( nMiliSec ) CLASS FWTVlc
LOCAL cTime := "00:00:00"
LOCAL nHora, nMinuto, nSegundo

   IF nMiliSec > 0
      nMiliSec := INT( nMiliSec / 1000 )
      nHora := INT( nMiliSec / 3600 )
      nMiliSec := nMiliSec - ( nHora * 3600 )
      nMinuto := INT( nMiliSec / 60 )
      nSegundo := nMiliSec - ( nMinuto * 60 )
      cTime := STRZERO( nHora, 2 ) + ":" + STRZERO( nMinuto, 2 ) + ":" + STRZERO( nSegundo, 2 )
   ENDIF
RETURN cTime

METHOD VLCevent( cEvent, aParams ) CLASS FWTVlc

   //   now by internal TIMER
   //   ::VLCstate()              // check Play-State
   //   SysRefresh()

   DO CASE
      CASE cEvent == "MediaPlayerNothingSpecial"
         // ::Marquee( "NothingSpecial", "top-right" )
      CASE cEvent == "MediaPlayerOpening"
         // ::Marquee( "Opening", "top-right" )
      CASE cEvent == "MediaPlayerBuffering"
         // ::Marquee( "Buffering", "top-right" )
      CASE cEvent == "MediaPlayerPlaying"
         // ::Marquee( "Record : " + LTRIM( STR( ::nRECNO ) ), "top-right" )

      CASE cEvent == "MediaPlayerPaused"
      CASE cEvent == "MediaPlayerForward"
      CASE cEvent == "MediaPlayerBackward"
      CASE cEvent == "MediaPlayerStopped"

      CASE cEvent == "MediaPlayerEncounteredError"
*         onDummy( TIME(), "MediaPlayer Encountered Error" )
         MsgInfo( "MediaPlayer Encountered Error" + CRLF + ::cFileName )
         //  ::Play_Next()

      CASE cEvent == "MediaPlayerEndReached"
*         onDummy( TIME(), "MediaPlayer End Reached" )
         // MsgInfo( "MediaPlayer End Reached" )
         //  ::Play_Next()

      CASE cEvent == "MediaPlayerStopAsyncDone"
      CASE cEvent == "MediaPlayerTimeChanged"
      CASE cEvent == "MediaPlayerPositionChanged"
      CASE cEvent == "MediaPlayerSeekableChanged"
      CASE cEvent == "MediaPlayerPausableChanged"
      CASE cEvent == "MediaPlayerMediaChanged"
      CASE cEvent == "MediaPlayerTitleChanged"
      CASE cEvent == "MediaPlayerLengthChanged"
      CASE cEvent == "MediaPlayerChapterChanged"
      CASE cEvent == "MediaPlayerVout"
      CASE cEvent == "MediaPlayerMuted"
      CASE cEvent == "MediaPlayerUnmuted"
      CASE cEvent == "MediaPlayerAudioVolume"

      CASE cEvent == "Click"
      CASE cEvent == "DblClick"
         // MsgInfo( "DblClick " + VAR2CHAR( aParams ) )
         //  ::ovideo:toggleFullscreen()

      CASE cEvent == "KeyDown"
         // MsgInfo( "KeyDown " + VAR2CHAR( aParams ) )
*         OnDummy( TIME(), "KeyDown  ", VAR2CHAR( aParams ), VK_F9 )

      CASE cEvent == "KeyPress"
         // MsgInfo( "KeyPress " + VAR2CHAR( aParams ) )
*         OnDummy( TIME(), "KeyPress ", VAR2CHAR( aParams ), VK_F9 )
         IF aParams[ 1 ] = VK_F9
            ::ovideo:toggleFullscreen()
         ENDIF

      CASE cEvent == "KeyUp"

      CASE cEvent == "MouseDown"
         // MsgInfo( "MouseDown " + VAR2CHAR( aParams ), VALTYPE(aParams) )
         IF aParams[ 1 ] = MK_RBUTTON
            IF !EMPTY( ::bRClicked )
               EVAL( ::bRClicked, aParams[ 4 ], aParams[ 3 ] )
            ENDIF
         ENDIF
      CASE cEvent == "MouseMove"
      CASE cEvent == "MouseUp"
   ENDCASE
   SysRefresh()

RETURN NIL

METHOD VLCstate() CLASS FWTVlc
LOCAL bOldError  := ERRORBLOCK( { | e | BREAK( e ) } )
LOCAL nPosi      := 0
LOCAL cPosi
LOCAL oError
LOCAL nDuration
LOCAL xKey
LOCAL nPlayState

   BEGIN SEQUENCE
      IF ::lRun = .T.
         nPlayState := ::State()

         DO CASE
            CASE nPlayState = VLC_INPUT_STATE_IDLE
            CASE nPlayState = VLC_INPUT_STATE_OPENING
            CASE nPlayState = VLC_INPUT_STATE_BUFFERING
            CASE nPlayState = VLC_INPUT_STATE_PLAYING

               IF ::lStream = .F.

                  cPosi := ::GetTimeStr()
                  //  nPosi := TIMETOSEC( cPosi )
                  nPosi := ::Time2MiliSec( cPosi )

                  nDuration := INT( ::GetLength() / 1000 )

                  IF !EMPTY( nDuration )
                     IF nPosi >= nDuration - 1
*                        OnDummy( TIME(), "EOF", nPosi, nDuration )

                        ::lRun := .F.
                        ::Stop()
                        ::SetTime( 0 )

                        IF ::IsFullScreen()
                           ::ovideo:toggleFullscreen()
                        ENDIF

                        DO CASE
                           CASE ::lLoop = .T.
                              ::Play()
                           CASE ::lEndless = .T.
                              //   ::Play_Next()
                        ENDCASE
                     ENDIF
                  ENDIF

               ENDIF

            CASE nPlayState = VLC_INPUT_STATE_PAUSED
            CASE nPlayState = VLC_INPUT_STATE_STOPPING
            CASE nPlayState = VLC_INPUT_STATE_ENDED
            CASE nPlayState = VLC_INPUT_STATE_ERROR
         ENDCASE
      ENDIF
   END SEQUENCE
   ERRORBLOCK( bOldError )
RETURN NIL

METHOD CheckFullScreen() CLASS FWTVlc
LOCAL cFile      := "Start"
STATIC clastFile := ""

   IF ::oVideo:fullscreen = .T.
      IF ::oAudio:mute == .T.
         ::oAudio:toggleMute()

         ::Marquee( "Record : " + LTRIM( STR( ::nRECNO ) ), "top-right", 1000 * 5 )
      ENDIF

      cFile := ::cFileName
      IF clastFile <> cFile
         clastFile := cFile
         // CopyToClipboard( cFile )
      ENDIF
   ELSE
      IF ::oAudio:mute == .F.
         ::oAudio:toggleMute()
      ENDIF
   ENDIF
RETURN NIL

METHOD Play_Next() CLASS FWTVlc
LOCAL cItem := ""
   IF !EMPTY( ::bPlayNext )
      cItem := EVAL( ::bPlayNext )
      IF !EMPTY( cItem )
         ::SetFile( cItem )
         ::Play()
      ENDIF
   ENDIF
RETURN NIL

*+ EOF: FWVLC.PRG


ReadM3U.PRG
Code: Select all  Expand view  RUN
*+--------------------------------------------------------------------
*+
*+ Source Module => c:\fwh\0\IPTV\READM3U.PRG
*+
*+    Copyright(C) 1983-2022 by Auge & Ohr
*+
*+    Functions: Procedure ImportM3U()
*+               Static Procedure DoReadM3U()
*+               Static Procedure DoCheck()
*+               Static Procedure ReadExtinf()
*+               Static Procedure ReadName()
*+               Static Procedure ReadLogo()
*+               Static Procedure ReadGroup()
*+               Static Procedure Read_Country()
*+               Static Procedure Read_Language()
*+               Static Procedure ReadTVID()
*+               Static Procedure ReadChNo()
*+               Static Procedure ReadRadio()
*+               Static Procedure ReadShift()
*+               Static Procedure CheckAddAfter()
*+               Static Function CalcPos()
*+
*+       Tables: USE (cDBF) EXCLUSIVE ALIAS "IMPORT" VIA "DBFCDX"
*+
*+    Reformatted by Click! 2.05.40 on Aug-2-2022 at  9:10 pm
*+
*+--------------------------------------------------------------------

#include "fivewin.ch"
#include "common.ch"

*+--------------------------------------------------------------------
*+
*+    Procedure ImportM3U()
*+
*+    Called from ( fwiptv.prg )   1 - static function buildmenu()
*+
*+--------------------------------------------------------------------
*+
PROCEDURE ImportM3U( oBrw )
LOCAL cFile, nMaxLen, nEvery, nCount, cDBF
LOCAL cTitle   := "Open Playlist"
LOCAL nStart   := 1
LOCAL zPath    := hb_DirBase()
LOCAL aFilters := { { "M3U Playlist", "*.M3U" } }

   //   cFile := Getfile( aFilters, cTitle, zPath, .F., .F., 1 )
   cFile := cGetfile( "M3U Playlist|*.M3U|" + "all Files|*.*", cTitle,, zPath )

   IF .NOT. EMPTY( cFile )
      IF ".M3U" $ UPPER( cFile )
         DoReadM3U( cFile )

         cDBF := STRTRAN( UPPER( cFile ), ".M3U", ".DBF" )
         IF FILE( cDBF )
            IF MsgYesNo( "Append " + cDBF + " ?" )
               SELECT 1
               APPEND FROM ( cDBF )
               GO TOP
               oBrw:SetFocus()
               oBrw:Refresh()
            ENDIF
         ENDIF
      ENDIF
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure DoReadM3U()
*+
*+    Called from ( readm3u.prg )   1 - procedure importm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE DoReadM3U( cFile )
LOCAL cAppdir     := hb_DirBase()
LOCAL lTVgroup    := .F.
LOCAL lTVName     := .F.
LOCAL lTVid       := .F.
LOCAL cMarker     := CHR( 10 ) + CHR( 10 )
LOCAL cMemo, aLines, n, nMax, nPosi, cLine, cDBF, nEvery
LOCAL cTVname
LOCAL lTVradio
LOCAL cTVlogo
LOCAL cTVid
LOCAL cTVchno
LOCAL cTVgroup
LOCAL cTVurl
LOCAL cTVCountry
LOCAL cTVLanguage
LOCAL cTVshift
LOCAL aRow, nRow, nComma

   IF FILE( cFile )

      SELECT 2
      cDBF := STRTRAN( UPPER( cFile ), ".M3U", ".DBF" )
      IF !FILE( cDBF )
         CreateDbf( cDBF )
      ENDIF
      USE (cDBF) EXCLUSIVE ALIAS "IMPORT" VIA "DBFCDX"
      ZAP

      cMemo := HB_MEMOREAD( cFile )

      cMarker := CHR( 10 ) + CHR( 13 )
      cMemo := STRTRAN( cMemo, CHR( 10 ), cMarker )

      aLines := AtInside( cMarker, cMemo )
      // aLines := HB_ATOKENS( cMemo, cMarker )

      nMax := LEN( aLines )
      nEvery := ROUND( nMax / 100, 0 )

      // SetProperty( "IPTVMAIN", "ProgressBar_1", "Value", 0 )
      // DoMethod( "IPTVMAIN", "Progressbar_1", "show" )

      FOR n := 1 TO nMax
         cLine := TRIM( aLines[ n ] )
         IF EMPTY( cLine )
            LOOP
         ENDIF
         IF "EXTM3U" $ cLine
            LOOP
         ENDIF

         cTVname := ""
         lTVradio := .F.
         cTVlogo := ""
         cTVid := ""
         cTVchno := ""
         cTVgroup := ""
         cTVurl := ""
         cTVCountry := ""
         cTVLanguage := ""
         cTVshift := ""

         IF SUBSTR( LOWER( cLine ), 1, 4 ) = "http"
            cTVurl := cLine
            // CheckAddAfter( @cTVurl )
            REPLACE FIELD->TVURL WITH STRTRAN( cTVurl, CHR( 34 ), "" )
            LOOP
         ELSE
            lTVgroup := .F.
            aRow := AtInside( " ", cLine )
            FOR nRow := 1 TO LEN( aRow )
               cLine := aRow[ nRow ]
               DO CASE
                  CASE EMPTY( cLine )

                  CASE "EXTINF:-1," $ cLine
                     lTVName := .T.
                     ReadExtinf( @cTVname, cLine, @lTVName )
                     lTVgroup := .F.
                     lTVid := .F.

                  CASE "EXTINF:-1" $ cLine
                     lTVName := .F.
                     lTVgroup := .F.
                     lTVid := .F.

                  CASE "EXTINF:0" $ cLine
                     lTVName := .F.
                     ReadExtinf( @cTVname, cLine, @lTVName )
                     lTVgroup := .F.
                     lTVid := .F.

                  CASE AT( "tvg-name=", cLine ) > 0
                     lTVName := .T.
                     ReadName( @cTVname, cLine, @lTVName )
                     lTVgroup := .F.
                     lTVid := .F.

                  CASE AT( "tvg-logo=", cLine ) > 0
                     lTVName := .T.
                     ReadLogo( @cTVlogo, cLine, @cTVname, @lTVName )
                     lTVgroup := .F.
                     lTVid := .F.

                  CASE AT( "tvg-language=", cLine ) > 0
                     Read_Language( @cTVLanguage, cLine )
                     lTVName := .F.
                     lTVgroup := .F.
                     lTVid := .F.

                  CASE AT( "tvg-country=", cLine ) > 0
                     Read_Country( @cTVCountry, cLine )
                     lTVName := .F.
                     lTVgroup := .F.
                     lTVid := .F.

                  CASE AT( "tvg-id=", cLine ) > 0
                     lTVid := .T.
                     ReadTVID( @cTVid, cLine, @cTVName )
                     lTVgroup := .F.
                     lTVName := .F.

                  CASE AT( "tvg-chno=", cLine ) > 0
                     ReadChNo( @cTVchno, cLine )
                     lTVgroup := .F.
                     lTVName := .F.
                     lTVid := .F.

                  CASE AT( "radio=", cLine ) > 0
                     ReadRadio( @lTVradio, cLine )
                     lTVgroup := .F.
                     lTVName := .F.
                     lTVid := .F.

                  CASE AT( "group-title=", cLine ) > 0
                     lTVgroup := .T.
                     lTVName := .F.
                     ReadGroup( @cTVgroup, cLine, @cTVname, @lTVgroup, @lTVName )
                     lTVid := .F.

                  CASE AT( "tvg-shift", cLine ) > 0
                     ReadShift( @cTVshift, cLine )
                     lTVgroup := .F.
                     lTVName := .F.
                     lTVid := .F.

                  OTHERWISE
                     IF lTVgroup = .T.
                        cTVgroup += " " + cLine
                     ENDIF
                     IF lTVName = .T.
                        cTVname += " " + cLine
                     ENDIF
                     IF lTVid = .T.
                        cTVid += " " + cLine
                     ENDIF
               ENDCASE
            NEXT
         ENDIF

         DoCheck( @cTVname, @cTVlogo, @cTVurl, @cTVgroup )

         APPEND BLANK
         IF EMPTY( cTVname )
            // REPLACE FIELD->TVNAME WITH STRTRAN( UPPER(cTVgroup), CHR( 34 ), "" )
         ELSE
            REPLACE FIELD->TVNAME WITH LTRIM( STRTRAN( UPPER( cTVname ), CHR( 34 ), "" ) )
         ENDIF
         IF EMPTY( VAL( cTVchno ) )
            REPLACE FIELD->TVCHNO WITH RECNO()
         ELSE
            REPLACE FIELD->TVCHNO WITH VAL( STRTRAN( cTVchno, CHR( 34 ), "" ) )
         ENDIF
         REPLACE FIELD->TVID WITH STRTRAN( cTVid, CHR( 34 ), "" )

         REPLACE FIELD->TVLOGO WITH STRTRAN( cTVlogo, CHR( 34 ), "" )

         // CheckAddAfter( @cTVurl )

         // can be longer > 255 so use MEMO
         REPLACE FIELD->TVURL WITH STRTRAN( cTVurl, CHR( 34 ), "" )

         REPLACE FIELD->TVLANG WITH STRTRAN( UPPER( cTVLanguage ), CHR( 34 ), "" )
         REPLACE FIELD->TVGROUP WITH STRTRAN( UPPER( cTVgroup ), CHR( 34 ), "" )
         REPLACE FIELD->TVRADIO WITH lTVradio

         // IF ( n % nEvery ) = 0
         //    SetProperty( "IPTVMAIN", "ProgressBar_1", "Value", CalcPos( n, nMax ) )
         //    DO EVENTS
         //     SysRefresh()
         // ENDIF

      NEXT

      // DoMethod( "IPTVMAIN", "Progressbar_1", "hide" )

   ENDIF

   IF USED()
      CLOSE
   ENDIF

   SELECT 1

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure DoCheck()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE DoCheck( cTVname, cTVlogo, cTVurl, cTVgroup )
LOCAL nComma

   cTVname := ALLTRIM( cTVname )
   cTVlogo := ALLTRIM( cTVlogo )
   cTVurl := ALLTRIM( cTVurl )
   cTVgroup := ALLTRIM( cTVgroup )

   nComma := AT( ",", cTVlogo )
   IF nComma > 0
      IF EMPTY( cTVname )
         cTVname := SUBSTR( cTVgroup, nComma + 1 )
      ENDIF
      cTVlogo := SUBSTR( cTVlogo, 1, nComma - 1 )
   ENDIF

   cTVurl := STRTRAN( cTVurl, CRLF, "" )
   cTVurl := STRTRAN( cTVurl, CHR( 0 ), "" )
   nComma := AT( ",", cTVurl )
   IF nComma > 0
      IF EMPTY( cTVname )
         cTVname := SUBSTR( cTVgroup, nComma + 1 )
      ENDIF
      cTVurl := SUBSTR( cTVurl, 1, nComma - 1 )
   ENDIF

   nComma := AT( ",", cTVgroup )
   IF nComma > 0
      IF EMPTY( cTVname )
         cTVname := SUBSTR( cTVgroup, nComma + 1 )
      ENDIF
      cTVgroup := SUBSTR( cTVgroup, 1, nComma - 1 )
   ENDIF

   nComma := AT( ",", cTVname )
   IF nComma > 0
      cTVname := SUBSTR( cTVname, 1, nComma - 1 )
   ENDIF

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ReadExtinf()
*+
*+    Called from ( readm3u.prg )   2 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ReadExtinf( cTVname, cLine, lTVName )
LOCAL nComma
   nComma := AT( ",", cLine )
   IF nComma > 0
      cTVname := SUBSTR( cLine, nComma + 1 )
      lTVName := .T.
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ReadName()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ReadName( cTVname, cLine, lTVName )
LOCAL nComma
LOCAL nPosi  := AT( "tvg-name=", cLine )
   IF nPosi > 0
      cTVname := SUBSTR( cLine, nPosi + 9 )

      nComma := AT( ",", cTVname )
      IF nComma > 0
         cTVname := SUBSTR( cTVname, 1, nComma - 1 )
         lTVName := .T.
      ENDIF
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ReadLogo()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ReadLogo( cTVlogo, cLine, cTVname )
LOCAL nComma
LOCAL nPosi  := AT( "tvg-logo=", cLine )
   IF nPosi > 0
      cTVlogo := SUBSTR( cLine, nPosi + 9 )
      nComma := AT( ",", cTVlogo )
      IF nComma > 0
         IF EMPTY( cTVname )
            cTVname := SUBSTR( cTVlogo, nComma + 1 )
            cTVname := STRTRAN( cTVname, ".", " " )
            cTVname := ALLTRIM( cTVname )
         ENDIF
         cTVlogo := SUBSTR( cTVlogo, 1, nComma - 1 )
      ENDIF
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ReadGroup()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ReadGroup( cTVgroup, cLine, cTVname, lTVgroup, lTVName )
LOCAL nComma
LOCAL nPosi  := AT( "group-title=", cLine )
   IF nPosi > 0
      cTVgroup := SUBSTR( cLine, nPosi + 12 )
      nComma := AT( ",", cTVgroup )
      IF nComma > 0
         lTVgroup := .F.
         lTVName := .T.
         cTVname := SUBSTR( cTVgroup, nComma + 1 )
         cTVgroup := SUBSTR( cTVgroup, 1, nComma - 1 )
      ENDIF
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure Read_Country()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE Read_Country( cTVCountry, cLine )
LOCAL nPosi := AT( "tvg-country=", cLine )
   IF nPosi > 0
      cTVCountry := SUBSTR( cLine, nPosi + 12 )
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure Read_Language()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE Read_Language( cTVLanguage, cLine )
LOCAL nPosi := AT( "tvg-language=", cLine )
   IF nPosi > 0
      cTVLanguage := SUBSTR( cLine, nPosi + 13 )
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ReadTVID()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ReadTVID( cTVid, cLine, cTVName )
LOCAL nPosi := AT( "tvg-id=", cLine )
   IF nPosi > 0
      cTVid := SUBSTR( cLine, nPosi + 7 )
      IF EMPTY( cTVName )
         cTVName := UPPER( cTVid )
      ENDIF
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ReadChNo()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ReadChNo( cTVchno, cLine )
LOCAL nPosi := AT( "tvg-chno=", cLine )
   IF nPosi > 0
      cTVchno := SUBSTR( cLine, nPosi + 9 )
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ReadRadio()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ReadRadio( lTVradio, cLine )
LOCAL nPosi := AT( "radio=", cLine )
   IF nPosi > 0
      lTVradio := .T.
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ReadShift()
*+
*+    Called from ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ReadShift( cTVshift, cLine )
LOCAL nPosi := AT( "tvg-shift", cLine )
   IF nPosi > 0
      cTVshift := SUBSTR( cLine, nPosi + 9 )
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure CheckAddAfter()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE CheckAddAfter( cTVurl )
LOCAL nPosi := RAT( ".m3u8", cTVurl )
LOCAL nLen  := LEN( TRIM( cTVurl ) )

   IF nPosi > 0
      IF nPosi + 4 < nLen
         cTVurl := SUBSTR( cTVurl, 1, nPosi + 4 )
      ENDIF
   ENDIF

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Function CalcPos()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION CalcPos( nValue, iMax )                               // for Progressbar
LOCAL nRet   := 0
LOCAL nEvery
LOCAL xScale

   IF iMax < 100
      nEvery := 100 / iMax
      nRet := nValue * nEvery
   ELSE
      nEvery := INT( iMax / 100 )
      xScale := iMax * nEvery                                         // Scale to 100%
      nRet := iMax / xScale * nValue
   ENDIF

RETURN ROUND( nRet, 0 )

*+ EOF: READM3U.PRG


! Note : work in SELECT 2 Workspace while MAIN in SELECT 1

fwIPTV.PRG
Code: Select all  Expand view  RUN
Your message contains 65872 characters. The maximum number of allowed characters is 60000.


compile with

for BCC 32 Bit
Code: Select all  Expand view  RUN
BUILDh.BAT FWIPTV /DUSE_INC


for MSVC 64 Bit
Code: Select all  Expand view  RUN
BUILDh64.BAT FWIPTV /DUSE_INC


for BCC 32 Bit you can also use Go.BAT / FWIPTV.MAK
Code: Select all  Expand view  RUN
set BCDIR=c:\bcc7
%BCDIR%\bin\make -fFWIPTV.MAK
if errorlevel 0 FWIPTV.exe


Code: Select all  Expand view  RUN
HBDIR=C:\HARBOUR
BCDIR=C:\BCC7
FWDIR=C:\FWH

#change these paths as needed
.path.obj=.\objh

PRG           = \
FWIPTV.PRG      \
FWVLC.PRG       \
READM3U.PRG

PROJECT     : FWIPTV.EXE

FWIPTV.EXE : $(PRG:.PRG=.OBJ) FWIPTV.res
   echo off
   echo $(BCDIR)\lib\c0w32.obj + > b32.bc
   echo .\objh\FWIPTV.obj .\objh\FWVLC.obj .\objh\READM3U.obj, + >> b32.bc
   echo FWIPTV.exe, + >> b32.bc
   echo FWIPTV.map, + >> b32.bc

   echo $(FWDIR)\lib\FiveH.lib $(FWDIR)\lib\FiveHC.lib $(FWDIR)\lib\libmysql.lib + >> b32.bc
   echo $(FWDIR)\lib\hbpgsql.lib $(FWDIR)\lib\libpq.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbhpdf.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\libhpdf.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\png.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbwin.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\gtgui.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbrtl.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbvm.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hblang.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbmacro.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbrdd.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\rddntx.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\rddcdx.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\rddfpt.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbsix.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbdebug.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbcommon.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbpp.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbcpage.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbcplr.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbct.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbpcre.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\xhb.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbziparc.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbmzip.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbzlib.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\minizip.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbusrrdd.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbtip.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbzebra.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\hbcurl.lib + >> b32.bc
   echo $(HBDIR)\lib\win\bcc\libcurl.lib + >> b32.bc
   echo $(FWDIR)\lib\dolphin.lib + >> b32.bc
   echo $(BCDIR)\lib\cw32.lib + >> b32.bc
   echo $(BCDIR)\lib\uuid.lib + >> b32.bc
   echo $(BCDIR)\lib\import32.lib + >> b32.bc
   echo $(BCDIR)\lib\ws2_32.lib + >> b32.bc
   echo $(BCDIR)\lib\psdk\odbc32.lib + >> b32.bc
   echo $(BCDIR)\lib\psdk\nddeapi.lib + >> b32.bc
   echo $(BCDIR)\lib\psdk\iphlpapi.lib + >> b32.bc
   echo $(BCDIR)\lib\psdk\msimg32.lib + >> b32.bc
   echo $(BCDIR)\lib\psdk\psapi.lib + >> b32.bc
   echo $(BCDIR)\lib\psdk\rasapi32.lib + >> b32.bc
   echo $(BCDIR)\lib\psdk\gdiplus.lib + >> b32.bc
   echo $(BCDIR)\lib\psdk\shell32.lib , >> b32.bc

   IF EXIST FWIPTV.res echo FWIPTV.res >> b32.bc
   $(BCDIR)\bin\ilink32 -Gn -aa -Tpe -s @b32.bc
   del b32.bc

.PRG.OBJ:
  if not exist objh mkdir objh
  $(HBDIR)\bin\harbour $< /L /N /W /Oobjh\ /I$(FWDIR)\include;$(HBDIR)\include
  $(BCDIR)\bin\bcc32 -c -tWM -I$(HBDIR)\include -oobjh\$& objh\$&.c

FWIPTV.res : FWIPTV.rc
   $(BCDIR)\bin\brc32 -r FWIPTV.rc

---

Source is based on MiniGUI Extended Verson c:\minigui\Samples\vlc\myplayer.prg

* VideoLan VLC ActiveX demo
*
* Author: Carlos Vargas <cvargaz[at]donboscocorp.com
>

i have not used all Methode for IP-TV Player but add new Method
Code: Select all  Expand view  RUN
  METHOD VLCevent( cEvent, aParams )
   METHOD VLCstate()

and Property
Code: Select all  Expand view  RUN
  DATA lStream
   DATA lLoop
   DATA lEndless
   DATA bRClicked, bMenu, bPlayNext


in VLCevent() you can get Keyboard / Mouse "down" from ActiveX e.g. right-click for POPUP Menu

---

normal a "Stream" have no "Duration", it run endless
when play a Media it will end after "Duration" and here VLCstate() can help

Code: Select all  Expand view  RUN
           CASE nPlayState = VLC_INPUT_STATE_PLAYING
               // if File not "Stream"        
               IF ::lStream = .F.
                  cPosi := ::GetTimeStr()
                  nPosi := TIMETOSEC( cPosi )
                  nDuration := INT( ::GetLength() / 1000 )
                  IF !EMPTY( nDuration )
                     IF nPosi >= nDuration - 1


just before EOF of Media i can call "NEXT" or "LOOP"
Code: Select all  Expand view  RUN
                       DO CASE
                           CASE ::lLoop = .T.
                              ::Play()
                           CASE ::lEndless = .T.
                              ::Play_Next()
                        ENDCASE


some *.M3U does not contain a "Stream" but a "Media"

---

Codeblock bMenu

Code: Select all  Expand view  RUN
     // Codeblock for Menu "over" VLC ( not when playing )
      oVLCX:bMenu := { | nRow, nCol | VLCmenu( nRow, nCol, oDlg, 1 ) }


and will be use "internal"
Code: Select all  Expand view  RUN
      // ActiveX have no Property bRClicked so ADD it
      ::bRClicked = { | nRow, nCol | EVAL( ::bMenu, nRow, nCol, ::oParent, ::nIndex ) }


! Note : you can use multi Instanze of VLC ( ::nIndex ) which have "own" right-click Menu

Codeblock bPlayNext

Code: Select all  Expand view  RUN
     // Codeblock for Function to load next Item. MUST return String to load !
      oVLCX:bPlayNext := { || DoSkipNext() ) }


Code: Select all  Expand view  RUN
METHOD Play_Next()
LOCAL cItem := ""
   IF !EMPTY( ::bPlayNext )
      cItem := EVAL( ::bPlayNext )
      IF !EMPTY(cItem)
         ::SetFile(cItem)
         ::Play()
      ENDIF
   ENDIF
RETURN NIL


---

when start App it will create new DBF (if not Exist)

! Note : as URL can be > 255 you need a MEMO to be "compatible".
i use harbour Setting
Code: Select all  Expand view  RUN
PROCEDURE CreateDbf( datei )
   ...
   AADD( field_list, { "TVURL", "C", 640, 0 } )


download from above HMG-Forum "Playlist" and "Import" it ( see MENU of App )

you need to re-start to "fill" COMBOBOX with UNIQUE FIELD->TVGROUP

you can start with different DBF as Parameter where you have import Playlist
Index will create new every Time

---

you can Dblclick or ENTER in XBROWSE to start "Stream" ... it can take some Time until connect
when "Stream" it "playing" you can DblCLick on VLC or use F9 for "Fullscreen". ESC will return to normal Size

you can re-size WINDOW but XBROWSE FONT Size will "stay".
use CTRL and "+" of NumPad (or CTRL + Wheel) to "zoom" XBROWSE

btw. TIMER in MAIN using CheckFullScreen() will switch Sound ON when Maximize and OFF when Normalize

XBROWSE have implement increment search

---

todo : "mark" multiple Channel to display multiple VLC-Player at same Time on Screen
(Depend on Hardware and Connection Speed)
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: CLASS fwTVCL for IP-TV

Postby Jimmy » Tue Aug 02, 2022 8:02 pm

continue

fwIPTV.PRG
Code: Select all  Expand view  RUN
*+--------------------------------------------------------------------
*+
*+ Source Module => c:\fwh\0\IPTV\FWIPTV.PRG
*+
*+    Copyright(C) 1983-2022 by Auge & Ohr
*+
*+    Functions: Procedure Main()
*+               Procedure VLCmenu()
*+               Static Procedure DoInit()
*+               Static Function BuildMenu()
*+               Static Procedure DoFillCombo()
*+               Static Procedure ChangeCombo()
*+               Static Procedure ChangeFilter()
*+               Static Procedure DoReSize()
*+               Procedure CreateDbf()
*+               Static Procedure CreateIndex()
*+               Static Procedure SwitchFull()
*+               Procedure onDummy()
*+               Static Procedure OpenSndVol()
*+               Static Procedure Do_Store()
*+               Static Procedure Do_Say()
*+               Static Procedure DoLocate()
*+               Static Function DoSeekInc()
*+               Static Function DownloadFromWWW()
*+               Static Function IsProcessRun()
*+               Function VAR2CHAR()
*+               Function AtInside()
*+               Static Function DoShow()
*+               Static Function OwnerDrawItem()
*+
*+       Tables: USE (cDBF) ALIAS "TVURL" EXCLUSIVE VIA "DBFCDX"
*+
*+    Reformatted by Click! 2.05.40 on Aug-2-2022 at  9:10 pm
*+
*+--------------------------------------------------------------------

#include "fivewin.ch"
#include "common.ch"

#define SW_SHOW               5

#define COLOR_HIGHLIGHT      13
#define COLOR_HIGHLIGHTTEXT  14
#define COLOR_WINDOW          5
#define COLOR_WINDOWTEXT      6

REQUEST DBFCDX
REQUEST DBFNTX

STATIC oDlg, oBrw, oImage, oFont
STATIC lDebug    := .T.
STATIC aItems    := { "Hello", "World" }
STATIC oCombo
STATIC oVLCX
STATIC oControl
STATIC oplaylist
STATIC oVideo

STATIC cVar1   := "Name    "
STATIC cVar2   := "Channel "
STATIC cVar3   := "GERMAN  "
STATIC cVar4   := "Logo    "
STATIC cVar5   := "URL     "
STATIC cVar6   := "Group   "
STATIC nRadio  := 1
STATIC cCombo  := "all Record"
STATIC cLastCB := "all Record"

STATIC oGet1
STATIC oGet2
STATIC oGet3
STATIC oGet4
STATIC oGet5
STATIC oGet6
STATIC oRadio

STATIC cVersion := "v0.0.15"

*+--------------------------------------------------------------------
*+
*+    Procedure Main()
*+
*+--------------------------------------------------------------------
*+
PROCEDURE Main( cDBF )
LOCAL oCol, oTimer
LOCAL cAppdir := hb_DirBase()
LOCAL aRect   := { 0, 0, 0, 0 }

   DEFAULT cDBF TO "TVURL.DBF"

   SET ALTER TO "_LOGIT2.TXT"
*   OnDummy( TIME(), "Start˙App" )

   IF !FILE( cDBF )
      CreateDbf( cDBF )
   ENDIF

   SELECT 1
   USE (cDBF) ALIAS "TVURL" EXCLUSIVE VIA "DBFCDX"

   // create temporary Index
   CreateIndex( "TVURL.CDX" )
   SET INDEX TO ( "TVURL.CDX" )
   ORDSETFOCUS( "TVCHANNEL" )

   DEFINE FONT oFont NAME "TAHOMA" SIZE 0, - 12
#IFDEF __HMG__
   END FONT
#ENDIF

   DEFINE WINDOW oDlg FROM 0, 0 TO 600, 800 + 16 PIXEL TITLE "TVIP " + cVersion ICON "A1MAIN" MENU BuildMenu()

      // Syntax : oDlg, nRow, nCol, nWidth, nHeight, nIndex, oFont
      oVLCX := FWTVlc() :New( oDlg, 0, 0, 400, 300, 1, oFont )

      // Use Stream ( no Duration for EOF )
      oVLCX:lStream = .T.

      // Codeblock for Menu "over" VLC ( not when playing )
      oVLCX:bMenu := { | nRow, nCol | VLCmenu( nRow, nCol, oDlg, 1 ) }

      // Codeblock for Function to load next Item.
      // MUST return String to load !
      oVLCX:bPlayNext := { || NIL }

      @ 310, 010 COMBOBOX oCombo VAR cCombo ITEMS aItems SIZE 300, 300 PIXEL OF oDlg ON CHANGE ChangeCombo() ;
              OWNERDRAW OwnerDrawItem( Self, nIdCtl, oItemStruct )

      // need to "fill" here for OWNERDRAW
      DoInit()

      @ 310, 330 XIMAGE oImage SIZE 64, 64 OF oDlg                    // NOBORDER
      oImage:lBmpTransparent := .F.

      @ 340, 010 SAY "Name    " GET oGet1 VAR cVar1 SIZE 290, 026 PIXEL OF oDlg FONT oFont
      @ 370, 010 SAY "Channel " GET oGet2 VAR cVar2 SIZE 120, 026 PIXEL OF oDlg FONT oFont
      @ 410, 010 SAY "GERMAN  " GET oGet3 VAR cVar3 SIZE 370, 026 PIXEL OF oDlg FONT oFont
      @ 440, 010 SAY "Logo    " GET oGet4 VAR cVar4 SIZE 370, 026 PIXEL OF oDlg FONT oFont
      @ 470, 010 SAY "URL     " GET oGet5 VAR cVar5 SIZE 370, 026 PIXEL OF oDlg FONT oFont
      @ 500, 010 SAY "Group   " GET oGet6 VAR cVar6 SIZE 370, 026 PIXEL OF oDlg FONT oFont

      @ 370, 250 RADIO oRadio VAR nRadio ITEMS "TV", "Radio" OF oDlg SIZE 48, 16 PIXEL ON CHANGE ChangeFilter()

      @ 000, 400 XBROWSE oBrw SIZE 400, 540 PIXEL OF oDlg ON DBLCLICK DoShow( TVURL->TVURL ) FONT oFont ALIAS 'TVURL'

      ADD oCol TO oBrw DATA TVURL->TVCHNO HEADER "Channel"
      ADD oCol TO oBrw DATA TVURL->TVNAME HEADER "Name"

      oBrw:nMoveType := 5                                             // no Move
      oBrw:bKeyDown := { | nKey | IF( nKey == VK_RETURN, DoShow( TVURL->TVURL ), nil ) }
      oBrw:bLDblClick = { || DoShow( TVURL->TVURL ) }
      oBrw:bchange := { || Do_Store() }
      oBrw:bSeek := { | cSeek | DoSeekInc( cSeek ) }

      oBrw:CreateFromCode()

      SETKEY( VK_F1, { || MsgInfo( "under construction ..." ) } )
      // SETKEY( VK_F1, nil )
      //  SETKEY( VK_F7, { || DoLocate() } )
      SETKEY( VK_F9, { || SwitchFull() } )
      // SETKEY( ASC( "F" ), { || SwitchFull() } )
      // SETKEY( ASC( "I" ), { || ImportM3U( oBrw ) } )
      SETKEY( VK_ESCAPE, { || oVLCX:Stop() } )

      // TIMER only "need" to switch Sound ON / OFF in thos App
      DEFINE TIMER oTimer OF oDlg ACTION oVLCX:CheckFullScreen() INTERVAL 1000
      ACTIVATE TIMER oTimer

#IFDEF __HMG__
   END WINDOW
#ENDIF

   ChangeFilter()                                                     // does SET FILTER

   Do_Store()                                                         // DBF Field -> cVar
   oBrw:SetFocus()

   oDlg:Cargo := { oDlg:nWidth, oDlg:nHeight, 18 }
   AEVAL( oDlg:aControls, { | o | o:Cargo := { o:nTop, o:nLeft, o:nWidth, o:nHeight, 18 } } )                                               // o:oFont:nHeight

   ACTIVATE WINDOW oDlg CENTERED ;
           ON RESIZE DoReSize()

   // does not work with OWNERDRAW
   //           ON INIT DoInit() ;

   // EXCESS RELEASE OF FONT TAHOMA[ hFont : 0] ( nCount : 0 )
   //    <-TFONT:END(303) <-MAIN(0)
   // RELEASE FONT oFont

   oTimer:End()
   oVLCX:End()

*   OnDummy( TIME(), "Exit App" )
   SET ALTER TO

RETURN

*+--------------------------------------------------------------------
*+
*+    Procedure VLCmenu()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
PROCEDURE VLCmenu( nRow, nCol, oParent, nIndex )                      // called by FWTVlc:bRClicked
LOCAL oPopup

   DEFAULT nIndex TO 1

   IF hb_isObject( oParent )
      MENU oPopup POPUP
      MENUITEM "&POPUP Menu" ACTION MsgInfo( "Hello world " + VAR2CHAR( nIndex ) )
      SEPARATOR
      ENDMENU

      ACTIVATE POPUP oPopup WINDOW oParent AT nRow, nCol
   ENDIF

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure DoInit()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE DoInit()

   DoFillCombo()
   oCombo:SetItems( aItems )
   oCombo:Set( "all Record" )

   // not when using Ownerdraw
   // ChangeFilter()

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Function BuildMenu()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION BuildMenu()
LOCAL oMenu

   MENU oMenu
   MENUITEM "&Action"
   MENU
   MENUITEM "E&xit" RESOURCE "B1EXIT" ACTION oDlg:End()
   SEPARATOR
   MENUITEM "&Import" RESOURCE "B1IMPORT" ACTION ImportM3U( oBrw )
   SEPARATOR
   MENUITEM "&Sound" RESOURCE "B1SOUND" ACTION OpenSndVol( oDlg )
   ENDMENU
   ENDMENU

RETURN oMenu

*+--------------------------------------------------------------------
*+
*+    Static Procedure DoFillCombo()
*+
*+    Called from ( fwiptv.prg )   1 - static procedure doinit()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE DoFillCombo()
LOCAL nPosi

   aItems := { "all Record" }

   ORDSETFOCUS( "TVGROUP" )                                           // UNIQUE
   GO TOP
   DO WHILE !EOF()
      IF EMPTY( FIELD->TVGROUP )
         SKIP
         LOOP
      ENDIF
      AADD( aItems, FIELD->TVGROUP )
      SKIP
   ENDDO
   ORDSETFOCUS( "TVCHANNEL" )
   GO TOP

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ChangeCombo()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ChangeCombo()
*   OnDummy( TIME(), "ChangeCombo()", nRadio )
   cLastCB := cCombo
   IF nRadio <> 1
      cCombo := "all Record"
   ENDIF

   oCombo:Set( cCombo )
   oCombo:refresh()

   ChangeFilter()

   Do_Store()

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure ChangeFilter()
*+
*+    Called from ( fwiptv.prg )   2 - procedure main()
*+                                   1 - static procedure changecombo()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE ChangeFilter()
STATIC nLast := 0

   IF nRadio <> 1
      cCombo := "all Record"
      oCombo:Set( cCombo )
   ELSE
      oCombo:Set( cLastCB )
   ENDIF
   oCombo:refresh()

   DBCLEARFILTER()
   ORDSETFOCUS( "TVCHANNEL" )

   IF cCombo = "all Record"
      IF nRadio = 1
         SET FILTER TO FIELD->TVRADIO = .F.
         GOTO( 945 )                                                  // STAR TREK
      ELSE
         SET FILTER TO FIELD->TVRADIO = .T.
         GO TOP
      ENDIF
   ELSE
      IF nRadio = 1
         SET FILTER TO FIELD->TVRADIO = .F. .AND. FIELD->TVGROUP = cCombo
      ELSE
         SET FILTER TO FIELD->TVRADIO = .T. .AND. FIELD->TVGROUP = cCombo
      ENDIF
      GO TOP
   ENDIF

   IF hb_isObject( oBrw )
      oBrw:Refresh()
   ENDIF

   Do_Store()

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure DoReSize()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE DoReSize()
LOCAL aRect, nHwnd
LOCAL xFactor := oDlg:nWidth / oDlg:Cargo[ 1 ]
LOCAL yFactor := oDlg:nHeight / oDlg:Cargo[ 2 ]
LOCAL oCtrl, h, lUseFont, nSizeBox := 10
LOCAL oError, bOldError := ERRORBLOCK( { | e | BREAK( e ) } )

   ALTD()
*   OnDummy( TIME(), "x", xFactor, "y", yFactor )

   FOR each oCtrl in oDlg:aControls
      WITH OBJECT oCtrl

      :nTop := :Cargo[ 1 ] * yFactor
      :nLeft := :Cargo[ 2 ] * xFactor
      :nWidth := :Cargo[ 3 ] * xFactor
      :nHeight := :Cargo[ 4 ] * yFactor

      h := - :Cargo[ 5 ]
      h := - ROUND( ( h * yFactor ), 0 )

      lUseFont := .T.
      DO CASE
         CASE :IsKindOf( "FWTVLC" )
            lUseFont := .F.
         CASE :IsKindOf( "TXBROWSE" )
            lUseFont := .F.
         CASE :IsKindOf( "TXIMAGE" )
            lUseFont := .F.

         CASE :IsKindOf( "TCOMBOBOX" )
            :nHeight := :nWidth
            :HGet( h )
            lUseFont := .F.
            // ondummy( TIME(), :ClassName(), :Cargo[ 5 ], h, yFactor )

         CASE :IsKindOf( "TSAY" )
         CASE :IsKindOf( "TGET" )
            RoundRect( :hDC, :nLeft, :nTop, :nLeft + nSizeBox, :nTop + nSizeBox, 40, 40 )

         CASE :IsKindOf( "TRADIO" )

         OTHERWISE
            msginfo( "Error " + :ClassName() )
            lUseFont := .F.
      ENDCASE

      IF lUseFont = .T.
         BEGIN SEQUENCE
            // fwVLC have no oFont
            IF h != :oFont:nInpHeight
               :SetFont( :oFont:Modify( h ) )
            ENDIF
         END SEQUENCE
         ERRORBLOCK( bOldError )
      ENDIF

      :Refresh()
   END
   NEXT

RETURN

*+--------------------------------------------------------------------
*+
*+    Procedure CreateDbf()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+                ( readm3u.prg )   1 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
PROCEDURE CreateDbf( datei )
LOCAL field_list := {}

   AADD( field_list, { "TVNAME", "C", 070, 0 } )
   AADD( field_list, { "TVCHNO", "N", 005, 0 } )
   AADD( field_list, { "TVID", "C", 040, 0 } )
   AADD( field_list, { "TVGROUP", "C", 020, 0 } )
   AADD( field_list, { "TVLANG", "C", 020, 0 } )
   AADD( field_list, { "TVRADIO", "L", 001, 0 } )
   AADD( field_list, { "TVLOGO", "C", 255, 0 } )

   // Note : xBase comaptible are only 255
   //
   // AADD( field_list, { "TVURL", "C", 255, 0 } )
   AADD( field_list, { "TVURL", "C", 640, 0 } )

   // you can use MEMO instead when need to be compatible
   //
   // AADD( field_list, { "TVLOGO", "M", 10, 0 } )
   // AADD( field_list, { "TVURL", "M", 10, 0 } )

   DBCREATE( datei, field_list, "DBFCDX" )

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure CreateIndex()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE CreateIndex( _cdxname )
LOCAL aFields  := { "TVCHNO", "TVNAME", "TVID", "TVGROUP" }
LOCAL _tagname
LOCAL _keyfeld

   IF USED()
      FERASE( "TVURL.CDX" )

      _tagname := "TVCHANNEL"
      _KEYFELD := "TVCHNO"
      ORDCREATE( _cdxname, _tagname, _keyfeld )
      CLOSE INDEX

      _tagname := "TVSTATION"
      // _KEYFELD := "Upper(TVNAME)"
      _KEYFELD := "TVNAME"
      ORDCREATE( _cdxname, _tagname, _keyfeld )
      CLOSE INDEX

      _tagname := "TVIDNAME"
      _KEYFELD := "TVID"
      ORDCREATE( _cdxname, _tagname, _keyfeld, .t., .t. )
      CLOSE INDEX

      _tagname := "TVGROUP"
      // _KEYFELD := "Upper(TVGROUP)"
      _KEYFELD := "TVGROUP"
      ORDCREATE( _cdxname, _tagname, _keyfeld, .t., .t. )
      CLOSE INDEX

   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure SwitchFull()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE SwitchFull()
LOCAL oVideo

   IF hb_isObject( oVLCX )
      oVideo := oVLCX:Video
      // oVideo:fullscreen := .T.
      oVideo:toggleFullscreen()

   ENDIF

RETURN

*+--------------------------------------------------------------------
*+
*+    Procedure onDummy()
*+
*+    Called from ( fwiptv.prg )   2 - procedure main()
*+                                   1 - static procedure changecombo()
*+                                   1 - static procedure doresize()
*+                                   4 - static function doshow()
*+                ( fwvlc.prg )   8 - class fwtvlc
*+
*+--------------------------------------------------------------------
*+
PROCEDURE onDummy()
LOCAL iMax   := PCOUNT()
LOCAL i
LOCAL cText  := ""
LOCAL xValue

   IF lDebug = .T.
      FOR i := 1 TO iMax - 1
         cText += Var2Char( PValue( i ) ) + CHR( 9 )
      NEXT
      cText += Var2Char( PValue( iMax ) )

      IF EMPTY( cText )
         cText := TIME() + " no Parameter ? " + CRLF + PROCNAME( 1 ) + STR( PROCLINE( 1 ) ) + CRLF + PROCNAME( 2 ) + STR( PROCLINE( 2 ) )
      ENDIF
      SET CONSOLE OFF
      SET ALTER ON

      // ? cText
      QOUT( cText )

      SET ALTER OFF
      SET CONSOLE ON
   ENDIF

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure OpenSndVol()
*+
*+    Called from ( fwiptv.prg )   1 - static function buildmenu()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE OpenSndVol( oParent )
LOCAL cWin  := GETENV( "windir" )
LOCAL cPara

   //    IF IsProcessRun( "SndVol.exe" ) // GERMAN : Lautst„rkemixer
   //    ELSE

   // Parameter : -r Position of SndVol
   // calculate : nPosition := y * 65536 + x
   // x,y Position as PIXEL

   ShellExecute( oParent:hWnd, "open", cWin + "\System32\SndVol.exe", " -r  16384300", hb_DirBase(), SW_SHOW )
   //    ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure Do_Store()
*+
*+    Called from ( fwiptv.prg )   2 - procedure main()
*+                                   1 - static procedure changecombo()
*+                                   1 - static procedure changefilter()
*+                                   1 - static procedure dolocate()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE Do_Store()
LOCAL cImage, hBitmap
LOCAL cTempDir       := GETENV( "TEMP" )
LOCAL cLocalFileName := cTempDir + "\TVTEMP.BMP"
LOCAL nRecord

   IF hb_isObject( oImage )

      oImage:SetSource( "" )

      cImage := TRIM( FIELD->TVLOGO )
      IF DownloadFromWWW( cImage, cLocalFileName, .T. )
         oImage:SetSource( cLocalFileName )
         //      oImage:ReSize(, 64, 64 )
         oImage:FitRect()
         //       oImage:FitWidth()
         //       oImage:FitHeight()
         oImage:nUserControl := 0
         //      oImage:SetColor( CLR_WHITE, CLR_BLACK )
         oImage:SetColor( CLR_WHITE, CLR_GRAY )
         // oImage:Shadow()

         // oImage:Refresh()
         SysRefresh()
      ENDIF
   ENDIF

   IF USED()
      cVar1 := TVURL->TVNAME
      cVar2 := TVURL->TVCHNO
      cVar3 := TVURL->TVID
      cVar4 := TVURL->TVLOGO
      cVar5 := TVURL->TVURL
      cVar6 := TVURL->TVGROUP
      nRadio := IF( TVURL->TVRADIO, 2, 1 )

      Do_Say()
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure Do_Say()
*+
*+    Called from ( fwiptv.prg )   1 - static procedure do_store()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE Do_Say()
   IF hb_isObject( oGet1 )
      oGet1:refresh()
   ENDIF
   IF hb_isObject( oGet2 )
      oGet2:refresh()
   ENDIF
   IF hb_isObject( oGet3 )
      oGet3:refresh()
   ENDIF
   IF hb_isObject( oGet4 )
      oGet4:refresh()
   ENDIF
   IF hb_isObject( oGet5 )
      oGet5:refresh()
   ENDIF
   IF hb_isObject( oGet5 )
      oGet6:refresh()
   ENDIF
   IF hb_isObject( oRadio )
      oRadio:refresh()
   ENDIF
RETURN

*+--------------------------------------------------------------------
*+
*+    Static Procedure DoLocate()
*+
*+--------------------------------------------------------------------
*+
STATIC PROCEDURE DoLocate()                                           // unused
LOCAL nOldRec := RECNO()

STATIC cSeek := "                              "

   IF MsgGet( "Seek for Name", ;                                      // Title
              "Name :", ;                                             // Label
              @cSeek )                                                // A variable by reference

      IF USED()

         // LOCATE FOR FIELD->TVNAME = UPPER( TRIM( cSeek ) )
         ORDSETFOCUS( "TVSTATION" )
         SEEK( UPPER( TRIM( cSeek ) ) )
         IF FOUND()
            oBrw:Refresh()
         ELSE
            GO TOP
            SET SOFTSEEK ON
            SEEK( UPPER( TRIM( cSeek ) ) )
            // LOCATE FOR FIELD->TVNAME = UPPER( TRIM( cSeek ) )
            SET SOFTSEEK OFF
            oBrw:Refresh()
         ENDIF

         Do_Store()
      ENDIF
   ENDIF

RETURN

*+--------------------------------------------------------------------
*+
*+    Static Function DoSeekInc()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION DoSeekInc( cSeek )
LOCAL lRet := .F.
   IF USED()
      // SEEK on all Record
      SET FILTER TO
      ORDSETFOCUS( "TVSTATION" )
      SEEK( UPPER( TRIM( cSeek ) ) )
      IF FOUND()
         lRet := .T.
      END
   ENDIF

RETURN lRet

*+--------------------------------------------------------------------
*+
*+    Static Function DownloadFromWWW()
*+
*+    Called from ( fwiptv.prg )   1 - static procedure do_store()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION DownloadFromWWW( cUrl, cFile )
LOCAL oErr
LOCAL oHttp := Win_OleCreateObject( "MSXML2.ServerXMLHTTP" )

   IF FILE( cFile )
      hb_FileDelete( cFile )
   ENDIF

   IF .NOT. "http" $ cUrl
      RETURN .F.
   ENDIF

   BEGIN SEQUENCE WITH { | oErr | BREAK( oErr ) }
      oHttp:Open( "GET", cUrl, .F. )
      oHttp:setRequestHeader( "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0" )
      oHttp:Send()

      IF oHttp:Status = 200
         StrFile( oHttp:ResponseBody(), cFile )
      ENDIF
      oHttp:Abort()

   RECOVER USING oErr
      MsgStop( "Error download " + cUrl )
   END SEQUENCE

RETURN FILE( cFile )

*+--------------------------------------------------------------------
*+
*+    Static Function IsProcessRun()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION IsProcessRun( cApp )                                  // unused
LOCAL oProcesses, oProcess, oWMI, oLocator, nHwnd := 0
LOCAL lRet       := .F.

   oLocator := CreateObject( "wbemScripting.SwbemLocator" )
   IF EMPTY( oLocator )
      msginfo( "can not create wbemScripting.SwbemLocator" )
      oLocator := NIL
      RETURN .F.
   ELSE
      oWMI := oLocator:ConnectServer()
   ENDIF

   IF EMPTY( oWMI )
      msginfo( "can not connect oLocator:ConnectServer()" )
      oLocator := NIL
      oWMI := NIL
      RETURN .F.
   ELSE
      oProcesses = oWMI:ExecQuery( "SELECT * FROM Win32_Process" )

      IF oProcesses:Count > 0
         FOR EACH oProcess in oProcesses
            IF UPPER( TRIM( oProcess:Name ) ) = UPPER( TRIM( cApp ) )
               nHwnd := VAL( oProcess:Handle )
               //  oProcess:Terminate( 0 )
               lRet := .T.
               EXIT
            ENDIF
         NEXT
      ENDIF
   ENDIF

   oProcesses := NIL
   oWMI := NIL
   oLocator := NIL

   IF !( nHwnd == 0 )
      SetForegroundWindow( nHwnd )
      BringWindowToTop( nHwnd )
      ShowWindow( nHwnd, 1 )
      UpdateWindow( nHwnd )
   ENDIF

RETURN lRet

*+--------------------------------------------------------------------
*+
*+    Function VAR2CHAR()
*+
*+    Called from ( fwiptv.prg )   1 - procedure vlcmenu()
*+                                   2 - procedure ondummy()
*+                ( fwvlc.prg )   2 - class fwtvlc
*+
*+--------------------------------------------------------------------
*+
FUNCTION VAR2CHAR( cIn )
LOCAL cOut := hb_valToExp( cIn )
RETURN STRTRAN( cOut, '"', '' )

*+--------------------------------------------------------------------
*+
*+    Function AtInside()
*+
*+    Called from ( readm3u.prg )   2 - static procedure doreadm3u()
*+
*+--------------------------------------------------------------------
*+
FUNCTION AtInside( cMarker, cText )
LOCAL nPos := 1
LOCAL nIst := 0
LOCAL aRet := {}

   DO WHILE .T.
      nPos := AT( cMarker, cText )
      IF nPos > 0
         nIst ++
         AADD( aRet, LTRIM( SUBSTR( cText, 1, ( nPos - 1 ) ) ) )
         cText := SUBSTR( cText, ( nPos + 1 ), LEN( cText ) - nPos )
      ELSE
         AADD( aRet, LTRIM( cText ) )
         EXIT
      ENDIF
   ENDDO

RETURN aRet

*+--------------------------------------------------------------------
*+
*+    Static Function DoShow()
*+
*+    Called from ( fwiptv.prg )   3 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION DoShow( cFileName )
LOCAL aPos, aSize
LOCAL aRect := { 0, 0, 0, 0 }

   IF hb_isObject( oVLCX )

*      OnDummy( TIME(), "play " + cFileName )
      oVLCX:SetTime( 0 )

      oVLCX:SetFile( cFileName )
*      OnDummy( TIME(), "DoShow SetFile()" )

      oVLCX:Play()
*      OnDummy( TIME(), "call play()" )

      SysRefresh()

      IF oVLCX:IsPlaying()
*         OnDummy( TIME(), "isplaying" )
      ENDIF
   ENDIF

RETURN .T.

*+--------------------------------------------------------------------
*+
*+    Static Function OwnerDrawItem()
*+
*+    Called from ( fwiptv.prg )   1 - procedure main()
*+
*+--------------------------------------------------------------------
*+
STATIC FUNCTION OwnerDrawItem( Self, nIdCtl, oItem )
LOCAL oFont1, nClrText, nClrBack, cItem
LOCAL hDC    := oItem:hDC

   IF oItem:itemID >= 0
      cItem := oItem:itemData
      DEFINE Font oFont1 NAME oItem:itemData SIZE nil, oItem:nHeight
#IFDEF __HMG__
      END FONT
#ENDIF

      nClrText := IF( lAnd( oItem:itemState, 1 ), GetSysColor( COLOR_HIGHLIGHTTEXT ), GetSysColor( COLOR_WINDOWTEXT ) )
      nClrBack := IF( lAnd( oItem:itemState, 1 ), GetSysColor( COLOR_HIGHLIGHT ), GetSysColor( COLOR_WINDOW ) )

      FW_SayText( hDC, oItem:itemData, oItem:aRect, "L", oFont1, ;
                  nClrText, nARGB( 255, nClrBack ) )

      oFont1:End()
   ENDIF

RETURN 1

#IFDEF USE_INC
   #include "FWVLC.PRG"
   #include "READM3U.PRG"
#endif

*+ EOF: FWIPTV.PRG
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: CLASS fwTVCL for IP-TV

Postby Antonio Linares » Wed Aug 03, 2022 3:48 am

Dear Jimmy,

This is the first time that I see this hbmk2.exe error:
[vcvarsall.bat] Environment initialized for: 'x64'
Error BASE/1126 Argument error: STRTRAN (Quit)
Error BASE/1126 Argument error: STRTRAN
Called from STRTRAN(0)
Called from __HBMK(0)
Called from HBMK_LOCAL_ENTRY(0)
Called from __HBMK_FAKE_ENTRY(0)


Could you please copy here the entire error ? How to reproduce it ?

many thanks
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42121
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: CLASS fwTVCL for IP-TV

Postby Jimmy » Wed Aug 03, 2022 4:26 am

hi Antonio,
Antonio Linares wrote:Could you please copy here the entire error ? How to reproduce it ?

to produce Error use above Go64.BAT and test64.hbp under 64 Bit OS
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: CLASS fwTVCL for IP-TV

Postby Jimmy » Sat Aug 06, 2022 6:17 am

BUG :
Position of VLCmenu is not correct when WINDOW is not maximize

change Code to this
Code: Select all  Expand view  RUN
PROCEDURE VLCmenu( nRow, nCol, oParent, nIndex )
LOCAL aPos := GetCursorPos()
LOCAL aRect := oParent:GetRect()
...
   ACTIVATE POPUP oPopup WINDOW oParent AT aPos[1]-aRect[1] -40 ,aPos[2]-aRect[2] // nRow, nCol
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany

Re: CLASS fwTVCL for IP-TV

Postby Silvio.Falconi » Sat Aug 06, 2022 8:40 am

to make a test where is the activex ?
Since from 1991/1992 ( fw for clipper Rel. 14.4 - Momos)
I use : FiveWin for Harbour November 2023 - January 2024 - Harbour 3.2.0dev (harbour_bcc770_32_20240309) - Bcc7.70 - xMate ver. 1.15.3 - PellesC - mail: silvio[dot]falconi[at]gmail[dot]com
User avatar
Silvio.Falconi
 
Posts: 7072
Joined: Thu Oct 18, 2012 7:17 pm

Re: CLASS fwTVCL for IP-TV

Postby Jimmy » Sat Aug 06, 2022 7:02 pm

hi Silvio,
Silvio.Falconi wrote:to make a test where is the activex ?

VLC Homepage is
https://www.videolan.org/vlc/

! Note : open Combobox and download 64 Bit Version if you want to use 64 Bit App

remember to download "Playlist" from HMG Forum with Link above to "import" to Player

p.s.
do NOT use VLC UWP (from https://apps.microsoft.com/store/detail/vlc-uwp) as it have no ActiveX Interface
greeting,
Jimmy
User avatar
Jimmy
 
Posts: 1732
Joined: Thu Sep 05, 2019 5:32 am
Location: Hamburg, Germany


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 65 guests