Click here to Skip to main content
15,867,686 members
Articles / Desktop Programming / WPF
Article

The WPF Podcatcher Series - Part 1 (Introducing Podder)

Rate me:
Please Sign up or sign in to vote.
4.78/5 (25 votes)
6 Jan 2008CPOL7 min read 168.2K   1.9K   119   35
The first article in a series devoted to a WPF application that plays streaming podcasts off the Internet.
Podder_Screenshot.png

Introduction

Welcome to the first article in a series devoted to a WPF application I wrote, called Podder. Podder allows you to listen to podcasts streamed over the Web. The aim of this article is to introduce Podder and let people around the world start enjoying it. The goal of this entire series, however, is to review interesting aspects of Podder’s design and implementation.

At the time of this writing, the application is incomplete. There are still many features, both big and small, that I intend to add to Podder. However, it is far enough along at this point to get this series off the ground, so I decided that sooner is better than later. The file downloads, located at the top of this article, will most likely change every time there is a new article in the series. Podder is a living project.

Background

A podcast is like a radio show; it is a series of episodes recorded by the same person or people about some particular topic. It can contain any audio content, since it is just a regular audio file, such as MP3. An episode can contain interviews, monologues, music, the sound of one hand clapping, etc. Almost every podcast has an RSS feed associated with it, so that you can easily find all episodes in the podcast, and discover newly released episodes.

A podcatcher is a program that allows you to play podcast episodes. Most podcatchers allow you to subscribe to various podcast RSS feeds, and will automatically notify you when a new episode is available. Podder allows you to maintain a list of podcast RSS feeds, but does not yet provide any notifications when new episodes exist.

The Podder application was created after I had built two simple podcatcher prototypes; the first was in Silverlight and the other in WPF. Podder is much more sophisticated and feature-rich than those two prototypes, but they were excellent learning experiences necessary for me to figure out how to design Podder correctly.

Technologies Used

  • VS2008 & .NET 3.5
  • WPF
  • XLinq
  • C# 3.0

Podder Features

The application has the core features one might expect in a podcatcher, and a few extra bells and whistles that I enjoy using. Here is what you will find in Podder:

  • Store a list of podcast RSS feeds and view all available episodes
  • Stream episodes for immediate playback
  • Standard play, pause, and stop functionality
  • Seek through a podcast, like fast-forward and rewind
  • Indicate which episodes are your favorite, and view them in a “My Favorites” list. That list is persisted between runs of the application.
  • Remember which episodes you have already listened to because they are marked as “finished” when they complete. The list of finished episodes is persisted between runs.
  • Optionally play every episode in a podcast in an endless loop
  • Refresh the list of episodes in a podcast, which is useful for frequently updated podcast feeds
  • Open an episode in an external program (either a Web browser or an MP3 player, depending on the podcast)
  • Tooltip over episode item in ListView displays extra information such as publication date and file size
  • Window sizes, states, and positions persist between runs of the application
  • Various user interface settings persist between runs of the application
  • Pre-loaded with some podcasts, so new users can immediately start listening to episodes
  • Podder will eventually allow you to apply completely different user interfaces at runtime (a.k.a. “structural skinning”)

Picture Gallery

Here are some screenshots of Podder, using the default skin (at this point, it is the only skin). The first image shows the list of favorite episodes and a tooltip over an episode, displaying extra information about it.

Podder_Favorites.png

The next image shows the list of podcasts I have entered into Podder. Notice that the first item in the dropdown allows you to view the list of favorite episodes.

Podder_Podcasts.png

The screenshot below shows the context menu that appears when you right-click on an item in the ListView. The menu item allows you to open an episode in a Web browser or MP3 player, based on the URL provided in the podcast RSS feed’s <link> element. If it is a Web page URL, the page will open in your default browser. If it points directly to an audio file, it will open in your default audio player (such as Windows Media Player).

Podder_OpenInExternalProgram.png

The last image shows the dialog box used to add and remove podcasts to the application’s list of podcast RSS feeds. At the time of this writing, this dialog box does not provide any validation, but it will in a subsequent release.

Podder_ManagePodcasts.png

Points of Interest

There are many interesting things to explore in Podder. This section lists some of them, and the next articles in the series explore some of them in detail.

Structural Skinning

Podder supports what I call “structural skinning”. Structural skinning allows you to apply a completely new user interface to the application at runtime. You can replace all of the controls in the UI, as well as the color schemes, fonts, etc. It uses the Model-View-Controller (MVC) pattern, routed commands, collection views, and dynamic resource references to make this possible. A future article in this series will review this topic in depth. As of this writing, Podder does not have any additional skins, but it will soon.

EpisodePlayer

The application uses WPF’s MediaPlayer class to play episode MP3 files. I subclassed MediaPlayer to create EpisodePlayer, which encapsulates MediaPlayer manipulation and workaround for its quirks. A disproportionately large amount of my development effort was spent on working around strange behavior of MediaPlayer. I have ironed out all the issues, as best as I can.

Reading an RSS Feed with XLinq

A podcast’s RSS feed is just like any RSS feed, it is just an XML document. Since Podder was written against the .NET 3.5 Framework, I used XLinq to transform an RSS feed into instances of my Episode class. Using XLinq made the XML processing much easier.

Serializable Data Model

Podder does not use a database or XML file to save its data. When the window closes, it serializes the data model using BinaryFormatter and saves that binary stream to disk. When the application opens again, it deserializes the data in that file and the application then uses those objects.

The application’s domain classes are in the PodderLib project. Most of those classes derive from my BindableObject base class, which provides an implementation of INotifyPropertyChanged, amongst other things.

