We now have the video on our hard drive in the Flash (FLV) format, and although we could build a simple HTML page to embed the Flash videos to watch them locally, what we really want to do is convert the video from FLV format to WMV (Zune) or MP4 (iTunes) format. To do that, we'll use an open source tool called ffmpeg, which is a C++ library and command-line tool for converting, resizing, or resampling media from one format to another, with more than 50 formats supported.
In its simplest form, you can call ffmpeg.exe by passing in two command-line arguments, the source file that you want to convert and the name of the new file you want it converted to. For example, we can convert a Flash video file named source.flv into an MP4 (MPEG-4) format file named destination.mp4 using the command shown in Example 4-26.
Example 4-26. Converting a flash video to the MP4 video format
ffmpeg.exe -i "source.flv" "destination.mp4"
To convert the source.flv file into a .wmv (Windows Media Video) file, add the -vcodec wmv2
command-line arguments, as shown in Example 4-27.
Example 4-27. Converting a flash video to the WMV video format
ffmpeg.exe -i "source.flv" -vcodec wmv2 "destination.wmv"
You can even add metadata—such as the author, title, and comment—to the newly converted video by setting additional ffmpeg.exe command-line arguments, as shown in Example 4-28.
Example 4-28. Setting metadata when converting a video
ffmpeg.exe -title "My Video Title" -author "Dan" -comment "best video ever" -i "source.flv" -vcodec wmv2 "destination.wmv"
To call ffmpeg.exe programmatically, first we'll build a ConversionType enum
to state the possible types of conversion our application allows (see Example 4-29 and Example 4-30).
Example 4-30. Visual Basic code for the ConversionType enum
Public Enum ConversionType Mp4 Wmv End Enum
We want to programmatically call the ffmpeg.exe console application from code using the System.Diagnostics.Process
class. The call to ffmpeg is wrapped in the VideoConverter
class, which has one method, ConvertFlv
, with multiple overloads. The ConvertFlv
method overload we'll want to use accepts an InnerTubeVideo
and a ConversionType enum
(MP4 or WMV). We use this overload because we'll use the video's title, author, and description to set the video's metadata, as described in Example 4-28. Since these fields might contain illegal characters, in which case ffmpeg.exe would not work, we will use the ReplaceIllegalCharacters
method to clean them up.
As you can see in Example 4-31 and Example 4-32, we are building the command-line arguments to pass into ffmpeg.exe based on the type of conversion we are doing (MP4 or WMV).
Example 4-31. C# code for setting ffmpeg parameters
public static void ConvertFlv(InnerTubeVideo source, ConversionType conversion) { string title = FileHelper.ReplaceIllegalCharacters(source.Title); string author = FileHelper.ReplaceIllegalCharacters(source.Author); string description = FileHelper.ReplaceIllegalCharacters(source.Description); //set values based on switch string cmdLineArgs = String.Empty; string destination = String.Empty; switch (conversion) { case ConversionType.Mp4: //ffmpeg.exe -title "Chocolate Rain" -author "TayZonday" -comment "Original //Song by Tay Zonday" -i "Chocolate Rain.flv" "Chocolate Rain.mp4" destination = source.DownloadedMp4; cmdLineArgs = String.Format(" -title \"{0}\" -author \"{1}\" -comment \"{2}\" -i \"{3}\" \"{4}\"",title, author, description, source.DownloadedFlv, destination); break; case ConversionType.Wmv: //ffmpeg.exe -title "Chocolate Rain" -author "TayZonday" -comment "Original //Song by Tay Zonday" -i "Chocolate Rain.flv" -vcodec wmv2 "Chocolate Rain.wmv" destination = source.DownloadedWmv; cmdLineArgs = String.Format(" -title \"{0}\" -author \"{1}\" -comment \"{2}\" -i \"{3}\" -vcodec wmv2 \"{4}\"", title, author, description, source.DownloadedFlv, destination); break; } ConvertFlv(source.DownloadedFlv, destination, cmdLineArgs); }
Example 4-32. Visual Basic code for setting ffmpeg parameters
Public Shared Sub ConvertFlv(ByVal source As InnerTubeVideo, ByVal conversion _ As ConversionType) Dim title As String = FileHelper.ReplaceIllegalCharacters(source.Title) Dim author As String = FileHelper.ReplaceIllegalCharacters(source.Author) Dim description As String = FileHelper.ReplaceIllegalCharacters(source.Description) 'set values based on switch Dim cmdLineArgs As String = String.Empty Dim destination As String = String.Empty Select Case conversion Case ConversionType.Mp4 'ffmpeg.exe -title "Chocolate Rain" -author "TayZonday" -comment "Original Song 'by Tay Zonday" -i "Chocolate Rain.flv" "Chocolate Rain.mp4" destination = source.DownloadedMp4 cmdLineArgs = String.Format(" -title ""{0}"" -author ""{1}"" " & _ "-comment ""{2}"" -i ""{3}"" ""{4}""", title, author, _ description, source.DownloadedFlv, destination) Case ConversionType.Wmv 'ffmpeg.exe -title "Chocolate Rain" -author "TayZonday" -comment "Original Song 'by Tay Zonday" -i "Chocolate Rain.flv" -vcodec wmv2 "Chocolate Rain.wmv" destination = source.DownloadedWmv cmdLineArgs = String.Format(" -title ""{0}"" -author ""{1}"" -comment " & _ " ""{2}"" -i ""{3}"" -vcodec wmv2 ""{4}""", title, author, description, _ source.DownloadedFlv, destination) End Select ConvertFlv(source.DownloadedFlv, destination, cmdLineArgs) End Sub
As you may have noticed in Example 4-31 and Example 4-32, the last line of code calls another overload for the ConvertFlv
method, which actually calls ffmpeg from the command line, which we'll discuss next.
In Example 4-33 and Example 4-34, the ConvertFlv
method code includes the location of the ffmpeg.exe executable. The file itself is distributed in the SharedUtilities directory in an ffmpeg folder, so we can call Environment.CurrentDirectory
to point to the executable and store the path into the exePath
variable.
We'll also make sure that we have the source file and don't have the destination file. Assuming we have everything to run, we create a process and set some properties, such as the command-line arguments, the location of the .exe file, and other properties that will keep the console window from appearing while we convert a file. To get everything running, you call the Start
method of the convert
class. Since ffmpeg.exe will automatically close when it is finished converting a file, we'll use the Wait ForExit()
method, which means that the ConvertFlv
method will not return until the conversion is complete.
Example 4-33. C# code to create a process and call ffmpeg.exe
private static void ConvertFlv(string sourceFile, string destination, string cmdLineArgs) { //point to ffmpeg conversion tool string exePath = Path.Combine(Environment.CurrentDirectory, @"ffmpeg\ffmpeg.exe"); //ensure sourceFile files exist and the destination doesn't if (File.Exists(sourceFile) && File.Exists(exePath) && !File.Exists(destination)) { //Start a Process externally as we're converting from the command line using (Process convert = new Process()) { //Set properties convert.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; convert.StartInfo.CreateNoWindow = true; convert.StartInfo.RedirectStandardOutput = true; convert.StartInfo.UseShellExecute = false; convert.StartInfo.Arguments = cmdLineArgs; convert.StartInfo.FileName = exePath; convert.Start(); convert.WaitForExit(); } } }
Example 4-34. Visual Basic code to create a process and call ffmpeg.exe
Private Shared Sub ConvertFlv(ByVal sourceFile As String, ByVal destination As _ String, ByVal cmdLineArgs As String) 'point to ffmpeg conversion tool Dim exePath As String = Path.Combine(Environment.CurrentDirectory, _ "ffmpeg\ffmpeg.exe") 'ensure sourceFile files exist and the destination doesn't If File.Exists(sourceFile) AndAlso File.Exists(exePath) AndAlso _ (Not File.Exists(destination)) Then 'Start a Process externally as we're converting from the command line Using convert As New Process() 'Set properties convert.StartInfo.WindowStyle = ProcessWindowStyle.Hidden convert.StartInfo.CreateNoWindow = True convert.StartInfo.RedirectStandardOutput = True convert.StartInfo.UseShellExecute = False convert.StartInfo.Arguments = cmdLineArgs convert.StartInfo.FileName = exePath convert.Start() convert.WaitForExit() End Using End If End Sub
Now that we have converted the Flash videos into MP4 and/or WMV files, let's show how you can sync them to iTunes or the Zune client software.
Get Coding4Fun now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.