Project PlexRename

Currently I’m working on two small projects that would help me with design of my new mpconverter. First project is called PlexRename and second project is type of media converter that is based on FFMPEG. I’m planning to reuse some of these ideas in the future.

PlexRename is actually the first application that I wrote in C#. Also, my main concern is to implement Object Oriented Programming paradigm. All my project are available on GitHub

The purpose of this small tool is to rename files and make them compatible with Plex Server. For years I have been using following naming convention

SeriesName\Season Number\01×01 Title.mkv

The problem is that Plex has a problem getting metadata for some of the series episodes. Therefore files need to be renamed to this format

Series Name\Season Number\Series Name – S01E01 – Title.mkv

Also there are additional files related to each episodes. Those are thumb files and nfo files. They need to be renamed too. It is absolutely not possible to rename all files in my collection by hand. Recently Plex Server has some problems retrieving metadata for episodes that are named differently than recommended.

This is an interesting project because we need to somehow isolate index from each file name. In given example index is 01×01. To do this we create a List of indexes and assign related value S01E01. Now we have to iterate through the list of indexes and match it to the one inside a file name. Initially I had some issues with performance. I used Dictionary and replaced later with List of Indexes. We have to remember that List if fairly large. Average series season has no more that fifteen episodes. However, some older series could have even up to twenty five episodes in a season. If we run it against large collection of files of 1,500 + the entire process is potentially time consuming. As a result, we should do our iteration only once and retrieve any possible information from a file name when we are dealing with a string directly at the beginning instead of looping through the List of files, finding indexes and than getting information like Series Name.

You have to remember that this tool will only help you if you have TV Series collection that used naming convention compatible with Kodi as I described in above example.

Application is still in development.

Object Oriented Programming. Importance of data types.

Anyone who starts reading about OOP or watches video tutorials about the subject knows that learning curve is very steep. Even if you have some experience of creating your own classes and objects, you still may not be fully comfortable creating complex projects. In fact some of the developers will try to limit number of new objects and classes for sake of avoiding complexity. I hope that after reading this article you will gain enough confidence to tackle OOP on your own.

It all starts with terms like inheritance and polymorphism. Then you are adding new definitions. Soon it feels like things are mushrooming and entire OOP concept is overwhelming. Learning about classes and object is not enough. You need to understand how objects talk to each other. And to make things even more interesting we have Design Patterns that should help us avoid some common mistakes.

Before you begin, you should have some basic understanding of what is data type. Not to overcomplicate things we can have string that represent words, int represent numbers and bool represents true or false. We could also have types that represent objects and classes. You should also be familiar with term constructor and what it does. It’s method that does not return any type, but instead defines object that we want to instantiate. Constructor method has the same name as a class name.

Below is a very simple method called DoSomething ().

public string DoSomething (string name) 
	return name + “ hello world”;

If you are not familiar with writing methods in C#, then you are probably asking yourself question why word string is repeated twice? It is because this particular method not only takes string as parameter inside a bracket, but it also returns string as output. Therefore the first string is a return type.

If I would ask you to rank importance of each element of this method, what order would you give? Maybe it would look like this.

1. DoSomething
2. name
3. string

Out of these three elements only one will remain constant. I can rename the method to SomethingElse(). I can replace “name” with another word. However if I delete both string types, than I do not need anything inside the brackets and there is no need for this method to return any value.

I have to admit that I was not fully aware of importance of types in writing the code. I read about interfaces. This definition of interfaces comes from MSDN website.

“An interface is like an abstract base class. Any class or struct that implements the interface must implement all its members. An interface can’t be instantiated directly. Its members are implemented by any class or struct that implements the interface. Interfaces can contain events, indexers, methods, and properties.”

There is a lot of going on in this definition. We have information about what can be included inside an interface and that it must be implemented by a class that wants to use it. I think our attention is completely drawn to this idea and we have this sort of physical representation of what interface is.