Persisted Window Settings

Both the main window and the “Manage Podcasts” dialog box remember their size, state, and location between runs of the app. They both derive from my ConfigurableWindow base class to gain that functionality for free. That class was built specifically for Podder, but can be used in any WPF program.

So Much More…

It is difficult to create a list of “interesting” aspects of an application’s code base, because everyone sees things differently. If you are interested in seeing what else Podder has to offer, I suggest you download the source code and explore it on your own. If you have any questions, feel free to leave a question or comment on this article’s message board.

Not Yet Implemented

  • Ability to dynamically discover and apply external skins
  • Awareness of an active Internet connection, or lack thereof
  • An improved Podcast management dialog
  • User-friendly error handling
  • An aesthetically pleasing UI
  • Notifications of when a new episode exists in one of your feeds
  • A whole lot more!

Special Thanks

Craig Shoemaker, the host of Polymorphic Podcast, provided a lot of helpful feedback, insightful suggestions, and encouragement.

Karl Shifflett helped a lot with testing and submitting bug reports. He also gave some tasteful feature requests.

Sacha Barber indirectly assisted because his article about XLinq helped me get up to speed with XLinq enough so that I could use it to parse RSS feeds.

Revision History

  • January 6, 2008 - Created the article

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Josh creates software, for iOS and Windows.

He works at Black Pixel as a Senior Developer.

Read his iOS Programming for .NET Developers[^] book to learn how to write iPhone and iPad apps by leveraging your existing .NET skills.

Use his Master WPF[^] app on your iPhone to sharpen your WPF skills on the go.

Check out his Advanced MVVM[^] book.

Visit his WPF blog[^] or stop by his iOS blog[^].

See his website Josh Smith Digital[^].

Comments and Discussions

 
General[Message Removed] Pin
nompel20-Sep-08 14:57
nompel20-Sep-08 14:57 
NewsPodder v2 Has Been Released! Pin
Josh Smith6-Mar-08 9:26
Josh Smith6-Mar-08 9:26 
GeneralQuestion on Data Binding Usage [modified] Pin
aerospaceboy3-Feb-08 9:37
aerospaceboy3-Feb-08 9:37 
GeneralRe: Question on Data Binding Usage Pin
Josh Smith3-Feb-08 10:01
Josh Smith3-Feb-08 10:01 
GeneralCool.... Pin
marlongrech7-Jan-08 11:33
marlongrech7-Jan-08 11:33 
GeneralRe: Cool.... Pin
Josh Smith7-Jan-08 11:42
Josh Smith7-Jan-08 11:42 
GeneralRe: Cool.... Pin
marlongrech7-Jan-08 12:03
marlongrech7-Jan-08 12:03 
GeneralNice but... Pin
Rama Krishna Vavilala7-Jan-08 3:47
Rama Krishna Vavilala7-Jan-08 3:47 
GeneralRe: Nice but... [modified] Pin
User 2710097-Jan-08 5:20
User 2710097-Jan-08 5:20 
GeneralRe: Nice but... Pin
Josh Smith7-Jan-08 5:57
Josh Smith7-Jan-08 5:57 
GeneralI like the bindable object idea Pin
Sacha Barber7-Jan-08 7:29
Sacha Barber7-Jan-08 7:29 
GeneralRe: I like the bindable object idea Pin
Josh Smith7-Jan-08 7:50
Josh Smith7-Jan-08 7:50 
GeneralRe: I like the bindable object idea Pin
Sacha Barber7-Jan-08 9:14
Sacha Barber7-Jan-08 9:14 
GeneralRe: I like the bindable object idea Pin
roland rodriguez7-Jan-08 11:06
roland rodriguez7-Jan-08 11:06 
GeneralRe: I like the bindable object idea Pin
Josh Smith7-Jan-08 11:14
Josh Smith7-Jan-08 11:14 
GeneralRe: I like the bindable object idea Pin
roland rodriguez7-Jan-08 11:19
roland rodriguez7-Jan-08 11:19 
GeneralRe: I like the bindable object idea Pin
Josh Smith7-Jan-08 11:25
Josh Smith7-Jan-08 11:25 
GeneralRe: I like the bindable object idea Pin
Maximilian Hänel12-Apr-08 9:13
Maximilian Hänel12-Apr-08 9:13 
GeneralRe: I like the bindable object idea Pin
Josh Smith12-Apr-08 9:18
Josh Smith12-Apr-08 9:18 
GeneralRe: I like the bindable object idea Pin
Maximilian Hänel14-Apr-08 1:28
Maximilian Hänel14-Apr-08 1:28 
I'm curious why you do not use XamlReader /XamlWriter for this purpose? It should work perfectly with DependencyObject derivates.

cu

"All languages allow you to write crap code, VB just makes it easier (IMO)."
Michael P Butler

GeneralRe: I like the bindable object idea Pin
Josh Smith15-Apr-08 5:06
Josh Smith15-Apr-08 5:06 
GeneralRe: I like the bindable object idea Pin
Maximilian Hänel15-Apr-08 5:09
Maximilian Hänel15-Apr-08 5:09 
GeneralRe: Nice but... Pin
Rama Krishna Vavilala7-Jan-08 9:23
Rama Krishna Vavilala7-Jan-08 9:23 
GeneralRe: Nice but... Pin
Josh Smith7-Jan-08 9:35
Josh Smith7-Jan-08 9:35 
GeneralRe: Nice but... Pin
Rama Krishna Vavilala7-Jan-08 9:51
Rama Krishna Vavilala7-Jan-08 9:51 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.