When you listen to a podcast, your podcast player downloads the RSS feed of the publisher. Then, it checks the locally downloaded files and downloads the new ones as they come along. In this small project, I will develop a small C# application that downloads the entire media from an RSS feed.

All the information in the RSS feed is public, and all RSS clients download these media files.

Here’s how the program works in a nutshell:

  • It accepts two arguments: the URL of the RSS feed and the target directory to save the files into
  • It then downloads the RSS feed into a temporary XML file
  • It parses the XML and gets the following values: Title, publication date and the URL to download
  • It loops through all the entries in the feed and saves the files to the local file system (It skips existing files so you can run it multiple times, and it won’t re-download unnecessarily)
  • Finally, it deletes the temp XML file

That’s all! Not a fancy podcatcher; it’s a fun little project you can use to archive your favourite podcasts.

The entire source code for the C# 6.0 Console Application is below. Enjoy!

using System.Xml;
using System.Net;

string feedUrl = args[0];
string feedLocalFileNnme = "temp-feed.xml";

string targetLocalDirectory = args[1].TrimEnd('/');

using (var client = new WebClient())
{
    Console.WriteLine($"Downloading {feedUrl} to {feedLocalFileNnme}");
    client.DownloadFile(feedUrl, feedLocalFileNnme);
}

string rawXml = File.ReadAllText(feedLocalFileNnme);
var xmlDocument = new XmlDocument();
xmlDocument.LoadXml(rawXml);

XmlNodeList itemNodeList = xmlDocument.SelectNodes("/rss/channel/item");

for (int i = 0; i < itemNodeList.Count; i++)
{
    XmlNode titleNode = itemNodeList[i].SelectNodes("title")[0];
    XmlNode enclosureNode = itemNodeList[i].SelectNodes("enclosure")[0];
    XmlNode pubDateNode = itemNodeList[i].SelectNodes("pubDate")[0];
    string urlToDownload = enclosureNode.Attributes["url"].Value;
    DateTime pubDate = DateTime.Parse(pubDateNode.InnerText);
    string localFileName = $"{targetLocalDirectory}/{GetDate(pubDate)}-{titleNode.InnerText}.mp3";
    if (!File.Exists(localFileName))
    {
        using (var client = new WebClient())
        {
            Console.WriteLine($"Downloading {urlToDownload} to {localFileName}");
            client.DownloadFile(urlToDownload, localFileName);
            Thread.Sleep(2000);
        }
    }
    else
    {
        Console.WriteLine($"Skipping. File at {localFileName} already exists.");
    }
    
    string GetDate(DateTime pubDate)
    {
        return $"{pubDate.Year}-{pubDate.Month.ToString().PadLeft(2, '0')}-{pubDate.Day.ToString().PadLeft(2, '0')}";
    }
}

File.Delete(feedLocalFileNnme);

Table of Contents

Usage

dotnet run -- {RSS URL} {Target Local Directory}

Resources

Categories: tools

Volkan Paksoy

Volkan Paksoy is a software developer with more than 15 years of experience, focusing mostly on C# and AWS. He’s a home lab and self-hosting fan who loves to spend his personal time developing hobby projects with Raspberry Pi, Arduino, LEGO and everything in-between.