Skip to content

Instantly share code, notes, and snippets.

@wietze
Created August 7, 2016 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wietze/65f8eac0232d052f41d5b28ab5a62c65 to your computer and use it in GitHub Desktop.
Save wietze/65f8eac0232d052f41d5b28ab5a62c65 to your computer and use it in GitHub Desktop.
Podcast from stream
import os
import time
import datetime
from dateutil.parser import parse
from pytz import timezone
import re
import glob
import socket
from subprocess import call
from feedgen.feed import FeedGenerator
import SimpleHTTPServer, SocketServer
"""
This script can be used to create your own podcast based on an existing stream.
Upon running this script, the specified stream will be recorded for the specified duration and
saved into an MP3 file. After the recording has finished, a SimpleHTTPServer is launched which
hosts the recordings and provides a podcast feed.
"""
OUTPUT_DIR = "./" # Directory to save the podcasts to.
DURATION = 60 * 60 # The duration (in seconds) of the recording.
STREAM_URL = "" # URL of the audio stream.
PODCAST_TITLE = "Podcast" # Title of the podcast.
PODCAST_FEED_PORT = 8080 # Port number used for accessing the podcasts.
PODCAST_FEED_DURATION = 60 * 60 # The duration (in seconds) of the availability of the podcast feed
# after the recording has finished.
NUMBER_OF_PODCASTS = 3 # The number of podcasts that will be offered. The oldest redundant
# recording(s) will be removed.
def log(msg): print ("[{}] {}".format(time.strftime("%X"), msg))
def record_stream(url, file, duration):
log("Started recording")
code = call(["avconv", "-probesize", "10000", "-i", url, "-map", "0:0", "-c:a", "copy", "-t",
str(duration + 30), "-y", "-loglevel", "error", file])
log("Finished recording")
return code
def clean_up_files():
for i, file in enumerate(sorted(glob.glob("*.mp3"), key=os.path.getmtime, reverse=True)):
if i < NUMBER_OF_PODCASTS: continue
os.remove(file)
log("Removed {}".format(file))
def generate_feed(port):
log("Started generating feed")
address = get_network_ip()
full_address = "http://{0}:{1}".format(address, port)
fg = FeedGenerator()
fg.load_extension('podcast')
fg.podcast.itunes_category('Technology', 'Podcasting')
fg.id(full_address)
fg.title(PODCAST_TITLE)
fg.author( {'name':'', 'email':''} )
fg.logo('{0}/logo.jpg'.format(full_address))
fg.subtitle('Podcast of {}.'.format(PODCAST_TITLE))
fg.link(href='{}/podcast.xml'.format(full_address), rel='self')
fg.language('en')
files = glob.glob("*.mp3")
for filename in files:
fe = fg.add_entry()
url = "{}/{}".format(full_address,filename)
fe.id(url)
p = re.search('([0-9]{6})\]( \(([0-9])\))*\.mp3$', filename)
if p is not None:
title = '{} of '.format(PODCAST_TITLE) + \
"{0:%A} {0:%d} {0:%B} {0:%Y}".format(parse(p.group(1)))
title = title + \
(" - part {}".format(1 + int(p.group(3))) if p.group(3) is not None else '')
fe.title(title)
else:
fe.title(filename)
size = os.path.getsize(filename)
fe.enclosure(url, bytes(size), 'audio/mpeg')
localtz = timezone('Europe/Amsterdam')
datet = localtz.localize(datetime.datetime.fromtimestamp(os.path.getctime(filename)))
fe.published(datet)
fe.pubdate(datet)
fg.rss_str(pretty=True)
fg.rss_file('podcast.xml')
log("Finished generating feed")
def get_network_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('www.google.co.uk', 0))
return s.getsockname()[0]
def start_podcaster(port, duration):
os.system("python -m SimpleHTTPServer {} & sleep {} ; kill $!".format(port, duration))
if __name__ == "__main__":
os.chdir(OUTPUT_DIR)
code = record_stream(STREAM_URL, "Podcast [{}].mp3".format(time.strftime("%Y%m%d")), DURATION)
if code != 0: log("WARNING: Recording unsuccessful")
clean_up_files()
generate_feed(PODCAST_FEED_PORT)
start_podcaster(PODCAST_FEED_PORT, PODCAST_FEED_DURATION)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment