Sign in to follow this  
Followers 0
trancexx

Live Streaming

40 posts in this topic

#1 ·  Posted (edited)

Let's see how to listen to internet radio station using minimum resources plus just a little bit more, not to be too boring.

Script:

LiveStreaming.au3

You can take a look on how shanet used it to make a little radio application

Streaming is done with WM ASF Reader Filter. Additional info can be found on MSDN. Link if you would be interested.

AutoItObject is requirement. That UDF is located here or to be more precise here (download link).

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites



Hm, is still not a standard library, or i am missing something? :x


 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

It will never be. Why?


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

It will never be. Why?

Well, some(?) newbies will post questions like:

There is an error

LiveStreaming.au3(6,10) : ERROR: can't open include file "AutoitObject.au3"

#include "AutoitObject.au3"


 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

That's ok MrCreatoR. It's all part of the learning process.

If someone would say there is an error

: ==> Error in expression.

...then that would be something. _Quit() misses AdlibUnRegister().

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Wouldn't it be better to just add to your post that it requires the AutoitObject.au3 UDF with a link to where to download it? That way you don't have to think up new ways to pointlessly insult people.


If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Share this post


Link to post
Share on other sites

Wouldn't it be better to just add to your post that it requires the AutoitObject.au3 UDF with a link to where to download it? That way you don't have to think up new ways to pointlessly insult people.

Are you implying that I insulted MrCreatoR?

MrCreatoR is the person I respect greatly. I would never insult him, and most certainly not in a pointless way.

I could insult you with no problem though.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

#8 ·  Posted (edited)

That isn't the point of his post, he just asked you to please include that it requires the UDF, and preferably a link as well please?

I am really interested at looking at this working.

Thanks.

--EDIT--

It wont work for me? I have the UDF and it keeps freezing.

Edited by shanet

[font="Comic Sans MS"]My code does not have bugs! It just develops random features.[/font]My Projects[list][*]Live Streaming (Not my project, but my edited version)[right]AutoIt Wrappers![/right][/list]Pure randomness[list][*]Small Minds.......................................................................................................[size="1"]Simple progress bar that changes direction at either sides.[/size][*]ChristmasIt AutoIt Christmas Theme..........................................................[size="1"]I WAS BOOOORED![/size][*]DriveToy..............................................................................................................[size="1"]Simple joke script. Trick your friends into thinking their computer drive is haywire![/size][/list]In Development[list][*]Your Background Task Organiser[*]AInstall Second Generation[/list]BEFORE POSTING ON THE FORUMS, TRY THIS:
%programfiles%/AutoIt3/autoit3.chm

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Share this post


Link to post
Share on other sites

Hmm...

Posted code works with AutoItObject. Latest version of AutoItObject is the official AutoItObject. If any other AutoItObject would be (or was) required then I would have mentioned it.

Also I would be the judge of where is the place for me to post what I want to post. More ever, I expect people that would run the code to have at least enough knowledge to go pass the obvious. This is example scripts forum. This script is an example of streaming. Believe it or not AutoitObject is irrelevant to explain the procedure- the main purpose of the thread.

@shanet, try some other radio station. That one can be down.

http://norway.discovertrance.com:8000 http://94.76.208.7:8001 http://u15c.di.fm:80/di_minimal http://scfire-dtc-aa01.stream.aol.com:80/stream/1003 ;...


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

HI, just wanted to chime in here. I like how simple it seems. I wonder how large a non-AIO version of this would be? Anyway, if one had the desire to begin coding like this how would one go about getting started? What's all of this about interfaces and dispatches or what ever they are called?

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

Tested with last AutoItObject 1.2.2.0 version and works well !

Thanks Posted Image

some working tests :

http://212.45.104.50:8050

http://119.207.75.238:11250

http://173.193.14.170:8012

Edited by wakillon

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

#13 ·  Posted (edited)

HI, just wanted to chime in here. I like how simple it seems. I wonder how large a non-AIO version of this would be? Anyway, if one had the desire to begin coding like this how would one go about getting started? What's all of this about interfaces and dispatches or what ever they are called?

There is nothing special in the coding style I used. It's the same as it always is with AutoIt. What makes the difference is the usage of some COM interfaces available on Windows systems. These merits were not available to AutoIt users before AutoItObject, at least not in a sensible way.

Considering they are the essence of windows systems it should be clear that benefits are huge. Modern programming on windows can't be imagined without COM.

Object interface is just what the name says. Every object is set of pointers. Interface definition is a collection of pointers to methods/functions translated to human language. It's how you communicate with the machine. Every object is described by its interface. Every COM object in essence have IUnknown interface. On top of that it adds its own goods extending the definition of the base. That's how new interfaces are created.

To summarize it on AutoIt level...

Object is set of available functions. Interface is a list of those functions.

Windows have a whole set of objects available for the users on the system. Anyone can choose to use them. In fact, they are like huge collection of UDFs waiting to be used.

Edited by trancexx

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites

Hmm...

Posted code works with AutoItObject. Latest version of AutoItObject is the official AutoItObject. If any other AutoItObject would be (or was) required then I would have mentioned it.

Also I would be the judge of where is the place for me to post what I want to post. More ever, I expect people that would run the code to have at least enough knowledge to go pass the obvious. This is example scripts forum. This script is an example of streaming. Believe it or not AutoitObject is irrelevant to explain the procedure- the main purpose of the thread.

@shanet, try some other radio station. That one can be down.

