FE 'tkGooies' Utilities

'VIDEOtools' group

A Tcl-Tk GUI for
WEBCAM Video-And-Audio
MOVIE-CAPTURE

(an 'ffmpeg' Front End)

(FE = Freedom Environment)

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'VIDEOtools' Page >

This
tkWebcamVideoAudioCapture
('ffmpeg' frontend) tkGooie Page

INTRODUCTION to the
'tkMovieCapture_WEBCAM_ VideoAndAudio_ ffmpegFrontEnd' tkGooie

In May 2014, at wiki.tcl.tk, I published a 'front end' GUI utility for recording a movie from a computer monitor and the audio system of the computer.

In addition to being made available at the Tclers' Wiki at wiki.tcl.tk, that code is available on this site at a

'tkMovieCapture_ ComputerMonitorAndAudio_ ffmpegFrontEnd' page.

I could have tried to make that utility also serve to record video from a webcam (in place of a computer monitor).

BUT there are enough differences in video specifications (input device, input format, ...) and in the help text for webcam recording versus computer monitor recording that it seemed better to make a separate utility for webcam recording.

Keeping the two separate will also allow for more simplicity (less confusion) if enhancements are added in the future --- for example, in the area of input device 'discovery'.

So a webcam-and-audio recording utility is the subject of this page.


THE GOALS

My goals for the Tcl-Tk script for this GUI were:

  • Provide 'entry' and other widgets for the approximately 14 parameters that can be specified to 'ffmpeg' in creating a movie file from a webcam.

    Also provide working defaults for the 'ffmpeg' parameters.

  • Provide an 'entry' widget for an output movie filename, with a default name provided.

  • Provide an 'entry' widget to allow the user to specify a movie player program with which to view a completed movie file.

  • Provide a 'Launch' button to start the movie capture.

  • Provide an 'entry' widget to allow the user to specify a 'delay time' before 'ffmpeg' is started up --- so that the user has time to do some preparation ...

    such as looking up from starting the recording via the computer monitor, to look at the webcam and smile, before 'ffmpeg' recording is started.

  • Provide a 'Play' button to initiate playing of the completed movie file.

  • To avoid overwhelming the user with the number of recording parameters available for a given, user-selected container format . . .

    provide a 'checkbutton' on the GUI to show the 'ffmpeg' video-audio-other parameters only if the user requests to see them --- or wants to change them.


THE GUI LAYOUT

Like for the 'movie-capture-from-computer-monitor-and-audio' utility that I posted here, I made a 'text-sketch' for the GUI for this 'webcam-movie-capture' 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.


   Frame
   names      --------------------------------------------------------------------------------------
     |        Webcam-and-Audio Movie-Capture - a front-end for the 'ffmpeg' command
     V        [window title]
              --------------------------------------------------------------------------------------
 .fRbuttons   {Exit} {Help} {LaunchMovieCapture} {PlayMovie}  X ShowDetailedInputParms (video,audio,other) Delay time (secs): 8__ 

 .fRmsg       'Delay time' allows some setup time before the 'ffmpeg'-window pops up and ffmpeg starts
              capturing the video. For example: It allows time to face the webcam and smile.
              [This initial message in a label widget may be changed when the 'Launch' button is clicked.]

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

 .fRfile      Output movie filename : /tmp/${USER}_webcam_capture_movie.mkv______________  {Browse...}

 .fRplayer    Player for the movie file: totem________ Examples: totem  gmplayer  mplayer  ffplay  vlc

 [The following frames are shown if the 'ShowDetailedInputParms' checkbuttons is set ON.]

              --------------------------------------------------------------------------------------
 .fRvideohead Video parameters:
              --------------------------------------------------------------------------------------

 .fRvidsize   Video size: 1024x768____ Examples: 640x480 , 800x600 , 1024x768

 .fRvformat   Video-in format: video4linux2_- Examples: video4linux2 ('v4l2')   video4linux ('v4l')

 .fRvsource   Video Source: /dev/video0___ Examples: /dev/video0  /dev/video1    Video rate (frames/sec): 25_

 .fRvcodec    Video codec: libx264_____ Examples: libx264  mpeg4  mpeg1video  flv  ...

 .fRvother    Other video parms: -vpre /usr/share/ffmpeg/libx264-lossless_ultrafast.ffpreset_______

              -------------------------------------------------------------------------------------
 .fRaudiohead Audio parameters:
              -------------------------------------------------------------------------------------

 .fRaformat    Audio format: alsa____   Examples: alsa  oss        Audio Channels: 1_ Examples: 1  2

 .fRainterface Audio interface: pulse____   Examples: pulse  hw:0,0  /dev/dsp     

 .fRacodec     Audio codec: pcm_s16le__ Examples: pcm_s16le  libmp3lame  libfaac  vorbis

 .fRaother     Other audio parms: -ar 22050 -ab 96k_________________________________________________

              --------------------------------------------------------------------------------------
 .fRother     Other 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 recording. Stop the
              recording by re-opening the 'xterm' window and typing 'q'. The terminal does not close after
              'ffmpeg' stops, so that you can examine msgs. THEN CLOSE the terminal window. 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

  • 4 'button' widgets
  • 24 'label' widgets (many are for entry fields)
  • 13 'entry' widgets
  • 1 'checkbutton' widget
  • 6 'radiobutton' widgets
  • 0 'scale' widgets
  • 0 'canvas' widgets
  • 0 'listbox' widgets
  • 0 'text' widgets

