FE 'tkGooie' Utilities


'VIDEOtools' (and 'AUDIOtools') group


Media Files (movies/audio)

(FE = Freedom Environment)

FE Home Page > FE Downloads Page > FE 'tkGooies' Description Page >

FE 'tkGooies' 'VIDEOtools' Page > This Page

INTRODUCTION to 'tkBatchMediaFindPlay'

In 2013 December, I contributed script code at wiki.tcl.tk on a page titled 'tkImageViewer - for Mask-Selecting Images from a Directory Hierarchy' --- to provide a Tk GUI 'front end' to a combination of the 'find' command and a user-selectable image viewer command/program.

The GUI was designed to offer the user a choice from several image viewer programs --- such as ImageMagick 'display' or 'ffplay' or 'eog' (Eye of Gnome). It is quite easy to switch out any of these viewer programs/commands to replace them with another image viewer that is available in a user's operating environment.

The 'tkBatchImageViewer' utility was implemented as a Tk script and 2 shell scripts. As such, it should be implementable with very few changes in various Linux/BSD/Mac/Unix operating system environments.

I added the 'tkBatchImageViewer' utility to my list of 'done and to-do' Tk script utilities. And soon I was thinking about another utility that I would like to add to that list.

Soon after submitting (and updating/enhancing) the 'find'-and-imageViewer' FrontEnd utility, I realized that, with relatively few changes, the Tk script and the 2 shell scripts could be altered to provide a way to 'find' movie (and/or audio) files and play them with any of the many 'media-player' programs that are available on Linux and other such systems.

Some of the 'media-player' programs that I was aware of were:

  • mplayer
  • gmplayer
  • ffplay
  • totem
  • VLC
  • smplayer
  • gnome-mplayer

Several of these are GUI front-ends to the 'mplayer' program --- or they use media library routines that were used to implement the 'mplayer' program. At least one uses the 'Gstreamer' media library.