Sometimes interface will be compared to auto parts that fit together or power plug that goes to wall outlet. That power outlet with some extension cord is actually good example. Our plug needs to comply with physical design. We can chain multiple extension cords together because all of them conform to requirement. As I said before, we are probably so much into plugin our cords together that we dismiss importance of what is actually being passed between them, which is electric current. So there you have it, the type that would work with extension cord is electric current.

This is an example of an interface with one method called LogEntry ()

public interface ILogger
    string LogEntry ();

Of course any class that would like to use this interface would have to implement this method. Right now method is called LogEntry (), but I could rename it. However it is far more important for this method to return type string than anything else. Otherwise, it would not be possible to write any entry to our log file.

I think you are starting to get an idea about importance of data types in designing our projects. We could have multitude of objects and classes and absolutely no idea how they work together. We could get lost in searching for method names and interfaces. But as soon we shift our attention to types that are being passed and returned between various methods, we gain clarity of purpose.

I would like to demonstrate this idea with two different examples that ultimately will give the same output. They both approach issue differently and both of them use different types. We start with this line of code:

var selectedMovies = movies.GetByYear(2000).GetById(1).GetByGenre("Action");

We want to filter out some movie collection based on certain criteria. First filter would get us all movies by year. Second filter would get movies with some group id number and finally third filter would return all action movies.

We have two classes that remain unchanged, Movie class and Repository class.

public class Movie
        public string Title { get; set; }
        public int Year { get; set; }
        public int GroupId { get; set; }
        public string Genre { get; set; }


public  class Repository

        private List localDb;

        public Repository()
            localDb = new List();


        public IEnumerable GetAllMovies()
            localDb = new List();

            var movie1 = new Movie() { Title = "Movie1", Year = 2000, GroupId = 1, Genre = "Action" };
            var movie2 = new Movie() { Title = "Movie2", Year = 1999, GroupId = 1, Genre = "Drama" };
            var movie3 = new Movie() { Title = "Movie3", Year = 2000, GroupId = 1, Genre = "Comedy" };
            var movie4 = new Movie() { Title = "Movie4", Year = 2000, GroupId = 2, Genre = "Action" };
            var movie5 = new Movie() { Title = "Movie5", Year = 1999, GroupId = 2, Genre = "Drama" };
            var movie6 = new Movie() { Title = "Movie6", Year = 1999, GroupId = 2, Genre = "Drama" };
            var movie7 = new Movie() { Title = "Movie7", Year = 1999, GroupId = 2, Genre = "Horror" };


            return localDb;

The first approach is to utilize a class that we call Library. Its constructor will take a List of Movie as parameter and hold its data inside a private list. We have two methods GetByYear () and GetById () that return Library object and one method GetByGenre() that returns IEnumerable list of Movie. It’s important that GetByYear () and GetById () return Library object, because that gives them access to any other methods defined inside Library class. And something else interesting is happening here, two Library object talk to each other through constructor and both of them have access to a private list that otherwise is not visible to other objects.

public  class Library
        private IEnumerable MoviesLibrary;

        public Library(IEnumerable movies)

            this.MoviesLibrary = movies.ToList();


        public Library GetByYear(int year)
            return new Library(this.MoviesLibrary.Where(movie => movie.Year == year));


        public Library GetById(int id)
            return new Library(this.MoviesLibrary.Where(movie => movie.GroupId == id));


        public IEnumerable GetByGenre(string genre)
            return this.MoviesLibrary.Where(movie => movie.Genre == genre);


        public void Display()			
            foreach (var movie in this.MoviesLibrary)
Console.WriteLine("Title: {0} , Year {1}, Group: {2}, Genre: {3}",	 movie.Title,movie.Year,movie.GroupId, movie.Genre);