http://norway.discovertrance.com:8000 
http://94.76.208.7:8001 
http://u15c.di.fm:80/di_minimal 
http://scfire-dtc-aa01.stream.aol.com:80/stream/1003 
;...

yay!

the second one is working!

Maybe soon you could include a .ini file or something that reads radio stations so you can choose from pre-defined stations?

shanet


[font="Comic Sans MS"]My code does not have bugs! It just develops random features.[/font]My Projects[list][*]Live Streaming (Not my project, but my edited version)[right]AutoIt Wrappers![/right][/list]Pure randomness[list][*]Small Minds.......................................................................................................[size="1"]Simple progress bar that changes direction at either sides.[/size][*]ChristmasIt AutoIt Christmas Theme..........................................................[size="1"]I WAS BOOOORED![/size][*]DriveToy..............................................................................................................[size="1"]Simple joke script. Trick your friends into thinking their computer drive is haywire![/size][/list]In Development[list][*]Your Background Task Organiser[*]AInstall Second Generation[/list]BEFORE POSTING ON THE FORUMS, TRY THIS:
%programfiles%/AutoIt3/autoit3.chm

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

yay!

the second one is working!

Maybe soon you could include a .ini file or something that reads radio stations so you can choose from pre-defined stations?

shanet

ini file or combobox ! Posted Image

#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

; LIVE STREAM PLAYER
;.......script written by trancexx (trancexx at yahoo dot com)
#include "AutoitObject.au3"

Opt("MustDeclareVars", 1)

HotKeySet("{ESC}", "_Quit") ; Esc to exit any time
Global $sMediaFile = "http://ns24907.ovh.net:8000" ; any other. Pay attention to format

; Error monitoring
Global $oCOMError = ObjEvent("AutoIt.Error", "_ErrFunc")

; Let the magic begin...
_AutoItObject_StartUp()
; DLLs to use
Global $oUSER32DLL = _AutoItObject_DllOpen("user32.dll")
; GUI
Global $hGUI = GUICreate("Live Streaming", 320, 80)
Global $hVolSlider = GUICtrlCreateSlider(10, 14, 28, 64, 10 + 16)
GUICtrlSetTip(-1, "100 %VOL")
GUICtrlCreateLabel("VOL", 40, 21, 68, 20)
GUICtrlSetFont(-1, 9, -1, 2, "Curier New")
Global $hButtonPlay = GUICtrlCreateButton("&Pause", 80, 20, 80, 25)
Global $hButtonstop = GUICtrlCreateButton("Stop", 170, 20, 80, 25)
Global $hLabelInfo = GUICtrlCreateLabel("  ...Connecting...", 70, 60, 130, 25)
GUICtrlSetFont(-1, 9, -1, 2, "Arial")
Global $hCombo = GUICtrlCreateCombo ( "http://ns24907.ovh.net:8000", 170, 55, 140 )  
GUICtrlSetData ( -1, "http://212.45.104.50:8050|http://119.207.75.238:11250|http://173.193.14.170:8012|http://173.193.14.170:8008", "http://ns24907.ovh.net:8000" )
Global $hLevMet
; Objects
Global $oGraphBuilder, $oMediaControl, $oBasicAudio, $oAudioMeterInformation

; Level-meter
_AudioVolObject($oAudioMeterInformation)
If Not @error Then ; if this objects are available on the system then add control for it
    $hLevMet = GUICtrlCreateProgress(230, 15, 40, 60, 4)
    AdlibRegister("_LevelMeter", 45)
EndIf

; Misc variables
Global $iPlaying = 1, $iVol
; Show GUI
GUISetState()

; Main loop
While 1
    Switch GUIGetMsg()
        Case -3
            ExitLoop
        Case $hButtonPlay
            If $iPlaying Then
                $oMediaControl.Pause()
                GUICtrlSetData($hButtonPlay, "&Play")
                $iPlaying = 0
            Else
                $sMediaFile=GUICtrlRead ( $hCombo )
                ConsoleWrite ( "$sMediaFile : " & $sMediaFile & @Crlf )
                $oMediaControl.Run()
                ;$sMediaFile = 'http://173.193.14.170:8004'
                GUICtrlSetData($hButtonPlay, "&Pause")
                $iPlaying = 1
            EndIf
        Case $hButtonstop           
                $oMediaControl.stop()
                GUICtrlSetData($hButtonPlay, "&Play")
                $sMediaFile=''
                $iPlaying = 0           
    EndSwitch
    If $iVol <> GUICtrlRead($hVolSlider) Then
        $iVol = GUICtrlRead($hVolSlider)
        If IsObj($oBasicAudio) Then $oBasicAudio.put_Volume(-Exp(($iVol) / 10.86))
        GUICtrlSetTip($hVolSlider, 100 - $iVol & " %VOL")
    EndIf
    If $sMediaFile Then _RenderFile($sMediaFile)
WEnd

; Free before the end
_Quit()
;THE END

Func _Quit()
    ; Release objests
    _ReleaseBuilder($oGraphBuilder, $oMediaControl, $oBasicAudio)
    $oAudioMeterInformation = 0
    ; Bye bye
    Exit
EndFunc   ;==>_Quit

Func _LevelMeter()
    Local $aCall = $oAudioMeterInformation.GetPeakValue(0)
    If IsArray($aCall) Then
        Local $iCurrentRead = 100 * $aCall[1]
        GUICtrlSetData($hLevMet, $iCurrentRead + 1)
        GUICtrlSetData($hLevMet, $iCurrentRead)
    EndIf