Like for the 'find-and-image-viewer' utility, I made a 'text-sketch' for the GUI for the 'find-and-media-player' utility:

   'find'-mediaplayer Front End -  a Tk Multi-Movie/Audio-File-Player Utility
   [window title]
   {Exit} {Help} {LaunchPlayerJob}            {CountFilenames} {ShowFilenames}
   Full Filename Mask (for movie/audio): ________________________  {Browse...}
   MediaPlayer : O 'mplayer'   O 'ffplay'  O 'gnome-mplayer'  O 'totem'  O 'VLC'
   DisplaySize: O DEFAULT-size (up to fullscreen)  O FULLSCREEN (without toolbars)
   Search Levels for Mask:  O ONE  O ALL subdirectories of selected directory
   Case Sense for Mask Search:  O case-sensitive  O case-INsensitive
   File Size (MegaBytes):  _________  O bigger-than  O smaller-than
   File Age (Days) : ________________ O older-than  O younger-than
   File Type: ___________   (Warning: SLOW) Examples: 'MPEG v4' or 'MPEG sequence'
   or  'Flash'  or  'Apple QuickTime'  or  'Microsoft ASF'  or  'layer III'  or 'PCM'


   Square brackets indicate a comment (not to be placed 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.

GUI Components

From the GUI 'sketch' above, it is seen that the GUI consists of about

   -  5 button widgets
   -  9 label widgets
   -  4 entry widgets
   - 15 radiobutton widgets in 6 groups
   -  0 checkbutton widgets
   -  0 scale widgets
   -  0 listbox widgets
   -  0 canvas widgets
   -  0 text widgets

There are a couple of lines added to this GUI, compared to the GUI for the 'find-and-image-viewer' utility:

  • a 'Display Size' line, to specify whether the 'player' should start in a full-screen mode (which, for most media-players means that toolbars are not shown, so that the full screen can be used for the movie)

  • an additional 'label' line at the bottom, to allow for displaying more examples of strings that can be specified for the FileType search option.



This 'Front End' Tk script is essentially a 'wrapper' for TWO commands --- the 'find' command that assembles the files to be 'played' and a media-player command (of the user's choice, from among several).

NOTE that among the 8 'parameter-lines' of this GUI, only 2 have to do with the media-player:

  • the line of radiobuttons used to select the 'player'
  • the 'Display Size' line (fullscreen or not).

The other parameters are for the 'find' command.

The Media Players

As far as choosing which movie player to use, I am partial to using ones based on the 'mplayer' program, because I have encountered a few movies that would not play with 'VLC' but would play with 'mplayer'. And I have never experienced the opposite.

However, in various Linux forums, I have seen many people express their preference for the VLC player. This may partly be because there seems to have been quite a bit of development time spent on handling streaming media via various Internet protocols.

Since this 'find-and-mediaPlayer' utility is intended mainly for finding-and-playing files on 'local' disk drives, those Internet features do not come into play here. But there are still going to be those who prefer 'VLC', so 'VLC' is presented as an option on this GUI.

Beauty (or lack thereof)

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 be able to sweep through a hierarchy of sub-directories and pick out movie and/or audio files to 'play' based on a rather 'rich' set of selection capabilities --- such as 'file-mask' and/or 'file-size' and/or 'file-age' and/or 'file-type'.

I am certainly interested in making pretty GUI's --- as I have expressed via GUI experiments that I posted at wiki.tcl.tk in pages titled

  • "Experiments in making embellished GUI's"
  • "Version 2 of a demo of THEMES for Tk GUI's, using images and colors".

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).


On the basis of the sketch above, I ended up with the GUI seen in the following image.

Note that there are a couple of radiobuttons that allow you to choose whether application of the file-mask is 'case-sensitive' or 'case-INsensitive'. For example, if you chose 'case-INsensitive' and the mask were set to '*.mp3', then files with the suffix '.MP3' would also be selected.

And there are a couple of radiobuttons that allow you to choose whether to do the 'mask-search' at the current directory level only --- or to sweep through all sub-directories of the current 'base' directory, looking for media files that satisfy the criteria chosen via this GUI.

Here is a place where I MAY make a future enhancement: I may change the 'ONE' radiobutton to an 'N-levels' radiobutton --- and if that radiobutton is selected, an entry field will be activated where the user can enter a choice of N (with the entry field being initialized with '1').


Here is another image of the GUI, showing a different setting of most of the radiobuttons --- and entries placed in the file-size and file-age entry fields.

NOTE that most simple media-players --- like 'ffplay' --- are oriented toward playing a single file at a time. And the more complex media-players --- like 'mplayer', 'totem', and 'VLC' --- are oriented toward playing a single large movie file or a lot of smaller media files via a 'playlist'.

This 'find-and-media-player' front-end utility is oriented toward SELECTING media files (based on criteria such as a file-mask, file-size, file-age, and/or file-type) from an ENTIRE HIERARCHY OF SUB-DIRECTORIES --- as well as allowing mask-search in a SINGLE directory.

This utility SORTS the found-files by filename and then starts a loop in which each file is shown by the user-selected media player. When the user closes the media-player window, the next file is started up in the media-player.

So this utility does not have the flexibility of a 'playlist' approach. The user is not given an opportunity to change the order in which the selected files are played. (I will offer that capability when I make a Tk GUI 'front end' for the 'mplayer' command --- which is on my 'to-do' list.)

On the other hand, this utility offers the user the ability to quickly and auto-magically sweep through a directory hierarchy, selecting files by a 'rich' set of criteria, and 'play' the selected movie files (and/or audio files) --- which may be scattered throughout that hierarchy.

By using the file-mask option (and file-age and file-size and file-type options), the user has quite a bit of selection ability. The user can avoid a lot of 'manual' searching for files by letting the 'find' command find the desired files --- in a flash (pun intended).

ALSO, note that this utility can be useful without even using any of the 'player' programs. Say you want to know the NUMBER or NAMES of the media files satisfying a set of criteria (file-mask, file-size, file-age, file-type) --- under a certain directory. Then set the criteria and click on the 'CountFilenames' or 'ShowFilenames' button.

IN FACT, by using the 'ShowFilenames' button you can get a list from which to build a 'playlist' file. The filenames are shown in a popup Tk 'text' widget --- from which you can paste the names into a text-editor window of your choice.


Note also that this utility can be used to 'play' a single file. Just select a full filename and do not change the last part of the filename to a mask. Then click the 'LaunchPlayer' button. (Remember to unset any criteria which the selected file would not satisfy. Note that you can click on the 'CountFilenames' button to see if it returns a value of 1, rather than 0.)


The File-Type search option

The 'file-type' search capability is based on using the 'file' command to return a file-type string --- FOR EACH FILE being processed by the 'find' command.

The 'file' command returns text strings like the following, for MOVIE files:

  Typical file suffix      'file' output (not the video or audio
  ('container' indicator)         format, but the 'container' format)
  ----------------------   -----------------------------------------

  mp4                      ISO Media, MPEG v4 system, version 1
  mpg or mpeg              MPEG sequence, v1, system multiplex
  flv                      Macromedia Flash Video
  mov                      ISO Media, Apple QuickTime movie
  wmv                      Microsoft ASF

  avi (with DivX video)    RIFF (little-endian) data, AVI, 640 x 480, 30.00 fps,
                                        video: DivX 3 Fast-Motion

  avi (with Xvid video)    RIFF (little-endian) data, AVI, 640 x 480, 30.00 fps,
                                        video: XviD

  avi (w. Cinepak video)   RIFF (little-endian) data, AVI, 160 x 120, 10.00 fps,
                                        video: Cinepak, audio: uncompressed PCM (mono, 8000 Hz)

  MPEG = Motion Picture Experts Group
  ASF = Advanced Systems Format
  RIFF = Resource Interchange File Format
  AVI = Audio Video Interleave
  PCM = Pulse Code Modulation

And 'file' returns text strings like the following, for AUDIO files:

  suffix  'file' output
  ------- -----------------------------------------

  mp3     MPEG ADTS, layer III, v1, 128 kbps, 44.1 kHz, Stereo
  wav     RIFF (little-endian) data, WAVE audio, Microsoft PCM, 8 bit, mono 22050 Hz

  ADTS = Audio Data Transport Stream

Although the file-mask and file-size and file-age options can reduce the number of files to which the 'file' command is applied, adding 'file' command processing to files processed by the 'find' command will add a lot of processing to the find-search.

So be aware that specifying 'FileType' on the GUI will often result in much slower response than when leaving that field blank.

But the FileType capability is useful when one is dealing with media files for which the WRONG SUFFIX was supplied --- OR media files that were NOT PROVIDED WITH A SUFFIX.

The following image shows the 'File-Type' entry field being employed.

See the 'ASF' entry at the bottom of the GUI --- and the '*' file-mask being used in the entry field near the top of the GUI.


Below, I provide the Tk script code for this 'multi-subdirectory tkBatchMediaPlayer' utility.

I follow my usual 'canonical' structure for Tk code for this Tk script:

  0) Set general window & widget parms (win-name, win-position,
     win-color-scheme, fonts, widget-geometry-parms, win-size-control,

  1a) Define ALL frames (and sub-frames, if any).
  1b) Pack   ALL frames and sub-frames.

  2) Define & 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 have started doing in 2013 is using 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 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 experimentation: You might want to change the fonts used for the various GUI widgets. For example, you could change '-weight' from 'bold' to 'normal' --- or '-slant' from 'roman' to 'italic'. 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_filemask'         - called by the 'Browse...' button
                           next to the filemask entry field

  'check_for_criterion_change'     - called by the proc

  'findFiles_andCountListOrPlay'   - called by the 'LaunchPlayerJob' button
                                     --- and the 'CountFilenames' and
                                     'ShowFilenames' buttons

  'popup_msgVarWithScroll' - called by 'Help' button to show HELPtext var.
                             Also used via the 'CountFilenames' and
                             'ShowFilenames' buttons.