Now let’s try something different. Instead of Library class we can create extension methods that would provide similar functionality. Extension methods differ from regular methods that they require word “this” inside a brackets. For example “this Repository” means that this method will work with Repository type and “this IEnumerable of Movie” can be used with any IEnumerable list of Movie. Also notice that types that are being returned by these methods. GetByYear () , GetById(), and GetByGenre () return IEnumerbale list of Movie. Returning type can be passed as parameter to another method.

public static class Extensions

	public static IEnumerable GetByYear(this Repository repository, int year)
		return repository.GetAllMovies().Where(p=>p.Year == year).Select(p => p);

	public static IEnumerable GetById(this IEnumerable movies, int groupId)
		return movies.Where(p=>p.GroupId == groupId).Select(p => p);
	public static IEnumerable GetByGenre(this IEnumerable movies, string genre)
		return movies.Where(p=>p.Genre == genre).Select(p => p);


Finally this how we will use our classes

Library class:

var repository = new Repository();
var listOfMovies = repository.GetAllMovies();
var movies = new Library(listOfMovies);
var selectedMovies = movies.GetByYear(2000).GetById(1).GetByGenre("Action");

foreach(var movie in selectedMovies)
Console.WriteLine("Title: {0} , Year {1}, Group: {2}, Genre: {3}", movie.Title,movie.Year,movie.GroupId, movie.Genre);

Output: Title: Movie1 , Year 2000, Group: 1, Genre: Action

Extension methods:

var repository = new Repository()
var selectedMovies  = repository.GetByYear(2000).GetById(1).GetByGenre("Action");
foreach(var movie in selectedMovies)
Console.WriteLine("Title: {0} , Year {1}, Group: {2}, Genre: {3}", movie.Title,movie.Year,movie.GroupId, movie.Genre);

Output: Title: Movie1 , Year 2000, Group: 1, Genre: Action

As you can see we have some flexibility when comes to writing our code and as long we understand what types are being passed and returned we should be confident in our design choices. I would strongly recommend before even writing any lines of code to think through some basic structure of classes and objects required. In addition, we have to be flexible too. Sometimes what looks great on paper maybe complete disaster when comes to performance and we have to quickly adjust our design. At that point it is far easier to come to a solution when we shift our attention to types that are required and passed between our objects.

My home media setup.

I would like to tell you little bit more about my home media setup. I started playing with an idea of hooking up my computer to TV set when HTPC was still in infancy stage and my first build was very modest. It included 250G hard drive, dual core Intel CPU and analog Hauppauge TV tuners. As for recording engine I decided to go with BeyondTV. I tested other product but I was not impressed with GUI and its overall experience. Everything was running smooth until HD content started moving to the frontend and my HTPC was becoming noisier at the same time. Snapstream also decided to fold its activities in consumer market. Rebuild was inevitable. This time I went with AMD quad core, 2TB and internal Ceton TV tuners. I also ditched BeyondTV and move over to Windows Media Center. Recently, I removed Ceton tuners and replaced them with SiliconDust HDHomerun Prime. HTPC is showing some signs of wear and tear, however the only thing I would replace right now is a power unit and chassis fan. The AMD CPU is on low side of thermal usage. Its TDP is only 45W, so I can use fan less passive cooling. That CPU is a real gem and unfortunately is no longer available on the market.

Initially, I had also additional hard drive inside. It was storing some movies that I had in my collection. However, due to inconvenience of not being able play them on another computer, I decided to build small size home server. After doing some research, I settled on utilizing LimeTech unRaid, inside a Fractal Design small factor chassis. You can put up to 6 hard drives inside that tight space. Initially, I used dual core Atom CPU, and about 2 years ago I replaced it with new generation Atom CPU that has 8 cores. It is still low power, yet way more powerful.

My main computer is also something that I put together couple years ago. It has an Intel quad core CPU of older generation. It is sufficient for my needs, and at this point replacement is not necessary.

