YAD and Zenity – Input Start/Stop Times to Trim Video

I have a bash script and a php script that function in concert to trim audio/video files using start/stop times.

PHP script:

<?php
// Create datetime objcects
$dt1 = new DateTime($argv[1]);
$dt2 = new DateTime($argv[2]);

// Conver difference to seconds
$dt3 = $dt2->format('U') - $dt1->format('U');

// echo $dt3."n";
$h = (int)($dt3 / 3600);
$dt3 %= 3600;
$m = (int)($dt3 / 60);
$dt3 %= 60;
$s = $dt3;

// Dump as H:M:S
echo $h . ":" . $m . ":" . $s;

?>

chopvideoaudio.sh script:

#!/bin/bash
INFILE=$1
START=$2
STOP=$3
OUTFILE=$4

OFFSET=`php TimeDiff.php "$START" "$STOP"`

echo "Disecting $INFILE starting from $START to $STOP (duration $OFFSET)"
ffmpeg -ss "$START" -t "$OFFSET" -i "$INFILE" "$OUTFILE"

Usage:

./chopvideoaudio.sh [input.mp4] [startchop] [stopchop] [output.mp4]

Where [startchop] and [stopchop] are both absolute timestamps from the beginning of the track.

Example command to run this script:

./chopvideoaudio.sh input.mp4 00:01:20 00:01:45 output.mp4

I want a YAD (yet another dialog) script that will open up a dialog box(es) containing an input field to enter a custom file type (e.g. mp3, mp4, avi). Then input fields for the two timestamps, in which I can enter two custom timestamps. After pressing OK the script will run and extract the section from between the two timestamps.

I would also be interested in a solution using Zenity, but I prefer YAD.

Asked By: whitewings

||

You can Use Zenity as follows:-

  1. For File-selection:

    file=$(zenity --file-selection --file-filter='*.mp4 *.mp3 *.avi')
    

    or

    file=$(zenity --file-selection --title="Select Input File" --file-filter='*.mp4' --file-filter='*.mp3' --file-filter=*.avi)
    
  2. For Text-Entry:

    startchop=$(zenity --entry --text=startchop)
    stopchop=$(zenity --entry --text=stopchop)
    

    or Zenity-Forms:-

    zenity --forms --text="Time-stamps" --add-entry=startchop --add-entry=stopchop
    

Now: echo $file $startchop $stopchop gives you output like: input.mp4 00:01:20 00:01:45

i.e you can use variables $file, $startchop and $stopchop. Customize the command as you wish!


EDIT:-

Suggested chopvideoaudio.sh script:

#!/bin/bash
INFILE=$(zenity --title="Select Input File" --file-selection --file-filter='*.mp4' --file-filter='*.mp3' --file-filter=*.avi)
$TIMESTAMPS=$(zenity --forms --text="Time-stamps" --add-entry=startchop --add-entry=stopchop)
START=$(echo $TIMESTAMPS | cut -d '|' -f 1)
STOP=$(echo $TIMESTAMPS | cut -d '|' -f 2)
OUTFILENAME=$(zenity --entry --text=filename)
OUTFILETYPE=$(zenity --list --titile="Select File Type" --text="file types selection" --column="Select" --column="File Type" --radiolist false avi true mp4 false mp3)
OUTFILE="$OUTFILENAME".$OUTFILETYPE

OFFSET=`php TimeDiff.php "$START" "$STOP"`

echo "Disecting $INFILE starting from $START to $STOP (duration $OFFSET)"
ffmpeg -ss "$START" -t "$OFFSET" -i "$INFILE" "$OUTFILE"

Usage: only run ./chopvideoaudio.sh

Explanation:-

  • INFILE=$(zenity --title="Select Input File" --file-selection --file-filter='*.mp4' --file-filter='*.mp3' --file-filter=*.avi) will display GUI File selection window by Zenity:

    screen0

  • $TIMESTAMPS=$(zenity --forms --text="Time-stamps" --add-entry=startchop --add-entry=stopchop) will display GUI Tex entry box in which you have to enter timestamps:

    timestamps

    And from above $START and $STOP get both values respectively.

  • OUTFILE="$OUTFILENAME".$OUTFILETYPE is the combination of (A text entry for output file-name) OUTFILENAME=$(zenity --entry --text=filename)

    And The GUI file-type selection dialogue by OUTFILETYPE=$(zenity --list --title="Select File Type" --text="file type selection" --column="Select" --column="File Type" --radiolist false avi true mp4 false mp3):

    file-type-selection

Hence By means of this example:-

  • $INFILE returns selected file for input (e.g input.mp4)
  • $START & $STOP returns 00:01:20 and 00:01:45 respectively.
  • $OUTFILE returns output file-name with file-type (e.g output.mp4)
Answered By: Pandya

Here is a solution using yad, bash only (no php), with one dialog:

#!/bin/bash
 
eval $(yad --width=400 --form --field=input:FL --field=start --field=end --field=output:SFL "" "00:00:00" "00:00:00" "" | awk -F'|' '{printf "INPUT="%s"nSTART=%snEND=%snOUTPUT="%s"n", $1, $2, $3, $4}')
[[ -z $INPUT || -z $START || -z $END || -z $OUTPUT ]] && exit 1

DIFF=$(($(date +%s --date="$END")-$(date +%s --date="$START")))
OFFSET=""$(($DIFF / 3600)):$(($DIFF / 60 % 60)):$(($DIFF % 60))
 
ffmpeg -ss "$START" -t "$OFFSET" -i "$INPUT" "$OUTPUT"

Here is a screenshot of what it will look like. Please note that the text of the buttons will be automatically adapted to your choosen language. I’m French speaker obviously!

![screenshots of the dialog

The drawback of this one dialog only is that with yad, you cannot pre-select file extension for file input. If this is mandatory, here is two steps/dialogs solution:

#!/bin/bash
 
INPUT=$(yad --width=600 --height=400 --file-selection --file-filter='*.mp3 *.mp4 *.avi')

eval $(yad --width=400 --form --field=start --field=end --field=output:SFL "00:00:00" "00:00:00" "${INPUT/%.*}-out.${INPUT##*.}" | awk -F'|' '{printf "START=%snEND=%snOUTPUT="%s"n", $1, $2, $3}')
[[ -z $START || -z $END || -z $OUTPUT ]] && exit 1

DIFF=$(($(date +%s --date="$END")-$(date +%s --date="$START")))
OFFSET=""$(($DIFF / 3600)):$(($DIFF / 60 % 60)):$(($DIFF % 60))
 
ffmpeg -ss "$START" -t "$OFFSET" -i "$INPUT" "$OUTPUT"

That shows a file picker and then a timestamp window like this:

screenshots of the dialog

Answered By: thdox