Like with the 'find-and-imageViewer' Tk GUI utility, 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

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 videos from cameras that Russians seem to commonly have mounted in their cars --- and which, thanks to that, provide us with many videos of irate Russian motorists pounding on other Russian motorists.

Here is a link to CODE for the Tk script 'find_and_mediaPlayer_FrontEnd.tk'.

Shell script #1 (called by the Tk script) :

And here is the code for the first of 2 shell scripts called by this Tk script. This is a wrapper script for the 'find' command.

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 CODE for the SHELL script 'findMediaFiles_forCriteria.sh'.

Shell script #2 (called by the Tk script) :

And here is the code for the shell script that provides the 'for' loop that feeds each media filename to the chosen player program.

You can put this script in the same directory with the Tk script. Shell script #1 includes some code (involving the '$0' variable) to determine the location of the directory containing this shell script (and all 3 scripts) by extracting the name of the directory in which shell-script-1 lies.

Here is a link to CODE for the SHELL script 'forLoop_playListOfMediaFiles.sh'.


This set of 3 scripts could be put in a sub-directory of the user's home directory, such as $HOME/apps/tkBatchMediaPlayer.

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 the user can click on the icon to startup the 'front end'.


This set of 3 scripts adds another utility to my list of 'done-and-to-do' utilities --- in the 'Front Ends' category.

