article

Internet Radio streaming and recording

Email
Submitted on: 12/3/2017 3:31:41 PM
By: David Patterson 
Level: Advanced
User Rating: Unrated
Compatibility: VB 6.0
Views: 695
 
     This application receives Internet radio mpeg broadcasts using a winsock.
Radio stations are bookmarked using a simple text file which is easily edited in notepad.
The ice and Meta stream data are interpreted.
It plays the stream using calls to the videolan VLCPlugin2. (Videolan must be installed on the PC.)
Mpeg streams can be recorded. Recording can be continuous or by track. Recordings can be limited to a specified time duration.
Audio monitoring is available for Win 7
It is based on original work and a lot of reading of published examples! (Thanks to all who came before)
It has been tested on windows 7 and XP.

This article has accompanying files

 
				

Internet Radio streaming and recording

Streaming is easy..

Let's assume you have a line of text with the URl of a raio station. It could have been copied from a site or from Winamps's file info when streaming a shoutcast:
http://comet.shoutca.st:8111/
Break the URL down to an address, a port and anything extra.
To get a VB winsock ("WS") to stream this site:
Set the winsock protocol to 0
Issue the command WS.Connect "comet.shoutca.st", "8111"
Send a GET command after the winsock connects:
dim tstart as single Const reqHeader = "GET / HTTP/1.0" & vbNewLine Const reqHeaderEnd = "User-Agent: WinampMPEG/2.7" & _ vbNewLine & "Accept: */*" & vbNewLine & "Connection: Close" & vbLf & vbLf
tstart = Timer    Do While ((WS.state <>sckConnected) Or ((Timer - tstart) < 5))        If ((WS.state = sckError) Or _        (WS.state = sckClosed) Or (WS.state = sckClosing)) Then        WS.Close        debug.print "Error: The socket failed to connect"        Exit Sub        End If     DoEvents    Loop
'if there is any extra text after the port or after the 'site address (if no port is specified), it will need to 'be sent in the get request 'In this example iptext and extra are text boxes 'with the IP address and any additional text 'Nb. Head requests end with two blank lines
       If (extra.Text = "") Then head$ = reqHeader Else _        head$ = "GET " + extra.Text + " HTTP/1.0" & vbNewLine    head$ = head$ & "Host: "& ipText.Text & vbNewLine    head$ = head$ & reqHeaderEnd    debug.print "Sending header " & head$ & vbNewLine    WS.SendData head$
and deal with the winsock callbacks:
Dim buf$
Private Sub WS_DataArrival(ByVal bytesTotal As Long) Dim inBuf As String Static working
   ' let's prevent interrupion of our processing    If working Then Exit Sub
On Local Error GoTo bad
working = True                  ' prevent re-entrant data processing WS.GetData inBuf, bytesTotal   ' grab all the wsk data buf$ = buf$ + inBuf             ' add to the big buffer
'     process the buffer '     do stuff '     remember to clear the buffer during the processing
working = False '   allow data processing in WS_DataArrival Exit Sub
bad: debug.print "Error" + Str(Err.Number) + " " + Err.Description Err.Clear working = False End Sub
Private Sub WS_ConnectionRequest(ByVal requestID As Long) WS.Accept requestID End Sub
Private Sub WS_Error(ByVal Number As Integer, Description As String, _ ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, _ ByVal HelpContext As Long, CancelDisplay As Boolean) debug.print vbNewLine + "WS Error " + Description + _ " (" + Str(Number) + ") " + Str(Scode) WS.Close End Sub

Recording..

Recording requires putting the winsock data in a file.. Let's assume a file has been opened with the handle FF and that a boolean variable recording has been set to True. All we have to do is to add this to the do stuff section of WS_DataArrival
       If (recording) Then            If (Len(buf$) > 65535) Then     ' 64k buffer filled            Put #FF, Loc(FF) + 1, buf$      ' add to file            buf$ = ""                      ' clear the big buffer            End If        Else            buf$ = ""        End If
When recording is over, add a simple mp3 tag and close the file

Listening to the stream..

