Jump to content
Sign in to follow this  
EKY32

Play MP3 (Radio Streaming) from a server

Recommended Posts

EKY32

Hey there,

I'm trying to load a radio stream to my app from this station:

Кавказ ФМ

the source code of the webpage using that swf player led me to the main streamer website: http://music.nextweb.ru:9500

for example when you navigate to this channel http://music.nextweb.ru:9500/adigeiskaya using Firefox it loads the radio streaming in a built-in player, and with IExplorer it notifies to save an mp3 file with 310MB of size named adigeiskaya.mp3 so it is the streaming file that i want to load to my app.

how can i read a remote mp3 file without downloading it locally?

thank you.


[font="'trebuchet ms', helvetica, sans-serif;"]Please mark the answer of your question if you found it.[/font]

Share this post


Link to post
Share on other sites
trancexx

I wrote script called LiveStreaming.au3. You can use it for streaming from "http://music.nextweb.ru:9500/adigeiskaya". It uses AutoItObject even though now it can be written to use built-in functions.

At least two more users wrote streaming scripts later based on that one so search a bit.

If you like WMP you can use its objects to stream too, examples of that exist on the forum.

  • Like 1

♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
EKY32

thank you i made a deep search and saw some examples I liked the one using bass.dll coz i'ts the only one that worked for me.

anyway i'll see your script thank you.


[font="'trebuchet ms', helvetica, sans-serif;"]Please mark the answer of your question if you found it.[/font]

Share this post


Link to post
Share on other sites
EKY32

Nice script by trancexx :

I love you man thank you. :thumbsup:

Edited by EKY32

[font="'trebuchet ms', helvetica, sans-serif;"]Please mark the answer of your question if you found it.[/font]

Share this post


Link to post
Share on other sites
EKY32

I'm sorry i had to get back because your script mr.trancexx returns a "failed to stream" error while it's working successfully with the radio stations up there.. so i cant give the user the ability to know that streaming is really failed.

#include <AutoitObject.au3>
Opt("MustDeclareVars", 1)

Global $oGraphBuilder, $oMediaControl, $oBasicAudio, $oAudioMeterInformation, $hLevMet, $iPlaying = 1, $iVol
Global $sMediaFile = "http://music.nextweb.ru:9500/kavkaz-fm"
Global $oCOMError = ObjEvent("AutoIt.Error", "_ErrFunc")

_AutoItObject_StartUp()
Global $oUSER32DLL = _AutoItObject_DllOpen("user32.dll")


Global $hGUI = GUICreate("tinyAdiga Live Streaming", 278, 80)
Global $hButtonPlay = GUICtrlCreateButton("&Pause", 80, 20, 115, 25)
Global $hLabelInfo = GUICtrlCreateLabel("  ...Connecting...", 90, 60, 130, 25)


GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            ExitLoop
        Case $hButtonPlay
            If $iPlaying Then
                $oMediaControl.Pause()
                GUICtrlSetData($hButtonPlay, "&Play")
                $iPlaying = 0
            Else
                $oMediaControl.Run()
                GUICtrlSetData($hButtonPlay, "&Pause")
                $iPlaying = 1
            EndIf
    EndSwitch
    If $sMediaFile Then _RenderFile($sMediaFile)
WEnd

_Quit()


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



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

thanks.


[font="'trebuchet ms', helvetica, sans-serif;"]Please mark the answer of your question if you found it.[/font]

Share this post


Link to post
Share on other sites
trancexx

I was developer in the meantime so I had chance to make AutoIt better.
Find line that goes like this:

If $oCOMError.number Then

...and replace with:

If @error Then

You can delete the other line that mentions $oCOMError.number.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
EKY32

thank you very much, i'm still getting errors in the console with:

$oMediaControl.Stop()

$oGraphBuilder.Release()

should i replace them?


[font="'trebuchet ms', helvetica, sans-serif;"]Please mark the answer of your question if you found it.[/font]

Share this post


Link to post
Share on other sites
trancexx

No, of course not. Console is used for debugging, just comment out ConsoleWrite for production version.


♡♡♡

.

eMyvnE

Share this post


Link to post
Share on other sites
EKY32

I'm sorry i'm not sure i understood you, i can comment it out but it's just returning that the 2 lines are not for objects.

$oMediaControl.Stop()

$oGraphBuilder.Release()

! COM Error !  Number: 0x00000000   ScriptLine: 110 - Variable must be of type 'Object'.
! COM Error !  Number: 0x00000000   ScriptLine: 113 - Variable must be of type 'Object'.

forgive me.


[font="'trebuchet ms', helvetica, sans-serif;"]Please mark the answer of your question if you found it.[/font]

Share this post


Link to post
Share on other sites
trancexx

I said comment out ConsoleWrite, I didn't say comment out the whole error handler.

Your error function should be:

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

Do you understand now?

The messages you get are there for purpose and so is COM error handler.

...This way your code is backward and forward compatible. If you aren't interested in backward compatibility and want even better forward compatibility then use beta AutoIt and remove COM error handler and AutoItObject dependency completely by switching to built-in ObjCreateInterface,

Edited by trancexx
  • Like 1

♡♡♡

.

eMyvnE

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  

×