All but the 'label' widgets provide operating parameters/options in this utility.

Hence there are about 4 + 13 + 1 + 6 = 24 user-specifiable options via the GUI of this utility.


Beautification of the GUI

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 starting a recording session with 'ffmpeg' as simple as a click on a 'Launch' button.

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 the image
in a separate browser window or tab.

The operation can be as simple as clicking on the 'LaunchMovieCapture' button --- and then clicking on the 'PlayMovie' button, after the movie file has been created --- if you take the initial defaults.

Note that there are several radiobuttons that allow you to choose the 'container format' of the output file.

But you can simply take the default container format.

    (You can change the default by changing a 'set CONTAINERformat' statement at the bottom of the Tk script.)


If the user wants to change (or simply check) the video and audio and 'other' parameters that are set according to a choice of the 'container format', the user can click on the 'ShowDetailedInputParms' 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 the image
in a separate browser window or tab.

THE CONTAINER FORMATS

I have 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 movie file capture.

So I have created   '.mkv'   '.mp4'   '.mpg'   '.flv'   and   '.avi' files.

I have grayed out the WEBM radiobutton.

That radiobutton is intended to eventually allow for creating a movie in the 'webm' format that Google is promoting.

The 'webm' format 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 do 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 make it easy to implement and activate that option.


DESCRIPTION OF THE CODE

Below, I provide the Tk script code for this 'movie-capture-from-computer-webcam' 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 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 experimentation with the GUI:

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 :



  'set_defaults_for_container' - called by bindings on the CONTAINER
                                 radiobuttons.

                                 Sets defaults for the GUI widgets for a given
                                 container type.

  'capture_movie'              - called by the 'LaunchMovieCapture' button.

                                 Launches the 'ffmpeg' program --- with user-selected
                                 recording parameters. Calls an external shell script
                                 whose code is provided below.

  'play_movie'                 - called by the 'PlayMovie' button.

                                 Launches a user-selected movie 'player' program.

  'pack_detail_frames'         - called by button1-release binding on the
                                 ShowDetailedInputParms checkbutton.

  'popup_msgVarWithScroll'     - called by 'Help' button to show HELPtext var.


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


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 'Pets Gone Wild' videos.


Tcl-Tk CODE for the 'ffmpeg' Front End GUI

Here is a link to the code for the Tk script:

'webcamAndAudio_MovieCapture_ ffmpeg_ FrontEnd.tk'


Shell script (called by the Tk script) :

And here is a link to the code for the shell script called by this Tk script:

'ffmpeg_webcamAndAudio_ MovieCapture.sh'

Having the 'ffmpeg' call in a shell script instead of embedded in the Tk script facilitates testing and debugging.

For example, this script can be tested independently of the Tk script.

    In fact, this shell script could be modified to serve as a 'hard-coded' (non-GUI, command line) means of recording webcam sessions.

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.


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/tkMovieCaptureFromWebCam

Then the user can use their desktop system (such as Gnome or MATE or KDE) to set up the Tk script as an icon on the desktop.

Then, whenever the user wants to record a webcam session, the user can click on the icon to startup this 'front end' to the 'ffmpeg' command.


LINK TO A MOVIE CAPTURE EXAMPLE

Here is a link to a movie capture (made from a webcam) that I did with this GUI.

It is a capture of a 640x480 resolution webcam into an 800x600 movie.

This movie file is actually an edited version of the original movie capture.

I captured the original in a Matroska container format with the video recorded in H.264 format and the audio in PCM format.

I used a shell script (in the 'feNautilusScripts' system, 'VIDEOtools' group) that uses 'ffmpeg' to clip an input movie file --- to clip off the beginning and end of the original movie capture --- leaving a movie just 7 seconds long.

The shell script put the movie out in a different (more compact) format --- an 'mp4' container format with the video in H.264 format and the audio in AAC format.


SOME POSSIBLE ENHANCEMENTS

I have no major enhancements that I can think of for the Tk script at this time.

However, in the future, I may find that I may want/need to change some default video or audio or 'other' parameters for some of the container formats.

And I may find that it is worthwhile implementing the WEBM format.

    There has been a report that a user recorded a webcam video, with this utility, when the user was in the webcam field of view.

    His lips were not synced to the audio, reportedly.

    There are probably a couple of parameters that can be added to the 'ffmpeg' command to cause the audio to sync with the video --- at least for certain container-video-audio file formats.

    The audio-sync may be OK for certain container-video-audio format combinations, without adding any parameters to 'ffmpeg'.

    I may look into that someday --- especially if I use this utility to record from a webcam while I am talking in the field of view, and I confirm the audio-sync issue.

    But for now, I have a plethora of Tcl-Tk projects to work on --- such as . . .

I plan 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.


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
Webcam Video-And-Audio
Movie-Capture

--- 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 02 at http://wiki.tcl.tk/40194.

This FE web page was created 2015 Jan 13.
(as a backup and alternative to the wiki.tcl.tk page)

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 25.
(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.