EndFunc   ;==>_LevelMeter

Func _AudioVolObject(ByRef $oAudioMeterInformation)
    Local Const $sCLSID_MMDeviceEnumerator = "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
    Local Const $sIID_IMMDeviceEnumerator = "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
    Global $dtagIMMDeviceEnumerator = $dtagIUnknown & _
            "EnumAudioEndpoints hresult(dword;dword;ptr*);" & _
            "GetDefaultAudioEndpoint hresult(dword;dword;ptr*);" & _
            "GetDevice hresult(wstr;ptr*);" & _
            "RegisterEndpointNotificationCallback hresult(ptr);" & _
            "UnregisterEndpointNotificationCallback hresult(ptr);"
    Local $dtagIMMDevice = $dtagIUnknown & _
            "Activate hresult(ptr;dword;variant*;ptr*);" & _
            "OpenPropertyStore hresult(dword;ptr*);" & _
            "GetId hresult(wstr*);" & _
            "GetState hresult(dword*);"
    Local Const $sIID_IAudioMeterInformation = "{C02216F6-8C67-4B5B-9D00-D008E73E0064}"
    Local $dtagIAudioMeterInformation = $dtagIUnknown & _
            "GetPeakValue hresult(float*);" & _
            "GetMeteringChannelCount hresult(dword*);" & _
            "GetChannelsPeakValues hresult(dword;float*);" & _
            "QueryHardwareSupport hresult(dword*);"
    ; MMDeviceEnumerator
    Local $oMMDeviceEnumerator = _AutoItObject_ObjCreate($sCLSID_MMDeviceEnumerator, $sIID_IMMDeviceEnumerator, $dtagIMMDeviceEnumerator)
    If @error Then Return SetError(1, 0, 0)
    ; DefaultAudioEndpoint
    Local $aCall = $oMMDeviceEnumerator.GetDefaultAudioEndpoint(0, 0, 0) ; eRender, eConsole
    If Not IsArray($aCall) Then Return SetError(2, 0, 0)
    Local $oDefaultDevice = _AutoItObject_WrapperCreate($aCall[3], $dtagIMMDevice)
    ; AudioMeterInformation
    Local $pIID_IAudioMeterInformation = _AutoItObject_CLSIDFromString($sIID_IAudioMeterInformation)
    $aCall = $oDefaultDevice.Activate(Number(DllStructGetPtr($pIID_IAudioMeterInformation)), 1, 0, 0)
    If Not IsArray($aCall) Then Return SetError(3, 0, 0)
    $oAudioMeterInformation = _AutoItObject_WrapperCreate($aCall[4], $dtagIAudioMeterInformation)
    ; That's it
    Return True
EndFunc   ;==>_AudioVolObject

Func _InitBuilder(ByRef $oGraphBuilder, ByRef $oMediaControl, ByRef $oBasicAudio)
    ; Needed identifiera
    Local $sCLSID_FilterGraph = "{E436EBB3-524F-11CE-9F53-0020AF0BA770}"
    Local $sIID_IGraphBuilder = "{56A868A9-0AD4-11CE-B03A-0020AF0BA770}"
    ; More...
    Local $tIID_IMediaControl = _AutoItObject_CLSIDFromString("{56A868B1-0AD4-11CE-B03A-0020AF0BA770}")
    Local $tIID_IBasicAudio = _AutoItObject_CLSIDFromString("{56A868B3-0AD4-11CE-B03A-0020AF0BA770}")
    ; Define IGraphBuilder methods
    Local $dtagIGraphBuilder = $dtagIUnknown & _
            "AddFilter hresult(ptr;wstr);" & _
            "RemoveFilter hresult(ptr);" & _
            "EnumFilters hresult(ptr*);" & _
            "FindFilterByName hresult(wstr;ptr*);" & _
            "ConnectDirect hresult(ptr;ptr;ptr);" & _
            "Reconnect hresult(ptr);" & _
            "Disconnect hresult(ptr);" & _
            "SetDefaultSyncSource hresult();" & _ ; IFilterGraph
            "Connect hresult(ptr;ptr);" & _
            "Render hresult(ptr);" & _
            "RenderFile hresult(wstr;ptr);" & _
            "AddSourceFilter hresult(wstr;wstr;ptr*);" & _
            "SetLogFile hresult(dword_ptr);" & _
            "Abort hresult();" & _
            "ShouldOperationContinue hresult();" ; IGraphBuilder
    ; Wrapp IGraphBuilder interface
    $oGraphBuilder = _AutoItObject_ObjCreate($sCLSID_FilterGraph, $sIID_IGraphBuilder, $dtagIGraphBuilder)
    If @error Then Return SetError(1, 0, False)
    ; IMediaControl IDispatch
    Local $aCall = $oGraphBuilder.QueryInterface(Number(DllStructGetPtr($tIID_IMediaControl)), 0)
    If IsArray($aCall) And $aCall[2] Then
        $oMediaControl = _AutoItObject_PtrToIDispatch($aCall[2])
    Else
        Return SetError(2, 0, False)
    EndIf
    Local $pBasicAudio
    ; Get pointer to IBasicAudio interface
    $aCall = $oGraphBuilder.QueryInterface(Number(DllStructGetPtr($tIID_IBasicAudio)), 0)
    If IsArray($aCall) And $aCall[2] Then
        $pBasicAudio = $aCall[2]
    Else
        Return SetError(3, 0, False)
    EndIf
    ; IBasicAudio is dual interface. Defining vTable methods:
    Local $dtagIBasicAudio = $dtagIDispatch & _
            "put_Volume hresult(long);" & _
            "get_Volume hresult(long*);" & _
            "put_Balance hresult(long);" & _
            "get_Balance hresult(long*);" ; IBasicAudio
    ; Wrapp it:
    $oBasicAudio = _AutoItObject_WrapperCreate($pBasicAudio, $dtagIBasicAudio)
    If @error Then Return SetError(4, 0, False)
    Return True ; There