I plan to work on front ends for 'mplayer', 'ffmpeg', and 'find'. But I may return to this set of 3 scripts to provide some enhancements.

maxdepth N

I indicated near the top of this page that I may change the 'ONE' radiobutton to an 'N-levels' radiobutton. If that radiobutton is selected, an entry field will be activated where the user can enter a choice of N (with the entry field being initialized with '1'). This capability would be implemented via the '-maxdepth' parameter of the 'find' command.

There is also a '-mindepth' parameter of the 'find' command. But I have never encountered a situation where I felt I needed to use that parameter.


Probably even more useful than the 'maxdepth' capability would be allowing on the GUI for use of the '-prune' parameter of the 'find' command.

To implement the '-prune' feature would require adding yet another entry widget to the GUI --- to allow for entering one or more sub-directory names (or masks).

As I pointed out on the 'find-and-imageViewer' FrontEnd page, I found a simple example that verifies that the 'find' command can prune using 'masks' as well as complete directory names:

  find . -type d -name '.git*' -prune -o -type f -print


I leave the 'N-levels' and '-prune' enhancement possiblities to a future date. These two features are similar in that they allow the user avoid 'dropping into' a (large) sub-directory of image files which the user does not wish to process.

I will install these 3 scripts in a $HOME/apps/tkBatchMediaPlayer directory, as suggested above in an 'install' section. I will define an icon on my desktop by which I can start up this GUI and keep testing it in coming months.

Then, if I encounter a need for either of those features ('N-levels' or 'prune'), I may implement them and update the code on this page.


There are a lot of parameters available with the 'find' command, but I think I have probably implemented the ones that are most useful to use for this 'multiple-subdirectory media-file-select-and-display' utility.

That said, I will probably find a '-prune' capability to be quite desirable.


As I have said on several other code-donation pages on this wiki ...

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.

UPDATE 2014jan08

In doing some testing for a 'front end' Tk GUI for the 'find' command, I found that the 'find' command does some unexpected 'round off' stuff when processing a '-size' parameter. For example, if one has a size parameter like '-size +1M', this asks for files that are greater than 1 Megabyte in size.

However, as the 'find' command checks each file, it apparently rounds off its size to the nearest Megabyte BEFORE the comparison. Hence any file less than 1.5 Megabytes in size is not included in the strictly-greater-than-1Meg 'found' list. In other words, a 1.4 Meg file is considered to be a 1 Meg file and does not pass the greater-than-1Meg test.

Furthermore, unlike the age test (example: '-mtime +$Ndays') which does a greater-than-or-equal-to test triggered by the plus sign, the 'plus' size test does a greater-than test --- but no equal-to test.

