Created
August 7, 2016 17:21
-
-
Save wietze/65f8eac0232d052f41d5b28ab5a62c65 to your computer and use it in GitHub Desktop.
Podcast from stream
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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