Tuesday, April 15, 2014

I'm Back!

So, I haven't posted much for a while. That's because I've been travelling and speaking and talking to old friends and meeting new folks. I've got a bit of a "break", so I hope to catch up on some articles I've been meaning to get to. Overall, the last 6 weeks have been a lot of fun (and a bit tiring).

Here's a recap:

Pluralsight Author Summit
At the beginning of March, I was in Salt Lake City (UT) for the Pluralsight Author Summit. This was a great weekend of talking to the folks at Pluralsight and spending time with other authors from around the world. It was also great to see Pluralsight's commitment to education, and it makes me want to produce more courses. (Stay tuned; I'll be starting a new course soon.)

Code Camps
I also spoke at 2 Code Camps: Utah Code Camp in Salt Lake City (UT) and Desert Code Camp in Chandler (AZ). Both of these events were a lot of fun. It was my 2nd time at the Utah Code Camp, and it grew a lot in the last year. It was cool to meet some people who already knew me through my Pluralsight courses. And (as usual), I found some people I didn't know to have lunch with. It was a great facility with nice, big rooms. I had about 100 people in each of my presentations.

It was my 7th time out to Desert Code Camp. The weather in the Phoenix area is actually very pleasant in April and November. And since I've been out there so many times, I've got lots of friends. It was great to catch up with people I haven't seen for a while and to meet more new people.

Distant User Groups
I've been travelling for user groups as well. I went out to Las Vegas (NV) for dotNETGroup.org. That group is also growing, and I had a really great time talking about Dependency Injection. One of my favorite things is to see a group that has grown since the last time I spoke there. Getting more and more people involved in our developer community events makes us stronger as a whole.

And last week, I went up to Berkeley (CA) to speak at EastBay .NET. It turns out that Berkeley and Phoenix are the same distance from where I live in So Cal. I spent a couple days in the Bay Area and got to see some friends I haven't seen for a while. And I met new people as well. I ran into someone who came to the user group on the BART platform (Hi, Nicolay!), and we got to talk for a while.

Local User Groups
And I spoke at a bunch of local user groups as well (where "local" means Orange County, Los Angeles, San Bernardino, and San Diego -- basically, within 100 miles of where I live). I see the local folks a bit more often, but even so, I got to catch up with some folks I haven't seen for a few months.

In addition, the San Diego .NET Developers Group celebrated its 20th anniversary (and before you ask, it used to be a VB group). David McCarter has done some great things with the group over the years, and he invited some of the "founding fathers" to come and talk about the beginning of the group. In addition, he got Scott Hunter from Microsoft to come down and speak (pretty impressive since it was the same week as BUILD).

For a full listing (and links to a user group that may be near you), you can check out March Speaking Engagements and April Speaking Engagements.

I don't have anything scheduled for the next few weeks. But I'm working on some new events. In case you haven't figured it out yet, I love to speak -- actually, I love to teach and watch people learn. So, there will definitely be more to come.

Happy Coding!

Monday, March 31, 2014

April 2014 Speaking Engagements

March was a busy month. I got to travel to Salt Lake City and Las Vegas, and I spoke all around Southern California (LA, Orange County, San Diego). I had a lot of fun, and it was great to make a bunch of new friends and talk to devs working with different tools.

April is shaping up to be pretty busy, too. I've got 3 events planned so far, and there's a couple more waiting in the wings. If you're in the area, be sure to stop by.

Saturday, April 5, 2014
Desert Code Camp
Chander, AZ
o IEnumerable, ISaveable, IDon'tGetIt: Understanding .NET Interfaces
o Learn the Lingo: Design Patterns
o T, Earl Grey, Hot: Generics in .NET

The Desert Code Camp is always a lot of fun. I've been out there 6 times so far. I'm looking forward to seeing a bunch of old friends and making some new ones.

Tuesday, April 8, 2014
Inland Empire .NET User's Group
San Bernardino, CA
Topic: Shields Up! Defensive Coding in C#

Thursday, April 10, 2014
EastBay .NET
Berkeley, CA
Topic: Shields Up! Defensive Coding in C#

Defensive Coding is all about making sure our code is robust and effective. We want to make sure that our users have the best experience possible. And this means that we need to be prepared for the unexpected and make sure that our application behaves appropriately.

Stay tuned. More items will show up as they get confirmed.

Happy Coding!

Sunday, March 9, 2014

New Video: Generic Interfaces

Last month, I started a series on C# Generics on my YouTube channel. Part 2 is now available: C# Generics- Part 2: Interfaces