So I have made several changes to the Tk script and the shell script above --- to improve the size-checking:

  • Changed the 'granularity' of the size prompt of the Tk GUI --- from Megabytes to Kilobytes.

  • Changed the '-size +${Nmeg}M' *MEGABYTES* size check in the shell script to a '-size +${Nbytes}c' *CHARACTERS* size check --- by converting the kilobytes (entered by a user) to bytes.

  • Covered the unlikely case of a file being exactly N kilobytes in size when the user enters N in the Kilobytes entry field --- by adding an 'equal to' check to the 'greater than' (plus) check of the size parameter. More precisely, I changed the statement

             -size +${SIZEinBYTES}c
            ( -size +${SIZEinBYTES}c -o -size ${SIZEinBYTES}c ).

Now there should be no 'holes' in the search for files of a 'bigger or smaller' size.

I have replaced the code for the Tk script and the shell script above with the new code with the few lines of changes.

UPDATE 2014apr26

In using this 'tkBatchMediaPlayer' on 'deep' directories --- that is, a 'find' search on about 200-plus subdirectories with 2,000-plus files in those subdirectories --- I found a few improvements that I needed to make in this Tk script and 2 associated shell scripts.

I found the following 'needs'.

1) When I used the 'CountFilenames' and 'ShowFilenames' and 'LaunchPlayerJob' buttons with the same 'find' criteria, the same long 'find' search would have to be repeated --- unnecessarily. I needed to save the 'found-filenames' in an output file, and work off of that list of files when the 'find' criteria had not been changed by the user.

2) On a long 'find' search, a 'progress indicator' was needed to let the user know if the 'find' command was doing its job --- and to let the user know how far/fast the search was proceeding. Similarly, a 'progress indicator' was needed to let the user know which 'found-media-file' was being shown when hundreds of media files were being played.

To handle these needs, I made the following changes to the 3 scripts.

*** In the Tk script, set the filename of a temporary file to be used to hold the names of image files found by the 'find' search --- in variable 'outFILE'.

*** In the Tk script, added 'PREV' variables to be used to hold about 8 previous 'find' search criteria --- to be used to indicate when the user has changed a 'find' criterion.

*** In the Tk script, added a proc called 'check_for_criterion_change' --- to determine if a criterion variable has been changed by the user.

*** In the Tk script, replaced the 'getFiles_andCountListOrPlay.sh' shell script --- that had 'count', 'print', and 'play' sections --- by a 'findMediaFiles_forCriteria.sh' shell script that performs just the 'find' search and puts the found-files in a temporary '$outFILE' file --- only if one of the 'find' search criteria was changed by the user.

*** Made the 'findMediaFiles_forCriteria.sh' shell script from the 'getFiles_andCountListOrPlay.sh' shell script. Changed the arguments passed to the shell script to be just the 'find' search criteria variables --- not the media-player variables.

*** In the Tk script, provided an 'xterm' window to the 'exec' statement for the 'findMediaFiles_forCriteria.sh' shell script, to allow for better visibility of how a lengthy 'find' is progressing. The 'find' command in the 'findMediaFiles_forCriteria.sh' shell script was changed to show directories being searched, as well as files being found, in order to provide a better 'progress indicator'.

*** In the 'forLoop_playListOfMediaFiles.sh' script, added 'CNT' and 'TOTALfiles' variables and an 'echo' statement --- so that the 'xterm' window that is used to 'exec' this script in the Tk script will display to the user a count of how many of the 'found-media-files' have been played so far.

I have made these changes and replaced the Tk script and the 2 shell scripts above. (Now I am feeling like this is a quite robust utility.)

Bottom of the page for Batch-Find-and-Play Media Files (movies/audio) --- a utility in the FE 'tkGooies' system, in the 'VIDEOtools' (and 'AUDIOtools') 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. >
< Go to FE 'tkGooies' 'VIDEOtools' Page >
< Go to FE 'tkGooies' Description page >
< Go to FE Home page. >

The code was created in 2013 --- and posted 2013 Dec 15 at

This FE web page was created 2014 May 13 ---
as a backup and alternative to the wiki.tcl.tk page.
Page was changed slightly 2015 Oct 05.