I like to listen to some radio shows. Specifically for that purpose I have dedicated computer with my own software solution. Initially, this computer was a small factor Atom build, and about two years ago I replaced it with a 5th generation Intel NUC. This computer runs 24/7 recording my favorite shows.  It converts them to mp3 format and creates RSS feeds. It has a running web server too, so I can get my podcasts anytime I want.  Very convenient and it is something I use on daily basis.

Latest addition to this setup is another small factor computer that runs Windows Media Center. This is really low end AMD CPU with similarly low TDP that should be able to run fan less, unfortunately I had to enable CPU fan due to overheating, probably due to incorrectly installed display drivers. Anyway, it runs smooth right now in my bedroom.  Before I started putting this computer together, I considered various options like Android TV or NVidia Shield. At the end I decided to stay with Windows Media Center.

As a backup, in case my HTPC fails I have a Roku device. However it is being rarely used.

Windows Media Center on HTPC is a primary TV recording engine. For watching archived media we use Kodi with MySQL running on unRaid server. This way it can be shared on all our computers. For mobile consumption I use Plex clients on my iPhone and NVidia Shield K1 tablet. Plex server docker is running on unRaid too. Recently, I started testing Kodi addon called PlexKodiConnect that allows using Plex server database as backend for Kodi. The biggest plus of this setup is that you can have a mobile client for Kodi. Technically speaking Kodi actually becomes a client for Plex Server.

I have to admit that I do not use that feature as much as I thought I would. Initially, I wanted to sync some content to Plex on my smartphone and watch it later at home in Kodi. However, I found that shorter clips are more suited for my commuting activity. Probably I will return my Kodi setup to its original MySQL backend. As for Plex, I like it as mobile client or even on Roku, but desktop application is lacking flexibility that Kodi provides. In addition, my wife simply does not like Plex’s UI.

As you can see this is fairly simple setup without major bells and whistles. Hardware is a little bit outdated, but for the most part it is serving its purpose. Although, I’m not replacing anything yet, in the future I would definitely go the route of lower power consumption.

Programming. How hard it can be? Part 2

How to build familiarity with a subject that we know nothing about? This is a million dollar question. I realize the difficulty that we are facing. Different people have different learning styles. For some of us classroom setting might be the right one. Others will rely on some tutorials and visual help. There is also tendency to learn things the right way, whatever that means. It is logical to start with introducing some simple concepts like loops and eventually move on to objects, methods and classes. It does make sense if you are looking from that perspective.

Most of us are guilty of believing that what works for us must be also good for general public. I will advise some caution on that matter. Sometimes, I have my doubts too, whether I’m learning things in a correct way and if I actually wasted some valuable time. There is always some risk associated with it.

I have to admit that I‘m not a big fan of step by step tutorials. Neither I like exercises and programming challenges. I’m sure they are valuable tools. However I would like you to consider couple things before you proceed on your coding venture. Think about what software application is and how it works. It could be desktop, web application or a phone app. You take information from somewhere in form of a file. You store that information in memory or in a database. You perform some manipulation on that data and finally you display it to the end user. You may also take some input, validate it and pass it somewhere else. This is rather general description but it is actually true for most scenarios.

Does learning all these necessary steps seem like a proper challenge? Considering that you might be learning programming on your own and you have limited time to spare, would you devote most of it to do some online exercises or concentrate on things that actually make up elements of an application?

As for doing it the right way, I would strongly advise taking different approach. You probably thinking that in order to do something you need to have enough knowledge. Yes and no. Of course it is better when you expand on subject as much as possible. On the other hand should you wait until you learn everything that is possible on that topic? Let me give some example that is close to learning programming and that is learning foreign language. Imagine that for some reason you find yourself traveling in a foreign land and your vocabulary is very limited. Would you try to communicate your needs with words that you already know, or you would not talk at all because your grammar is incorrect? Maybe you have to build more complex sentences with few words that you are familiar with. After all you are not going to wait until you will get it right. That would seem like a wasted opportunity.

