#!/usr/bin/python """ Little script to convert Realaudio stream to mp3 & download podcasts To use it you need: - mplayer with win32 codecs - lame to encode the wav in mp3 - please set the path to store the mp3 files Copyright Jkx 2004 / Licence GPL Modifications by James Minchin (http://chaucery.com/) 8-Feb-2006 - updated deprecated mplayer parameters - changed some Unix functions to Python (OS-neutral) functions - added support for .ra streams 25-Feb-2006 - fixed path parameter (temp file still where script runs though) 15-Oct-2006 - fix stream url containing containing querystring, ie. '?' 9-Apr-2007 - added direct naive podcast downloads (gets first entry in feed) - added Ogg Vorbis encoding option 10-Apr-2007 - added optional parameter to set output filename 1-Jul-2007 - fixed podcast to always download first audio found 4-Nov-2007 - fix podcast filenames containing '?' - add optional parameter to set filename prefix on podcasts - fix Real streams containing '&' 25-Nov-2007 - fix podcast title containing '/' - abort when temp filename already in use (eg. when 2 simultanous streams using same name """ import os, sys, string, time path = "e:/multimedia/rip" #os.getcwd() # destination folder mplayer = "e:/multimedia/mplayer/mplayer" # location of MPlayer lame = "e:/multimedia/lame/lame" # location of Lame mp3 encoder ogg = "e:/multimedia/oggenc2.exe" # location of Ogg Vorbis encoder hr = "*" * 78 def rip(url, filename): """ rip stream """ os.system('%s -cache 320 -vc dummy -vo null -ao pcm:waveheader:file=%s "%s"' % (mplayer, filename, url)) def encode(filename, path): """ encode stream with lame and delete it """ dateBit = time.strftime("%Y%b%d", time.localtime()) dest= os.path.join(path, filename[:-4] + '_' + dateBit + '.mp3') # changed from 64bps constant to variable bit rate of quality 8 (9 = lowest) #os.system('%s -b 64 %s %s' % (lame, filename, dest) ) os.system('%s -V 8 --vbr-new %s %s' % (lame, filename, dest) ) #os.system('%s -q 0 -o %s %s' % (ogg, dest, filename) ) os.remove(filename) def parseSource(sourceFile): if sourceFile.startswith('http://'): # this is a url not a file import urllib f=urllib.urlopen(sourceFile) else: try: f = open(sourceFile) except IOError: print "Unable to open %s" % ramFile return None,None data = f.read() f.close() url = None import re #==== look for mp3 podcast matches = re.match(".*?[^<]*(.*?).*?]+url=\"([^\"]*)\".*?", data, re.DOTALL) if matches != None: title = matches.group(1) url = matches.group(2) print "Found podcast '%s' at\n%s" % (title, url) #==== fix title so it only contains valid chars for saving file #==== workaround url containing weird ampersand encoding - (for CBC Spark podcast) return url.replace("&","&"), title.replace("/","_").replace(" ","_").replace(":","_").replace("__","_").replace("?","") #==== no podcast, check for Real stream instead urlMatches = re.match(".*(rtsp://.*)", data) if urlMatches != None: url = urlMatches.group(1).strip() if url: print 'Found an rtsp stream at:\n%s' % url filename=string.split(url,'/')[-1] qPos = filename.find('?') if qPos <> -1: filename = filename[:qPos] if filename.endswith('.rm') or filename.endswith('.ra'): return url,filename[:-3]+'.wav' else: print "Unable to find the .ram file" return None,None else: print "Unable to find the podcast or rtsp stream" return None,None def reportHook(block_count, block_size, total_size): total_kb = total_size/1024 print "%d kB of %d kB downloaded\r" % (block_count * (block_size/1024), total_kb ), def main(): print hr url,filename = parseSource(sys.argv[1]) if url and filename: if url.endswith(".mp3"): if len(sys.argv) == 3: filename = sys.argv[2] + "_" + filename filename = os.path.join(path, filename) + '.mp3' print hr print "Downloading to %s..." % filename import urllib # socket.setdefaulttimeout() urllib.urlretrieve(url, filename, reporthook=reportHook) print "...Completed." print hr else: if len(sys.argv) == 3: filename = sys.argv[2] + '.wav' if os.path.exists(filename): print "ERROR: temporary file %s already exists" % (filename) sys.exit(1) else: print "Ripping file to %s" % (os.path.join(path,filename)) print hr rip(url,filename) print hr encode(filename, path) print "SUCCESS: Download complete" print hr else: print "ERROR: Could not find audio to download" print hr def usage(): me = sys.argv[0] (head, tail) = os.path.split(me) print "Convert realaudio to mp3 or download latest mp3 podcast - usage:\n" print " %s infile [outfile]\n" % tail print "infile: a file or url of a podcast or Real audio" print "outfile: optional filename to save to\n" print "eg. %s ramfile.ram AppleWeek" % tail print " %s http://XXXX/stream.ram" % tail print " %s http://XXXX/podcast.xml\n" % tail print "Files will be stored in %s" % path if __name__ == '__main__': if len(sys.argv) < 2: usage() else: main()