Blog

Create a video transcoder GUI with Zenity and ffmpeg

Create a video transcoder GUI with Zenity and ffmpeg

Copyright © TechPad.co.uk

Create a GUI application for your Linux computer to allow you to graphically unleash the powers of ffmpeg to transcode video formats.

The Gnome desktop includes a very nice built-in application called Zenity, which allows you to create a simple dialog-based graphical user interface using a Bash shell script. Zenity is quite easy to use, when you get the hang of it, and making Zenity scripts is also a really good way to learn more about Bash and other Linux commands. 

In this tutorial we're going to use four things, Bash scripting, Zenity, Awk and ffmpeg, to create a graphical user interface to the command line driven ffmpeg video transcoding application. When the script is finished, we'll add it to the Gnome Nautilus file manager so we can simply right-click on a video file and convert it into another format. 

If you download videos from elsewhere and want to watch them on a portable media device, this could be just the thing you need. So besides being a useful guide to picking up some new skills, you'll also get a working application you can keep and use at the end. You can use the same principles to make graphical interfaces to any command line applications you want.

Right, let's get cracking!

Step 1: Install the software

If you're running Gnome, you won't need to install Zenity as it's part of the Gnome desktop. Likewise, Bash is installed already, as is Awk, but you may need to install ffmpeg - the transcoding application that we're using. On a Debian-based system, like Ubuntu, you can do this by entering the command: 

sudo apt-get install ffmpeg


Step 2: Create a Zenity info dialog

Open up a text editor, such as Gedit, which is bundled with Gnome and add a line to the top of the file which reads #!/bin/bash. When you execute the script later on, this will start Bash and it will continue down the rest of the file executing the commands as it goes.

To keep the script a bit cleaner, we can create some constants to use throughout the script. We'll make one here for the window title, which we'll call WindowTitle. It's important not to leave any spaces between the variable name (WindowTitle) the = symbol or the content in double quotes, otherwise you get an error. We'll also create another constant called MessageIntro to contain a message informing the user of what they need to do.

Then, we'll kick off the script properly by using Zenity to create an info window. We'll set this to a width of 100 pixels and add an if/then statement afterwards, which will either continue or exit the script depending on what the user does. 

 

#!/usr/bin/bash

WindowTitle="Video Transcoder"
MessageIntro="Please select the file you want to transcode"

$(zenity --info --title "$WindowTitle" --width 100 --text "$MessageIntro");
if [ $? = 1 ];
then exit
fi

Now, save the file as videotranscoder.sh. Go to your terminal, cd to the directory that the script is in and execute it by typing sh videotranscoder.sh

It should create an info window containing the text we defined above. If you get an error, check that you've got the spacing right. Bash is quite fussy about this. 

Step 3: Create a Zenity file selection dialog

Now we need to get the user to select the file that they want to transcode and store the name and location of the file so we can use it in the command we give to ffmpeg. Since we're also adding some text to this file selection dialog, as we need to tell the user what to do, we'll also need to create another constant and add it to our list at the top. 

MessageSelectFile="Please select the file you want to transcode"

 

To do this we need to use the Zenity --file-selection dialog option.This creates a GTK file selection dialog, just like the one you'll use every day on your Gnome desktop. Beneath the if/then statement on the first --info dialog we need to add the following code.

SourceFile$(zenity --title "$WindowTitle" --width 500 --text "$MessageSelectFile");

echo "Source: $SourceFile"
if [ $? = 1 ];
then exit
fi

Now, save your script and execute it by typing sh videotranscoder.sh and you should see a file selection dialog follow the initial info window. When you've selected your file, the details of it are stored in the SourceFile variable. We echo this to the shell so you can monitor what's happening when we run things from the command line, but you don't need to do this. 

Step 4: Create a Zenity radiolist dialog

We want to allow the user to select what video format they want to transcode their source file to, and for this we can use the Zenity --radiolist option. This is quite similar to the radio buttons used in HTML, however, there's a little less control with Zenity. 

We'll now create a Zenity command which creates a two column list of options. The user can then click the button next to the format they want and we'll store the value in a variable called OutputFormat. 

We need to add two constants to our collection at the top of the script: 

MessageSelectFormat="Select output format"
MessageSelectFormatVerbose="Please select the format you want to convert your file to"

 