EndFunc   ;==>_InitBuilder

Func _ReleaseBuilder(ByRef $oGraphBuilder, ByRef $oMediaControl, ByRef $oBasicAudio)
    $oMediaControl.Stop()
    $oBasicAudio = 0
    $oMediaControl = 0
    $oGraphBuilder.Release() ;<-!
    $oGraphBuilder = 0
EndFunc   ;==>_ReleaseBuilder

Func _RenderFile(ByRef $sMediaFile)
    _ReleaseBuilder($oGraphBuilder, $oMediaControl, $oBasicAudio)
    _InitBuilder($oGraphBuilder, $oMediaControl, $oBasicAudio)
    If Not _WMAsfReaderLoad($sMediaFile) Then
        $oUSER32DLL.MessageBeep("int", "dword", 48)
        $sMediaFile = ""
        Return SetError(1, 0, False)
    EndIf
    $oCOMError.number = 0 ; set no-error condition
    $oMediaControl.Run()
    ; Check for error
    If $oCOMError.number Then
        GUICtrlSetFont($hLabelInfo, 9, -1, 1, "Arial")
        GUICtrlSetData($hLabelInfo, "Streaming failed")
        GUICtrlSetColor($hLabelInfo, 0xFF0000)
        MsgBox(48, "Error", "Failed to stream", 0, $hGUI)
    Else
        GUICtrlSetFont($hLabelInfo, 9, -1, 1, "Arial")
        GUICtrlSetData($hLabelInfo, "    Connected!")
    EndIf
    $sMediaFile = ""
    Return True
EndFunc   ;==>_RenderFile

Func _WMAsfReaderLoad($sFile)
    Local Const $sCLSID_WMAsfReader = "{187463A0-5BB7-11d3-ACBE-0080C75E246E}"
    ; IBaseFilter definition
    Local Const $sIID_IBaseFilter = "{56a86895-0ad4-11ce-b03a-0020af0ba770}"
    Local $dtagIBaseFilter = $dtagIUnknown & _
            "GetClassID hresult(ptr*);" & _; IPersist
            "Stop hresult();" & _
            "Pause hresult();" & _
            "Run hresult(int64);" & _
            "GetState hresult(dword;dword*);" & _
            "SetSyncSource hresult(ptr);" & _
            "GetSyncSource hresult(ptr*);" & _ ; IMediaFilter
            "EnumPins hresult(ptr*);" & _
            "FindPin hresult(wstr;ptr*);" & _
            "QueryFilterInfo hresult(ptr*);" & _
            "JoinFilterGraph hresult(ptr;wstr);" & _
            "QueryVendorInfo hresult(wstr*);" ; IBaseFilter
    ; Create object
    Local $oBaseFilter = _AutoItObject_ObjCreate($sCLSID_WMAsfReader, $sIID_IBaseFilter, $dtagIBaseFilter)
    If @error Then Return SetError(1, 0, False)
    ; AddFilter is "must" to be able to use it
    $oGraphBuilder.AddFilter($oBaseFilter.__ptr__, "anything")
    ; File will be loaded using FileSourceFilter object
    ; IFileSourceFilter definition
    Local Const $sIID_IFileSourceFilter = "{56a868a6-0ad4-11ce-b03a-0020af0ba770}"
    Local $dtagIFileSourceFilter = $dtagIUnknown & _
            "Load hresult(wstr;ptr);" & _
            "GetCurFile hresult(ptr*;ptr);"
    Local $tIID_IFileSourceFilter = _AutoItObject_CLSIDFromString($sIID_IFileSourceFilter)
    ; Ask for FileSourceFilter object from BaseFilter
    Local $aCall = $oBaseFilter.QueryInterface(Number(DllStructGetPtr($tIID_IFileSourceFilter)), 0)
    If Not IsArray($aCall) Then Return SetError(2, 0, False)
    ; Wrapp it
    Local $oFileSourceFilter = _AutoItObject_WrapperCreate($aCall[2], $dtagIFileSourceFilter)
    ; Load the file now
    $oFileSourceFilter.Load($sFile, 0)
    $aCall = $oFileSourceFilter.GetCurFile(0, 0)
    Local $pFile = $aCall[1]
    Local $sLoaded = DllStructGetData(DllStructCreate("wchar[" & __Au3Obj_PtrStringLen($pFile) + 1 & "]", $pFile), 1)
    __Au3Obj_CoTaskMemFree($pFile)
    ConsoleWrite($sLoaded & @CRLF)
    ; Get pointer to EnumPins object
    $aCall = $oBaseFilter.EnumPins(0)
    If Not IsArray($aCall) Or Not $aCall[1] Then Return SetError(3, 0, False)
    Local $pEnum = $aCall[1]
    ; Define IEnumPins methods
    Local $dtagIEnumPins = $dtagIUnknown & _
            "Next hresult(dword;ptr*;dword*);" & _
            "Skip hresult(dword);" & _
            "Reset hresult();" & _
            "Clone hresult(ptr*);"
    ; Wrapp it
    Local $oEnum = _AutoItObject_WrapperCreate($pEnum, $dtagIEnumPins)
    ; Will enumerate all PINs and render them
    Local $pPin
    While 1
        $aCall = $oEnum.Next(1, 0, 0)
        If Not IsArray($aCall) Then Return SetError(4, 0, False)
        $pPin = $aCall[2]
        If $pPin Then
            $oGraphBuilder.Render($pPin)
            _AutoItObject_IUnknownRelease($pPin); releasing non-wrapped object when no longer needed
        EndIf
        If $aCall[0] Then ExitLoop
    WEnd
    ; All's ok
    Return True