I presume you have Videolan VLC player installed. It's free!
Use project references to include the Videolan VLC ActiveX Plugin (C:\Program Files (x86)\Videolan\VLC\axvlc.dll on my machine)
declare the plugin Private VLC As VLCPlugin2
in form load() ' .... Init VLC Library Set VLC = New VLCPlugin2
url$ = "http://comet.shoutca.st:8111/"
' Get videolan to play it: VLC.playlist.items.Clear' Clear the Playlist VLC.playlist.Add url$' Add radiostation URL VLC.playlist.playItem (0)' Play the first Item of the Playlist
when you're finished VLC.playlist.stop
in form_unload() Set VLC = Nothing

Program specification:

The station list is saved in a simple text format which can be edited in Notepad.
  • The format is:
    • station name |URL
    • note the space after the station name, followed by the "|" character
  • The Url should include the port. In the absence of a port, port 80 is assumed
  • eg. Run City 97.4 |http://listen.radionomy.com:80/RunCity974
  • Any text after the port number is sent in the get request
  • in the Run City 97.4 example
    • "Run City 97.4" is the stream name (can be a dummy name)
    • url = listen.radionomy.com
    • port = 80
    • header = GET /RunCity974 HTTP/1.0
    • Plus..
      • Host: listen.radionomy.com
      • User-Agent: WinampMPEG/2.7
      • Accept: */*
      • Connection: Close
      • Plus 2 line feeds
The station list is selectable in a list box. One click adds the station to the form boxes. Two click adds and then opens the stream.
If recording to mp3:
  • a 64K buffer is written to disk until stopped
  • a simple V1.1 MP3 tag is added
  • songs can be split by name or data recorded continuously
  • A recording time limit can be set by entering a non zero value in the limit box
  • The VLC tags are used to get information on
    • genre (VLC.mediaDescription.genre)
    • playing, etc (VLC.input.state)
    • track (VLC.mediaDescription.nowPlaying)
  • The track details may contain the song title, artist and station name
  • Track details are used to separate song tracks
  • NB 1 minute of data does not produce exactly 1 minute of play back
Assuming the stream is in mpeg format: The station response "ice" data is collected from the remote header returned after the GET request
  • "name:" Station name
  • "genre:" Station genre
  • "br:" Station bitrate in Kbits
  • "url:" Station URL - Set as a link in the site box, if found
  • "content-type:" compression format (mpeg etc)
The mpeg data stream is examined to extract the meta data
  • Mpeg Version and layer
  • Samplerate
  • Bitrate
  • CRC protection status
  • padding status
  • privacy
  • Stereo / mono channel status
  • Audio stereo intensity
  • MS stereo
  • Copyright
  • Original
  • Emphasis

Audio Monitoring

Monitoring has been tested in Windows 7. Left and right master channel levels are shown in real time. Master volume and balance levels are configerable. Audio Monitoring is not available for XP.
D.R.Patterson 2/12/2017

winzip iconDownload article

Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. Afterdownloading it, you will need a program like Winzip to decompress it.Virus note:All files are scanned once-a-day by Planet Source Code for viruses, but new viruses come out every day, so no prevention program can catch 100% of them. For your own safety, please:
  1. Re-scan downloaded files using your personal virus checker before using it.
  2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.
  3. Scan the source code with Minnow's Project Scanner

If you don't have a virus scanner, you can get one at many places on the net including:McAfee.com


Report Bad Submission
Use this form to tell us if this entry should be deleted (i.e contains no code, is a virus, etc.).
This submission should be removed because:

Your Vote

What do you think of this article (in the Advanced category)?
(The article with your highest vote will win this month's coding contest!)
Excellent  Good  Average  Below Average  Poor (See voting log ...)
 

Other User Comments

12/4/2017 11:34:56 AMDavid

excelent, thank you.
(If this comment was disrespectful, please report it.)

 

Add Your Feedback
Your feedback will be posted below and an email sent to the author. Please remember that the author was kind enough to share this with you, so any criticisms must be stated politely, or they will be deleted. (For feedback not related to this particular article, please click here instead.)
 

To post feedback, first please login.