I'm a big fan of interfaces (as evidenced in IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces). When we add generics to interfaces, we get code that is flexible and reusable. In this video, we take a look at 2 different interfaces that are so similar that we can't help but want to combine them. It turns out that merging them into a single interface is made easy with generics.

Future videos will look at generics in methods as well as generic constraints. So stay tuned for more to come.

C# Generics:
Part 1: Collections
Part 2: Interfaces

Happy Coding!

Thursday, February 27, 2014

March 2014 Speaking Engagements

It looks like March will be pretty busy for me. I have four events scheduled so far:

Wednesday, March 5, 2014
SoCal .NET Developers Group
Buena Park, CA
Topic: Dependency Injection: A Practical Introduction

Saturday, March 15, 2014
Utah Code Camp
Salt Lake City, UT
Learn to Love Lambdas
Clean Code: Homicidal Maniacs Read Code, Too!

Tuesday, March 18, 2014
Disney .NET Developers Group
Burbank, CA
Topic: Keep Your UI Responsive with the BackgroundWorker Component

Thursday, March 20, 2014
SoCal .NET Architecture
Newport Beach, CA
Topic: Abstract Art: Getting Things "Just Right"

Tuesday, March 25, 2014
San Diego .NET User Group
San Diego, CA
Topic: IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces

Thursday, March 27, 2014
Las Vegas, NV
Topic: Dependency Injection: A Practical Introduction

Dependency Injection continues to be a popular topic. DI is extremely useful for creating loosely coupled applications. Unfortunately, most devs are introduced to DI by being thrown into code that uses a Dependency Injection container (such as Unity, Ninject, or StructureMap). We start learning DI by implementing it manually. That way, we understand the concepts and the steps involved. After we have a good handle on that, we look at how containers can help take care of the tedious bits and also provide extra functionality.

Stay tuned: I have a number of event scheduled at the beginning of April. So, if you're in Phoenix AZ, Los Angeles CA, San Bernardino CA, or the San Francisco Bay area, you'll have a chance to come see me soon.

Hope to see you at an upcoming event. And if you want me to come to your event, just drop me a note.

Happy Coding!

Friday, February 21, 2014

Demystifying the "var" Keyword in C#

There are some misconceptions about the "var" keyword in C#. The "var" keyword was added to the C# language to solve a specific problem, but developers use it in other parts of their code as well (and there's nothing wrong with that). We'll take a look at what "var" is (and what it isn't), look at the reason it was created, and then I'll show where I use it and my reasoning behind that.

This whole discussion has been spurred by some questions that I've received from a few developers recently:

     Does using "var" affect performance?
     Does "var" indicate a variant type that we have in other languages?

Let's answer these questions by looking at how "var" works.

"var" Is Just a Shortcut
(The way that most developers use it)
Where we most often see "var", it is just a shortcut to writing out the type for a variable. The idea is that the compiler can figure out the actual type based on what we are assigning to the variable, so we don't have to be explicit about the type. Let's start with a simple example:

These lines of code are 100% equivalent from a technical perspective. (We'll talk about the readability perspective a bit later.) Both the "message1" and "message2" variables of are type "string". And they are both strongly typed.

We can see that "message1" is strongly typed by putting our mouse over the "var" keyword:

This clearly shows that "message1" is a string. Since the compiler can figure out the type based on the assignment, we can use "var" as a shortcut and let the compiler fill in the rest.

The variable is strongly typed. This is not a variant or dynamic variable that we might see in other languages. When "message1" is declared and initialized, it is a string, and it will always be a string. If we try to assign an integer to "message1" later in our code, we will get a compiler error.

There is no performance difference between these two lines of code. We can look at the IL (the intermediate language produced by the compiler) to verify this:

This shows the local variables for a particular method. We can see that "var message1" and "string message2" compile down to exactly the same code. This means that there is no performance difference between these 2 statements. All of the work is done at compile-time.

Let's look at an example with a more complex type:

As above, these two lines of code are equivalent. both "persons1" and "persons2" are of type "List<Person>". If we look at the IL that is generated, we see that both variables have the same type:

This type looks a little strange because it has a generic parameter and the assembly and namespaces are listed. But this just means "List<Person>".

Why "var" Exists
So, we've seen how most developers use "var" -- it's a way for us to create variables without having to write out the specific type. But, this isn't a good reason for adding a new keyword to a language; "var" was actually added for a completely different purpose.

With C# 3.0 (.NET 3.5), we got LINQ, Language INtegrated Query, and it's one of the most awesome things that's been added to C#. One thing that was added to make LINQ work well was the concept of anonymous types.

An anonymous type is a new type that is created "on-the-fly". And just like an anonymous delegate, an anonymous type does not have a name (well, it actually does, we just can't see it). Here's an example:

This declares a variable called "anonPerson" and assigns an anonymous type to it. We create an anonymous type by using the "new" keyword and then supplying property names and values inside curly braces. This example creates a type with 2 properties: FirstName and LastName.

This is a situation where we must use "var". Why? Well, think about the type of the "anonPerson" variable. What is it? By definition, it is an anonymous type which doesn't have a name, so we really have no way to refer to it. So instead, we use "var" and let the compiler deal with it. We can see how the compiler deals with it by hovering the mouse over the "var" keyword:

This shows us that "anonPerson" is an anonymous type, which has been designated 'a. That type consists of 2 properties: FirstName and LastName. The compiler has figured out these are both strings because we assigned strings to the properties.

Now, most of the time, we don't go around creating anonymous types. But, if we use projections with LINQ, we can easily end up with anonymous types. Let's take a look at some more code. First, we have some variables:

Again, these 2 lines of code are equivalent. The "People.GetPeople()" method returns a populated List consisting of 7 Person objects. The "Person" type is pretty simple; just 4 properties:

Next, let's query one of our variables using LINQ:

This will query the "people2" variable and find all of the items where the "FirstName" property is "John". Then in the "select" portion, it creates a new anonymous type based on 2 of the properties of the "Person" class. This is known as a projection, where we take the values of one type (or multiple types) and map them to a new type.

If we hover the mouse over the "var", we can see the actual type:

We get an "IEnumerable<T>" back from this query (which is pretty normal). And if we look, we see that the "T" is actually an anonymous type. This properties for this type happen to match the anonymous type that we created manually above: FirstName and LastName.

So, we can see that when we do projections in LINQ that result in anonymous types, we must use the "var" keyword since the anonymous type does not have a name.

Restrictions to Using "var"
Because of how "var" is implemented, there are a few restrictions on where we can use "var". These will result in compiler errors if we don't adhere to them.

First, we can only use "var" in a local scope where the variable is declared and initialized in a single statement. This makes sense if we think about it. Since the variable is strongly typed, the compiler needs to know what type it is when it is declared. It figured out the type by looking at the value that is being assigned. If the variable is not immediately initialized, then the compiler cannot determine the type.

Second, "var" cannot be used for class-level fields. This is something that people often try to do. "var" is pretty much limited to variables that are locally scoped to a method.

There are the restrictions that most people run into problems with. There are a few more restrictions, but we don't run across them as often. For more information, check out the MSDN article on Implicitly Typed Local Variables.

How I Use "var"
What we've seen is that "var" compiles to exactly the same IL as if we are explicit with our types. And we've also seen that there is no performance difference when we use "var". So, the question becomes, when should we use "var" and when should we be explicit?

Note: We're talking about the non-required use of "var" in declaring variables like in our first example. We've already seen that we must use "var" with anonymous types.

There are many schools of thought on this. Since there is no technical difference, it really comes down to a matter of preference. I've heard of some developers who say that we should use "var" wherever we can (meaning, wherever the restrictions allow us to use "var"). The thinking behind this is that if the types need to change in the future, then the code that declares the variables does not need to be updated. I understand the thinking behind this, but I don't necessarily agree with it.

Focus on Readability
Whenever I use "var", I think about the readability of my code. I'm a big proponent of making code that is easy to approach, follow, maintain, and debug (you can check out my materials on Clean Code if you need convincing of that).

So, let's go back to our examples from above, and I'll tell you where I do use "var" and where I don't.

For this example, I do use "var". For the "person1" variable, I can easily tell the type because it is stated in the assignment. This is a "List<Person>" variable.

In my view, "person2" is a bit harder to read (this is my subjective viewpoint, of course). Since "List<Person>" is repeated on both sides of the assignment operator, it just gets in the way of me picking out the important bits of this statement. This is even more pronounced when we have longer types, like "Dictionary<int, Person>".

Here's another example:

In this situation, I do not use "var". For the "people1" variable, it is not immediately clear what the type is. I need to know the return type of the "GetPeople()" method. It is easy to get that value, by hovering the mouse over either "GetPeople" or "var", but that's an extra step.

For the "people2" variable, I don't have to take any additional steps. I can see that the type is "List<Person>" right in the code.

These are just my views on the subject. If you are in a team environment, it is more important that everyone on the team takes the same approach. If we all do the same thing, then other developers know what to expect when they open up our code.

Wrap Up
I use "var" pretty unconsciously at this point. And that's probably why I get asked about it so much. When we're new to "var", we might think that it creates a variant or dynamic variable. Or we might think that there is some technical reason why we should or should not use it.

But the reality is that "var" does not have any effect on the compiled output. The variables are still strongly typed, and the IL that is generated is exactly the same as if we put in the explicit type. There are a few places where we must use "var" (such as with anonymous types), but most often "var" is simply used as a shortcut. Since the compiler can figure out what the actual type is, we don't have to put that in.

The primary thing we need to keep in mind when we're writing code is that someone else will have to read it. So, we want to make sure that when we do use these types of shortcuts, we don't diminish the readability of our code.

Happy Coding!

Tuesday, February 18, 2014

1000 Ratings for C# Interfaces

My C# Interfaces course on Pluralsight hit a milestone today: 1000 ratings:

Thanks to everyone who took the time to watch the course and rate it. Be sure to check out my other courses as well: http://pluralsight.com/training/Authors/Details/jeremy-clark

Happy Coding!

Sunday, February 16, 2014

Jeremy's Screencast Production: Hardware, Software, and Process

Several people have asked about the screencast setup that I use for Pluralsight and YouTube: software, hardware, process. Just so I don't have to write the same email again, I'm going to put everything here. I've been using the same tools for the last 6 months or so, so I've had a chance to "dial in" what works for me.

Let's take a look at what I do and the tools I use. I'm not getting any kick-backs from the product vendors, and I'll provide Amazon links for the hardware just because it's easy (no kick-backs from Amazon, either).

We'll start by looking at the software that I use and what I like about it.

Screen Capture
For screen capture, I use Camtasia Recorder 8 (which is part of Camtasia Studio from TechSmith). They have both a Windows and a Mac version. I use the Windows version, so I'll only speak to that.

Here's a screenshot of Camtasia Recorder:

Camtasia Recorder for screen capture and Camtasia Studio for editing go hand-in-hand. The features that are available in Recorder wouldn't be very useful to other video editing applications. You can see that there are options to determine which parts of the screen you will capture as well as whether you're capturing the webcam and audio.

In addition, the audio options allow you to capture system sounds (or not), and the cursor is captured separately so that you can edit it later. All very useful.

I haven't used the webcam recording in a released video (yet). You can thank me later for not having to look at me.

Video Editing
As mentioned above, I use Camtasia Studio for editing. My needs are pretty simple, so I haven't found that I really wanted something that wasn't there (other than "automatically fix the audio" which I'll talk about below).

Here's a screenshot (which looks better on a big monitor with lots of stuff showing/zoomed in):

I won't go over all the features of Camtasia; you can learn about that from the website. But there are a few things that I really like and I use frequently.

As mentioned in the "Screen Capture" section, Camtasia Recorder captures the mouse as a separate object. This means that we can remove it or add effects during the editing process:

I don't generally do too much with the cursor. Primarily, I uncheck the "Mouse cursor visible" option during the slide portions of my videos. I really like that I don't have to think about this during recording, and I can easily fix it during editing.

You can also add "click" effects so that there is a visual change when the mouse is clicked. I don't generally use these, but I see how it could be very useful in a product tutorial where you're showing someone how to use an application.

I also spend quite a bit of time with the Audio tab:

I don't use the processing options (like the volume leveling or noise removal); I don't really have the problems that these options solve. But I do use the "Silence" button quite a bit as well as the "Volume down" button. I'll talk more about these when I go through the production process.

Finally, I really like the Callouts that are available:

I frequently use the "Spotlight" option (which is shown here). And I also use the arrows quite a bit. These are really useful for drawing the viewer's eye to just the right thing on the screen. I've also done a bit of animation with the arrows (to move an arrow around the screen to point to different things). But I usually don't get too complex with my video effects.

And there are lots of other features available as well, including zooming, scene transitions, and narration.

Video Rendering
Camtasia also offers quite a few options when rendering video. You can render to various formats, different bitrates and resolutions, and you can also add a watermark to the video during the rendering process (this is how I get the Pluralsight logo in the bottom right corner of those videos).

Camtasia will also let you do batch rendering of multiple projects. This is really good for something like Pluralsight where I usually have 7 to 10 separate clips that make up a module.

Here's a picture of my "studio":

As you can see, things are pretty simple. The piece of hardware that makes the biggest difference to the quality of the screencast is the microphone.

I use the RĂ˜de Podcaster microphone along with a swing arm and shock mount (Amazon link). This is a USB mic that plugs straight into my laptop, and I'll have to say that this is the best purchase that I've ever made. To demonstrate the difference that good audio makes, compare the following videos:

Laptop mic: C# Properties
Podcaster: Anatomy of a Lambda Expression

Now you might say that I should have used a headset mic instead of the built-in laptop mic, but it turned out that the mic built in to my MacBook Air was actually better quality that the Logitech headset that I had. Either way, the Podcaster is way ahead of the other options.

I also know a lot of screencasters who use the Blue Yeti (Amazon link) and are happy with the results. Again, you'll probably also want a swing arm (for convenience) and a shock mount to isolate the microphone from vibrations from the keyboard. You may also want a pop filter (the Podcaster has an integrated pop filter which works pretty well).

Swing Arm / Work Table
The microphone is attached to a table that is 40 inches tall. This is a good height for me. And because the microphone is mounted on a swing arm, I have the option of recording standing up or sitting down (on a barstool). Being able to change positions is especially welcome when doing all-day recording sessions.

The swing arm is also good because I can simply move the microphone out of the way when it comes time to edit. With my setup, I can move the microphone so that it sits behind the monitor.

Shuttle Control
My newest piece of hardware is a shuttle control. I have the ShuttlePRO V.2 from Controur Design (Amazon link). I've only used this on one video so far (C# Generics Part 1), but this has made a *huge* difference. One of my biggest frustrations in editing was getting exactly the right frame (especially when trying to adjust audio or edit portions of video). The mouse is too fiddly, and the keyboard behaves inconsistently depending on what has focus. The shuttle control eliminates that frustration.

I picked this one based on a blog entry from Scott Hanselman (Human Computer Interaction Diversity - 7 Devices that AREN'T a mouse and keyboard). He points out that Tod created a Camtasia profile for this device (Camtasia Studio and the ShuttlePro V2). I'm sure that I'll be customizing the buttons for the things that work for me, but I've found these settings to be a really good starting point.

[Update 03/03/2014: It turns out that Tod is Tod Gentille, another Pluralsight author, and I got to meet him at the Pluralsight Author's Summit this weekend. He's a great guy, and I was happy to be able to thank him in person for creating these settings.]

This stuff plugs into a 13" MacBook Air that's a couple years old (i7-2667M and 4GB RAM). I haven't had any problems with video capture, audio capture, or performance -- no stuttering or other craziness. One big advantage of this laptop is the SSD; I've been told that having an SSD (opposed to a spinning hard drive) makes a huge difference in overall editing and rendering experience.

Rendering is acceptable. I generally record and output at 1024x768, and rendering times are about 1 to 1 (meaning 1 minute of video takes about 1 minute to render). The CPUs max out during rendering, so make sure your computer is well-ventilated during this process.

Finally, I'll talk about my process. This is what works for me. I have published about 20 hours of finished video over the last 6 months, and I've done a bit of tweaking of my process along the way.

Preparing for a video takes a bit of time. This is the "creative" part of the process. And this is where I plan, create slides and put together the demo code.

I often get asked about whether I write a script. The answer is, I have a partial script. For the "slide" portion of the videos, I put together a script. I'm pretty good with live presentations, but for some reason, I trip over myself when I'm trying to talk slides during a screencast. So for this portion, I script out what I'm going to say.

For the "demo" portion of the videos, I have an outline of the points I want to hit along with any code snippets that I'm going to type. I'm really good at talking coherently while I'm coding (for some strange reason), so I don't need a full script. In addition, a full script would probably be distracting since I couldn't read from the script and type code at the same time.

It took me a while to "dial in" the settings for my microphone. I spent a bit of time playing with the gain settings and varying my distance from the mic. If the gain was too high, then I got a lot of background noise. If the gain was too low, then I had to be really close to the mic to be picked up. I ended up with a gain setting of 90 and a distance of 2 inches from the microphone.

I got a really good tip from another screencaster. To help you keep a consistent distance from the microphone, attach a gauge of some sort. I have a chopstick rubber-banded to the side of  the microphone that sticks out 2 inches. This helps me keep a consistent distance during the recording process (with the Podcaster, you speak into the end of the mic). Here's a picture of that:

As far as the recording process itself, I will do separate recordings for "slides" and "demos". And for Pluralsight where I may have multiple "slide" clips in a row, I record each clip separately.

When I'm recording, I don't stop recording if I make a mistake. I simply take a breath and try the line again. For slides, this isn't too difficult. Sometimes I need to backup a slide or hit the back arrow to reset an animation, but it's pretty easy to keep going.

For demos, it gets a little trickier. Since I started with live presentations before I did screencasts, I had a tendency to point to things with the mouse. But with screencasting, I "point" to things during the editing process by adding arrows and callouts. So, I generally try to stay "hands off the mouse" as much as possible during recording. This also makes it easier to do clean edits when I'm fixing mistakes.

Now, I'm pretty fortunate: I can talk and type at the same time. So, I record the audio and demo all at once. I do make mistakes (a lot). I'm often backing up to a previous point in the code to try a line again. If you don't let the mistakes frustrate you, it's pretty easy to keep going. That's what editing is for; it doesn't have to be a perfect recording.

If you can't talk and type at the same time, you can always add narration later on during the editing process. I know of a couple of screencasters who do this.

I spend the bulk of my time in editing. In order to try to streamline the process, I've adapted to making 3 editing passes.

Pass #1: Cut To Length
The first pass is cutting out all of the mistakes. This step takes a long time as I go through and cut out the "dead air" when I pause to get the right words, and also when I need to cut out the mistakes. I find that I cut out about 30% of the raw footage during this pass.

For example, the C# Generics Part 1 video was a little over 25 minutes of raw footage that I cut down to 14 minutes of completed video. For my Dependency Injection On-Ramp course for Pluralsight, I had 3 hours 48 minutes of raw video that was cut down to 2 hours and 37 minutes of final footage. I've found that this is pretty consistent, and I can estimate the final video length based on the raw footage. (This is all based on my recording quirks and mistakes, of course.)

Pass #2: Audio Adjustment
I would love to have a "fix audio" button. Like I said, I spent a bit of time dialing in the settings for my microphone to get the cleanest recording that I can, but I still need to do some audio editing.

I don't get any background noise in my setup, but I do have smacking noises that come from my lips and gums. This is generally when I open my mouth to start a phrase. I still haven't figured out what causes this, and I've tried a few different things (wet mouth, dry mouth), and a friend of mine even sent me an interesting link about it: http://filmsound.org/QA/mouthclick.htm.

I've learned to see these extraneous noises in the audio waveform, and I can select and silence them pretty easily. I'll also remove breathing sounds, but I don't need to do this very often. After enough experience recording, I find myself turning my head away from the mic if I need to take a big breath.

I don't have much of a problem with "pops" (hard "P" or "H" sounds). As mentioned above, the Podcaster has a built-in pop filter, and that works pretty well. I get an occasional "pop", and these are easy to fix by locating the sound (usually just 1 frame) and then clicking the "Volume down" button about 5 times. These are fairly rare in my recordings, though.

I have tried the noise removal tools in Camtasia, but they don't seem to pick up the noises that I'm concerned about. And if I change the settings so that they do get picked up, then it alters the rest of the audio as well. So for the time being, I'm sticking with the manual process even though it's a bit more work.

The reason the "Audio Adjustment" pass is separate from the "Cut To Length" pass is that I found I was spending time fixing audio on segments that I later cut out. That was a waste of time. And I also found that it was easier for me to concentrate on one thing at a time.

Pass #3: Video Effects
The last step of the process is adding the video effects. This includes simple things like transitions between "slides" and "demo" and also adding the callouts and animation. This is usually the easiest and fastest editing pass because I generally don't add effects to "slide" portions, and I limit my effects during "demo" portions to highlighting important elements.

Rendering is pretty straight-forward. As mentioned above, my laptop renders at about a 1 to 1 ratio. And I have the common rendering settings saved in Camtasia. So, this step is usually just hitting the "Produce and share" button, picking the saved setting, and choosing an output location.

Rendering with Camtasia has been rock-solid. But I will give you a warning if you output to WMV files (which I do): Windows Media Player has a problem playing WMVs (yikes!). So, when you're watching the output in Media Player, you may see "smearing" of the cursor or multiple pointers on the screen at the same time. But don't worry, if you view the video with another player (like VLC) or upload it to YouTube, it will look just fine.

Wrap Up
I've actually been wanting to do screencasts for quite a while. I'm glad that I finally started in earnest last year. I'm hoping to fill up my YouTube channel with lots of good stuff this year (and I'll have some new Pluralsight courses as well).

So, now you know how I produce a screencast. These are the things that work for me. Hopefully, you'll be able to use some of these tips in your own productions.

Happy Coding!