Now we need to add another chunk of code beneath the last one we created to get the source file. Again, be careful with the spaces. If you miss them out, you could get errors when you run the script. 

OutputFormat=$(zenity --title "$WindowTitle" | $MessageSelectFormat" --width 500 --list --text "$MessageSelectFormatVerbose" --radiolist --column "Select" --column "Output format" TRUE mp4 FALSE mkv FALSE wmv FALSE flv);

echo "Format: $OutputFormat"

if [ $? = 1 ];
then exit
fi

If you save the script and run it, it should now give you an info window, a file selection dialog and then a radiolist. The values stored should be echoed to the terminal. 

Step 5: Create a Zenity entry dialog

We now want to get the user to provide a filename for the output file and we can do this with the Zenity --entry dialog option. In the constants section at the top of your script, you'll now need to add the following line: 

MessageEnterFilename="Enter output filename"
MessageEnterFilenameVerbose="Enter output filename without suffix, ie. Shaun Of The Dead"

Then, beneath the last section we added, you need to add the code to create the Zenity --entry dialog. 

OutputFilename=$(zenity --title "$WindowTitle | $MessageEnterFilename" --width 500 --entry --text "$MessageEnterFilenameVerbose");

Since spaces could be problematic, we'll also introduce an extra line in here which uses AWK to search for any spaces and turn them into underscores.This uses backticks ` not apostrophes, so make sure you use the right character. Add this below the last chunk of code. 

 

OutputFilename=`echo "$OutputFilename.$OutputFormat" | awk '{$1=$1}1' OFS="_"`

This will convert a filename such as "Shaun Of The Dead.mp4" to "Shaun_Of_The_Dead.mp4", making it less problematic to store or pass to ffmpeg in our command line call, but it's not strictly necessary. 

In closing this section, we'll as usual echo the variable we captured back to the terminal and add an if/then statement with an exit. 

echo "Filename: $OutputFilename"

if [ $? = 1 ];
then exit
fi

Step 6: Create a Zenity directory selection dialog

We want to allow the user to choose where we store the transcoded file, and we can do this using the --file-selection dialog we used in step 3 with an added parameter called --directory. This simply allows you to select a directory rather than a file. 

Add this line to your constants at the top of the script: 

MessageSelectDirectory="Select destination directory"

 

Then, add this chunk of code at the bottom of the file. Again, we'll add an if/then statement and echo the response from the user back to the shell so we can check that it's all hunky dory. 

Directory=$(zenity --title "$WindowTitle" | $MessageSelectDirectory" --width 500 --file-selection --directory);

echo "Directory: $Directory"

if [ $? = 1 ];
then exit
fi

Step 7: Execute the ffmpeg command and use Zenity progress

Now it's time for the exciting bit. We now have a little application which captures the following data from the user: the location and filename of the source file; the format the user wants to convert the file to; the location of the directory the file needs to be stored at, and the name of the new transcoded file. All we need to do now is pass all of this information to our command line transcoder ffmpeg. 

We also want to give the user something to watch while the file is transcoding, so they know that the script has not just stopped, and for this we can use the --progress --pulsate command. This adds a progress bar to the application which pulsates from side to side. It doesn't show how long is left to run, but it does at least show them that something is happening, as transcoding can be a time-consuming process. Add this code to the bottom of your file. 

ffmpeg -vcodec copy -acodec copy -i "$SourceFile" "$Directory/$OutputFilename" 2>&1 | zenity --width 500 --title "$WindowTitle | $MessageProgressTitle" --text "$MessageProgress" --progress --pulsate --auto-close

 

What this does is uses the same video codec (vcodec) and audio codec (acodec), takes the input file (i) from the $SourceFile variable and outputs it to the $Directory using the chosen $OutputFilename. 

Then we pipe the output of ffmpeg using the "2>&1 |" part and add a pulsating progress bar and close automatically when we're done.

After you've added that chunk of code, you'll want to echo the command back to the shell and add the usual if/then bit. 

echo "Command: ffmpeg -vcodec copy -acodec copy -i "$SourceFile" "$Directory/$OutputFilename""

if [ $? = 1 ];
then exit
fi

Now, you can run your script and test it out. It should work!

Step 8: Create an info window on success

When ffmpeg has done it's magic, we need to tell the user, so we'll trigger another Zenity --info window dialog to pop up at the end, then we'll exit the script. At the moment, the pulsating progress bar just disappears at the end. 

We're going to add some text to our info dialog with the --text option and the variable $MessageComplete, so you'll need to add this to your collection of constants at the top of the script. 

 

MessageComplete="Your file has been transcoded"

Then, you can close your script with the final info window, and echo a Done message in the terminal if the script is executed from the shell itself. 

zenity --info --title "$WindowTitle" --text "$MessageComplete"
echo "Done"
exit

OK. We're done with the bulk of the scripting now. Give it a blast and see if it works. If you can't be arsed to type it all out, you can download a copy of the script here

Step 9: Execute the script from your Gnome panel

To save you the bother of using the command line to start the script, you can add a shortcut icon for it to your Gnome panel. Right-click on the panel and select "Add to Panel" > "Custom Application Launcher" > "Add". 

 

In the name field, enter a name for your script, ie. Video Transcoder. In the command field, enter "sh /home/matt/Scripts/videotranscoder.sh", where the path and filename matches yours. Click the icon on the top right corner to choose a custom icon to use, and then hit OK. You can now trigger the application from your panel without the need to open a shell. 

Step 10: Add the script to your Nautilus scripts

If you want even more ease of use, you could now add the script to your Nautilus scripts collection. Nautilus scripts are shell and Python scripts that can be executed by right clicking on a file - so you'll be able to find a video that needs transcoding and select your transcoding application from the menu to have it converted in an instant. 

Open the Nautilus file manager and click the small icon at the top right below the back button. The will open the location bar. In here, you need to enter /home/matt/.gnome2 (where matt is your username) and then hit return. 

This will take you to the .gnome2 directory, within which you should find a folder called nautilus-scripts. Copy your videotranscoder.sh file into here.

Now open the directory and right click on your script then select "Properties" > "Permissions" > "Allow executing file as program".

 

Now find a video, right click it and select "Scripts" > "videotranscoder.sh" and your GUI should start up and allow you to convert the file. 

If you can't even be bothered to read the above, you can jump straight to the code and save yourself the hassle of typing by clicking here



Published: TechPad.co.uk Wednesday 30 December 2009, 9:49 am
Views: 899 times
Filed under: Zenity Bash coding Awk ffmpeg transcoding

(No votes yet)



Login to leave your comments

Please login

Username
Password
  Remember me
Reset password | Send activation code

Related items

How to copy DVD movies to your iPhone or iPod
How to copy DVD movies to your iPhone or iPod
Want to watch your DVDs on your iPhone or ... 5 (1 vote) *1 comment
How to create a Linux iPlayer download GUI using Zenity
How to create a Linux iPlayer download GUI using Zenity
Here's how I created a simple graphical ut... no votes (No votes)
Rip DVDs and transcode movies in Linux with Arista Transcoder
Rip DVDs and transcode movies in Linux with Arista Transcoder
Rip DVDs and watch them on your iPod, PS3 ... no votes (No votes) *1 comment
Using PHP's DOMDocument to scale images
Using PHP's DOMDocument to scale images
How to use PHP's built-in DOMDocument clas... 5 (1 vote)
Protecting against SQL injection and XSS attacks in PHP
Protecting against SQL injection and XSS attacks in PHP
Learn how to write PHP code that is protec... 5 (1 vote)

Recently added

How to create a Linux iPlayer download GUI using Zenity
How to create a Linux iPlayer download GUI using Zenity
Here's how I created a simple graphical ut... no votes (No votes)
A taste of iPhone support coming in Ubuntu Lucid Lynx
A taste of iPhone support coming in Ubuntu Lucid Lynx
Ubuntu's Lucid Lynx release, which comes o... no votes (No votes)
Frequently asked questions on NexentaCore
Frequently asked questions on NexentaCore
Frequently asked questions about NexentaCo... no votes (No votes)
Create a video transcoder GUI with Zenity and ffmpeg
Create a video transcoder GUI with Zenity and ffmpeg
Create a GUI application for your Linux co... 4 (1 vote)

Most viewed


Recent comments


Analytics sites

Web Analytics 2.0
Web Analytics 2.0
Probably the best and most ...
Excellent Analytics free Excel plugin
Excellent Analytics free Excel plugin
Excellent Analytics is a si...
VKI Studios blog
VKI Studios blog
Web analytics blog by the C...