My findings for taking programming skills to the next level prove to be on opposite site to what I just described. So, there is no one rule fits all approach. I will write about in different article.

You are probably thinking what kind a nut job is telling you to disregard all rules, avoid tutorials and build functioning application from scratch when you cannot even write simple method. Yeah, that’s pretty much what I would like you to do. In fact, I would make this mandatory. Fire up Google and ask some questions. Figure out what elements do you need to scan folder. Get file names and paths and show them in some list.

If you serious about programming, you can absolutely do it by yourself.


To be continued…

Programming. How hard it can be? Part 1

Couple years ago, I picked up a book about Java with a clear intent of learning programming. After reading “Hello World” chapter and some other paragraphs, I put it back on a shelve and never looked back. There was nothing wrong with that book. It was written by highly respectable authors and it also had very good reviews on Amazon. Yet, the learning curve was too steep at that moment. Instead of giving up completely, I read two other books about VBA programming for Microsoft Excel and Access. As required, I did all necessary exercises and eventually after completing it I did not retain much of that information.

The choice of the language itself was not premeditated. At that time, Java seemed to me like a good starting point. I did not know too much about different languages, and since there are so many of them, the choice I had to make was rather accidental.

Now, if you asking yourself a question where should I start or what programming language I should learn, then this article series may provide some clarity on the subject. My intention is not to give you ready solution, but instead explain some of the things that may seem not that obvious to somebody who wants to start on a path of becoming programmer or developer.

Everybody says that learning programming is about passion and writing code. Although it’s true to some extent, it goes beyond that. It is more about method that you use and rationale behind it. Authors of a book may have a good intentions putting “Hello World” and other paragraphs about loops and if statements, but at the end you as reader feel like you hit a brick wall. Also, ask yourself a question how many of these authors are actually self-taught programmers? Some of them probably are, but in most cases they have a good professional background with Computer Science degree. Now imagine if I asked you do you want to be an Architect or a Lawyer and I gave you some books to study. Then I will tell you to do all exercises and promise to return to check your progress in six months. Does this seem like something realistic? Probably not, yet many aspiring programmers and developers fall into this trap when they subscribe to this way of thinking.

Choice of the language is not that obvious either. Type in Google or YouTube question what language I should learn and you will get tons of answers and opinions. Some people will recommend starting with Python; others will direct you straight to C++. Everybody has some rationale behind it and they would give you a list of associated benefits. Python is considered as one of the friendliest languages to learn. C++ has an opinion of one of the hardest to digest. So, if someone is telling you to start with C++ because after you learn this language everything else would seem easy. I would add another statement that you need to learn how to write a novel. Once you master it, you will definitely know how to write an essay too.

Now let’s go back to my story from the beginning. I picked up that Java book thinking how hard it can be to learn programming? Apparently, there is more to it than just reading some material or even writing some code. I will explain this in upcoming articles. It also made me think why I failed on my first attempt and why I was somewhat successful plowing through VBA material. It’s all about familiarity with subject at hand. I had some experience working with VBA and databases at my workplace. I was completely at home and I was only expanding on my knowledge. Java on the other hand was a terra incognita that quickly closed the gates and kept me at bay while I was hoping to get inside one day.


I started working on converter at the beginning of last summer. I was not concerned with the code itself but rather I wanted to get something that would do the job. I created other tools before, but as you can already guess, I did them mostly to automate some specific aspect of my HTPC setup.

I had a need to move Plex database from my server to another computer. At first it looked like difficult task, but then I realized that I had some pieces of the code already written. Thirty minutes later, I had a working solution and functioning Plex server running on NUC.  It hit me that I should get my programming skills to the next level.  Over the next couple months, through trial and error, I finally was able to get on the right track. I will write series of articles about that process that might be beneficial to some of you.

