FE 'tkGooies' Utilities'VIDEOtools' group
A Tk GUI ('tkGooie') for
|
GUI interface of the VIDEO EDITOR 'tkGooie' (a Front End for the 'ffmpeg' command)(FE = Freedom Environment) |
FE Home Page >
FE Downloads Page >
FE 'tkGooies' Description Page >
FE 'tkGooies' 'VIDEOtools' Page >
This
'tkMovieClipCropConvertEtc'
Movie Editor tkGooie Page
INTRODUCTION to In 2014 May and June, I published 2 utilities for recording a movie
at the wiki.tcl.tk web site. I have reproduced (i.e. backed up) that code --- and description of the code --- at two pages on this freedomenv.com site:
I had mentioned on those pages that I planned to work on at least one other 'front end' for 'ffmpeg' --- for example, for clipping, cropping, audio-extraction, audio-addition, and some other movie file editing functions. Such a movie-editing utility (a front-end for the 'ffmpeg' command) is the subject of this page. THE GOALS My goals for the Tcl-Tk script for this GUI were:
THE GUI LAYOUT Like for the 2 'movie-capture' utilities that I posted here, I made a 'text-sketch' for the GUI for this 'movie-edit' utility. |
CONVENTIONS for the GUI 'text-sketch' below:
* SQUARE-BRACKETS indicate a comment not to be included on the GUI.
* BRACES indicate a Tk 'button' widget.
* UNDERSCORES indicate a Tk 'entry' widget.
* A COLON indicates that the text before the colon is on a 'label' widget.
* CAPITAL-O indicates a Tk 'radiobutton' widget.
* CAPITAL-X indicates a Tk 'checkbutton' widget.
--------------------------------------------------------------------------------------
Movie Clip, Crop, Etc. Utility - a front-end for the 'ffmpeg' command
[window title]
--------------------------------------------------------------------------------------
[On the left of the following frames will be a Tk 'listbox' widget in frame '.fRleft'.
The following frames will be contained in frame '.fRright'.]
'.fRright'
SubFrame
names
|
V
.fRbuttons {Exit} {Help} {ExecOption} {PlayOutMovie} {PlayInMovie} X MoreMovieOutParms (video,audio,other)
.fRmsg Select a movie-processing option from the listbox on the left. Then provide the processing
parameters at the prompts in the 'ExecOption Parameters' section that appears below.
An 'xterm' window will appear when processing starts. You can see processing messages in
that window. When processing is finished, use the 'PlayMovie' button to show the movie.
[This initial message in a label widget may be changed when the 'Exec' button is clicked.]
.fRinfile Input movie filename : $env(HOME)/input_movie.mkv_______________________ {Browse...}
--------------------------------------------------------------------------------------
.fRoutHead Output File parameters:
--------------------------------------------------------------------------------------
.fRcontainer Container format: O Matroska (.mkv) O Mpeg4 (.mp4) O Mpeg (.mpg) O Flash (.flv) O AVI (.avi) O WEBM (.webm)
.fRoutfile Output movie filename : /tmp/$env(USER)_output_movie.mkv___________________
.fRplayer Player for the movie file: totem________ Examples: totem gmplayer mplayer ffplay vlc
--------------------------------------------------------------------------------------
.fRoptsHead ExecOption Parameters: [This label may dynamically change according to option selected.
Examples: ' (CLIP)' or ' (CROP)' may be added after 'Parameters:'.]
--------------------------------------------------------------------------------------
.fRexecOpts [The sub-frames and widgets that appear here
will depend on the listbox line currently selected.
An example for CLIP is seen in an image below.]
.fRvidaud [This frame and its following subframes are shown if
the 'MoreMovieOutParms' checkbuttons is set ON.]
'.fRvidaud'
SubFrame
names
|
V
--------------------------------------------------------------------------------------
.fRvideoHead Video-out parameters:
--------------------------------------------------------------------------------------
.fRvidsize Video-out size: 1024x768____ Examples: 640x480 800x600 1024x768 ...
.fRvrate Video-out rate (frames/sec): 25_ Examples: 25 30 24 ...
.fRvcodec Video-out coder: libx264_____ Examples: libx264 mpeg4 mpeg1video flv ...
.fRvother Other video-out parms: -vpre /usr/share/ffmpeg/libx264-lossless_ultrafast.ffpreset_______
-------------------------------------------------------------------------------------
.fRaudioHead Audio-out parameters:
-------------------------------------------------------------------------------------
.fRachannels Audio-out Channels: 1_ Examples: 1 2
.fRacodec Audio-out codec: pcm_s16le__ Examples: pcm_s16le libmp3lame libfaac vorbis
.fRaother Other audio-out parms: -ar 22050 -ab 96k_________________________________________________
--------------------------------------------------------------------------------------
.fRother Other output recording parameters:
--------------------------------------------------------------------------------------
.fRthreads Threads: 1___ (to take advantage of a multi-core computer)
.fRguide NOTE: This utility runs 'ffmpeg' in an 'xterm' window. Startup and coding messages from 'ffmpeg'
can be seen in that window. You may minimize the 'xterm' window while processing, if you do not
want to monitor the processing messages. When processing is done, the terminal does not close,
so that you can examine messages. The output file, if good, can be shown in a movie player,
that you specify above. See 'Help' for details.
[a 'label' widget]
---------------------------------------------------------------------------------------
GUI Components From the GUI 'sketch' above, it is seen that the GUI consists of about
All but the 'label' widgets provide operating parameters or options in this utility. Hence there are about 6 + 14 + 1 + 6 = 27 options on this utility --- not counting the user-selectable options in the 'listbox' (approximately another 12, eventually). Functionality over Beauty I should point out here that I was not especially interested in coming up with a 'beautiful utility'. I just wanted a utility that would make 'semi-interactive' editing of movie files with 'ffmpeg' as simple as a few clicks --- on a 'listbox' and an 'Exec button' and a 'Play button' --- and perhaps entering a few characters in a couple of 'entry' widgets. I am certainly interested in making pretty GUI's --- as my pages on and have indicated. But at this time, I am satisfied to implement the 'functionality', and let the 'beauty' go for a later date (when I have more beauty tools/code at hand). SCREENSHOTS OF THE GUI On the basis of the GUI-layout sketch above, I ended up with the GUI seen in the following image. |
Poke this image to see a full-size version,
shown in a separate browser window or tab.
The basic operating sequence is
You can change some of the initial values on the GUI, like the initial container-format, by changing a 'set CONTAINERformat' statement at the bottom of the Tk script. If the user wants to change (or simply examine) the video and audio and 'other' parameters that are set according to a choice of the 'container format', the user can click on the 'MoreMovieOutParms' 'checkbutton' at the top of the GUI. When that 'checkbutton' is clicked, the GUI expands downward, as can be seen in the following image. |
Poke this image to see a full-size version,
shown in a separate browser window or tab.
When the 'ExecOption button' is clicked and an 'ffmpeg' edit operation starts, an 'xterm' window pops up that shows the messages coming from the 'ffmpeg' program during its operation. Below is an example from a CROP run. |
Some 'ffmpeg' build info is at the top of the messages from 'ffmpeg' --- up to the 'Input #0' line. The lines between the 'Input #0' line and the 'frame=' line are the initial messages that 'ffmpeg' puts out before starting the encoding of the output file. The lines after the 'frame=' line are 'summary' lines that were output at the end of the edit run. The 'frame=' line is updated 'in place' during the encoding. The string 'time=12.64' in the 'frame=' line indicates that the output file that was created is about 12 seconds in duration. The string 'frame= 387' in the 'frame=' line indicates that the output file that was created contains 387 image frames. (The warning message above the 'frame=' line |
width or height not divisible by 16 (320x120), compression will suffer
is not as serious as it sounds. The resulting output movie file usually looks as good as the input file.) Note the prompt 'File ... already exists. Overwrite? (y/N)' under the 'Stream' lines. I had done a previous run and the output file remained. I simply entered 'y' at the prompt, and 'ffmpeg' processing resumed. THE CONTAINER FORMATS For the 'movie capture' utilities, I tested the 5 active (non-grayed-out) container-format 'radiobuttons' to confirm that the video-audio-other parameters that I have provided for each container-format do indeed result in a successful output movie file creation. So I have created '.mkv' '.mp4' '.mpg' '.flv' and '.avi' files. I have grayed out the WEBM radiobutton. That is intended to eventually allow for creating a movie in the 'webm' format that Google is promoting. It uses a Matroska-like container format and a Vorbis audio format and a 'VP8' video format. You can see some information on the WEBM format at a Wikipedia page on the WEBM format. I did not have the video codec that is needed to make that file format --- and my 2009 version of 'ffmpeg' may not be capable of creating a WEBM file. But I include most of the program code to easily implement and activate that WEBM option. DESCRIPTION OF THE CODE Below, I provide the Tk script code for this 'movie-edit' utility. I follow my usual 'canonical' structure for Tk code for this Tk script: |
0) Set general window and widget parms (win-name, win-position,
win-color-scheme, fonts-for-widgets, widget-geometry-parms,
text-array-for-labels-etc, win-size-control).
1a) Define ALL frames (and sub-frames, if any).
1b) Pack ALL frames and sub-frames.
2) Define and pack all widgets in the frames, frame by frame.
Within each frame, define ALL the widgets.
Then pack the widgets.
3) Define keyboard and mouse/touchpad/touch-sensitive-screen action
BINDINGS, if needed.
4) Define PROCS, if needed.
5) Additional GUI initialization (typically with one or more of
the procs), if needed.
This Tk coding structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations. This structure makes it easy for me to find code sections --- while generating and testing a Tk script, and when looking for code snippets to include in other scripts (code re-use). I call your attention to step-zero. One thing that I started doing in 2013 is use of a text-array for text in labels, buttons, and other widgets in the GUI. This can make it easier for people to internationalize my scripts. I will be using a text-array like this in most of my scripts in the future. Experimenting with the GUI As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus scripts, so far), I provide the four main 'pack' parameters --- '-side', '-anchor', '-fill', '-expand' --- on all of the 'pack' commands for the frames and widgets. That helps me when I am initially testing the behavior of a GUI (the various widgets within it) as I resize the main window. I think that I have used a pretty nice choice of the 'pack' parameters. The label and button and radiobutton widgets stay fixed in size and relative-location if the window is re-sized --- while the input/output filename and 'player-program' entry widgets expand/contract horizontally whenever the window is re-sized horizontally. You can experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various frames and widgets --- to get the widget behavior that you want. Additional GUI experimentation: You might want to change the fonts used for the various GUI widgets. For example, you could change '-weight' from 'normal' to 'bold' --- or change '-slant' from 'roman' to 'italic' --- or change the font sizes. Or change font families. In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing. I use variables to set geometry parameters of widgets --- parameters such as border-widths and padding. And I have included the '-relief' parameter on the definitions of frames and widgets. Feel free to experiment with those 'appearance' parameters as well. If you find the gray palette of the GUI is not to your liking, you can change the value of the RGB parameter supplied to the 'tk_setPalette' command near the top of the code. Some features in the code There are plenty of comments in the code, to describe what most of the code-sections are doing. You can look at the top of the PROCS section of the code to see a list of the procs used in this script, along with brief descriptions of how they are called and what they do. The main procs are : |
'get_INfilename' - called by the movie in-file 'Browse' button.
'get_chars_before_last' - called by the proc 'get_INfilename'.
'set_defaults_for_container' - called by bindings on the CONTAINER
radiobuttons.
Sets defaults for the video-audio-other
GUI widgets, for a given container type.
'loadOptsFrame_perListboxSelection' - called by a click on the listbox.
Calls on a 'show_*_opts' proc depending on
the listbox line (movie-exec-operation) selected.
Example proc name: 'show_CLIP_opts'
'exec_movie_operation' - called by a click on the 'ExecOption' button.
Calls on a 'set_*_cmd' proc depending on
the listbox line (media-file-operation) selected.
Example proc name: 'set_CLIP_cmd'
Then executes the 'ffmpeg' command string built by
the 'set_*_cmd' proc --- in an 'xterm' window.
--------------------------------------------------------------------------------------
For each ExecOption added to the listbox, a 'show_*_opts' proc and a 'set_*_cmd' proc
should be provided --- like the following.
(And calls will need to be added to the 2 procs above:
'loadOptsFrame_perListboxSelection' and 'exec_movie_operation'.)
--------------------------------------------------------------------------------------
'show_CLIP_opts' - called by a button1-release binding on the listbox,
which calls the 'loadOptsFrame_perListboxSelection' proc.
Loads 'clip' frames and widgets into an 'execOpts' frame.
'set_CLIP_cmd' - called by the 'exec_movie_operation' proc which is called
by the 'ExecOption' button.
Sets an 'ffmpeg' command string for CLIPPING --- to be
used in the proc 'exec_movie_operation'.
--------------------------------------------------------------------------------------
'show_CROP_opts' - called by a button1-release binding on the listbox,
which calls the 'loadOptsFrame_perListboxSelection' proc.
Loads 'crop' frames and widgets into an 'execOpts' frame.
'set_CROP_cmd' - called by the 'exec_movie_operation' proc which is called
by the 'ExecOption' button.
Sets an 'ffmpeg' command string for CROPPING --- to be
used in the proc 'exec_movie_operation'.
--------------------------------------------------------------------------------------
'show_PROPSin_opts' - called by a button1-release binding on the listbox,
which calls the 'loadOptsFrame_perListboxSelection' proc.
Loads 'PROPSin' frames and widgets into an 'execOpts' frame.
'set_PROPSin_cmd' - called by the 'exec_movie_operation' proc which is called
by the 'ExecOption' button.
Sets an 'ffmpeg' command string for showing properties
of the input media file. The command string is to be used
in the proc 'exec_movie_operation'.
--------------------------------------------------------------------------------------
'show_PROPSout_opts' - called by a button1-release binding on the listbox,
which calls the 'loadOptsFrame_perListboxSelection' proc.
Loads 'PROPSout' frames and widgets into an 'execOpts' frame.
'set_PROPSout_cmd' - called by the 'exec_movie_operation' proc which is called
by the 'ExecOption' button.
Sets an 'ffmpeg' command string for showing properties
of the output media file. The command string is to be used
in the proc 'exec_movie_operation'.
--------------------------------------------------------------------------------------
'show_CONVERT_opts' - called by a button1-release binding on the listbox,
which calls the 'loadOptsFrame_perListboxSelection' proc.
Loads 'crop' frames and widgets into an 'execOpts' frame.
'set_CONVERT_cmd' - called by the 'exec_movie_operation' proc which is called
by the 'ExecOption' button.
Sets an 'ffmpeg' command string for CONVERTING the input
media file to a new container and/or video and/or audio
format. The command string is to be used in the proc
'exec_movie_operation'.
--------------------------------------------------------------------------------------
'play_movie_out' - called by the 'PlayOutMovie' button. Launches a movie
'player' program on the output movie file.
'play_movie_in' - called by the 'PlayInMovie' button. Launches a movie
'player' program on the input movie file.
'set_width_of_labels' - called in the 'Additional GUI Initialization'
section at the bottom of this script.
Sets a nice common width of the labels on the
left of each of the GUI sections:
- output/container
- video
- audio
- other
according to the font being used for labels.
'pack_more_outparms_frame' - called by button1-release binding on the
'MoreMovieOutParms' checkbutton.
Shows the 'video', 'audio', and 'other' frames
of the GUI if the 'MoreMovieOutParms' checkbutton
is ON. OR, 'forgets' the frame containing
the 'video', 'audio', and 'other' frames.
'popup_msgVarWithScroll' - called by 'Help' button to show HELPtext var.
Also used to show various warning/error/info
messages to the user.
I used the following statement to allow the GUI to be expanded in the x-direction, but NOT the y-direction. wm resizable . 1 0 whether or not the 'video-audio-other' parameter frames are showing. That is, whether or not the 'MoreMovieOutParms checkbutton' is ON or OFF. A fervent hope It is my hope that the copious comments in the code will help Tcl-Tk coding 'newbies' get started in making GUI's like this. Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to watch 'Motorcycles Gone Wild' videos. Tcl-Tk CODE for the 'ffmpeg' Front End GUI Here is a link to the code for the Tk script: 'movieClipCropEtc_ffmpeg_FrontEnd.tk' Shell script (called by the Tk script) : There is one 'external' shell script that is used to implement the 'PROPERTIES-IN' and the 'PROPERTIES-OUT' options. It is needed because the 'ffmpeg' command has not been written to query the 'properties' of a media file in a 'smooth' way. This is explained more clearly in comments in the shell script, below. You can put this script in the same directory with the Tk script. The Tk script includes some code (involving the 'argv0' variable) to determine the location of the shell script by extracting the name of the directory in which the Tk script lies. Here is a link to the code for the shell script called by this Tk script: 'movieFilePROPERTIES_ffmpeg-i.sh' INSTALLING THE SCRIPTS: The Tk script and the shell script could be put in a sub-directory of the user's home directory, such as $HOME/apps/tkEditMovies. Then the user can use their desktop system (such as Gnome or KDE) to set up the Tk script as an icon on the desktop. Then, whenever the user wants to edit a movie, the user can click on the icon to startup this 'front end' to the 'ffmpeg' command. LINK TO A MOVIE EDIT EXAMPLE On the code contribution page Movie Capture from Computer Monitor-and-Audio - a front-end for the 'ffmpeg' command ... on this site ... I put a link to a movie capture (from a computer monitor) that I did with that GUI. It is a capture of an 800x600 portion a computer monitor screen as I demonstrate the 'dynamic-font-resizing' of the font-selector that I published at the page titled YAFSG - Yet Another Font Selector GUI --- as I move the 'scale' widget on that font-selector GUI. The movie shows the 'xterm' window at the beginning and the end of the movie. I used this movie-edit utility (the CLIP option) to clip off the beginning and the end of that movie --- making this new movie. For the CLIP parameters, I used a start-time of 00:00:05 and a duration-time of 00:00:39. In other words, out of the 48-second input-movie, I made a 39-second output movie by extracting the clip from 00:00:05 to 00:00:44. In making this clipped movie, I made a movie with container-video-audio format mp4-h264-aac, while the container-video-audio format of the INPUT movie was mkv(matroska)-h264-pcm. SOME POSSIBLE ENHANCEMENTS As you can see in the listbox in the images above, I have implemented the following 'exec-options':
But there are about 7 more options that I may implement in coming months:
There are many Tk scripts on my 'to do' list in the categories of
I will probably take a break from this 'ffmpeg'-based 'tkMovieEdit' utility for a month or two. But I may create an 'ffmpeg'-based 'tkAudioEdit' utility, before tackling some 3D/math/ODE projects. IN CONCLUSION As I have said on several other code-donation pages on wiki.tcl.tk ... There's a lot to like about a utility that is 'free freedom' --- that is, no-cost and open-source so that you can modify/enhance/fix it without having to wait for someone else to do it for you (which may be never). A BIG THANK YOU to Ousterhout for starting Tcl-Tk, and a BIG THANK YOU to the Tcl-Tk developers and maintainers who have kept the simply MAH-velous 'wish' interpreter going. 2014jun30 UPDATE - on 'ffmpeg' and its fork, 'avconv' See a '2014jun30 UPDATE' note near the bottom of the 'tkMovieCapture_ComputerMonitorAndAudio_ffmpegFrontEnd' page. That note contains some info on using 'avconv' instead of 'ffmpeg'. |
Bottom of this page for To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times. OR, use the History-list option of your web browser. OR ...
< Go to Top of Page, above. >Page history: The code was created in 2014 --- and posted 2014 Jun 18 at http://wiki.tcl.tk/40305.
This FE web page was created 2015 Jan 17 ---
as a backup and alternative to the wiki.tcl.tk page.
NOTE: |