EndFunc   ;==>_WMAsfReaderLoad

Func _ErrFunc()
    ;~  ConsoleWrite("! COM Error !  Number: 0x" & Hex($oCOMError.number, 8) & "   ScriptLine: " & $oCOMError.scriptline & " - " & $oCOMError.windescription & @CRLF)
EndFunc   ;==>_ErrFunc
Edited by wakillon

AutoIt 3.3.14.2 X86 - SciTE 3.6.0WIN 8.1 X64 - Other Example Scripts

Share this post


Link to post
Share on other sites

#17 ·  Posted (edited)

Here is my edited version.

New Features:

  • Close to tray option.
  • Stations.ini
  • Set Default - not via GUI (yet)

Close to tray option

By checking the Close to Tray checkbox, you can close the GUI to the tray.

Normal minimizing is still normal, and if you uncheck the checkbox, it closes using exactly the same procedure as the original project.

stations.ini

You can now include new stations without having to edit the code! Just specify your new stations in stations.ini and they will all be there when you next start the software.

NOTE: ONLY ONE STATION PER LINE!

NOTE: IF YOU INCLUDE ONE STATION MULTIPLE TIMES THE SOFTWARE WILL NOT KNOW!

Set Default

As stated above, there is not yet a GUI to specify the default station, however that does NOT mean it is hard!

Just go into your stations.ini file and put your new default station on the top line. MAKE SURE IT IS NOT REPEATED AS THE SOFTWARE WILL NOT KNOW!

Well, that's it so far, I think I did a good job with what I did, and trancexx with his.

shanet out

Edited by shanet

[font="Comic Sans MS"]My code does not have bugs! It just develops random features.[/font]My Projects[list][*]Live Streaming (Not my project, but my edited version)[right]AutoIt Wrappers![/right][/list]Pure randomness[list][*]Small Minds.......................................................................................................[size="1"]Simple progress bar that changes direction at either sides.[/size][*]ChristmasIt AutoIt Christmas Theme..........................................................[size="1"]I WAS BOOOORED![/size][*]DriveToy..............................................................................................................[size="1"]Simple joke script. Trick your friends into thinking their computer drive is haywire![/size][/list]In Development[list][*]Your Background Task Organiser[*]AInstall Second Generation[/list]BEFORE POSTING ON THE FORUMS, TRY THIS:
%programfiles%/AutoIt3/autoit3.chm

Share this post


Link to post
Share on other sites

#18 ·  Posted (edited)

Also, I thought some icons would be a good idea?

Here are five I thought would work best with this software.

shanet

Edited by shanet

[font="Comic Sans MS"]My code does not have bugs! It just develops random features.[/font]My Projects[list][*]Live Streaming (Not my project, but my edited version)[right]AutoIt Wrappers![/right][/list]Pure randomness[list][*]Small Minds.......................................................................................................[size="1"]Simple progress bar that changes direction at either sides.[/size][*]ChristmasIt AutoIt Christmas Theme..........................................................[size="1"]I WAS BOOOORED![/size][*]DriveToy..............................................................................................................[size="1"]Simple joke script. Trick your friends into thinking their computer drive is haywire![/size][/list]In Development[list][*]Your Background Task Organiser[*]AInstall Second Generation[/list]BEFORE POSTING ON THE FORUMS, TRY THIS:
%programfiles%/AutoIt3/autoit3.chm

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

ini file or combobox ! Posted Image

#AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6

; LIVE STREAM PLAYER
;.......script written by trancexx (trancexx at yahoo dot com)
#include "AutoitObject.au3"

Opt("MustDeclareVars", 1)

HotKeySet("{ESC}", "_Quit") ; Esc to exit any time
Global $sMediaFile = "http://ns24907.ovh.net:8000" ; any other. Pay attention to format

; Error monitoring
Global $oCOMError = ObjEvent("AutoIt.Error", "_ErrFunc")

; Let the magic begin...
_AutoItObject_StartUp()
; DLLs to use
Global $oUSER32DLL = _AutoItObject_DllOpen("user32.dll")
; GUI
Global $hGUI = GUICreate("Live Streaming", 320, 80)
Global $hVolSlider = GUICtrlCreateSlider(10, 14, 28, 64, 10 + 16)
GUICtrlSetTip(-1, "100 %VOL")
GUICtrlCreateLabel("VOL", 40, 21, 68, 20)
GUICtrlSetFont(-1, 9, -1, 2, "Curier New")
Global $hButtonPlay = GUICtrlCreateButton("&Pause", 80, 20, 80, 25)
Global $hButtonstop = GUICtrlCreateButton("Stop", 170, 20, 80, 25)
Global $hLabelInfo = GUICtrlCreateLabel("  ...Connecting...", 70, 60, 130, 25)
GUICtrlSetFont(-1, 9, -1, 2, "Arial")
Global $hCombo = GUICtrlCreateCombo ( "http://ns24907.ovh.net:8000", 170, 55, 140 )  
GUICtrlSetData ( -1, "http://212.45.104.50:8050|http://119.207.75.238:11250|http://173.193.14.170:8012|http://173.193.14.170:8008", "http://ns24907.ovh.net:8000" )
Global $hLevMet
; Objects
Global $oGraphBuilder, $oMediaControl, $oBasicAudio, $oAudioMeterInformation

