1

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.

4
  • You want to enter two timestamps and then extract 25 seconds of AV. If you were to enter 00:00 and 10:00 (i.e. a 10 minute interval) how should we identify which 25 seconds of that 10 minutes to extract? – roaima Feb 21 '15 at 22:25
  • @roaima Not sure I understand your question. If I was to enter 00:00:00 in the first timestamp field and in the second timestamp field enter 00:10:00, then 10 minutes would be extracted from the audio or video starting at the beginning of the audio or video file. – whitewings Feb 21 '15 at 22:38
  • that's what I would have expected but you mentioned 25 seconds in your question, seemingly out of nowhere. Ah I see - it refers to your example command line. – roaima Feb 22 '15 at 8:26
  • @user8547 Have you found any solution? – Pandya Feb 26 '15 at 9:30
5
+100

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=%s\nEND=%s\nOUTPUT=\"%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!

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=%s\nEND=%s\nOUTPUT=\"%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"
4
  • Tx! One thing that could improve this is if the script was modified so that the 00:00:00's appear in the timestamp dialog boxes by default. That way I would only have to type in some of the numbers. But it's no big deal either way. – whitewings Feb 26 '15 at 13:31
  • 2
    @user8547, I've edited my answer to pre-fill with "00:00:00" for start/end field, and pre-fill with output filename as basenamee-out.ext. – thdox Feb 27 '15 at 17:04
  • The second script is so nice! More extensions can be added to the line that starts with INPUT= in order to access more file-types, for example *.m4a *.ogg *.flac *.aac – cipricus Feb 11 '20 at 15:45
  • I use the last script with videos too, but for that the last line should be then changed to ffmpeg -ss "$START" -t "$OFFSET" -i "$INPUT" -c copy -map 0 "$OUTPUT". (Otherwise it is re-encoding the video instead of just copying it, taking time and memory, and giving a smaller size and 1/2 reduced bitrate.) – cipricus Feb 8 at 10:46
2

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)
5
  • Could you give me the full code based on the code in my original post? I'm not familiar enough with Zenity to take what you've given me and make it work. – whitewings Feb 22 '15 at 18:21
  • @user8547 Do you want to select file (browse via GUI window) input.mp4 and output.mp4 and what do you mean by entering custom file type? Caan you Explain Input & Output File (and it's type) procedure? – Pandya Feb 24 '15 at 11:55
  • I've added suggested script in my post. – Pandya Feb 24 '15 at 12:13
  • Tx Pandya, but I went with thdox's answer instead, as I prefer his two-step dialog solution without the need for the php script. – whitewings Feb 26 '15 at 13:29
  • 1
    OK, No problem. BTW that is simple calculation for time difference like this. – Pandya Feb 26 '15 at 13:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.