The converter was meant to be a quick fix to one problem. As I described previously, I was not satisfied with other tools and that’s why I started to working on this one. Unfortunately, the source code is very messy and it is getting to the point when implementing new features is near impossible. Not to mention, that creating different user interfaces would pose some challenges. Therefore, beta 0.4 will most likely be the last iteration of this app in this form.

In the future I would like to have web based app that has exactly the same functionality. That means I would like to be able to access application’s web interface on another computer in my house. I would like view available recordings and add them to queue. The good news is that I have pretty good idea about the components that this new app has to include. I do not have to start everything from scratch. Although, transferring some ideas into Object Oriented Programming proves to be sometimes difficult. Again, I will write some articles about it too.

On HTPC front, I tested DVR capabilities of yet to be released beta version of Plex server and to tell the truth I have some mixed feelings about it. Initially, I wanted to restrict my blog to programming, but on the second thought I will include this type of topics too.

Stay tuned.


New Feature: Queue up movies from a channel


This release contains one important fix and a new feature. Some of the users reported that GUI was crashing during startup showing error that date tag could not be properly converted. Beta 0.4 should take care of it once for all. In addition there is a new feature that will allow you queue up recordings from a specific channel that shows many movies. What you have to do is to select name of the channel and profile you would like to use. Then save it. It should show up in the right panel. Any modifications you would like to make later, would require deleting that channel from a list and save it again.

Once you select the channels you want you can either run app from a Task Scheduler or go to Tools and select Build Queue.

Queue Channels is available under Tools.

Update: Fixed scanning speed of an input folder

This is the last update in this calendar year. It fixes the scanning speed of an input folder. Previous update introduced this issue.

I made some changes to the used method. Originally, we had to know location of a header id number for WTV file. These numbers differed from one operating system to another. Now, we take sample file, map it ourselves by using header name and pass it to the method that extracts metadata. This way we do not need to worry about what Windows version we are using. I tested application on Windows 7 and Windows 10. It should work on Windows 8 too.

Although scanning speed is really fast, you need to consider how many recordings you have in your Recorded TV folder. I have about 3.5 TB of data that takes about 2 minutes to scan over LAN.

Please let me know if you encounter any issues.

Beta 0.2 released

This updated attempts to fix following issues:

  • Added support for Windows 8
  • Preventing manual recordings from being processed
  • Preventing Windows Media Center sample files from being processed
  • Added logs for queue and encoder
  • Removed duplicate episode tag in nfo files
  • Filename tag in xml files was showing full name instead of filename without extension

Note. When updating this application, please remove all xml files from \mpconverter\metadata folder.

Initial scan of Input Folder takes longer than previously. It can actually take couple minutes. This is due to changed method and this is something that will be addressed in future release. I recommend monitoring activity in \metadata folder during initial scan.

“WindowsApplication1 has stopped working” error

Problem:  Application was installed correctly.  However, after editing settings and changing input folder location from “C:\Recorded TV” to “C\Users\Public\Libraries\Recorded TV” application is unable to start properly.

Cause: Some of the WTV files have their metadata tags empty.  It is most likely caused by Windows Media Center sample files or corrupted recordings.

Solution: Edit Folder Options. Select View Tab and check “show hidden, folders”.  Navigate to “C\Users\Public\Libraries\Recorded TV\Sample Media” and delete its content. Next go to “C:\Users\YourUserName\Appdata\Roaming\mcponverter\metadata” and delete its content too. Start application and let it scan Recorded TV folder.

Note: Sample WTV files do not have recording and broadcast dates. Application extracts metadata and creates xml files inside \metadata folder but when it starts again it parses xml files and it expects dates to be there. I will try to address this issue in next release. It is possible that your sample folder is already empty. In this case, some of the files may have similar issue.

This application was developed on Windows 7. I was able to test it on Windows 10.  It was not tested on Windows 8. Each Window version reads WTV metadata little bit differently. This is something you should be aware of.