; Level-meter
_AudioVolObject($oAudioMeterInformation)
If Not @error Then ; if this objects are available on the system then add control for it
    $hLevMet = GUICtrlCreateProgress(230, 15, 40, 60, 4)
    AdlibRegister("_LevelMeter", 45)
EndIf

; Misc variables
Global $iPlaying = 1, $iVol
; Show GUI
GUISetState()

; Main loop
While 1
    Switch GUIGetMsg()
        Case -3
            ExitLoop
        Case $hButtonPlay
            If $iPlaying Then
                $oMediaControl.Pause()
                GUICtrlSetData($hButtonPlay, "&Play")
                $iPlaying = 0
            Else
                $sMediaFile=GUICtrlRead ( $hCombo )
                ConsoleWrite ( "$sMediaFile : " & $sMediaFile & @Crlf )
                $oMediaControl.Run()
                ;$sMediaFile = 'http://173.193.14.170:8004'
                GUICtrlSetData($hButtonPlay, "&Pause")
                $iPlaying = 1
            EndIf
        Case $hButtonstop           
                $oMediaControl.stop()
                GUICtrlSetData($hButtonPlay, "&Play")
                $sMediaFile=''
                $iPlaying = 0           
    EndSwitch
    If $iVol <> GUICtrlRead($hVolSlider) Then
        $iVol = GUICtrlRead($hVolSlider)
        If IsObj($oBasicAudio) Then $oBasicAudio.put_Volume(-Exp(($iVol) / 10.86))
        GUICtrlSetTip($hVolSlider, 100 - $iVol & " %VOL")
    EndIf
    If $sMediaFile Then _RenderFile($sMediaFile)
WEnd

; Free before the end
_Quit()
;THE END

Func _Quit()
    ; Release objests
    _ReleaseBuilder($oGraphBuilder, $oMediaControl, $oBasicAudio)
    $oAudioMeterInformation = 0
    ; Bye bye
    Exit
EndFunc   ;==>_Quit

Func _LevelMeter()
    Local $aCall = $oAudioMeterInformation.GetPeakValue(0)
    If IsArray($aCall) Then
        Local $iCurrentRead = 100 * $aCall[1]
        GUICtrlSetData($hLevMet, $iCurrentRead + 1)
        GUICtrlSetData($hLevMet, $iCurrentRead)
    EndIf
EndFunc   ;==>_LevelMeter

Func _AudioVolObject(ByRef $oAudioMeterInformation)
    Local Const $sCLSID_MMDeviceEnumerator = "{BCDE0395-E52F-467C-8E3D-C4579291692E}"
    Local Const $sIID_IMMDeviceEnumerator = "{A95664D2-9614-4F35-A746-DE8DB63617E6}"
    Global $dtagIMMDeviceEnumerator = $dtagIUnknown & _
            "EnumAudioEndpoints hresult(dword;dword;ptr*);" & _
            "GetDefaultAudioEndpoint hresult(dword;dword;ptr*);" & _
            "GetDevice hresult(wstr;ptr*);" & _
            "RegisterEndpointNotificationCallback hresult(ptr);" & _
            "UnregisterEndpointNotificationCallback hresult(ptr);"
    Local $dtagIMMDevice = $dtagIUnknown & _
            "Activate hresult(ptr;dword;variant*;ptr*);" & _
            "OpenPropertyStore hresult(dword;ptr*);" & _
            "GetId hresult(wstr*);" & _
            "GetState hresult(dword*);"
    Local Const $sIID_IAudioMeterInformation = "{C02216F6-8C67-4B5B-9D00-D008E73E0064}"
    Local $dtagIAudioMeterInformation = $dtagIUnknown & _
            "GetPeakValue hresult(float*);" & _
            "GetMeteringChannelCount hresult(dword*);" & _
            "GetChannelsPeakValues hresult(dword;float*);" & _
            "QueryHardwareSupport hresult(dword*);"
    ; MMDeviceEnumerator
    Local $oMMDeviceEnumerator = _AutoItObject_ObjCreate($sCLSID_MMDeviceEnumerator, $sIID_IMMDeviceEnumerator, $dtagIMMDeviceEnumerator)
    If @error Then Return SetError(1, 0, 0)
    ; DefaultAudioEndpoint
    Local $aCall = $oMMDeviceEnumerator.GetDefaultAudioEndpoint(0, 0, 0) ; eRender, eConsole
    If Not IsArray($aCall) Then Return SetError(2, 0, 0)
    Local $oDefaultDevice = _AutoItObject_WrapperCreate($aCall[3], $dtagIMMDevice)
    ; AudioMeterInformation
    Local $pIID_IAudioMeterInformation = _AutoItObject_CLSIDFromString($sIID_IAudioMeterInformation)
    $aCall = $oDefaultDevice.Activate(Number(DllStructGetPtr($pIID_IAudioMeterInformation)), 1, 0, 0)
    If Not IsArray($aCall) Then Return SetError(3, 0, 0)
    $oAudioMeterInformation = _AutoItObject_WrapperCreate($aCall[4], $dtagIAudioMeterInformation)
    ; That's it
    Return True
