"""
vlc2cue.py
By Anton Vredegoor. Last edit: Monday July 25, 2011.
Send comments to: anton.vredegoor@gmail.com
License: GPL, however there are no warranties, use at your own risk.
This needs vlc.py, see http://wiki.videolan.org/Python_bindings
The idea is to play an online audio stream locally while also
saving it to an mp3 file and record some meta data in a cue file.
I made this because I often forget the name of the song I
listened to, so I have to wait till it is played again, or compare
twitter feeds with the file date of my recorded mp3. And vlc
seems not to record meta info, at least not for mp3.
Writing this also made me appreciate and become more
comfortable with vlc.py. It is very nice!
As a further benefit, vlc and many other players (foobar f.e.) can
read cue files. So now I not only have the names of the songs I like
but by clicking on them in the playlist (a playlist that has multiple
songs in a single mp3 file) the cursor moves more or less to the
starting time of the song. It probably depends on the accuracy
with which the broadcaster announces the change of track.
"""
import vlc
import time
import os
def new_filename(ext = '.mp3'):
"find a free filename in 00000000..99999999"
D = set(x[:8] for x in os.listdir('.')
if (x.endswith(ext) or x.endswith('.cue')) and len(x) == 12)
for i in xrange(10**8):
s = "%08i" %i
if s not in D:
return s
def initialize_cue_file(name,instream,audiofile):
"create a cue file and write some data, then return it"
cueout = '%s.cue' %name
outf = file(cueout,'w')
outf.write('PERFORMER "%s"\n' %instream)
outf.write('TITLE "%s"\n' %name)
outf.write('FILE "%s" WAVE\n' %audiofile)
outf.flush()
return outf
def initialize_player(instream, audiofile):
"initialize a vlc player which plays locally and saves to an mp3file"
inst = vlc.Instance()
p = inst.media_player_new()
cmd1 = "sout=#duplicate{dst=file{dst=%s},dst=display}" %audiofile
cmd2 ="no-sout-rtp-sap"
cmd3 = "no-sout-standard-sap"
cmd4 ="sout-keep"
med=inst.media_new(instream,cmd1,cmd2,cmd3,cmd4)
med.get_mrl()
p.set_media(med)
return p, med
def write_track_meta_to_cuefile(outf,instream,idx,meta,millisecs):
"write the next track info to the cue file"
outf.write(' TRACK %02i AUDIO\n' %idx)
outf.write(' TITLE "%s"\n' %meta)
outf.write(' PERFORMER "%s"\n' %instream)
m = millisecs // 60000
s = (millisecs - (m*60000)) // 1000
hs = (millisecs - (m*60000) - (s*1000)) //10
ts = '%02i:%02i:%02i' %(m,s,hs)
outf.write(' INDEX 01 %s\n' %ts)
outf.flush()
def test():
#some online audio stream for which this currently works ....
instream = 'http://streamer-mtc-aa05.somafm.com:80/stream/1018'
#if the output filename ends with mp3 vlc knows which mux to use
ext = '.mp3'
name = new_filename(ext)
audiofile = '%s%s' %(name,ext)
outf = initialize_cue_file(name,instream,audiofile)
p,med = initialize_player(instream, audiofile)
p.play()
np = None
i = 0
while 1:
time.sleep(.1)
new = med.get_meta(12)
if new != np:
i +=1
t = p.get_time()
print "millisecs: %i" %t
write_track_meta_to_cuefile(outf,instream,i,new,t)
np = new
print "now playing: %s" %np
if __name__=='__main__':
test()
Diff to Previous Revision
--- revision 1 2011-07-22 14:54:52
+++ revision 2 2011-07-25 15:55:38
@@ -1,5 +1,7 @@
"""
-By Anton Vredegoor. Last edit: Friday July 22, 2011.
+vlc2cue.py
+
+By Anton Vredegoor. Last edit: Monday July 25, 2011.
Send comments to: anton.vredegoor@gmail.com
@@ -30,46 +32,43 @@
import time
import os
-def new_filename():
+def new_filename(ext = '.mp3'):
"find a free filename in 00000000..99999999"
D = set(x[:8] for x in os.listdir('.')
- if x.endswith('.mp3') and len(x) == 12)
+ if (x.endswith(ext) or x.endswith('.cue')) and len(x) == 12)
for i in xrange(10**8):
s = "%08i" %i
- if s in D:
- D.discard(s)
- i += 1
- else:
+ if s not in D:
return s
-def initialize_cue_file(name,infile,mp3out):
+def initialize_cue_file(name,instream,audiofile):
"create a cue file and write some data, then return it"
cueout = '%s.cue' %name
outf = file(cueout,'w')
- outf.write('PERFORMER "%s"\n' %infile)
+ outf.write('PERFORMER "%s"\n' %instream)
outf.write('TITLE "%s"\n' %name)
- outf.write('FILE "%s" WAVE\n' %mp3out)
+ outf.write('FILE "%s" WAVE\n' %audiofile)
outf.flush()
return outf
-def initialize_player(infile, mp3out):
+def initialize_player(instream, audiofile):
"initialize a vlc player which plays locally and saves to an mp3file"
inst = vlc.Instance()
p = inst.media_player_new()
- cmd1 = "sout=#duplicate{dst=file{dst=%s},dst=display}" %mp3out
+ cmd1 = "sout=#duplicate{dst=file{dst=%s},dst=display}" %audiofile
cmd2 ="no-sout-rtp-sap"
cmd3 = "no-sout-standard-sap"
cmd4 ="sout-keep"
- med=inst.media_new(infile,cmd1,cmd2,cmd3,cmd4)
+ med=inst.media_new(instream,cmd1,cmd2,cmd3,cmd4)
med.get_mrl()
p.set_media(med)
return p, med
-def write_track_meta_to_cuefile(outf,infile,idx,meta,millisecs):
+def write_track_meta_to_cuefile(outf,instream,idx,meta,millisecs):
"write the next track info to the cue file"
outf.write(' TRACK %02i AUDIO\n' %idx)
outf.write(' TITLE "%s"\n' %meta)
- outf.write(' PERFORMER "%s"\n' %infile)
+ outf.write(' PERFORMER "%s"\n' %instream)
m = millisecs // 60000
s = (millisecs - (m*60000)) // 1000
hs = (millisecs - (m*60000) - (s*1000)) //10
@@ -78,13 +77,14 @@
outf.flush()
def test():
- name = new_filename()
#some online audio stream for which this currently works ....
- infile = 'http://streamer-mtc-aa05.somafm.com:80/stream/1018'
+ instream = 'http://streamer-mtc-aa05.somafm.com:80/stream/1018'
#if the output filename ends with mp3 vlc knows which mux to use
- mp3out = '%s.mp3' %name
- outf = initialize_cue_file(name,infile,mp3out)
- p,med = initialize_player(infile, mp3out)
+ ext = '.mp3'
+ name = new_filename(ext)
+ audiofile = '%s%s' %(name,ext)
+ outf = initialize_cue_file(name,instream,audiofile)
+ p,med = initialize_player(instream, audiofile)
p.play()
np = None
i = 0
@@ -95,7 +95,7 @@
i +=1
t = p.get_time()
print "millisecs: %i" %t
- write_track_meta_to_cuefile(outf,infile,i,new,t)
+ write_track_meta_to_cuefile(outf,instream,i,new,t)
np = new
print "now playing: %s" %np