FE 'tkGooies' Utilities

'VIDEOtools' group

A Tk GUI ('tkGooie') for
Movie Clip / Crop / Convert / Etc.
MOVIE-EDITING


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
'tkMovieClipCropConvertEtc_ MovieEditor_ ffmpegFrontEnd'

In 2014 May and June, I published 2 utilities for recording a movie

  • from a COMPUTER MONITOR and the audio system of a computer

  • from a COMPUTER WEBCAM and the audio system of a computer

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:

  • Provide 'entry' widgets for an input movie file and an output media file --- along with a 'Browse' button to easily select the input file.

  • Provide a 'listbox' widget by which to select the edit operation to be performed --- CLIP, CROP, CONVERT, etc.

    The 'listbox' will allow for adding many more audio editing functions in the future --- as opposed to using radiobuttons, for example.

    Also provide PROPERTIES-IN and PROPERTIES-OUT options to query the properties of the input and output files --- after they have been selected and created, respectively.

  • Provide 'entry' widgets for the approximately 8-plus parameters that can be specified to 'ffmpeg' to specify the container-video-audio parameters for creating the output movie file.

    Provide working defaults for the parameters.

  • Provide a 'ExecOption button' to start the execution of the option that the user selected from the listbox.

  • Provide an 'entry' widget to allow the user to specify a movie-player program with which to play either the input or the output media file.

  • To avoid overwhelming the user with the number of recording parameters available, provide a 'checkbutton' on the GUI to only show the video-audio-other parameters if the user requests to see them.


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

  • 6 'button' widgets
  • 32 'label' widgets (many are for entry fields)
  • 14 'entry' widgets
  • 1 'checkbutton' widget
  • 6 'radiobutton' widgets (in one group)
  • 1 'listbox' widget (with scrollbars)
  • 0 'scale' widgets
  • 0 'canvas' widgets
  • 0 'text' widgets

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

  1. click on the 'listbox' to select an option, like CLIP.

  2. enter a couple of option parameters in the widgets that pop up in the 'ExecOption Parameters' section/frame of the GUI.

  3. optionally use the 'PROPERTIES-IN' and/or the 'PlayInMovie' options to get information needed to set some editing parameters

  4. optionally change the 'container' format for the output file, via the radiobuttons on the GUI --- and optionally use the 'MoreMovieOutParms checkbutton' to reveal the video-audio-other parameters that can be changed.

  5. click on the 'ExecOption' button to launch the 'ffmpeg' job.

  6. when the output is complete, use the 'PlayOutMovie' button (and perhaps the 'PROPERTIES-OUT' option) on the output media file.

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':

  • CLIP
  • CROP
  • PROPERTIES-IN
  • PROPERTIES-OUT
  • CONVERT

But there are about 7 more options that I may implement in coming months:

  • CHG-VOLUME
  • EXTRACT-AUDIO
  • REMOVE-AUDIO
  • ADD-AUDIO
  • TIME-LAPSE
  • FLIP
  • EXTRACT-IMAGES

There are many Tk scripts on my 'to do' list in the categories of

  • 3D tools

  • Math proofs / demos / animations

  • Ordinary differential equation (ODE) simulations (animations)

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
a Tk GUI for
Movie Clip / Crop / Convert / Etc
MOVIE EDITING

--- an 'ffmpeg' Front End
--- a utility in the FE 'tkGooies' system,
in the 'VIDEOtools' group.

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.

This page was changed 2015 Oct 05.
(Small changes.)

Page was changed 2019 Feb 28.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jun 22.
(Specified image widths in percents to size the images according to width of the browser window.)


NOTE:
The code here MAY BECOME more 'up-to-date' than the code posted on the Tcler's Wiki ---
wiki.tcl-lang.org --- formerly wiki.tcl.tk.