EndFunc   ;==>_AudioVolObject

Func _InitBuilder(ByRef $oGraphBuilder, ByRef $oMediaControl, ByRef $oBasicAudio)
    ; Needed identifiera
    Local $sCLSID_FilterGraph = "{E436EBB3-524F-11CE-9F53-0020AF0BA770}"
    Local $sIID_IGraphBuilder = "{56A868A9-0AD4-11CE-B03A-0020AF0BA770}"
    ; More...
    Local $tIID_IMediaControl = _AutoItObject_CLSIDFromString("{56A868B1-0AD4-11CE-B03A-0020AF0BA770}")
    Local $tIID_IBasicAudio = _AutoItObject_CLSIDFromString("{56A868B3-0AD4-11CE-B03A-0020AF0BA770}")
    ; Define IGraphBuilder methods
    Local $dtagIGraphBuilder = $dtagIUnknown & _
            "AddFilter hresult(ptr;wstr);" & _
            "RemoveFilter hresult(ptr);" & _
            "EnumFilters hresult(ptr*);" & _
            "FindFilterByName hresult(wstr;ptr*);" & _
            "ConnectDirect hresult(ptr;ptr;ptr);" & _
            "Reconnect hresult(ptr);" & _
            "Disconnect hresult(ptr);" & _
            "SetDefaultSyncSource hresult();" & _ ; IFilterGraph
            "Connect hresult(ptr;ptr);" & _
            "Render hresult(ptr);" & _
            "RenderFile hresult(wstr;ptr);" & _
            "AddSourceFilter hresult(wstr;wstr;ptr*);" & _
            "SetLogFile hresult(dword_ptr);" & _
            "Abort hresult();" & _
            "ShouldOperationContinue hresult();" ; IGraphBuilder
    ; Wrapp IGraphBuilder interface
    $oGraphBuilder = _AutoItObject_ObjCreate($sCLSID_FilterGraph, $sIID_IGraphBuilder, $dtagIGraphBuilder)
    If @error Then Return SetError(1, 0, False)
    ; IMediaControl IDispatch
    Local $aCall = $oGraphBuilder.QueryInterface(Number(DllStructGetPtr($tIID_IMediaControl)), 0)
    If IsArray($aCall) And $aCall[2] Then
        $oMediaControl = _AutoItObject_PtrToIDispatch($aCall[2])
    Else
        Return SetError(2, 0, False)
    EndIf
    Local $pBasicAudio
    ; Get pointer to IBasicAudio interface
    $aCall = $oGraphBuilder.QueryInterface(Number(DllStructGetPtr($tIID_IBasicAudio)), 0)
    If IsArray($aCall) And $aCall[2] Then
        $pBasicAudio = $aCall[2]
    Else
        Return SetError(3, 0, False)
    EndIf
    ; IBasicAudio is dual interface. Defining vTable methods:
    Local $dtagIBasicAudio = $dtagIDispatch & _
            "put_Volume hresult(long);" & _
            "get_Volume hresult(long*);" & _
            "put_Balance hresult(long);" & _
            "get_Balance hresult(long*);" ; IBasicAudio
    ; Wrapp it:
    $oBasicAudio = _AutoItObject_WrapperCreate($pBasicAudio, $dtagIBasicAudio)
    If @error Then Return SetError(4, 0, False)
    Return True ; There
EndFunc   ;==>_InitBuilder

Func _ReleaseBuilder(ByRef $oGraphBuilder, ByRef $oMediaControl, ByRef $oBasicAudio)
    $oMediaControl.Stop()
    $oBasicAudio = 0
    $oMediaControl = 0
    $oGraphBuilder.Release() ;<-!
    $oGraphBuilder = 0
EndFunc   ;==>_ReleaseBuilder

Func _RenderFile(ByRef $sMediaFile)
    _ReleaseBuilder($oGraphBuilder, $oMediaControl, $oBasicAudio)
    _InitBuilder($oGraphBuilder, $oMediaControl, $oBasicAudio)
    If Not _WMAsfReaderLoad($sMediaFile) Then
        $oUSER32DLL.MessageBeep("int", "dword", 48)
        $sMediaFile = ""
        Return SetError(1, 0, False)
    EndIf
    $oCOMError.number = 0 ; set no-error condition
    $oMediaControl.Run()
    ; Check for error
    If $oCOMError.number Then
        GUICtrlSetFont($hLabelInfo, 9, -1, 1, "Arial")
        GUICtrlSetData($hLabelInfo, "Streaming failed")
        GUICtrlSetColor($hLabelInfo, 0xFF0000)
        MsgBox(48, "Error", "Failed to stream", 0, $hGUI)
    Else
        GUICtrlSetFont($hLabelInfo, 9, -1, 1, "Arial")
        GUICtrlSetData($hLabelInfo, "    Connected!")
    EndIf
    $sMediaFile = ""
    Return True
EndFunc   ;==>_RenderFile

Func _WMAsfReaderLoad($sFile)
    Local Const $sCLSID_WMAsfReader = "{187463A0-5BB7-11d3-ACBE-0080C75E246E}"
    ; IBaseFilter definition
    Local Const $sIID_IBaseFilter = "{56a86895-0ad4-11ce-b03a-0020af0ba770}"
    Local $dtagIBaseFilter = $dtagIUnknown & _
            "GetClassID hresult(ptr*);" & _; IPersist
            "Stop hresult();" & _
            "Pause hresult();" & _
            "Run hresult(int64);" & _
            "GetState hresult(dword;dword*);" & _
            "SetSyncSource hresult(ptr);" & _
            "GetSyncSource hresult(ptr*);" & _ ; IMediaFilter
            "EnumPins hresult(ptr*);" & _
            "FindPin hresult(wstr;ptr*);" & _
            "QueryFilterInfo hresult(ptr*);" & _
            "JoinFilterGraph hresult(ptr;wstr);" & _
            "QueryVendorInfo hresult(wstr*);" ; IBaseFilter
    ; Create object
    Local $oBaseFilter = _AutoItObject_ObjCreate($sCLSID_WMAsfReader, $sIID_IBaseFilter, $dtagIBaseFilter)
    If @error Then Return SetError(1, 0, False)
    ; AddFilter is "must" to be able to use it
    $oGraphBuilder.AddFilter($oBaseFilter.__ptr__, "anything")
    ; File will be loaded using FileSourceFilter object
    ; IFileSourceFilter definition
    Local Const $sIID_IFileSourceFilter = "{56a868a6-0ad4-11ce-b03a-0020af0ba770}"
    Local $dtagIFileSourceFilter = $dtagIUnknown & _
            "Load hresult(wstr;ptr);" & _
            "GetCurFile hresult(ptr*;ptr);"
    Local $tIID_IFileSourceFilter = _AutoItObject_CLSIDFromString($sIID_IFileSourceFilter)
    ; Ask for FileSourceFilter object from BaseFilter
    Local $aCall = $oBaseFilter.QueryInterface(Number(DllStructGetPtr($tIID_IFileSourceFilter)), 0)
    If Not IsArray($aCall) Then Return SetError(2, 0, False)
    ; Wrapp it
    Local $oFileSourceFilter = _AutoItObject_WrapperCreate($aCall[2], $dtagIFileSourceFilter)
    ; Load the file now
    $oFileSourceFilter.Load($sFile, 0)
    $aCall = $oFileSourceFilter.GetCurFile(0, 0)
    Local $pFile = $aCall[1]
    Local $sLoaded = DllStructGetData(DllStructCreate("wchar[" & __Au3Obj_PtrStringLen($pFile) + 1 & "]", $pFile), 1)
    __Au3Obj_CoTaskMemFree($pFile)
    ConsoleWrite($sLoaded & @CRLF)
    ; Get pointer to EnumPins object
    $aCall = $oBaseFilter.EnumPins(0)
    If Not IsArray($aCall) Or Not $aCall[1] Then Return SetError(3, 0, False)
    Local $pEnum = $aCall[1]
    ; Define IEnumPins methods
    Local $dtagIEnumPins = $dtagIUnknown & _
            "Next hresult(dword;ptr*;dword*);" & _
            "Skip hresult(dword);" & _
            "Reset hresult();" & _
            "Clone hresult(ptr*);"
    ; Wrapp it
    Local $oEnum = _AutoItObject_WrapperCreate($pEnum, $dtagIEnumPins)
    ; Will enumerate all PINs and render them
    Local $pPin
    While 1
        $aCall = $oEnum.Next(1, 0, 0)
        If Not IsArray($aCall) Then Return SetError(4, 0, False)
        $pPin = $aCall[2]
        If $pPin Then
            $oGraphBuilder.Render($pPin)
            _AutoItObject_IUnknownRelease($pPin); releasing non-wrapped object when no longer needed
        EndIf
        If $aCall[0] Then ExitLoop
    WEnd
    ; All's ok
    Return True
EndFunc   ;==>_WMAsfReaderLoad

Func _ErrFunc()
    ;~  ConsoleWrite("! COM Error !  Number: 0x" & Hex($oCOMError.number, 8) & "   ScriptLine: " & $oCOMError.scriptline & " - " & $oCOMError.windescription & @CRLF)
EndFunc   ;==>_ErrFunc

Sorry, I didn't notice that you had posted one?

However the GUI is screwed up.

And channel change doesn't work.

And I don't see any .ini file.

Also, your stop button does the same thing as the pause button.

Maybe the text in pause would make more sense as stop?

Anyway, that's enough of me killing your version, nice shot.

Look at mine?

shanet

Edited by shanet

[font="Comic Sans MS"]My code does not have bugs! It just develops random features.[/font]My Projects[list][*]Live Streaming (Not my project, but my edited version)[right]AutoIt Wrappers![/right][/list]Pure randomness[list][*]Small Minds.......................................................................................................[size="1"]Simple progress bar that changes direction at either sides.[/size][*]ChristmasIt AutoIt Christmas Theme..........................................................[size="1"]I WAS BOOOORED![/size][*]DriveToy..............................................................................................................[size="1"]Simple joke script. Trick your friends into thinking their computer drive is haywire![/size][/list]In Development[list][*]Your Background Task Organiser[*]AInstall Second Generation[/list]BEFORE POSTING ON THE FORUMS, TRY THIS:
%programfiles%/AutoIt3/autoit3.chm

Share this post


Link to post
Share on other sites

Looks good and works great!

Thanks for this contribution!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0